This is an automated email from the ASF dual-hosted git repository.
jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git
The following commit(s) were added to refs/heads/master by this push:
new c49b3326f [SEDONA-596] [SEDONA-597] Add ST_SimplifyVW,
ST_SimplifyPolygonHull (#1467)
c49b3326f is described below
commit c49b3326fa67ecccd904d7fc1716088ad6878b66
Author: Jia Yu <[email protected]>
AuthorDate: Fri Jun 7 14:43:34 2024 -0700
[SEDONA-596] [SEDONA-597] Add ST_SimplifyVW, ST_SimplifyPolygonHull (#1467)
* [TASK-77] Add ST_SimplifyVW (#185)
* feat: Add ST_SimplifyVW
* fix: snowflake test wrong argument
* fix: snowflake test
* Update versions
* [TASK-140] Add ST_SimplifyPolygonHull (#187)
* Update versions
---------
Co-authored-by: Furqaan Khan <[email protected]>
---
.../java/org/apache/sedona/common/Functions.java | 17 +++++
.../org/apache/sedona/common/FunctionsTest.java | 55 ++++++++++++++++
docs/api/flink/Function.md | 73 ++++++++++++++++++++++
docs/api/snowflake/vector-data/Function.md | 69 ++++++++++++++++++++
docs/api/sql/Function.md | 73 ++++++++++++++++++++++
.../main/java/org/apache/sedona/flink/Catalog.java | 2 +
.../apache/sedona/flink/expressions/Functions.java | 26 ++++++++
.../java/org/apache/sedona/flink/FunctionTest.java | 20 ++++++
python/sedona/sql/st_functions.py | 28 +++++++++
python/tests/sql/test_dataframe_api.py | 9 +++
python/tests/sql/test_function.py | 17 +++++
.../sedona/snowflake/snowsql/TestFunctions.java | 24 +++++++
.../sedona/snowflake/snowsql/TestFunctionsV2.java | 24 +++++++
.../org/apache/sedona/snowflake/snowsql/UDFs.java | 31 +++++++++
.../apache/sedona/snowflake/snowsql/UDFsV2.java | 31 +++++++++
.../scala/org/apache/sedona/sql/UDF/Catalog.scala | 2 +
.../sql/sedona_sql/expressions/Functions.scala | 16 +++++
.../sql/sedona_sql/expressions/st_functions.scala | 8 +++
.../apache/sedona/sql/dataFrameAPITestScala.scala | 18 ++++++
.../org/apache/sedona/sql/functionTestScala.scala | 18 ++++++
20 files changed, 561 insertions(+)
diff --git a/common/src/main/java/org/apache/sedona/common/Functions.java
b/common/src/main/java/org/apache/sedona/common/Functions.java
index dcd5fbf6a..161d862db 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -43,7 +43,9 @@ import org.locationtech.jts.operation.valid.IsSimpleOp;
import org.locationtech.jts.operation.valid.IsValidOp;
import org.locationtech.jts.operation.valid.TopologyValidationError;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
+import org.locationtech.jts.simplify.PolygonHullSimplifier;
import org.locationtech.jts.simplify.TopologyPreservingSimplifier;
+import org.locationtech.jts.simplify.VWSimplifier;
import
org.locationtech.jts.triangulate.polygon.ConstrainedDelaunayTriangulator;
import org.wololo.jts2geojson.GeoJSONWriter;
@@ -1243,6 +1245,21 @@ public class Functions {
return TopologyPreservingSimplifier.simplify(geometry,
distanceTolerance);
}
+ public static Geometry simplifyVW(Geometry geometry, double tolerance) {
+ // JTS squares the tolerance in its implementation, inorder to keep it
consistent square rooting the input tolerance
+ // source:
https://github.com/locationtech/jts/blob/7ef2b9d2e6f36ce5e7a787cff57bd18281e50826/modules/core/src/main/java/org/locationtech/jts/simplify/VWLineSimplifier.java#L41
+ tolerance = Math.sqrt(tolerance);
+ return VWSimplifier.simplify(geometry, tolerance);
+ }
+
+ public static Geometry simplifyPolygonHull(Geometry geometry, double
vertexFactor, boolean isOuter) {
+ return PolygonHullSimplifier.hull(geometry, isOuter, vertexFactor);
+ }
+
+ public static Geometry simplifyPolygonHull(Geometry geometry, double
vertexFactor) {
+ return simplifyPolygonHull(geometry, vertexFactor, true);
+ }
+
public static String geometryType(Geometry geometry) {
return "ST_" + geometry.getGeometryType();
}
diff --git a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
index 3456fef9e..8915c2cab 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -1310,6 +1310,61 @@ public class FunctionsTest extends TestBase {
assertEquals(expected, e.getMessage());
}
+ @Test
+ public void simplifyVW() throws ParseException {
+ Geometry geom = Constructors.geomFromEWKT("LINESTRING(5 2, 3 8, 6 20,
7 25, 10 10)");
+ String actual = Functions.simplifyVW(geom, 30).toString();
+ String expected = "LINESTRING (5 2, 7 25, 10 10)";
+ assertEquals(expected, actual);
+
+ actual = Functions.simplifyVW(geom, 10).toString();
+ expected = "LINESTRING (5 2, 3 8, 7 25, 10 10)";
+ assertEquals(expected, actual);
+
+ geom = Constructors.geomFromEWKT("POLYGON((8 25, 28 22, 28 20, 15 11,
33 3, 56 30, 46 33,46 34, 47 44, 35 36, 45 33, 43 19, 29 21, 29 22,35 26, 24
39, 8 25))");
+ actual = Functions.simplifyVW(geom, 10).toString();
+ expected = "POLYGON ((8 25, 28 22, 28 20, 15 11, 33 3, 56 30, 46 33,
47 44, 35 36, 45 33, 43 19, 29 21, 35 26, 24 39, 8 25))";
+ assertEquals(expected, actual);
+
+ actual = Functions.simplifyVW(geom, 80).toString();
+ expected = "POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 43 19,
24 39, 8 25))";
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void simplifyPolygonHull() throws ParseException {
+ Geometry geom = Constructors.geomFromEWKT("POLYGON ((131 158, 136 163,
161 165, 173 156, 179 148, 169 140, 186 144, 190 137, 185 131, 174 128, 174
124, 166 119, 158 121, 158 115, 165 107, 161 97, 166 88, 166 79, 158 57, 145
57, 112 53, 111 47, 93 43, 90 48, 88 40, 80 39, 68 32, 51 33, 40 31, 39 34, 49
38, 34 38, 25 34, 28 39, 36 40, 44 46, 24 41, 17 41, 14 46, 19 50, 33 54, 21
55, 13 52, 11 57, 22 60, 34 59, 41 68, 75 72, 62 77, 56 70, 46 72, 31 69, 46
76, 52 82, 47 84, 56 90, 66 [...]
+ String actual = Functions.asWKT(Functions.simplifyPolygonHull(geom,
0.3, true));
+ String expected = "POLYGON ((161 165, 173 156, 186 144, 190 137, 185
131, 174 124, 166 119, 166 79, 158 57, 68 32, 40 31, 25 34, 17 41, 14 46, 11
57, 56 91, 33 97, 23 100, 22 107, 28 131, 80 135, 73 145, 85 157, 99 162, 122
170, 161 165))";
+ assertEquals(expected, actual);
+
+ actual = Functions.asWKT(Functions.simplifyPolygonHull(geom, 0.3));
+ assertEquals(expected, actual);
+
+ actual = Functions.asWKT(Functions.simplifyPolygonHull(geom, 0.3,
false));
+ expected = "POLYGON ((131 158, 116 158, 99 162, 89 137, 76 130, 59
127, 28 131, 46 116, 36 100, 64 94, 75 72, 41 68, 33 54, 68 32, 90 48, 112 53,
145 57, 158 57, 161 97, 158 115, 158 121, 190 137, 169 140, 179 148, 161 165,
131 158))";
+ assertEquals(expected, actual);
+
+ actual = Functions.asWKT(Functions.simplifyPolygonHull(geom, 0.1,
false));
+ expected = "POLYGON ((89 137, 36 100, 64 94, 75 72, 33 54, 112 53, 145
57, 161 165, 89 137))";
+ assertEquals(expected, actual);
+
+ actual = Functions.asWKT(Functions.simplifyPolygonHull(geom, 0.1));
+ expected = "POLYGON ((161 165, 173 156, 186 144, 190 137, 158 57, 68
32, 40 31, 25 34, 17 41, 14 46, 11 57, 22 107, 28 131, 85 157, 99 162, 122 170,
161 165))";
+ assertEquals(expected, actual);
+
+ geom = Constructors.geomFromEWKT("MULTIPOLYGON (((131 158, 136 163,
161 165, 173 156, 179 148, 169 140, 186 144, 190 137, 185 131, 174 128, 174
124, 166 119, 158 121, 158 115, 165 107, 161 97, 166 88, 166 79, 158 57, 145
57, 112 53, 111 47, 93 43, 90 48, 88 40, 80 39, 68 32, 51 33, 40 31, 39 34, 49
38, 34 38, 25 34, 28 39, 36 40, 44 46, 24 41, 17 41, 14 46, 19 50, 33 54, 21
55, 13 52, 11 57, 22 60, 34 59, 41 68, 75 72, 62 77, 56 70, 46 72, 31 69, 46
76, 52 82, 47 84, 56 90, 66 90 [...]
+ actual = Functions.asWKT(Functions.simplifyPolygonHull(geom, 0.3,
true));
+ expected = "MULTIPOLYGON (((161 165, 173 156, 186 144, 190 137, 185
131, 174 124, 166 119, 166 79, 158 57, 68 32, 40 31, 25 34, 17 41, 14 46, 11
57, 56 91, 33 97, 23 100, 22 107, 28 131, 80 135, 73 145, 85 157, 99 162, 122
170, 161 165)))";
+ assertEquals(expected, actual);
+
+ geom = Constructors.geomFromEWKT("LINESTRING (10 10, 20 20, 30 30)");
+ Geometry finalGeom = geom;
+ assertThrows("Input geometry must be polygonal",
IllegalArgumentException.class, () -> {
+ Functions.simplifyPolygonHull(finalGeom, 0.1);
+ });
+ }
+
@Test
public void force3DObject2D() {
int expectedDims = 3;
diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index b3ea497ab..660658491 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -3042,6 +3042,56 @@ Output:
3021
```
+## ST_SimplifyPolygonHull
+
+Introduction: This function computes a topology-preserving simplified hull,
either outer or inner, for a polygonal geometry input. An outer hull fully
encloses the original geometry, while an inner hull lies entirely within. The
result maintains the same structure as the input, including handling of
MultiPolygons and holes, represented as a polygonal geometry formed from a
subset of vertices.
+
+Vertex reduction is governed by the `vertexFactor` parameter ranging from 0 to
1, with lower values yielding simpler outputs with fewer vertices and reduced
concavity. For both hull types, a `vertexFactor` of 1.0 returns the original
geometry. Specifically, for outer hulls, 0.0 computes the convex hull; for
inner hulls, 0.0 produces a triangular geometry.
+
+The simplification algorithm iteratively removes concave corners containing
the least area until reaching the target vertex count. It preserves topology by
preventing edge crossings, ensuring the output is a valid polygonal geometry in
all cases.
+
+Format:
+
+```
+ST_SimplifyPolygonHull(geom: Geometry, vertexFactor: Double, isOuter: Boolean
= true)
+```
+
+```
+ST_SimplifyPolygonHull(geom: Geometry, vertexFactor: Double)
+```
+
+Since: `v1.6.1`
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyPolygonHull(
+ ST_GeomFromText('POLYGON ((30 10, 40 40, 45 45, 50 30, 55 25, 60 50,
65 45, 70 30, 75 20, 80 25, 70 10, 30 10))'),
+ 0.4
+)
+```
+
+Output:
+
+```
+POLYGON ((30 10, 40 40, 45 45, 60 50, 65 45, 80 25, 70 10, 30 10))
+```
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyPolygonHull(
+ ST_GeomFromText('POLYGON ((30 10, 40 40, 45 45, 50 30, 55 25, 60 50,
65 45, 70 30, 75 20, 80 25, 70 10, 30 10))'),
+ 0.4, false
+)
+```
+
+Output:
+
+```
+POLYGON ((30 10, 70 10, 60 50, 55 25, 30 10))
+```
+
## ST_SimplifyPreserveTopology
Introduction: Simplifies a geometry and ensures that the result is a valid
geometry having the same dimension and number of components as the input,
@@ -3063,6 +3113,29 @@ Output:
POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 35 36, 43 19, 24 39, 8 25))
```
+## ST_SimplifyVW
+
+Introduction: This function simplifies the input geometry by applying the
Visvalingam-Whyatt algorithm.
+
+!!!Note
+ The simplification may not preserve topology, potentially producing
invalid geometries. Use
[ST_SimplifyPreserveTopology](#st_simplifypreservetopology) to retain valid
topology after simplification.
+
+Format: `ST_SimplifyVW(geom: Geometry, tolerance: Double)`
+
+Since: `v1.6.1`
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyVW(ST_GeomFromWKT('POLYGON((8 25, 28 22, 28 20, 15 11, 33 3,
56 30, 46 33,46 34, 47 44, 35 36, 45 33, 43 19, 29 21, 29 22,35 26, 24 39, 8
25))'), 80)
+```
+
+Output:
+
+```
+POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 43 19, 24 39, 8 25))
+```
+
## ST_Snap
Introduction: Snaps the vertices and segments of the `input` geometry to
`reference` geometry within the specified `tolerance` distance. The `tolerance`
parameter controls the maximum snap distance.
diff --git a/docs/api/snowflake/vector-data/Function.md
b/docs/api/snowflake/vector-data/Function.md
index 3674661cc..5f862e767 100644
--- a/docs/api/snowflake/vector-data/Function.md
+++ b/docs/api/snowflake/vector-data/Function.md
@@ -2254,6 +2254,54 @@ Output:
LINESTRING(177 10, 179 10, 181 10, 183 10)
```
+## ST_SimplifyPolygonHull
+
+Introduction: This function computes a topology-preserving simplified hull,
either outer or inner, for a polygonal geometry input. An outer hull fully
encloses the original geometry, while an inner hull lies entirely within. The
result maintains the same structure as the input, including handling of
MultiPolygons and holes, represented as a polygonal geometry formed from a
subset of vertices.
+
+Vertex reduction is governed by the `vertexFactor` parameter ranging from 0 to
1, with lower values yielding simpler outputs with fewer vertices and reduced
concavity. For both hull types, a `vertexFactor` of 1.0 returns the original
geometry. Specifically, for outer hulls, 0.0 computes the convex hull; for
inner hulls, 0.0 produces a triangular geometry.
+
+The simplification algorithm iteratively removes concave corners containing
the least area until reaching the target vertex count. It preserves topology by
preventing edge crossings, ensuring the output is a valid polygonal geometry in
all cases.
+
+Format:
+
+```
+ST_SimplifyPolygonHull(geom: Geometry, vertexFactor: Double, isOuter: Boolean
= true)
+```
+
+```
+ST_SimplifyPolygonHull(geom: Geometry, vertexFactor: Double)
+```
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyPolygonHull(
+ ST_GeomFromText('POLYGON ((30 10, 40 40, 45 45, 50 30, 55 25, 60 50,
65 45, 70 30, 75 20, 80 25, 70 10, 30 10))'),
+ 0.4
+)
+```
+
+Output:
+
+```
+POLYGON ((30 10, 40 40, 45 45, 60 50, 65 45, 80 25, 70 10, 30 10))
+```
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyPolygonHull(
+ ST_GeomFromText('POLYGON ((30 10, 40 40, 45 45, 50 30, 55 25, 60 50,
65 45, 70 30, 75 20, 80 25, 70 10, 30 10))'),
+ 0.4, false
+)
+```
+
+Output:
+
+```
+POLYGON ((30 10, 70 10, 60 50, 55 25, 30 10))
+```
+
## ST_SimplifyPreserveTopology
Introduction: Simplifies a geometry and ensures that the result is a valid
geometry having the same dimension and number of components as the input,
@@ -2266,6 +2314,27 @@ SELECT
ST_SimplifyPreserveTopology(polygondf.countyshape, 10.0)
FROM polygondf
```
+## ST_SimplifyVW
+
+Introduction: This function simplifies the input geometry by applying the
Visvalingam-Whyatt algorithm.
+
+!!!Note
+ The simplification may not preserve topology, potentially producing
invalid geometries. Use
[ST_SimplifyPreserveTopology](#st_simplifypreservetopology) to retain valid
topology after simplification.
+
+Format: `ST_SimplifyVW(geom: Geometry, tolerance: Double)`
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyVW(ST_GeomFromWKT('POLYGON((8 25, 28 22, 28 20, 15 11, 33 3,
56 30, 46 33,46 34, 47 44, 35 36, 45 33, 43 19, 29 21, 29 22,35 26, 24 39, 8
25))'), 80)
+```
+
+Output:
+
+```
+POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 43 19, 24 39, 8 25))
+```
+
## ST_Snap
Introduction: Snaps the vertices and segments of the `input` geometry to
`reference` geometry within the specified `tolerance` distance. The `tolerance`
parameter controls the maximum snap distance.
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 0c5dcf31d..ff0a58fbe 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -3031,6 +3031,56 @@ Output:
LINESTRING(177 10, 179 10, 181 10, 183 10)
```
+## ST_SimplifyPolygonHull
+
+Introduction: This function computes a topology-preserving simplified hull,
either outer or inner, for a polygonal geometry input. An outer hull fully
encloses the original geometry, while an inner hull lies entirely within. The
result maintains the same structure as the input, including handling of
MultiPolygons and holes, represented as a polygonal geometry formed from a
subset of vertices.
+
+Vertex reduction is governed by the `vertexFactor` parameter ranging from 0 to
1, with lower values yielding simpler outputs with fewer vertices and reduced
concavity. For both hull types, a `vertexFactor` of 1.0 returns the original
geometry. Specifically, for outer hulls, 0.0 computes the convex hull; for
inner hulls, 0.0 produces a triangular geometry.
+
+The simplification algorithm iteratively removes concave corners containing
the least area until reaching the target vertex count. It preserves topology by
preventing edge crossings, ensuring the output is a valid polygonal geometry in
all cases.
+
+Format:
+
+```
+ST_SimplifyPolygonHull(geom: Geometry, vertexFactor: Double, isOuter: Boolean
= true)
+```
+
+```
+ST_SimplifyPolygonHull(geom: Geometry, vertexFactor: Double)
+```
+
+Since: `v1.6.1`
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyPolygonHull(
+ ST_GeomFromText('POLYGON ((30 10, 40 40, 45 45, 50 30, 55 25, 60 50,
65 45, 70 30, 75 20, 80 25, 70 10, 30 10))'),
+ 0.4
+)
+```
+
+Output:
+
+```
+POLYGON ((30 10, 40 40, 45 45, 60 50, 65 45, 80 25, 70 10, 30 10))
+```
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyPolygonHull(
+ ST_GeomFromText('POLYGON ((30 10, 40 40, 45 45, 50 30, 55 25, 60 50,
65 45, 70 30, 75 20, 80 25, 70 10, 30 10))'),
+ 0.4, false
+)
+```
+
+Output:
+
+```
+POLYGON ((30 10, 70 10, 60 50, 55 25, 30 10))
+```
+
## ST_SimplifyPreserveTopology
Introduction: Simplifies a geometry and ensures that the result is a valid
geometry having the same dimension and number of components as the input,
@@ -3052,6 +3102,29 @@ Output:
POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 35 36, 43 19, 24 39, 8 25))
```
+## ST_SimplifyVW
+
+Introduction: This function simplifies the input geometry by applying the
Visvalingam-Whyatt algorithm.
+
+!!!Note
+ The simplification may not preserve topology, potentially producing
invalid geometries. Use
[ST_SimplifyPreserveTopology](#st_simplifypreservetopology) to retain valid
topology after simplification.
+
+Format: `ST_SimplifyVW(geom: Geometry, tolerance: Double)`
+
+Since: `v1.6.1`
+
+SQL Example
+
+```sql
+SELECT ST_SimplifyVW(ST_GeomFromWKT('POLYGON((8 25, 28 22, 28 20, 15 11, 33 3,
56 30, 46 33,46 34, 47 44, 35 36, 45 33, 43 19, 29 21, 29 22,35 26, 24 39, 8
25))'), 80)
+```
+
+Output:
+
+```
+POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 43 19, 24 39, 8 25))
+```
+
## ST_Snap
Introduction: Snaps the vertices and segments of the `input` geometry to
`reference` geometry within the specified `tolerance` distance. The `tolerance`
parameter controls the maximum snap distance.
diff --git a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
index 051a0ebe5..91eebd9c4 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -155,6 +155,8 @@ public class Catalog {
new Functions.ST_StartPoint(),
new Functions.ST_ShiftLongitude(),
new Functions.ST_SimplifyPreserveTopology(),
+ new Functions.ST_SimplifyVW(),
+ new Functions.ST_SimplifyPolygonHull(),
new Functions.ST_Split(),
new Functions.ST_Subdivide(),
new Functions.ST_SymDifference(),
diff --git
a/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
b/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
index cad1be4bc..79d1a8b26 100644
--- a/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
+++ b/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
@@ -1037,6 +1037,32 @@ public class Functions {
}
}
+ public static class ST_SimplifyVW extends ScalarFunction {
+ @DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class)
+ public Geometry eval(@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o,
+ @DataTypeHint("Double") Double distanceTolerance)
{
+ Geometry geom = (Geometry) o;
+ return org.apache.sedona.common.Functions.simplifyVW(geom,
distanceTolerance);
+ }
+ }
+
+ public static class ST_SimplifyPolygonHull extends ScalarFunction {
+ @DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class)
+ public Geometry eval(@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o,
+ @DataTypeHint("Double") Double vertexFactor,
+ @DataTypeHint("Boolean") Boolean isOuter) {
+ Geometry geom = (Geometry) o;
+ return
org.apache.sedona.common.Functions.simplifyPolygonHull(geom, vertexFactor,
isOuter);
+ }
+
+ @DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class)
+ public Geometry eval(@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o,
+ @DataTypeHint("Double") Double vertexFactor) {
+ Geometry geom = (Geometry) o;
+ return
org.apache.sedona.common.Functions.simplifyPolygonHull(geom, vertexFactor);
+ }
+ }
+
public static class ST_Subdivide extends ScalarFunction {
@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry[].class)
public Geometry[] eval(@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o,
diff --git a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
index 8afd16012..f128b31d2 100644
--- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
@@ -1152,6 +1152,26 @@ public class FunctionTest extends TestBase{
assertEquals("POLYGON ((0 0, 1 0, 1 1, 0 0))", result.toString());
}
+ @Test
+ public void testSimplifyVW() {
+ Table table = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POLYGON ((0 0,
1 0, 1 0.9, 1 1, 0 0))') AS geom");
+ table =
table.select(call(Functions.ST_SimplifyPreserveTopology.class.getSimpleName(),
$("geom"), 2));
+ Geometry result = (Geometry) first(table).getField(0);
+ assertEquals("POLYGON ((0 0, 1 0, 1 1, 0 0))", result.toString());
+ }
+
+ @Test
+ public void testSimplifyPolygonHull() {
+ Table table = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POLYGON ((30
10, 40 40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))') AS geom");
+ String actual =
first(table.select(call(Functions.ST_SimplifyPolygonHull.class.getSimpleName(),
$("geom"), 0.3, false))).getField(0).toString();
+ String expected = "POLYGON ((30 10, 40 40, 10 20, 30 10))";
+ assertEquals(expected, actual);
+
+ actual =
first(table.select(call(Functions.ST_SimplifyPolygonHull.class.getSimpleName(),
$("geom"), 0.3))).getField(0).toString();
+ expected = "POLYGON ((30 10, 15 15, 10 20, 20 40, 45 45, 30 10))";
+ assertEquals(expected, actual);
+ }
+
@Test
public void testSplit() {
Table pointTable = tableEnv.sqlQuery("SELECT
ST_Split(ST_GeomFromWKT('LINESTRING (0 0, 1.5 1.5, 2 2)'),
ST_GeomFromWKT('MULTIPOINT (0.5 0.5, 1 1)'))");
diff --git a/python/sedona/sql/st_functions.py
b/python/sedona/sql/st_functions.py
index f12d6a9f2..1a3dd9809 100644
--- a/python/sedona/sql/st_functions.py
+++ b/python/sedona/sql/st_functions.py
@@ -1373,6 +1373,34 @@ def ST_SimplifyPreserveTopology(geometry: ColumnOrName,
distance_tolerance: Colu
"""
return _call_st_function("ST_SimplifyPreserveTopology", (geometry,
distance_tolerance))
+@validate_argument_types
+def ST_SimplifyVW(geometry: ColumnOrName, distance_tolerance:
ColumnOrNameOrNumber) -> Column:
+ """Simplify a geometry using Visvalingam-Whyatt algorithm within a
specified tolerance while preserving topological relationships.
+
+ :param geometry: Geometry column to simplify.
+ :type geometry: ColumnOrName
+ :param distance_tolerance: Tolerance for merging points together to
simplify the geometry as either a number or numeric column.
+ :type distance_tolerance: ColumnOrNameOrNumber
+ :return: Simplified geometry as a geometry column.
+ :rtype: Column
+ """
+ return _call_st_function("ST_SimplifyVW", (geometry, distance_tolerance))
+
+
+@validate_argument_types
+def ST_SimplifyPolygonHull(geometry: ColumnOrName, vertexFactor:
ColumnOrNameOrNumber, isOuter: Optional[Union[ColumnOrName, bool]] = None) ->
Column:
+ """Simplify a geometry using Visvalingam-Whyatt algorithm within a
specified tolerance while preserving topological relationships.
+
+ :param geometry: Geometry column to simplify.
+ :type geometry: ColumnOrName
+ :param vertexFactor: Tolerance for merging points together to simplify the
geometry as either a number or numeric column.
+ :type vertexFactor: ColumnOrNameOrNumber
+ :return: Simplified geometry as a geometry column.
+ :rtype: Column
+ """
+ args = (geometry, vertexFactor) if isOuter is None else (geometry,
vertexFactor, isOuter)
+
+ return _call_st_function("ST_SimplifyPolygonHull", args)
@validate_argument_types
def ST_Split(input: ColumnOrName, blade: ColumnOrName) -> Column:
diff --git a/python/tests/sql/test_dataframe_api.py
b/python/tests/sql/test_dataframe_api.py
index 060d675eb..2e201e538 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -193,6 +193,9 @@ test_configurations = [
(stf.ST_SetSRID, ("point", 3021), "point_geom", "ST_SRID(geom)", 3021),
(stf.ST_ShiftLongitude, ("geom",), "triangle_geom", "", "POLYGON ((0 0, 1
0, 1 1, 0 0))"),
(stf.ST_SimplifyPreserveTopology, ("geom", 0.2), "0.9_poly", "", "POLYGON
((0 0, 1 0, 1 1, 0 0))"),
+ (stf.ST_SimplifyVW, ("geom", 0.1), "0.9_poly", "", "POLYGON ((0 0, 1 0, 1
1, 0 0))"),
+ (stf.ST_SimplifyPolygonHull, ("geom", 0.3, False), "polygon_unsimplified",
"", "POLYGON ((30 10, 40 40, 10 20, 30 10))"),
+ (stf.ST_SimplifyPolygonHull, ("geom", 0.3), "polygon_unsimplified", "",
"POLYGON ((30 10, 15 15, 10 20, 20 40, 45 45, 30 10))"),
(stf.ST_Snap, ("poly", "line", 2.525), "poly_and_line", "" ,"POLYGON ((2.6
12.5, 2.6 20, 12.6 20, 12.6 12.5, 10.1 10, 2.6 12.5))"),
(stf.ST_Split, ("line", "points"), "multipoint_splitting_line", "",
"MULTILINESTRING ((0 0, 0.5 0.5), (0.5 0.5, 1 1), (1 1, 1.5 1.5, 2 2))"),
(stf.ST_SRID, ("point",), "point_geom", "", 0),
@@ -397,6 +400,10 @@ wrong_type_configurations = [
(stf.ST_ShiftLongitude, (None,)),
(stf.ST_SimplifyPreserveTopology, (None, 0.2)),
(stf.ST_SimplifyPreserveTopology, ("", None)),
+ (stf.ST_SimplifyVW, (None, 2)),
+ (stf.ST_SimplifyVW, ("", None)),
+ (stf.ST_SimplifyPolygonHull, ("", None)),
+ (stf.ST_SimplifyPolygonHull, (None, None)),
(stf.ST_Snap, (None, None, 12)),
(stf.ST_SRID, (None,)),
(stf.ST_StartPoint, (None,)),
@@ -520,6 +527,8 @@ class TestDataFrameAPI(TestBase):
return TestDataFrameAPI.spark.sql("SELECT ST_GeomFromWKT('POLYGON
((0 0, 3 0, 3 3, 0 0), (1 1, 2 2, 2 1, 1 1))') AS geom")
elif request.param == "0.9_poly":
return TestDataFrameAPI.spark.sql("SELECT ST_GeomFromWKT('POLYGON
((0 0, 1 0, 1 0.9, 1 1, 0 0))') AS geom")
+ elif request.param == "polygon_unsimplified":
+ return TestDataFrameAPI.spark.sql("SELECT ST_GeomFromWKT('POLYGON
((30 10, 40 40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))') AS geom")
elif request.param == "precision_reduce_point":
return TestDataFrameAPI.spark.sql("SELECT ST_Point(0.12, 0.23) AS
geom")
elif request.param == "closed_linestring_geom":
diff --git a/python/tests/sql/test_function.py
b/python/tests/sql/test_function.py
index 5d08c5de4..fcedfb794 100644
--- a/python/tests/sql/test_function.py
+++ b/python/tests/sql/test_function.py
@@ -896,6 +896,23 @@ class TestPredicateJoin(TestBase):
actual = self.spark.sql("SELECT ST_IsPolygonCW(ST_GeomFromWKT('POLYGON
((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30
20))'))").take(1)[0][0]
assert actual
+ def test_st_simplify_vw(self):
+ basedf = self.spark.sql("SELECT ST_GeomFromWKT('LINESTRING(5 2, 3 8, 6
20, 7 25, 10 10)') as geom")
+ actual = basedf.selectExpr("ST_SimplifyVW(geom, 30)").take(1)[0][0].wkt
+ expected = "LINESTRING (5 2, 7 25, 10 10)"
+ assert expected == actual
+
+ def test_st_simplify_polygon_hull(self):
+ basedf = self.spark.sql("SELECT ST_GeomFromWKT('POLYGON ((30 10, 40
40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))') as geom")
+ actual = basedf.selectExpr("ST_SimplifyPolygonHull(geom, 0.3,
false)").take(1)[0][0].wkt
+ expected = "POLYGON ((30 10, 40 40, 10 20, 30 10))"
+ assert expected == actual
+
+ actual = basedf.selectExpr("ST_SimplifyPolygonHull(geom,
0.3)").take(1)[0][0].wkt
+ expected = "POLYGON ((30 10, 15 15, 10 20, 20 40, 45 45, 30 10))"
+ assert expected == actual
+
+
def test_st_is_ring(self):
result_and_expected = [
[self.calculate_st_is_ring("LINESTRING(0 0, 0 1, 1 0, 1 1, 0 0)"),
False],
diff --git
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
index 94d8ac97a..8a39b3f01 100644
---
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
+++
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
@@ -864,6 +864,30 @@ public class TestFunctions extends TestBase {
"POLYGON ((8 25, 28 22, 15 11, 33 3, 56 30, 47 44, 35 36, 43
19, 24 39, 8 25))"
);
}
+
+ @Test
+ public void test_ST_SimplifyVW() {
+ registerUDF("ST_SimplifyVW", byte[].class, double.class);
+ verifySqlSingleRes(
+ "select
sedona.ST_AsText(sedona.ST_SimplifyVW(sedona.ST_GeomFromText('POLYGON((8 25, 28
22, 28 20, 15 11, 33 3, 56 30, 46 33,46 34, 47 44, 35 36, 45 33, 43 19, 29 21,
29 22,35 26, 24 39, 8 25))'), 10))",
+ "POLYGON ((8 25, 28 22, 28 20, 15 11, 33 3, 56 30, 46 33, 47
44, 35 36, 45 33, 43 19, 29 21, 35 26, 24 39, 8 25))"
+ );
+ }
+
+ @Test
+ public void test_ST_SimplifyPolygonHull() {
+ registerUDF("ST_SimplifyPolygonHull", byte[].class, double.class,
boolean.class);
+ verifySqlSingleRes(
+ "select
sedona.ST_AsText(sedona.ST_SimplifyPolygonHull(sedona.ST_GeomFromText('POLYGON
((30 10, 40 40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))'), 0.3, false))",
+ "POLYGON ((30 10, 40 40, 10 20, 30 10))"
+ );
+ registerUDF("ST_SimplifyPolygonHull", byte[].class, double.class);
+ verifySqlSingleRes(
+ "select
sedona.ST_AsText(sedona.ST_SimplifyPolygonHull(sedona.ST_GeomFromText('POLYGON
((30 10, 40 40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))'), 0.3))",
+ "POLYGON ((30 10, 15 15, 10 20, 20 40, 45 45, 30 10))"
+ );
+ }
+
@Test
public void test_ST_Split() {
registerUDF("ST_Split", byte[].class, byte[].class);
diff --git
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
index cc998e835..6f9448783 100644
---
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
+++
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
@@ -827,6 +827,30 @@ public class TestFunctionsV2
"POLYGON((8 25,28 22,15 11,33 3,56 30,47 44,35 36,43 19,24
39,8 25))"
);
}
+
+ @Test
+ public void test_ST_SimplifyVW() {
+ registerUDFV2("ST_SimplifyVW", String.class, double.class);
+ verifySqlSingleRes(
+ "select
ST_AsText(sedona.ST_SimplifyVW(ST_GeometryFromWKT('POLYGON((8 25, 28 22, 28 20,
15 11, 33 3, 56 30, 46 33,46 34, 47 44, 35 36, 45 33, 43 19, 29 21, 29 22,35
26, 24 39, 8 25))'), 10))",
+ "POLYGON((8 25,28 22,28 20,15 11,33 3,56 30,46 33,47 44,35
36,45 33,43 19,29 21,35 26,24 39,8 25))"
+ );
+ }
+
+ @Test
+ public void test_ST_SimplifyPolygonHull() {
+ registerUDFV2("ST_SimplifyPolygonHull", String.class, double.class,
boolean.class);
+ verifySqlSingleRes(
+ "select
ST_AsText(sedona.ST_SimplifyPolygonHull(ST_GeomFromText('POLYGON ((30 10, 40
40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))'), 0.3, false))",
+ "POLYGON((30 10,40 40,10 20,30 10))"
+ );
+ registerUDFV2("ST_SimplifyPolygonHull", String.class, double.class);
+ verifySqlSingleRes(
+ "select
ST_AsText(sedona.ST_SimplifyPolygonHull(ST_GeomFromText('POLYGON ((30 10, 40
40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))'), 0.3))",
+ "POLYGON((30 10,15 15,10 20,20 40,45 45,30 10))"
+ );
+ }
+
@Test
public void test_ST_Split() {
registerUDFV2("ST_Split", String.class, String.class);
diff --git
a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
index e503d4710..db4d394e1 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
@@ -1240,6 +1240,37 @@ public class UDFs {
);
}
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "distanceTolerance"})
+ public static byte[] ST_SimplifyVW(byte[] geometry, double
distanceTolerance) {
+ return GeometrySerde.serialize(
+ Functions.simplifyVW(
+ GeometrySerde.deserialize(geometry),
+ distanceTolerance
+ )
+ );
+ }
+
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "vertexFactor",
"isOuter"})
+ public static byte[] ST_SimplifyPolygonHull(byte[] geometry, double
vertexFactor, boolean isOuter) {
+ return GeometrySerde.serialize(
+ Functions.simplifyPolygonHull(
+ GeometrySerde.deserialize(geometry),
+ vertexFactor,
+ isOuter
+ )
+ );
+ }
+
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "vertexFactor"})
+ public static byte[] ST_SimplifyPolygonHull(byte[] geometry, double
vertexFactor) {
+ return GeometrySerde.serialize(
+ Functions.simplifyPolygonHull(
+ GeometrySerde.deserialize(geometry),
+ vertexFactor
+ )
+ );
+ }
+
@UDFAnnotations.ParamMeta(argNames = {"input", "blade"})
public static byte[] ST_Split(byte[] input, byte[] blade) {
return GeometrySerde.serialize(
diff --git
a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
index fbb4d2879..e2e0acdc5 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
@@ -984,6 +984,37 @@ public class UDFsV2
);
}
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "distanceTolerance"},
argTypes = {"Geometry", "double"}, returnTypes = "Geometry")
+ public static String ST_SimplifyVW(String geometry, double
distanceTolerance) {
+ return GeometrySerde.serGeoJson(
+ Functions.simplifyVW(
+ GeometrySerde.deserGeoJson(geometry),
+ distanceTolerance
+ )
+ );
+ }
+
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "vertexFactor",
"isOuter"}, argTypes = {"Geometry", "double", "boolean"}, returnTypes =
"Geometry")
+ public static String ST_SimplifyPolygonHull(String geometry, double
vertexFactor, boolean isOuter) {
+ return GeometrySerde.serGeoJson(
+ Functions.simplifyPolygonHull(
+ GeometrySerde.deserGeoJson(geometry),
+ vertexFactor,
+ isOuter
+ )
+ );
+ }
+
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "vertexFactor"},
argTypes = {"Geometry", "double"}, returnTypes = "Geometry")
+ public static String ST_SimplifyPolygonHull(String geometry, double
vertexFactor) {
+ return GeometrySerde.serGeoJson(
+ Functions.simplifyPolygonHull(
+ GeometrySerde.deserGeoJson(geometry),
+ vertexFactor
+ )
+ );
+ }
+
@UDFAnnotations.ParamMeta(argNames = {"input", "blade"}, argTypes =
{"Geometry", "Geometry"}, returnTypes = "Geometry")
public static String ST_Split(String input, String blade) {
return GeometrySerde.serGeoJson(
diff --git
a/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
b/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
index 846059e68..6d16bc9be 100644
--- a/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
+++ b/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
@@ -108,6 +108,8 @@ object Catalog {
function[ST_AsHEXEWKB](),
function[ST_AsGML](),
function[ST_AsKML](),
+ function[ST_SimplifyVW](),
+ function[ST_SimplifyPolygonHull](),
function[ST_SRID](),
function[ST_SetSRID](),
function[ST_GeometryType](),
diff --git
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
index 8d5b67bdf..ded1e31f7 100644
---
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
+++
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
@@ -346,6 +346,22 @@ case class ST_ReducePrecision(inputExpressions:
Seq[Expression])
}
}
+case class ST_SimplifyVW(inputExpressions: Seq[Expression])
+ extends InferredExpression(Functions.simplifyVW _) {
+
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
{
+ copy(inputExpressions = newChildren)
+ }
+}
+
+case class ST_SimplifyPolygonHull(inputExpressions: Seq[Expression])
+ extends
InferredExpression(inferrableFunction2(Functions.simplifyPolygonHull),
inferrableFunction3(Functions.simplifyPolygonHull)) {
+
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
{
+ copy(inputExpressions = newChildren)
+ }
+}
+
case class ST_AsText(inputExpressions: Seq[Expression])
extends InferredExpression(Functions.asWKT _) {
diff --git
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
index 6550fe575..9bb23391d 100644
---
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
+++
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
@@ -360,6 +360,14 @@ object st_functions extends DataFrameAPI {
def ST_Transform(geometry: String, targetCRS: String): Column =
wrapExpression[ST_Transform](geometry, targetCRS)
def ST_Transform(geometry: Column, targetCRS: Column): Column =
wrapExpression[ST_Transform](geometry, targetCRS)
+ def ST_SimplifyVW(geometry: Column, distanceTolerance: Column): Column =
wrapExpression[ST_SimplifyVW](geometry, distanceTolerance)
+ def ST_SimplifyVW(geometry: String, distanceTolerance: Double): Column =
wrapExpression[ST_SimplifyVW](geometry, distanceTolerance)
+
+ def ST_SimplifyPolygonHull(geometry: Column, vertexFactor: Column): Column =
wrapExpression[ST_SimplifyPolygonHull](geometry, vertexFactor)
+ def ST_SimplifyPolygonHull(geometry: String, vertexFactor: Double): Column =
wrapExpression[ST_SimplifyPolygonHull](geometry, vertexFactor)
+ def ST_SimplifyPolygonHull(geometry: Column, vertexFactor: Column, isOuter:
Column): Column = wrapExpression[ST_SimplifyPolygonHull](geometry,
vertexFactor, isOuter)
+ def ST_SimplifyPolygonHull(geometry: String, vertexFactor: Double, isOuter:
Boolean): Column = wrapExpression[ST_SimplifyPolygonHull](geometry,
vertexFactor, isOuter)
+
def ST_Union(a: Column, b: Column): Column = wrapExpression[ST_Union](a, b)
def ST_Union(a: String, b: String): Column = wrapExpression[ST_Union](a, b)
def ST_Union(geoms: Column): Column = wrapExpression[ST_Union](geoms)
diff --git
a/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
b/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
index cf663474b..4a1bf9f98 100644
---
a/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
+++
b/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
@@ -716,6 +716,24 @@ class dataFrameAPITestScala extends TestBaseScala {
assert(actualResult == expectedResult)
}
+ it("Passed ST_SimplifyVW") {
+ val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('LINESTRING(5 2, 3
8, 6 20, 7 25, 10 10)') AS geom")
+ val actual = baseDf.select(ST_SimplifyVW("geom",
30)).first().get(0).asInstanceOf[Geometry].toText
+ val expected = "LINESTRING (5 2, 7 25, 10 10)"
+ assertEquals(expected, actual)
+ }
+
+ it("Passed ST_SimplifyPolygonHull") {
+ val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((30 10,
40 40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))') AS geom")
+ var actual = baseDf.select(ST_SimplifyPolygonHull("geom", 0.3,
false)).first().get(0).asInstanceOf[Geometry].toText
+ var expected = "POLYGON ((30 10, 40 40, 10 20, 30 10))"
+ assertEquals(expected, actual)
+
+ actual = baseDf.select(ST_SimplifyPolygonHull("geom",
0.3)).first().get(0).asInstanceOf[Geometry].toText
+ expected = "POLYGON ((30 10, 15 15, 10 20, 20 40, 45 45, 30 10))"
+ assertEquals(expected, actual)
+ }
+
it("Passed ST_GeometryType") {
val pointDf = sparkSession.sql("SELECT ST_Point(0.0, 0.0) AS geom")
val df = pointDf.select(ST_GeometryType("geom"))
diff --git
a/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
b/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
index 174af005d..1b81fb909 100644
--- a/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
+++ b/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
@@ -655,6 +655,24 @@ class functionTestScala extends TestBaseScala with
Matchers with GeometrySample
assert(Hex.encodeHexString(df.first().get(0).asInstanceOf[Array[Byte]])
== s)
}
+ it("Passed ST_SimplifyVW") {
+ val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('LINESTRING(5 2, 3
8, 6 20, 7 25, 10 10)') AS geom")
+ val actual = baseDf.selectExpr("ST_SimplifyVW(geom,
30)").first().get(0).asInstanceOf[Geometry].toText
+ val expected = "LINESTRING (5 2, 7 25, 10 10)"
+ assertEquals(expected, actual)
+ }
+
+ it("Passed ST_SimplifyPolygonHull") {
+ val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((30 10,
40 40, 45 45, 20 40, 25 35, 10 20, 15 15, 30 10))') AS geom")
+ var actual = baseDf.selectExpr("ST_SimplifyPolygonHull(geom, 0.3,
false)").first().get(0).asInstanceOf[Geometry].toText
+ var expected = "POLYGON ((30 10, 40 40, 10 20, 30 10))"
+ assertEquals(expected, actual)
+
+ actual = baseDf.selectExpr("ST_SimplifyPolygonHull(geom,
0.3)").first().get(0).asInstanceOf[Geometry].toText
+ expected = "POLYGON ((30 10, 15 15, 10 20, 20 40, 45 45, 30 10))"
+ assertEquals(expected, actual)
+ }
+
it("Passed ST_NPoints") {
var test = sparkSession.sql("SELECT
ST_NPoints(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27
29.31,77.29 29.07)'))")
assert(test.take(1)(0).get(0).asInstanceOf[Int] == 4)