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