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 6fd7c530f7 Use the SIS-specific `DefaultGeocentricCRS` class in one 
place where we removed the `GeocentricCRS` interface. This is needed for 
avoiding an ambiguity when searching codes in an EPSG database.
6fd7c530f7 is described below

commit 6fd7c530f7d5181b5dd2fc5bb86af2ba2cc73999
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Apr 16 11:50:09 2024 +0200

    Use the SIS-specific `DefaultGeocentricCRS` class in one place where we 
removed the `GeocentricCRS` interface.
    This is needed for avoiding an ambiguity when searching codes in an EPSG 
database.
---
 .../sis/referencing/crs/DefaultTemporalCRS.java    |  1 +
 .../referencing/factory/AuthorityFactoryProxy.java |  1 +
 .../factory/ConcurrentAuthorityFactory.java        |  2 ++
 .../factory/GeodeticAuthorityFactory.java          |  2 ++
 .../referencing/factory/GeodeticObjectFactory.java |  4 +++
 .../factory/MultiAuthoritiesFactory.java           |  2 ++
 .../referencing/factory/sql/AuthorityCodes.java    | 10 ++++---
 .../referencing/factory/sql/EPSGCodeFinder.java    |  2 +-
 .../sis/referencing/factory/sql/TableInfo.java     | 35 ++++++++++++++++++++--
 9 files changed, 52 insertions(+), 7 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
index 8a55606a48..3644a65a34 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
@@ -152,6 +152,7 @@ public class DefaultTemporalCRS extends AbstractCRS 
implements TemporalCRS {
      *
      * @see 
org.apache.sis.referencing.factory.GeodeticObjectFactory#createTemporalCRS(Map, 
TemporalDatum, TimeCS)
      */
+    @SuppressWarnings("this-escape")
     public DefaultTemporalCRS(final Map<String,?> properties,
                               final TemporalDatum datum,
                               final TimeCS        cs)
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
index 8947411b87..7893b80b77 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
@@ -543,6 +543,7 @@ abstract class AuthorityFactoryProxy<T> {
     static final AuthorityFactoryProxy<?>[] PROXIES = new 
AuthorityFactoryProxy<?>[] {
         PROJECTED_CRS,      // Special kind of GeneralDerivedCRS.
         GEOGRAPHIC_CRS,     // Special kind of GeodeticCRS.
+        GEODETIC_CRS,
         VERTICAL_CRS,
         TEMPORAL_CRS,
         ENGINEERING_CRS,
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
index 34e23dddab..f7d6ab7758 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
@@ -937,6 +937,8 @@ public abstract class ConcurrentAuthorityFactory<DAO 
extends GeodeticAuthorityFa
      *
      * @return the coordinate reference system for the given code.
      * @throws FactoryException if the object creation failed.
+     *
+     * @since 1.5
      */
     @Override
     public GeodeticCRS createGeodeticCRS(final String code) throws 
FactoryException {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
index 4985f629fc..d32f19d9bc 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
@@ -332,6 +332,8 @@ public abstract class GeodeticAuthorityFactory extends 
AbstractFactory implement
      *
      * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS
      * @see org.apache.sis.referencing.CommonCRS#geocentric()
+     *
+     * @since 1.5
      */
     public GeodeticCRS createGeodeticCRS(final String code) throws 
NoSuchAuthorityCodeException, FactoryException {
         return cast(GeodeticCRS.class, createCoordinateReferenceSystem(code), 
code);
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
index 666eb45942..5ad6bca3f5 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
@@ -342,6 +342,8 @@ public class GeodeticObjectFactory extends AbstractFactory 
implements CRSFactory
      *
      * @see GeodeticAuthorityFactory#createGeodeticCRS(String)
      * @see DefaultGeocentricCRS#DefaultGeocentricCRS(Map, GeodeticDatum, 
CartesianCS)
+     *
+     * @since 1.5
      */
     @Override
     public GeodeticCRS createGeodeticCRS(final Map<String,?> properties,
@@ -420,6 +422,8 @@ public class GeodeticObjectFactory extends AbstractFactory 
implements CRSFactory
      *
      * @see DefaultGeocentricCRS#DefaultGeocentricCRS(Map, GeodeticDatum, 
SphericalCS)
      * @see GeodeticAuthorityFactory#createGeodeticCRS(String)
+     *
+     * @since 1.5
      */
     @Override
     public GeodeticCRS createGeodeticCRS(final Map<String,?> properties,
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
index 55fe728fb9..0bcfff9048 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
@@ -956,6 +956,8 @@ public class MultiAuthoritiesFactory extends 
GeodeticAuthorityFactory implements
      *
      * @return the coordinate reference system for the given code.
      * @throws FactoryException if the object creation failed.
+     *
+     * @since 1.5
      */
     @Override
     public GeodeticCRS createGeodeticCRS(final String code) throws 
FactoryException {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java
index a226b0cad9..9fd9585b36 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java
@@ -28,6 +28,7 @@ import org.opengis.referencing.operation.Projection;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.collection.IntegerList;
 import org.apache.sis.util.privy.AbstractMap;
+import org.apache.sis.util.privy.Strings;
 
 
 /**
@@ -336,17 +337,18 @@ final class AuthorityCodes extends 
AbstractMap<String,String> implements Seriali
 
     /**
      * Returns a string representation of this map for debugging purpose.
-     * This method does not let the default implementation format all entry, 
since it would be a costly operation.
+     * This method does not let the default implementation formats all entries,
+     * because it would be a costly operation.
      */
     @Override
     public String toString() {
-        final StringBuilder buffer = new 
StringBuilder("AuthorityCodes[").append(type.getSimpleName());
+        String size = null;
         synchronized (factory) {
             if (codes != null) {
-                buffer.append(", size ").append(results != null ? ">= " : "= 
").append(codes.size());
+                size = "size " + (results != null ? "≥ " : "= ") + 
codes.size();
             }
         }
-        return buffer.append(']').toString();
+        return Strings.toString(getClass(), "type", type.getSimpleName(), 
null, size);
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
index 85a92aab3b..04d74233f7 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
@@ -420,7 +420,7 @@ crs:    if (isInstance(CoordinateReferenceSystem.class, 
object)) {
          * It may be absent (typically, only datums or reference frames have 
that condition).
          */
         buffer.append("SELECT ").append(table.codeColumn).append(" FROM 
").append(table.table);
-        table.where(object.getClass(), buffer);         // Unconditionally 
append a "WHERE" clause.
+        table.where(object, buffer);                // Unconditionally append 
a "WHERE" clause.
         boolean isNext = false;
         for (final Condition filter : filters) {
             isNext |= filter.appendToWhere(buffer, isNext);
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java
index 1b16b321d5..c7ed64c976 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java
@@ -21,10 +21,14 @@ import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
 import org.opengis.referencing.datum.*;
 import org.opengis.referencing.operation.*;
+import org.opengis.referencing.IdentifiedObject;
 import org.opengis.parameter.ParameterDescriptor;
 import org.apache.sis.referencing.privy.WKTKeywords;
 import org.apache.sis.util.CharSequences;
 
+// Specific to the geoapi-4.0 branch:
+import org.apache.sis.referencing.crs.DefaultGeocentricCRS;
+
 
 /**
  * Information about a specific table. The MS-Access dialect of SQL is assumed;
@@ -60,6 +64,12 @@ final class TableInfo {
      * {@link EPSGDataAccess#createUnit(String)}
      *
      * The order is significant: it is the key for a {@code switch} statement.
+     *
+     * <h4>Ambiguity</h4>
+     * As of ISO 19111:2019, we have no standard way to identify the 
geocentric case from a {@link Class} argument
+     * because the standard does not provide the {@code GeocentricCRS} 
interface. This implementation fallbacks on
+     * the SIS-specific geocentric CRS class, with a {@link 
#where(IdentifiedObject, StringBuilder)} method which
+     * will substitute implementation-neutral objects by the Apache SIS class.
      */
     static final TableInfo[] EPSG = {
         CRS = new TableInfo(CoordinateReferenceSystem.class,
@@ -67,7 +77,7 @@ final class TableInfo {
                 "COORD_REF_SYS_CODE",
                 "COORD_REF_SYS_NAME",
                 "COORD_REF_SYS_KIND",
-                new Class<?>[] { ProjectedCRS.class,   GeographicCRS.class,   
GeodeticCRS.class,
+                new Class<?>[] { ProjectedCRS.class,   GeographicCRS.class,   
DefaultGeocentricCRS.class,
                                  VerticalCRS.class,    CompoundCRS.class,     
EngineeringCRS.class,
                                  DerivedCRS.class,     TemporalCRS.class,     
ParametricCRS.class},     // See comment below
                 new String[]   {"projected",          "geographic",          
"geocentric",
@@ -249,6 +259,27 @@ final class TableInfo {
         return CharSequences.isAcronymForWords(name, expected);
     }
 
+    /**
+     * Appends a {@code WHERE} clause together with a condition for searching 
the specified object.
+     * This method delegates to {@link #where(Class, StringBuilder)} with the 
type of the given object,
+     * except that some object properties may be inspected for resolving 
ambiguities.
+     *
+     * @param  object  the object to search in the database.
+     * @param  buffer  where to append the {@code WHERE} clause.
+     */
+    final void where(final IdentifiedObject object, final StringBuilder 
buffer) {
+        Class<?> userType = object.getClass();
+        if (object instanceof GeodeticCRS) {
+            final CoordinateSystem cs = ((GeodeticCRS) 
object).getCoordinateSystem();
+            if (cs instanceof EllipsoidalCS) {
+                userType = GeographicCRS.class;
+            } else if (cs instanceof CartesianCS || cs instanceof SphericalCS) 
{
+                userType = DefaultGeocentricCRS.class;
+            }
+        }
+        where(userType, buffer);
+    }
+
     /**
      * Appends a {@code WHERE} clause together with a condition for searching 
the most specific subtype,
      * if such condition can be added. The clause appended by this method 
looks like the following example
@@ -262,7 +293,7 @@ final class TableInfo {
      *
      * @param  userType  the type specified by the user.
      * @param  buffer    where to append the {@code WHERE} clause.
-     * @return the       subtype, or {@link #type} if no subtype was found.
+     * @return the subtype, or {@link #type} if no subtype was found.
      */
     final Class<?> where(final Class<?> userType, final StringBuilder buffer) {
         buffer.append(" WHERE ");

Reply via email to