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 <[email protected]>
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 {