This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 90a499a32d Resolve a "unspecified CRS" exception when reading a 
GeoTIFF with a three-dimensional CRS (a geographic or projected CRS + a 
vertical CRS on user-defined datum).
90a499a32d is described below

commit 90a499a32df159685838d09b6a4314d93697d0c4
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Dec 4 17:07:54 2024 +0100

    Resolve a "unspecified CRS" exception when reading a GeoTIFF with a 
three-dimensional CRS
    (a geographic or projected CRS + a vertical CRS on user-defined datum).
---
 .../sis/buildtools/coding/ReorganizeImports.java       |  2 +-
 .../main/org/apache/sis/referencing/CommonCRS.java     |  5 ++---
 .../apache/sis/storage/geotiff/reader/CRSBuilder.java  | 18 ++++++++++++++----
 .../storage/geotiff/reader/GridGeometryBuilder.java    |  6 +++---
 .../org/apache/sis/storage/base/TiledGridCoverage.java |  6 +++---
 5 files changed, 23 insertions(+), 14 deletions(-)

diff --git 
a/buildSrc/src/main/java/org/apache/sis/buildtools/coding/ReorganizeImports.java
 
b/buildSrc/src/main/java/org/apache/sis/buildtools/coding/ReorganizeImports.java
index ed067a7c6a..7840b294c6 100644
--- 
a/buildSrc/src/main/java/org/apache/sis/buildtools/coding/ReorganizeImports.java
+++ 
b/buildSrc/src/main/java/org/apache/sis/buildtools/coding/ReorganizeImports.java
@@ -77,7 +77,7 @@ import java.util.Set;
  *   gradle test
  *   git diff
  *   git add --update
- *   git commit --message "Merge of automatic reorganization of imports order."
+ *   git merge --continue --message "Merge of automatic reorganization of 
imports order."
  *   }
  *
  * Finally apply the same pattern on the {@code main} branch.
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 33edfaf6e3..af71e2350d 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@ -1284,11 +1284,10 @@ public enum CommonCRS {
 
         /**
          * Height measured above other kind of surface, for example a 
geological feature.
+         * The datum name is "Other surface". The coordinate system name is 
"Height".
          * The unit of measurement is metres.
-         *
-         * @deprecated More specific vertical datum should be used.
+         * This enumeration value is also used when the surface is unspecified.
          */
-        @Deprecated(since = "1.5", forRemoval = true)
         OTHER_SURFACE(false, Vocabulary.Keys.Height, 
Vocabulary.Keys.OtherSurface);
 
         /**
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
index 90c4fb1e7d..f3406fcb75 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
@@ -551,7 +551,7 @@ public final class CRSBuilder extends 
ReferencingFactoryContainer {
             case GeoCodes.ModelTypeGeographic: crs = createGeographicCRS(); 
break;
             default: warning(Resources.Keys.UnsupportedCoordinateSystemKind_1, 
crsType); break;
         }
-        if (crsType != GeoCodes.ModelTypeGeocentric) {
+        if (crsType != GeoCodes.ModelTypeGeocentric) try {
             final VerticalCRS vertical = createVerticalCRS();
             if (vertical != null) {
                 if (crs == null) {
@@ -560,6 +560,14 @@ public final class CRSBuilder extends 
ReferencingFactoryContainer {
                     crs = 
getCRSFactory().createCompoundCRS(Map.of(IdentifiedObject.NAME_KEY, 
crs.getName()), crs, vertical);
                 }
             }
+        } catch (Exception e) {
+            if (crs == null) {
+                throw e;
+            }
+            // A vertical CRS is not strictly needed with GeoTIFF if we have 
the horizontal component.
+            if (!alreadyReported) {
+                listeners.warning(e);
+            }
         }
         /*
          * At this point we finished parsing all GeoTIFF tags, both for 
metadata purpose or for CRS construction.
@@ -1538,11 +1546,13 @@ public final class CRSBuilder extends 
ReferencingFactoryContainer {
     private VerticalDatum createVerticalDatum() throws FactoryException {
         final int epsg = getAsInteger(GeoKeys.VerticalDatum);
         switch (epsg) {
-            case GeoCodes.undefined:
-            case GeoCodes.userDefined: {
+            case GeoCodes.undefined: {
                 alreadyReported = true;
                 throw new 
NoSuchElementException(missingValue(GeoKeys.VerticalDatum));
             }
+            case GeoCodes.userDefined: {
+                return CommonCRS.Vertical.OTHER_SURFACE.datum();
+            }
             default: {
                 return 
getDatumAuthorityFactory().createVerticalDatum(String.valueOf(epsg));
             }
@@ -1578,7 +1588,7 @@ public final class CRSBuilder extends 
ReferencingFactoryContainer {
                 final String name = getAsString(GeoKeys.VerticalCitation);
                 final VerticalDatum datum = createVerticalDatum();
                 final Unit<Length> unit = createLinearUnit(UnitKey.VERTICAL);
-                VerticalCS cs = 
CommonCRS.Vertical.MEAN_SEA_LEVEL.crs().getCoordinateSystem();
+                VerticalCS cs = 
CommonCRS.Vertical.OTHER_SURFACE.crs().getCoordinateSystem();
                 if (!Units.METRE.equals(unit)) {
                     cs = (VerticalCS) CoordinateSystems.replaceLinearUnit(cs, 
unit);
                 }
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/GridGeometryBuilder.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/GridGeometryBuilder.java
index bce928db1c..e8713e69d7 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/GridGeometryBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/GridGeometryBuilder.java
@@ -283,15 +283,15 @@ public final class GridGeometryBuilder extends 
GeoKeysLoader {
          * may need to be reduced.
          */
         int n = (crs != null) ? crs.getCoordinateSystem().getDimension() : 2;
-        final DimensionNameType[] axisTypes = new DimensionNameType[n];
-        final long[] high = new long[n];
+        final var axisTypes = new DimensionNameType[n];
+        final var high = new long[n];
         switch (n) {
             default: axisTypes[2] = DimensionNameType.VERTICAL; // Fallthrough 
everywhere.
             case 2:  axisTypes[1] = DimensionNameType.ROW;      high[1] = 
height - 1;
             case 1:  axisTypes[0] = DimensionNameType.COLUMN;   high[0] = 
width  - 1;
             case 0:  break;
         }
-        final GridExtent extent = new GridExtent(axisTypes, null, high, true);
+        final var extent = new GridExtent(axisTypes, null, high, true);
         boolean pixelIsPoint = (cellGeometry == CellGeometry.POINT);
         final MathTransformFactory factory = 
DefaultMathTransformFactory.provider();
         GridGeometry gridGeometry;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
index d654e224a6..1094a457d5 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
@@ -240,8 +240,8 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
     protected TiledGridCoverage(final TiledGridResource.Subset subset) {
         super(subset.domain, subset.ranges);
         final GridExtent extent = subset.domain.getExtent();
-        final int dimension = subset.sourceExtent.getDimension();
-        deferredTileReading = subset.deferredTileReading();
+        final int dimension = subset.virtualTileSize.length;
+        deferredTileReading = subset.deferredTileReading();     // May be 
shorter than other arrays of grid geometry.
         readExtent          = subset.readExtent;
         subsampling         = subset.subsampling;
         subsamplingOffsets  = subset.subsamplingOffsets;
@@ -449,7 +449,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
     @Override
     public RenderedImage render(GridExtent sliceExtent) {
         final GridExtent available = gridGeometry.getExtent();
-        final int dimension = available.getDimension();
+        final int dimension = virtualTileSize.length;       // May be shorter 
than grid geometry dimension.
         if (sliceExtent == null) {
             sliceExtent = available;
         } else {

Reply via email to