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 <martin.desruisse...@geomatys.com>
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()`.

Reply via email to