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

commit 6718873520c61007fdd8c42ad12f5d22f8f88746
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sat Dec 21 11:55:29 2024 +0100

    Add the netCDF attribute names of Mercator data (from Copernicus) as an 
alternative convention when CF attributes were not found.
    Those alternatives are ignored when CF attributes are found.
---
 .../apache/sis/storage/netcdf/AttributeNames.java  | 30 ++++++++++++++++++++++
 .../apache/sis/storage/netcdf/MetadataReader.java  | 27 +++++++++++--------
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/AttributeNames.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/AttributeNames.java
index 31d6985531..c8289cd34f 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/AttributeNames.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/AttributeNames.java
@@ -1034,6 +1034,16 @@ public class AttributeNames {
     public static final Dimension LATITUDE = new 
Dimension(DimensionNameType.ROW,
             ACDD.LAT_MIN, ACDD.LAT_MAX, null, ACDD.LAT_RESOLUTION, 
ACDD.LAT_UNITS, null);
 
+    /**
+     * The standard attribute names for latitudes, followed by alternatives 
that are sometime observed.
+     * The alternatives are tried only if no latitude or longitude 
<abbr>CR</abbr> attributes was found.
+     * Examples of sources of alternatives: Mercator data from Copernicus.
+     */
+    static final Dimension[] LATITUDE_ALTERNATIVES = {
+        LATITUDE,
+        new Dimension(DimensionNameType.ROW, "latitude_min", "latitude_max", 
null, null, null, null)
+    };
+
     /**
      * The set of attribute names for the minimal and maximal longitudes of 
the bounding box,
      * resolution and units. Longitudes are assumed to be in decimal degrees 
east, unless a
@@ -1058,6 +1068,16 @@ public class AttributeNames {
     public static final Dimension LONGITUDE = new 
Dimension(DimensionNameType.COLUMN,
             ACDD.LON_MIN, ACDD.LON_MAX, null, ACDD.LON_RESOLUTION, 
ACDD.LON_UNITS, null);
 
+    /**
+     * The standard attribute names for longitudes, followed by alternatives 
that are sometime observed.
+     * The alternatives are tried only if no latitude or longitude 
<abbr>CR</abbr> attributes was found.
+     * Examples of sources of alternatives: Mercator data from Copernicus.
+     */
+    static final Dimension[] LONGITUDE_ALTERNATIVES = {
+        LONGITUDE,
+        new Dimension(DimensionNameType.COLUMN, "longitude_min", 
"longitude_max", null, null, null, null)
+    };
+
     /**
      * The set of attribute names for the minimal and maximal elevations of 
the bounding box,
      * resolution and units. Elevations are assumed to be in metres above the 
ground, unless a
@@ -1082,6 +1102,16 @@ public class AttributeNames {
     public static final Dimension VERTICAL = new 
Dimension(DimensionNameType.VERTICAL,
             ACDD.VERT_MIN, ACDD.VERT_MAX, null, ACDD.VERT_RESOLUTION, 
ACDD.VERT_UNITS, ACDD.VERT_IS_POSITIVE);
 
+    /**
+     * The standard attribute names for heights, followed by alternatives that 
are sometime observed.
+     * The alternatives are tried only if no latitude, longitude or heights 
<abbr>CR</abbr> attributes was found.
+     * Examples of sources of alternatives: Mercator data from Copernicus.
+     */
+    static final Dimension[] VERTICAL_ALTERNATIVES = {
+        VERTICAL,
+        new Dimension(DimensionNameType.VERTICAL, "z_min", "z_max", null, 
null, null, null)
+    };
+
     /**
      * The set of attribute names for the start and end times of the bounding 
box, resolution and
      * units.
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
index 890cf53904..ec5dcd4b19 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -753,18 +753,25 @@ split:  while ((start = 
CharSequences.skipLeadingWhitespaces(value, start, lengt
          * If at least one geographic coordinate is available, add a 
GeographicBoundingBox.
          */
         boolean hasExtent;
-        hasExtent  = fillExtent(LONGITUDE, Units.DEGREE, AxisDirection.EAST,  
extent, 0);
-        hasExtent |= fillExtent(LATITUDE,  Units.DEGREE, AxisDirection.NORTH, 
extent, 2);
-        if (hasExtent) {
-            addExtent(extent, 0);
-            hasExtent = true;
-        }
+        int convention = 0;
+        do {
+            hasExtent  = fillExtent(LONGITUDE_ALTERNATIVES[convention], 
Units.DEGREE, AxisDirection.EAST,  extent, 0);
+            hasExtent |= fillExtent( LATITUDE_ALTERNATIVES[convention], 
Units.DEGREE, AxisDirection.NORTH, extent, 2);
+            if (hasExtent) {
+                addExtent(extent, 0);
+                hasExtent = true;
+                break;
+            }
+        } while (++convention < LONGITUDE_ALTERNATIVES.length);
         /*
          * If at least one vertical coordinate is available, add a 
VerticalExtent.
          */
-        if (fillExtent(VERTICAL, Units.METRE, null, extent, 0)) {
-            addVerticalExtent(extent[0], extent[1], verticalCRS);
-            hasExtent = true;
+        for (int i=0; i <= convention; i++) {
+            if (fillExtent(VERTICAL_ALTERNATIVES[i], Units.METRE, null, 
extent, 0)) {
+                addVerticalExtent(extent[0], extent[1], verticalCRS);
+                hasExtent = true;
+                break;
+            }
         }
         /*
          * Get the start and end times as temporal objects if available, or as 
numeric values otherwise.
@@ -811,7 +818,7 @@ split:  while ((start = 
CharSequences.skipLeadingWhitespaces(value, start, lengt
         double min = numericValue(dim.MINIMUM);
         double max = numericValue(dim.MAXIMUM);
         boolean hasExtent = !Double.isNaN(min) || !Double.isNaN(max);
-        if (hasExtent) {
+        if (hasExtent && dim.UNITS != null) {
             final String symbol = stringValue(dim.UNITS);
             if (symbol != null) {
                 try {

Reply via email to