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_Simplify and ST_SimplifyPreserveTopology functions
Date Wed, 06 Nov 2019 10:50:36 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 52089a1  Filter : add SQL/MM ST_Simplify and ST_SimplifyPreserveTopology functions
52089a1 is described below

commit 52089a12645caf05ae5b6f95597d15e25b39758d
Author: jsorel <johann.sorel@geomatys.com>
AuthorDate: Wed Nov 6 11:50:13 2019 +0100

    Filter : add SQL/MM ST_Simplify and ST_SimplifyPreserveTopology functions
---
 .../src/main/java/org/apache/sis/filter/SQLMM.java |  13 ++-
 .../java/org/apache/sis/filter/ST_Simplify.java    | 112 +++++++++++++++++++++
 .../sis/filter/ST_SimplifyPreserveTopology.java    | 112 +++++++++++++++++++++
 .../test/java/org/apache/sis/filter/SQLMMTest.java |  54 ++++++++++
 4 files changed, 286 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 8421887..28b6816 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
@@ -34,7 +34,7 @@ import org.apache.sis.util.ArgumentChecks;
  * @todo Implement all SQL/MM specification functions.
  *
  * @author  Johann Sorel (Geomatys)
- * @version 1.1
+ * @version 2.0
  * @since   1.1
  * @module
  */
@@ -58,7 +58,8 @@ final class SQLMM implements FunctionRegister {
      */
     @Override
     public Collection<String> getNames() {
-        return Arrays.asList(ST_Transform.NAME, ST_Centroid.NAME, ST_Buffer.NAME);
+        return Arrays.asList(ST_Transform.NAME, ST_Centroid.NAME, ST_Buffer.NAME,
+                ST_Simplify.NAME, ST_SimplifyPreserveTopology.NAME);
     }
 
     /**
@@ -79,9 +80,11 @@ 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);
+                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);
+                case ST_Simplify.NAME:                  return new ST_Simplify(parameters);
+                case ST_SimplifyPreserveTopology.NAME:  return new ST_SimplifyPreserveTopology(parameters);
                 default: throw new IllegalArgumentException(Resources.format(Resources.Keys.UnknownFunction_1,
name));
             }
         } catch (FactoryException e) {
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Simplify.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Simplify.java
new file mode 100644
index 0000000..2a7c0a8
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Simplify.java
@@ -0,0 +1,112 @@
+/*
+ * 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.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.internal.feature.Geometries;
+import org.apache.sis.util.ArgumentChecks;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.simplify.DouglasPeuckerSimplifier;
+import org.opengis.feature.FeatureType;
+import org.opengis.filter.expression.Expression;
+
+
+/**
+ * An expression which computes a geometry simplification.
+ * 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 tolerance. The evaluated value shall be
an instance of {@link Number}.
+ *       Distance is expressed in units of the geometry Coordinate Reference System.</li>
+ * </ol>
+ *
+ * <p>
+ * Note : this function is defined in PostGIS and H2GIS but not in SQL/MM 13249-3 2011.
+ * Likely in a newer version.
+ * </p>
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @version 2.0
+ * @since   2.0
+ * @module
+ */
+final class ST_Simplify extends NamedFunction implements FeatureExpression {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -7007942414561048416L;
+
+    /**
+     * Name of this function as defined by SQL/MM standard.
+     */
+    static final String NAME = "ST_Simplify";
+
+    /**
+     * 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.
+     */
+    ST_Simplify(final Expression[] parameters) {
+        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, gets the buffer of that geometry
and
+     * returns the result. If the geometry is not a supported implementation, returns {@code
null}.
+     */
+    @Override
+    public Object evaluate(final Object value) {
+        Object geometry = parameters.get(0).evaluate(value);
+        double distanceTolerance = parameters.get(1).evaluate(value, Number.class).doubleValue();
+        if (geometry instanceof Geometry) {
+            Geometry geom = DouglasPeuckerSimplifier.simplify((Geometry) geometry, distanceTolerance);
+            geom.setSRID(((Geometry) geometry).getSRID());
+            geom.setUserData(((Geometry) geometry).getUserData());
+            return geom;
+        }
+        return null;
+    }
+
+    /**
+     * Provides the 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 this expression.
+     * @param  addTo      where to add the type of properties evaluated by this expression.
+     * @return builder of type resulting from expression evaluation (never null).
+     * @throws IllegalArgumentException if the given feature type does not contain the expected
properties.
+     */
+    @Override
+    public PropertyTypeBuilder expectedType(final FeatureType valueType, final FeatureTypeBuilder
addTo) {
+        final AttributeTypeBuilder<?> pt = copyGeometryType(valueType, addTo);
+        return pt.setValueClass(Geometries.implementation(pt.getValueClass()).rootClass);
+    }
+}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_SimplifyPreserveTopology.java
b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_SimplifyPreserveTopology.java
new file mode 100644
index 0000000..4b9b75d
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_SimplifyPreserveTopology.java
@@ -0,0 +1,112 @@
+/*
+ * 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.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.internal.feature.Geometries;
+import org.apache.sis.util.ArgumentChecks;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.simplify.TopologyPreservingSimplifier;
+import org.opengis.feature.FeatureType;
+import org.opengis.filter.expression.Expression;
+
+
+/**
+ * An expression which computes a geometry simplification preserving topology.
+ * 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 tolerance. The evaluated value shall be
an instance of {@link Number}.
+ *       Distance is expressed in units of the geometry Coordinate Reference System.</li>
+ * </ol>
+ *
+ * <p>
+ * Note : this function is defined in PostGIS and H2GIS but not in SQL/MM 13249-3 2011.
+ * Likely in a newer version.
+ * </p>
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @version 2.0
+ * @since   2.0
+ * @module
+ */
+final class ST_SimplifyPreserveTopology extends NamedFunction implements FeatureExpression
{
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 6614108500745749460L;
+
+    /**
+     * Name of this function as defined by SQL/MM standard.
+     */
+    static final String NAME = "ST_SimplifyPreserveTopology";
+
+    /**
+     * 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.
+     */
+    ST_SimplifyPreserveTopology(final Expression[] parameters) {
+        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, gets the buffer of that geometry
and
+     * returns the result. If the geometry is not a supported implementation, returns {@code
null}.
+     */
+    @Override
+    public Object evaluate(final Object value) {
+        Object geometry = parameters.get(0).evaluate(value);
+        double distanceTolerance = parameters.get(1).evaluate(value, Number.class).doubleValue();
+        if (geometry instanceof Geometry) {
+            Geometry geom = TopologyPreservingSimplifier.simplify((Geometry) geometry, distanceTolerance);
+            geom.setSRID(((Geometry) geometry).getSRID());
+            geom.setUserData(((Geometry) geometry).getUserData());
+            return geom;
+        }
+        return null;
+    }
+
+    /**
+     * Provides the 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 this expression.
+     * @param  addTo      where to add the type of properties evaluated by this expression.
+     * @return builder of type resulting from expression evaluation (never null).
+     * @throws IllegalArgumentException if the given feature type does not contain the expected
properties.
+     */
+    @Override
+    public PropertyTypeBuilder expectedType(final FeatureType valueType, final FeatureTypeBuilder
addTo) {
+        final AttributeTypeBuilder<?> pt = copyGeometryType(valueType, addTo);
+        return pt.setValueClass(Geometries.implementation(pt.getValueClass()).rootClass);
+    }
+}
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 985609c..0ed8ba5 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
@@ -197,4 +197,58 @@ public final strictfp class SQLMMTest extends TestCase {
         assertEquals(19, env.getMinY(), STRICT);
         assertEquals(21, env.getMaxY(), STRICT);
     }
+
+    /**
+     * Test SQL/MM {@link ST_Simplify} function.
+     */
+    @Test
+    public void ST_SimplifyTest() {
+        assertRequireArguments("ST_Simplify");
+        /*
+         * Creates a single line for testing the simplify function. The CRS is not used by
this computation,
+         * but we declare it in order to verify that the information is propagated to the
result.
+         */
+        final LineString geometry = geometryFactory.createLineString(new Coordinate[]{new
Coordinate(10, 20), new Coordinate(15, 20), new Coordinate(20, 20)});
+        geometry.setUserData(HardCodedCRS.WGS84_φλ);
+        geometry.setSRID(4326);
+        /*
+         * Execute the function and check the result.
+         */
+        final LineString result = evaluate(LineString.class, null, factory.function("ST_Simplify",
factory.literal(geometry), factory.literal(10)));
+        assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+        assertEquals("SRID", 4326, result.getSRID());
+        Coordinate[] coordinates = result.getCoordinates();
+        assertEquals(2, coordinates.length);
+        assertEquals(10, coordinates[0].x, STRICT);
+        assertEquals(20, coordinates[0].y, STRICT);
+        assertEquals(20, coordinates[1].x, STRICT);
+        assertEquals(20, coordinates[1].y, STRICT);
+    }
+
+    /**
+     * Test SQL/MM {@link ST_SimplifyPreserveTopology} function.
+     */
+    @Test
+    public void ST_SimplifyPreserveTopologyTest() {
+        assertRequireArguments("ST_SimplifyPreserveTopology");
+        /*
+         * Creates a single line for testing the simplify function. The CRS is not used by
this computation,
+         * but we declare it in order to verify that the information is propagated to the
result.
+         */
+        final LineString geometry = geometryFactory.createLineString(new Coordinate[]{new
Coordinate(10, 20), new Coordinate(15, 20), new Coordinate(20, 20)});
+        geometry.setUserData(HardCodedCRS.WGS84_φλ);
+        geometry.setSRID(4326);
+        /*
+         * Execute the function and check the result.
+         */
+        final LineString result = evaluate(LineString.class, null, factory.function("ST_SimplifyPreserveTopology",
factory.literal(geometry), factory.literal(10)));
+        assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+        assertEquals("SRID", 4326, result.getSRID());
+        Coordinate[] coordinates = result.getCoordinates();
+        assertEquals(2, coordinates.length);
+        assertEquals(10, coordinates[0].x, STRICT);
+        assertEquals(20, coordinates[0].y, STRICT);
+        assertEquals(20, coordinates[1].x, STRICT);
+        assertEquals(20, coordinates[1].y, STRICT);
+    }
 }


Mime
View raw message