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 <[email protected]>
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 ");