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 ST_Centroid and ST_Buffer
Date Fri, 16 Aug 2019 12:37:54 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 aab81c7  Filter : add ST_Centroid and ST_Buffer
aab81c7 is described below

commit aab81c70f27783707592b4e3ae732db21f271f9b
Author: jsorel <johann.sorel@geomatys.com>
AuthorDate: Fri Aug 16 14:37:37 2019 +0200

    Filter : add ST_Centroid and ST_Buffer
---
 .../src/main/java/org/apache/sis/filter/SQLMM.java |  20 +++-
 .../main/java/org/apache/sis/filter/ST_Buffer.java | 116 +++++++++++++++++++++
 .../java/org/apache/sis/filter/ST_Centroid.java    | 114 ++++++++++++++++++++
 .../test/java/org/apache/sis/filter/SQLMMTest.java |  78 ++++++++++++++
 4 files changed, 323 insertions(+), 5 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 8a5f9ab..86d3196 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
@@ -16,13 +16,14 @@
  */
 package org.apache.sis.filter;
 
-import java.util.Set;
 import java.util.Collections;
-import org.opengis.util.FactoryException;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.sis.internal.feature.FunctionRegister;
+import org.apache.sis.util.ArgumentChecks;
 import org.opengis.filter.expression.Expression;
 import org.opengis.filter.expression.Function;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.internal.feature.FunctionRegister;
+import org.opengis.util.FactoryException;
 
 
 /**
@@ -40,7 +41,14 @@ public final class SQLMM implements FunctionRegister {
     /**
      * Names of all functions known to this register.
      */
-    private static final Set<String> FUNCTIONS = Collections.singleton(ST_Transform.NAME);
+    private static final Set<String> FUNCTIONS;
+    static {
+        Set<String> names = new HashSet<>();
+        names.add(ST_Transform.NAME);
+        names.add(ST_Centroid.NAME);
+        names.add(ST_Buffer.NAME);
+        FUNCTIONS = Collections.unmodifiableSet(names);
+    }
 
     /**
      * Creates the default register.
@@ -69,6 +77,8 @@ public final class SQLMM implements FunctionRegister {
         try {
             switch (name) {
                 case ST_Transform.NAME: return new ST_Transform(parameters);
+                case ST_Centroid.NAME: return new ST_Centroid(parameters);
+                case ST_Buffer.NAME: return new ST_Buffer(parameters);
                 default: throw new IllegalArgumentException("Unknown function " + name);
             }
         } catch (FactoryException e) {
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Buffer.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Buffer.java
new file mode 100644
index 0000000..c41532a
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Buffer.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.filter;
+
+import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.apache.sis.internal.feature.FeatureExpression;
+import org.apache.sis.internal.feature.Geometries;
+import org.apache.sis.util.ArgumentChecks;
+import org.locationtech.jts.geom.Geometry;
+import org.opengis.feature.AttributeType;
+import org.opengis.feature.FeatureType;
+import org.opengis.feature.PropertyType;
+import org.opengis.filter.expression.Expression;
+import org.opengis.util.FactoryException;
+
+
+/**
+ * An expression which compute a geometry buffer.
+ * This expression expects two arguments:
+ *
+ * <ol class="verbose">
+ *   <li>An expression returning a geometry object. The evaluated value shall be an
instance of
+ *       one of the implementations enumerated in {@link org.apache.sis.setup.GeometryLibrary}.</li>
+ *   <li>An expression returning a distance. The evaluated value shall be an instance
of
+ *      Number. Distance is expressed in the geometry Coordinate reference system.</li>
+ * </ol>
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since   1.0
+ * @module
+ */
+final class ST_Buffer extends NamedFunction implements FeatureExpression {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Name of this function as defined by SQL/MM standard.
+     */
+    static final String NAME = "ST_Buffer";
+
+    /**
+     * 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 not equal to 2.
+     * @throws FactoryException if CRS can not be constructed from the second expression.
+     */
+    ST_Buffer(final Expression[] parameters) throws FactoryException {
+        super(parameters);
+        ArgumentChecks.ensureExpectedCount("parameters", 2, parameters.length);
+    }
+
+    /**
+     * Returns the name of this function, which is {@value #NAME}.
+     */
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    /**
+     * Evaluates the first expression as a geometry object, transforms that geometry to the
CRS given
+     * by the second expression and returns the result.
+     */
+    @Override
+    public Object evaluate(final Object value) {
+        Object geometry = parameters.get(0).evaluate(value);
+        if (geometry instanceof Geometry) {
+            final Geometry jts = (Geometry) geometry;
+            final double distance = parameters.get(1).evaluate(value, Number.class).doubleValue();
+            final Geometry buffer = jts.buffer(distance);
+            buffer.setSRID(jts.getSRID());
+            buffer.setUserData(jts.getUserData());
+            return buffer;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the expected type of values produced by this expression when a feature of
the given
+     * type is evaluated.
+     *
+     * @param  valueType  the type of features on which to apply the expression.
+     * @return expected expression result type.
+     * @throws IllegalArgumentException if this method can not determine the property type
for the given feature type.
+     */
+    @Override
+    public PropertyType expectedType(final FeatureType valueType) {
+        final PropertyType expectedType = expectedType(0, valueType);
+        if (expectedType instanceof AttributeType<?>) {
+            AttributeType<?> att = (AttributeType<?>) expectedType;
+            if (Geometries.isKnownType(att.getValueClass())) {
+                return new FeatureTypeBuilder().addAttribute(att).setValueClass(Geometry.class).build();
+            }
+        }
+        throw new IllegalArgumentException("First expression must result in a geometric attribute");
       // TODO: localize.
+    }
+}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Centroid.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Centroid.java
new file mode 100644
index 0000000..d1df586
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Centroid.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.filter;
+
+import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.apache.sis.internal.feature.FeatureExpression;
+import org.apache.sis.internal.feature.Geometries;
+import org.apache.sis.util.ArgumentChecks;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Point;
+import org.opengis.feature.AttributeType;
+import org.opengis.feature.FeatureType;
+import org.opengis.feature.PropertyType;
+import org.opengis.filter.expression.Expression;
+import org.opengis.util.FactoryException;
+
+
+/**
+ * An expression which compute a geometry centroid.
+ * This expression expects one arguments:
+ *
+ * <ol class="verbose">
+ *   <li>An expression returning a geometry object. The evaluated value shall be an
instance of
+ *       one of the implementations enumerated in {@link org.apache.sis.setup.GeometryLibrary}.</li>
+ * </ol>
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since   1.0
+ * @module
+ */
+final class ST_Centroid extends NamedFunction implements FeatureExpression {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Name of this function as defined by SQL/MM standard.
+     */
+    static final String NAME = "ST_Centroid";
+
+    /**
+     * 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 not equal to 1.
+     * @throws FactoryException if CRS can not be constructed from the second expression.
+     */
+    ST_Centroid(final Expression[] parameters) throws FactoryException {
+        super(parameters);
+        ArgumentChecks.ensureExpectedCount("parameters", 1, parameters.length);
+    }
+
+    /**
+     * Returns the name of this function, which is {@value #NAME}.
+     */
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    /**
+     * Evaluates the first expression as a geometry object, transforms that geometry to the
CRS given
+     * by the second expression and returns the result.
+     */
+    @Override
+    public Object evaluate(final Object value) {
+        Object geometry = parameters.get(0).evaluate(value);
+        if (geometry instanceof Geometry) {
+            final Geometry jts = (Geometry) geometry;
+            final Point centroid = jts.getCentroid();
+            centroid.setSRID(jts.getSRID());
+            centroid.setUserData(jts.getUserData());
+            return centroid;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the expected type of values produced by this expression when a feature of
the given
+     * type is evaluated.
+     *
+     * @param  valueType  the type of features on which to apply the expression.
+     * @return expected expression result type.
+     * @throws IllegalArgumentException if this method can not determine the property type
for the given feature type.
+     */
+    @Override
+    public PropertyType expectedType(final FeatureType valueType) {
+        final PropertyType expectedType = expectedType(0, valueType);
+        if (expectedType instanceof AttributeType<?>) {
+            AttributeType<?> att = (AttributeType<?>) expectedType;
+            if (Geometries.isKnownType(att.getValueClass())) {
+                return new FeatureTypeBuilder().addAttribute(att).setValueClass(Point.class).build();
+            }
+        }
+        throw new IllegalArgumentException("First expression must result in a geometric attribute");
       // TODO: localize.
+    }
+}
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 c61c9bb..89e9660 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
@@ -22,8 +22,11 @@ import org.apache.sis.test.TestCase;
 import org.junit.Assert;
 import org.junit.Test;
 import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Envelope;
 import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.LineString;
 import org.locationtech.jts.geom.Point;
+import org.locationtech.jts.geom.Polygon;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.filter.FilterFactory2;
@@ -32,8 +35,12 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
 
 /**
+ * Tests {@link SQLMM} functions implementations.
  *
  * @author Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since   1.0
+ * @module
  */
 public class SQLMMTest extends TestCase {
     /**
@@ -93,4 +100,75 @@ public class SQLMMTest extends TestCase {
             Assert.assertEquals(10.0, trs.getY(), 0.0);
         }
     }
+
+    /**
+     * Test SQL/MM ST_Centroid function.
+     */
+    @Test
+    public void ST_CentroidTest() {
+
+        CoordinateReferenceSystem crs = CommonCRS.WGS84.geographic();
+
+        //test invalid
+        try {
+            factory.function("ST_Centroid");
+            Assert.fail("Creation with no argument should fail");
+        } catch (IllegalArgumentException ex) {
+            //ok
+        }
+
+        final LineString geometry = gf.createLineString(new Coordinate[]{new Coordinate(10,
20), new Coordinate(30, 20)});
+        geometry.setSRID(4326);
+        geometry.setUserData(crs);
+
+
+        final Function fct = factory.function("ST_Centroid", factory.literal(geometry));
+
+        //check result
+        final Object newGeom = fct.evaluate(null);
+        Assert.assertTrue(newGeom instanceof Point);
+        final Point trs = (Point) newGeom;
+        Assert.assertEquals(crs, trs.getUserData());
+        Assert.assertEquals(4326, trs.getSRID());
+        Assert.assertEquals(20.0, trs.getX(), 0.0);
+        Assert.assertEquals(20.0, trs.getY(), 0.0);
+
+    }
+
+    /**
+     * Test SQL/MM ST_Buffer function.
+     */
+    @Test
+    public void ST_BufferTest() {
+
+        CoordinateReferenceSystem crs = CommonCRS.WGS84.geographic();
+
+        //test invalid
+        try {
+            factory.function("ST_Buffer");
+            Assert.fail("Creation with no argument should fail");
+        } catch (IllegalArgumentException ex) {
+            //ok
+        }
+
+        final Point geometry = gf.createPoint(new Coordinate(10, 20));
+        geometry.setSRID(4326);
+        geometry.setUserData(crs);
+
+
+        final Function fct = factory.function("ST_Buffer", factory.literal(geometry), factory.literal(1.0));
+
+        //check result
+        final Object newGeom = fct.evaluate(null);
+        Assert.assertTrue(newGeom instanceof Polygon);
+        final Polygon trs = (Polygon) newGeom;
+        Assert.assertEquals(crs, trs.getUserData());
+        Assert.assertEquals(4326, trs.getSRID());
+        Envelope env = trs.getEnvelopeInternal();
+        Assert.assertEquals(9.0, env.getMinX(), 0.0);
+        Assert.assertEquals(11.0, env.getMaxX(), 0.0);
+        Assert.assertEquals(19.0, env.getMinY(), 0.0);
+        Assert.assertEquals(21.0, env.getMaxY(), 0.0);
+
+    }
 }


Mime
View raw message