sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jso...@apache.org
Subject [sis] branch geoapi-4.0 updated: Filter : add SQL/MM ST_LineString function
Date Tue, 26 Nov 2019 09:05:00 GMT
This is an automated email from the ASF dual-hosted git repository.

jsorel 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 45ce640  Filter : add SQL/MM ST_LineString function
45ce640 is described below

commit 45ce6402580c3d935a7a08f26da66e05a7d0c4fc
Author: jsorel <johann.sorel@geomatys.com>
AuthorDate: Tue Nov 26 10:04:47 2019 +0100

    Filter : add SQL/MM ST_LineString function
---
 .../src/main/java/org/apache/sis/filter/SQLMM.java |  2 +
 .../filter/{ST_Point.java => ST_LineString.java}   | 98 ++++++++++++++--------
 .../main/java/org/apache/sis/filter/ST_Point.java  |  7 +-
 .../test/java/org/apache/sis/filter/SQLMMTest.java | 20 +++++
 4 files changed, 89 insertions(+), 38 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/SQLMM.java b/core/sis-feature/src/main/java/org/apache/sis/filter/SQLMM.java
index 935b90a..ab3e3b5 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/SQLMM.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/SQLMM.java
@@ -71,6 +71,7 @@ final class SQLMM implements FunctionRegister {
                 ST_Envelope.NAME,
                 //ST_Intersects.NAME, TODO fixme, this class is not a proper function
                 ST_Point.NAME,
+                ST_LineString.NAME,
                 ST_Simplify.NAME,
                 ST_SimplifyPreserveTopology.NAME,
                 ST_Transform.NAME);
@@ -99,6 +100,7 @@ final class SQLMM implements FunctionRegister {
                 case ST_Envelope.NAME:                  return new ST_Envelope(parameters);
                 //case ST_Intersects.NAME:                return new ST_Intersects(parameters);
                 case ST_Point.NAME:                     return new ST_Point(parameters);
+                case ST_LineString.NAME:                return new ST_LineString(parameters);
                 case ST_Simplify.NAME:                  return new ST_Simplify(parameters);
                 case ST_SimplifyPreserveTopology.NAME:  return new ST_SimplifyPreserveTopology(parameters);
                 case ST_Transform.NAME:                 return new ST_Transform(parameters);
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_LineString.java
similarity index 50%
copy from core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java
copy to core/sis-feature/src/main/java/org/apache/sis/filter/ST_LineString.java
index 5e00125..03359ce 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_LineString.java
@@ -16,12 +16,18 @@
  */
 package org.apache.sis.filter;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 import org.apache.sis.feature.builder.AttributeTypeBuilder;
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.feature.builder.PropertyTypeBuilder;
 import org.apache.sis.internal.feature.FeatureExpression;
 import org.apache.sis.referencing.CRS;
 import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.LineString;
 import org.locationtech.jts.geom.Point;
 import org.opengis.feature.FeatureType;
 import org.opengis.filter.expression.Expression;
@@ -29,11 +35,11 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.util.FactoryException;
 
 /**
- * An expression which creates a point geometry from separate coordinates.
+ * An expression which creates a lineString geometry from coordinates.
  * This expression expects multiple combined arguments:
  * <ul>
- *   <li>X, Y</li>
- *   <li>X, Y, CoordinateReferenceSystem</li>
+ *   <li>list of Point</li>
+ *   <li>list of Point, CoordinateReferenceSystem</li>
  * </ul>
  *
  * <p>
@@ -45,12 +51,12 @@ import org.opengis.util.FactoryException;
  * @since   2.0
  * @module
  */
-public class ST_Point extends NamedFunction implements FeatureExpression {
+final class ST_LineString extends NamedFunction implements FeatureExpression {
 
     /**
      * Name of this function as defined by SQL/MM standard.
      */
-    static final String NAME = "ST_Point";
+    static final String NAME = "ST_LineString";
 
     private CoordinateReferenceSystem constantCrs;
 
@@ -58,25 +64,16 @@ public class ST_Point extends NamedFunction implements FeatureExpression
{
      * Creates a new function with the given parameters. It is caller's responsibility to
ensure
      * that the given array is non-null, has been cloned and does not contain null elements.
      *
-     * @throws IllegalArgumentException if the number of arguments is less then two.
+     * @throws IllegalArgumentException if the number of arguments is less then one.
      */
-    ST_Point(final Expression[] parameters) {
+    ST_LineString(final Expression[] parameters) {
         super(parameters);
-        if (parameters.length < 2) {
-            throw new IllegalArgumentException("ST_Point function expect 2 or more parameters");
+        if (parameters.length < 1) {
+            throw new IllegalArgumentException("ST_LineString function expect 2 or more parameters");
         }
 
-        if (this.parameters.size() > 2) {
-            Object cdt = this.parameters.get(2).evaluate(null);
-            if (cdt instanceof Number) {
-                try {
-                    constantCrs = CRS.forCode("EPSG:" + ((Number) cdt).intValue());
-                } catch (FactoryException ex) {
-                    warning(ex);
-                }
-            } else if (cdt instanceof CoordinateReferenceSystem) {
-                constantCrs = (CoordinateReferenceSystem) cdt;
-            }
+        if (this.parameters.size() > 1) {
+            constantCrs = getCrs(this.parameters.get(1), null);
         }
     }
 
@@ -90,34 +87,63 @@ public class ST_Point extends NamedFunction implements FeatureExpression
{
 
     @Override
     public Object evaluate(Object object) {
-        Number x = parameters.get(0).evaluate(object, Number.class);
-        Number y = parameters.get(1).evaluate(object, Number.class);
         CoordinateReferenceSystem crs = constantCrs;
-        if (crs == null && parameters.size() > 2) {
-            Object cdt = parameters.get(2).evaluate(object);
-            if (cdt instanceof Number) {
-                try {
-                    crs = CRS.forCode("EPSG:" + ((Number) cdt).intValue());
-                } catch (FactoryException ex) {
-                    warning(ex);
-                }
-            } else if (cdt instanceof CoordinateReferenceSystem) {
-                crs = (CoordinateReferenceSystem) cdt;
+        if (crs == null && parameters.size() > 1) {
+            crs = getCrs(parameters.get(1), object);
+        }
+
+        Object x = parameters.get(0).evaluate(object);
+        if (x == null) {
+          x = Collections.EMPTY_LIST;
+        } else if (x instanceof Point) {
+            x = Arrays.asList(x);
+        } else if (!(x instanceof Iterable)) {
+            warning(new Exception("ST_LineString called with an object which is not a iterable"));
+            return null;
+        }
+
+        Iterator i = ((Iterable) x).iterator();
+        final List<Coordinate> coords = new ArrayList<>();
+        while (i.hasNext()) {
+            Object cdt = i.next();
+            if (cdt instanceof Point) {
+                coords.add(((Point) cdt).getCoordinate());
+            } else if (cdt instanceof Coordinate) {
+                coords.add(((Coordinate) cdt));
+            } else {
+                //what should we do ?
             }
         }
 
-        final Point point = SQLMM.GF.createPoint(new Coordinate(x.doubleValue(), y.doubleValue()));
-        point.setUserData(crs);
-        return point;
+        final LineString geometry = SQLMM.GF.createLineString(coords.toArray(new Coordinate[coords.size()]));
+        geometry.setUserData(crs);
+        return geometry;
     }
 
     @Override
     public PropertyTypeBuilder expectedType(FeatureType valueType, FeatureTypeBuilder addTo)
{
-        final AttributeTypeBuilder<Point> atb = addTo.addAttribute(Point.class).setName(NAME);
+        final AttributeTypeBuilder<LineString> atb = addTo.addAttribute(LineString.class)
+                .setName(NAME)
+                .setMinimumOccurs(1)
+                .setMaximumOccurs(1);
         if (constantCrs != null) {
             atb.setCRS(constantCrs);
         }
         return atb;
     }
 
+    private CoordinateReferenceSystem getCrs(Expression exp, Object candidate) {
+        Object cdt = exp.evaluate(candidate);
+        if (cdt instanceof Number) {
+            try {
+                return CRS.forCode("EPSG:" + ((Number) cdt).intValue());
+            } catch (FactoryException ex) {
+                warning(ex);
+            }
+        } else if (cdt instanceof CoordinateReferenceSystem) {
+            return (CoordinateReferenceSystem) cdt;
+        }
+        return null;
+    }
+
 }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java
index 5e00125..a77b836 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Point.java
@@ -45,7 +45,7 @@ import org.opengis.util.FactoryException;
  * @since   2.0
  * @module
  */
-public class ST_Point extends NamedFunction implements FeatureExpression {
+final class ST_Point extends NamedFunction implements FeatureExpression {
 
     /**
      * Name of this function as defined by SQL/MM standard.
@@ -113,7 +113,10 @@ public class ST_Point extends NamedFunction implements FeatureExpression
{
 
     @Override
     public PropertyTypeBuilder expectedType(FeatureType valueType, FeatureTypeBuilder addTo)
{
-        final AttributeTypeBuilder<Point> atb = addTo.addAttribute(Point.class).setName(NAME);
+        final AttributeTypeBuilder<Point> atb = addTo.addAttribute(Point.class)
+                .setName(NAME)
+                .setMinimumOccurs(1)
+                .setMaximumOccurs(1);
         if (constantCrs != null) {
             atb.setCRS(constantCrs);
         }
diff --git a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
index 605d62e..2491ea0 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.filter;
 
+import java.util.Arrays;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.filter.FilterFactory;
@@ -340,6 +341,25 @@ public final strictfp class SQLMMTest extends TestCase {
     }
 
     /**
+     * Test SQL/MM {@link ST_Point} function.
+     */
+    @Test
+    public void ST_LineStringTest() {
+        assertRequireArguments("ST_LineString");
+        /*
+         * Execute the function and check the result.
+         */
+        final LineString result = evaluate(LineString.class, null, factory.function("ST_LineString",
+                factory.literal(Arrays.asList(new Coordinate(10.0, 20.0), new Coordinate(30.0,
40.0))),
+                factory.literal(HardCodedCRS.WGS84)));
+        assertEquals("userData", HardCodedCRS.WGS84, result.getUserData());
+        assertEquals(10.0, result.getCoordinates()[0].x, STRICT);
+        assertEquals(20.0, result.getCoordinates()[0].y, STRICT);
+        assertEquals(30.0, result.getCoordinates()[1].x, STRICT);
+        assertEquals(40.0, result.getCoordinates()[1].y, STRICT);
+    }
+
+    /**
      * Test SQL/MM {@link ST_Simplify} function.
      */
     @Test


Mime
View raw message