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 {