sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ama...@apache.org
Subject [sis] 33/45: WIP(Feature): start adding CRS resolution strategy for filter operations.
Date Tue, 12 Nov 2019 16:45:00 GMT
This is an automated email from the ASF dual-hosted git repository.

amanin pushed a commit to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git

commit abffc9c1281a7653d63759abf442a38784a40ac0
Author: Alexis Manin <amanin@apache.org>
AuthorDate: Thu Oct 10 11:16:48 2019 +0200

    WIP(Feature): start adding CRS resolution strategy for filter operations.
---
 .../java/org/apache/sis/filter/CRSMatching.java    | 100 +++++++++++++++++++++
 .../java/org/apache/sis/filter/package-info.java   |  45 +++++++++-
 .../main/java/org/apache/sis/referencing/CRS.java  |  80 +++++++++--------
 3 files changed, 184 insertions(+), 41 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java b/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java
new file mode 100644
index 0000000..78c4d9f
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java
@@ -0,0 +1,100 @@
+package org.apache.sis.filter;
+
+import java.util.Optional;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.util.FactoryException;
+
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.util.NullArgumentException;
+import org.apache.sis.util.Utilities;
+
+/**
+ * TODO: improve CRS conversion/suggestion by infering a geographic region of interest.
+ */
+public interface CRSMatching {
+
+    static CRSMatching left(final CoordinateReferenceSystem source) {
+        if (source == null) {
+            return new CRSMatching() {
+                @Override
+                public Match right(CoordinateReferenceSystem other) {
+                    if (other == null) return new NullMatch();
+                    else throw new IllegalArgumentException("No match can be established
with given CRS because source one is null.");
+                }
+            };
+        } else {
+            return new CRSMatching() {
+                @Override
+                public Match right(CoordinateReferenceSystem other) throws FactoryException
{
+                    if (other == null) throw new NullArgumentException("No match can be established
with previous CRS because input one is null");
+                    final CoordinateReferenceSystem commonCrs = CRS.suggestCommonTarget(null,
source, other);
+                    return new DefaultMatch(commonCrs, source, other);
+                }
+            };
+        }
+    }
+    Match right(final CoordinateReferenceSystem other) throws FactoryException;
+
+    interface Match {
+        Optional<CoordinateReferenceSystem> getCommonCRS();
+        Optional<CoordinateOperation> fromLeft();
+        Optional<CoordinateOperation> fromRight();
+    }
+
+    final class NullMatch implements Match {
+
+        @Override
+        public Optional<CoordinateReferenceSystem> getCommonCRS() {
+            return Optional.empty();
+        }
+
+        @Override
+        public Optional<CoordinateOperation> fromLeft() {
+            return Optional.empty();
+        }
+
+        @Override
+        public Optional<CoordinateOperation> fromRight() {
+            return Optional.empty();
+        }
+    }
+
+    final class DefaultMatch implements Match {
+
+        final CoordinateReferenceSystem commonCRS;
+        final Optional<CoordinateOperation> fromLeft;
+        final Optional<CoordinateOperation> fromRight;
+
+        public DefaultMatch(CoordinateReferenceSystem commonCRS, CoordinateReferenceSystem
left, CoordinateReferenceSystem right) throws FactoryException {
+            this.commonCRS = commonCRS;
+            fromLeft = createOp(left, commonCRS);
+            fromRight = createOp(right, commonCRS);
+        }
+
+        @Override
+        public Optional<CoordinateReferenceSystem> getCommonCRS() {
+            return Optional.of(commonCRS);
+        }
+
+        @Override
+        public Optional<CoordinateOperation> fromLeft() {
+            return fromLeft;
+        }
+
+        @Override
+        public Optional<CoordinateOperation> fromRight() {
+            return fromRight;
+        }
+    }
+
+    static Optional<CoordinateOperation> createOp(final CoordinateReferenceSystem source,
final CoordinateReferenceSystem target) throws FactoryException {
+        if (Utilities.equalsIgnoreMetadata(source, target)) {
+            return Optional.empty();
+        } else {
+            final CoordinateOperation op = CRS.findOperation(source, target, null);
+            return Optional.of(op);
+        }
+    }
+}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
index 7291456..cc40a87 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
@@ -19,12 +19,53 @@
  * Filters features according their properties.
  * A <cite>filter expression</cite> is a construct used to constraint a feature
set to a subset.
  *
+ * All operations in this package try to follow rules of both following standards:
+ * <ul>
+ *     <li><a href="https://www.iso.org/fr/standard/53698.html">ISO/IEC 13249-3:2011
- SQLMM</a></li>
+ *     <li><a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC®
Filter Encoding 2.0 Encoding Standard</a></li>
+ * </ul>
+ *
+ * <div class="section">General considerations:</div>
+ * <div class="section">Coordinate reference system handling:</div>
+ * As stated by Filter encoding 2.0.2, section 7.8.4, heterogeneous coordinate reference
systems must be handled by
+ * libraries, one way or another. The standard does not define any strategy. As Apache-SIS
contains a powerful
+ * transform system, we'll try to handle differences in the following way:
+ * <ul>
+ *     <li>
+ *         If all evaluated geometries define a srid, but their not the same, we'll try to
project them in a common
+ *         space. The strategy will be guided by {@link org.apache.sis.referencing.CRS#suggestCommonTarget(org.opengis.metadata.extent.GeographicBoundingBox,
org.opengis.referencing.crs.CoordinateReferenceSystem...) Referencing utility method}.
+ *         If it cannot provide a common space, we will fail any ongoing operation.
+ *     </li>
+ *     <li>
+ *         Missing information:
+ *         <ul>
+ *              <li>If no geometry contains any srid, consider they're defined in the
same space, and proceed</li>
+ *              <li>If one geometry define a CRS but the other do not, consider that
an ambiguity resides: fail.</li>
+ *         </ul>
+ *     </li>
+ * </ul>
+ *
+ * <div class="section">Optimisations</div>
+ * For now, few to no optimisation is done in the operators. Most of important ones would
require one of the two
+ * following things:
+ * <ul>
+ *     <li>
+ *         Context information: Filters does not know in advance the feature type they're
operating upon, which is
+ *         vital to define some calculus parameters, as property value conversion strategy,
spatial system changes, etc.
+ *         Such information would allow operators to prepare data at initialisation time.
+ *     </li>
+ *     <li>
+ *         User hints: some operations could be set faster at the cost of precision. To activate
such things, it would
+ *         require user consent. Most naïve example is spatial reference system conversion,
which could be de-activated
+ *         for systems with nearly equal parameters (see {@link org.apache.sis.util.Utilities#equalsApproximately(java.lang.Object,
java.lang.Object)}.
+ *     </li>
+ * </ul>
+ * extra-information for
+ * the operator, as well as hints from the user to allow sac
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.0
  *
- * @see <a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC® Filter
Encoding 2.0 Encoding Standard</a>
- *
  * @since 1.0
  * @module
  */
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index 1b9b49d..a8912d4 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@ -16,82 +16,84 @@
  */
 package org.apache.sis.referencing;
 
-import java.util.Map;
-import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import java.util.logging.LogRecord;
-import org.opengis.util.FactoryException;
+
 import org.opengis.geometry.Envelope;
-import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.geometry.Geometry;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.extent.BoundingPolygon;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.metadata.extent.GeographicExtent;
 import org.opengis.referencing.IdentifiedObject;
-import org.opengis.referencing.cs.CartesianCS;
-import org.opengis.referencing.cs.EllipsoidalCS;
-import org.opengis.referencing.cs.AxisDirection;
-import org.opengis.referencing.cs.CoordinateSystem;
-import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
 import org.opengis.referencing.crs.CRSFactory;
-import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.CompoundCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.referencing.crs.GeneralDerivedCRS;
 import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.crs.GeographicCRS;
-import org.opengis.referencing.crs.GeneralDerivedCRS;
 import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.crs.VerticalCRS;
-import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.datum.Datum;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Conversion;
-import org.opengis.referencing.operation.OperationNotFoundException;
-import org.opengis.metadata.citation.Citation;
-import org.opengis.metadata.extent.Extent;
-import org.opengis.metadata.extent.BoundingPolygon;
-import org.opengis.metadata.extent.GeographicBoundingBox;
-import org.opengis.metadata.extent.GeographicExtent;
 import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.OperationNotFoundException;
 import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.measure.Units;
+import org.opengis.util.FactoryException;
+
 import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.internal.referencing.AxisDirections;
+import org.apache.sis.internal.referencing.CoordinateOperations;
+import org.apache.sis.internal.referencing.DefinitionVerifier;
 import org.apache.sis.internal.referencing.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
-import org.apache.sis.internal.referencing.CoordinateOperations;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
-import org.apache.sis.internal.referencing.DefinitionVerifier;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Numerics;
-import org.apache.sis.referencing.cs.AxisFilter;
-import org.apache.sis.referencing.cs.CoordinateSystems;
-import org.apache.sis.referencing.cs.DefaultVerticalCS;
+import org.apache.sis.measure.Units;
+import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
+import org.apache.sis.metadata.iso.extent.Extents;
+import org.apache.sis.referencing.crs.DefaultCompoundCRS;
+import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.crs.DefaultProjectedCRS;
 import org.apache.sis.referencing.crs.DefaultVerticalCRS;
-import org.apache.sis.referencing.crs.DefaultCompoundCRS;
-import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
+import org.apache.sis.referencing.cs.AxisFilter;
+import org.apache.sis.referencing.cs.CoordinateSystems;
+import org.apache.sis.referencing.cs.DefaultVerticalCS;
+import org.apache.sis.referencing.factory.GeodeticObjectFactory;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
 import org.apache.sis.referencing.operation.CoordinateOperationContext;
-import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
 import org.apache.sis.referencing.operation.DefaultConversion;
-import org.apache.sis.referencing.factory.GeodeticObjectFactory;
-import org.apache.sis.referencing.factory.UnavailableFactoryException;
-import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
-import org.apache.sis.metadata.iso.extent.Extents;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.logging.Logging;
-import org.apache.sis.util.logging.WarningListener;
+import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.Utilities;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.Utilities;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.logging.WarningListener;
+import org.apache.sis.util.resources.Errors;
 
 // Branch-dependent imports
-import org.opengis.geometry.Geometry;
 
 
 /**
@@ -431,7 +433,7 @@ public final class CRS extends Static {
      * Suggests a coordinate reference system which could be a common target for coordinate
operations having the
      * given sources. This method compares the {@linkplain #getGeographicBoundingBox(CoordinateReferenceSystem)
      * domain of validity} of all given CRSs. If a CRS has a domain of validity that contains
the domain of all other
-     * CRS, than that CRS is returned. Otherwise this method verifies if a {@linkplain GeneralDerivedCRS#getBaseCRS()
+     * CRS, then that CRS is returned. Otherwise this method verifies if a {@linkplain GeneralDerivedCRS#getBaseCRS()
      * base CRS} (usually a {@linkplain org.apache.sis.referencing.crs.DefaultGeographicCRS
geographic CRS} instance)
      * would be suitable. If no suitable CRS is found, then this method returns {@code null}.
      *


Mime
View raw message