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 abd5100711 If the original CRS used the [0 … 360]° longitude range,
convert to the [−180 … +180]° range.
abd5100711 is described below
commit abd5100711f4c7d111117db883c3f9ee415dc1e9
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Fri Feb 28 15:16:14 2025 +0100
If the original CRS used the [0 … 360]° longitude range, convert to the
[−180 … +180]° range.
---
.../sis/storage/geotiff/writer/GeoEncoder.java | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
index 7bdd7ef79d..c6ade06582 100644
---
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
+++
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
@@ -38,6 +38,7 @@ import org.opengis.referencing.crs.VerticalCRS;
import org.opengis.referencing.crs.EngineeringCRS;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.cs.CartesianCS;
import org.opengis.referencing.cs.EllipsoidalCS;
import org.opengis.referencing.cs.VerticalCS;
@@ -79,6 +80,7 @@ import org.apache.sis.storage.geotiff.base.Resources;
import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.math.MathFunctions;
+import org.apache.sis.measure.Longitude;
import org.apache.sis.pending.jdk.JDK15;
@@ -135,6 +137,12 @@ public final class GeoEncoder {
*/
private AxisDirection[] axisDirections;
+ /**
+ * The longitude axis if the <abbr>CRS</abbr> is geodetic,
+ * or {@code null} if the <abbr>CRS</abbr> is projected or unknown.
+ */
+ private CoordinateSystemAxis longitudeAxis;
+
/**
* The conversion from grid coordinates to full CRS, which determines the
model transformation.
* This conversion may operate on more dimensions than the three
dimensions mandated by GeoTIFF.
@@ -412,6 +420,7 @@ public final class GeoEncoder {
{
final short type;
final CoordinateSystem cs = crs.getCoordinateSystem();
+ longitudeAxis = cs.getAxis(AxisDirections.indexOfColinear(cs,
AxisDirection.EAST));
addUnits(UnitKey.ANGULAR, cs);
if (cs instanceof EllipsoidalCS) {
type = GeoCodes.ModelTypeGeographic;
@@ -873,6 +882,24 @@ public final class GeoEncoder {
gridToCRS = Matrices.createTransform(axisDirections,
target).multiply(gridToCRS);
axisDirections = null; // For avoiding to do the
multiplication again.
}
+ /*
+ * If the first axis is a longitude axis, ensure that the longitude is
in the [−180 … +180]° range.
+ * We need this shift because the source CRS may be using the [0 …
360]° range (for example, when
+ * the data come from a netCDF file), but CRS in GeoTIFF are
implicitly in [−180 … +180]°.
+ */
+ if (longitudeAxis != null) try {
+ final double max =
Units.DEGREE.getConverterToAny(longitudeAxis.getUnit()).convert(Longitude.MAX_VALUE);
+ if (Math.abs(longitudeAxis.getMaximumValue() - max) > max /
Longitude.MAX_VALUE) { // Arbitrary tolerance.
+ final int translationColumn = gridToCRS.getNumCol() - 1;
+ double translation = gridToCRS.getElement(0,
translationColumn);
+ translation = Math.IEEEremainder(translation, 2*max);
+ if (translation == max) translation = -translation;
+ gridToCRS.setElement(0, translationColumn, translation);
+ }
+ } catch (IncommensurableException e) {
+ // Should never happen. If happen anyway, we will simply not shift
the longitude coordinate.
+ listeners.warning(e);
+ }
/*
* Copy matrix coefficients. This matrix size is always 4×4, no matter
the size of the `gridToCRS` matrix.
* So we cannot invoke `MatrixSIS.getElements()`.