Skip to content

Commit

Permalink
[SEDONA-601] Add ST_DelaunayTriangles (#1470)
Browse files Browse the repository at this point in the history
* [TASK-44] Add ST_DelaunayTriangles (#200)

* temp commit

* docs: add docs for all 3 engines

* chore: port to snowflake

* fix: snowflake tests

* fix: snowflake tests

* Update versions

---------

Co-authored-by: Furqaan Khan <46216254+furqaankhan@users.noreply.github.com>
  • Loading branch information
jiayuasu and furqaankhan authored Jun 7, 2024
1 parent 5279c36 commit 3fe212f
Show file tree
Hide file tree
Showing 20 changed files with 343 additions and 8 deletions.
38 changes: 30 additions & 8 deletions common/src/main/java/org/apache/sedona/common/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.locationtech.jts.simplify.PolygonHullSimplifier;
import org.locationtech.jts.simplify.TopologyPreservingSimplifier;
import org.locationtech.jts.simplify.VWSimplifier;
import org.locationtech.jts.triangulate.DelaunayTriangulationBuilder;
import org.locationtech.jts.triangulate.polygon.ConstrainedDelaunayTriangulator;
import org.wololo.jts2geojson.GeoJSONWriter;

Expand Down Expand Up @@ -403,7 +404,7 @@ public static Double mMin(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double min = Double.MAX_VALUE;
for(int i=0; i < points.length; i++){
if(java.lang.Double.isNaN(points[i].getM()))
if(Double.isNaN(points[i].getM()))
continue;
min = Math.min(points[i].getM(), min);
}
Expand All @@ -414,7 +415,7 @@ public static Double mMax(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double max = - Double.MAX_VALUE;
for (int i=0; i < points.length; i++) {
if(java.lang.Double.isNaN(points[i].getM()))
if(Double.isNaN(points[i].getM()))
continue;
max = Math.max(points[i].getM(), max);
}
Expand Down Expand Up @@ -461,7 +462,7 @@ public static Double zMax(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double max = - Double.MAX_VALUE;
for (int i=0; i < points.length; i++) {
if(java.lang.Double.isNaN(points[i].getZ()))
if(Double.isNaN(points[i].getZ()))
continue;
max = Math.max(points[i].getZ(), max);
}
Expand All @@ -472,7 +473,7 @@ public static Double zMin(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double min = Double.MAX_VALUE;
for(int i=0; i < points.length; i++){
if(java.lang.Double.isNaN(points[i].getZ()))
if(Double.isNaN(points[i].getZ()))
continue;
min = Math.min(points[i].getZ(), min);
}
Expand Down Expand Up @@ -590,13 +591,13 @@ public static int nDims(Geometry geometry) {
Double y_cord = geom.getY();
Double z_cord = geom.getZ();
Double m_cord = geom.getM();
if(!java.lang.Double.isNaN(x_cord))
if(!Double.isNaN(x_cord))
count_dimension++;
if(!java.lang.Double.isNaN(y_cord))
if(!Double.isNaN(y_cord))
count_dimension++;
if(!java.lang.Double.isNaN(z_cord))
if(!Double.isNaN(z_cord))
count_dimension++;
if(!java.lang.Double.isNaN(m_cord))
if(!Double.isNaN(m_cord))
count_dimension++;
return count_dimension;
}
Expand Down Expand Up @@ -762,6 +763,27 @@ public static Geometry closestPoint(Geometry left, Geometry right) {
}
}

public static Geometry delaunayTriangle(Geometry geometry) {
return delaunayTriangle(geometry, 0.0, 0);
}

public static Geometry delaunayTriangle(Geometry geometry, double tolerance) {
return delaunayTriangle(geometry, tolerance, 0);
}

public static Geometry delaunayTriangle(Geometry geometry, double tolerance, int flag) {
DelaunayTriangulationBuilder dTBuilder = new DelaunayTriangulationBuilder();
dTBuilder.setSites(geometry);
dTBuilder.setTolerance(tolerance);
if (flag == 0) {
return dTBuilder.getTriangles(geometry.getFactory());
} else if (flag == 1) {
return dTBuilder.getEdges(geometry.getFactory());
} else {
throw new IllegalArgumentException("Select a valid flag option (0 or 1).");
}
}

public static int zmFlag(Geometry geom) {
Coordinate coords = geom.getCoordinate();
boolean hasZ = !Double.isNaN(coords.getZ());
Expand Down
19 changes: 19 additions & 0 deletions common/src/test/java/org/apache/sedona/common/FunctionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,25 @@ public void pologonize() throws ParseException {
assertEquals(expected4, result4);
}

@Test
public void delaunayTriangles() throws ParseException {
Geometry poly = Constructors.geomFromEWKT("POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))");
Geometry point = Constructors.geomFromEWKT("POINT (110 170)");
Geometry combined = Functions.union(poly, point);
String actual = Functions.delaunayTriangle(combined).toText();
String expected = "GEOMETRYCOLLECTION (POLYGON ((20 40, 125 100, 50 60, 20 40)), POLYGON ((20 40, 50 60, 110 170, 20 40)), POLYGON ((110 170, 50 60, 125 100, 110 170)), POLYGON ((110 170, 125 100, 175 150, 110 170)))";
assertEquals(expected, actual);

poly = Constructors.geomFromEWKT("MULTIPOLYGON (((10 10, 10 20, 20 20, 20 10, 10 10)),((25 10, 25 20, 35 20, 35 10, 25 10)))");
actual = Functions.delaunayTriangle(poly, 20).toText();
expected = "GEOMETRYCOLLECTION (POLYGON ((10 20, 10 10, 35 10, 10 20)))";
assertEquals(expected, actual);

actual = Functions.delaunayTriangle(poly, 0, 1).toText();
expected = "MULTILINESTRING ((25 20, 35 20), (20 20, 25 20), (10 20, 20 20), (10 10, 10 20), (10 10, 20 10), (20 10, 25 10), (25 10, 35 10), (35 10, 35 20), (25 20, 35 10), (25 10, 25 20), (20 20, 25 10), (20 10, 20 20), (10 20, 20 10))";
assertEquals(expected, actual);
}

@Test
public void spheroidLength() {
Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(90, 0));
Expand Down
33 changes: 33 additions & 0 deletions docs/api/flink/Function.md
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,39 @@ Output:
11.309932474020195
```

## ST_DelaunayTriangles

Introduction: This function computes the [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) for the set of vertices in the input geometry. An optional `tolerance` parameter allows snapping nearby input vertices together prior to triangulation and can improve robustness in certain scenarios by handling near-coincident vertices. The default for `tolerance` is 0. The Delaunay triangulation geometry is bounded by the convex hull of the input vertex set.

The output geometry representation depends on the provided `flag`:

- `0` - a GeometryCollection of triangular Polygons (default option)
- `1` - a MultiLinestring of the edges of the triangulation

Format:

`ST_DelaunayTriangles(geometry: Geometry)`

`ST_DelaunayTriangles(geometry: Geometry, tolerance: Double)`

`ST_DelaunayTriangles(geometry: Geometry, tolerance: Double, flag: Integer)`

Since: `v1.6.1`

SQL Example

```sql
SELECT ST_DelaunayTriangles(
ST_GeomFromWKT('POLYGON ((10 10, 15 30, 20 25, 25 35, 30 20, 40 30, 50 10, 45 5, 35 15, 30 5, 25 15, 20 10, 15 20, 10 10))')
)
```

Output:

```
GEOMETRYCOLLECTION (POLYGON ((15 30, 10 10, 15 20, 15 30)), POLYGON ((15 30, 15 20, 20 25, 15 30)), POLYGON ((15 30, 20 25, 25 35, 15 30)), POLYGON ((25 35, 20 25, 30 20, 25 35)), POLYGON ((25 35, 30 20, 40 30, 25 35)), POLYGON ((40 30, 30 20, 35 15, 40 30)), POLYGON ((40 30, 35 15, 50 10, 40 30)), POLYGON ((50 10, 35 15, 45 5, 50 10)), POLYGON ((30 5, 45 5, 35 15, 30 5)), POLYGON ((30 5, 35 15, 25 15, 30 5)), POLYGON ((30 5, 25 15, 20 10, 30 5)), POLYGON ((30 5, 20 10, 10 10, 30 5)), POLYGON ((10 10, 20 10, 15 20, 10 10)), POLYGON ((15 20, 20 10, 25 15, 15 20)), POLYGON ((15 20, 25 15, 20 25, 15 20)), POLYGON ((20 25, 25 15, 30 20, 20 25)), POLYGON ((30 20, 25 15, 35 15, 30 20)))
```

## ST_Difference

Introduction: Return the difference between geometry A and B (return part of geometry A that does not intersect geometry B)
Expand Down
31 changes: 31 additions & 0 deletions docs/api/snowflake/vector-data/Function.md
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,37 @@ Output:
11.309932474020195
```

## ST_DelaunayTriangles

Introduction: This function computes the [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) for the set of vertices in the input geometry. An optional `tolerance` parameter allows snapping nearby input vertices together prior to triangulation and can improve robustness in certain scenarios by handling near-coincident vertices. The default for `tolerance` is 0. The Delaunay triangulation geometry is bounded by the convex hull of the input vertex set.

The output geometry representation depends on the provided `flag`:

- `0` - a GeometryCollection of triangular Polygons (default option)
- `1` - a MultiLinestring of the edges of the triangulation

Format:

`ST_DelaunayTriangles(geometry: Geometry)`

`ST_DelaunayTriangles(geometry: Geometry, tolerance: Double)`

`ST_DelaunayTriangles(geometry: Geometry, tolerance: Double, flag: Integer)`

SQL Example

```sql
SELECT ST_DelaunayTriangles(
ST_GeomFromWKT('POLYGON ((10 10, 15 30, 20 25, 25 35, 30 20, 40 30, 50 10, 45 5, 35 15, 30 5, 25 15, 20 10, 15 20, 10 10))')
)
```

Output:

```
GEOMETRYCOLLECTION (POLYGON ((15 30, 10 10, 15 20, 15 30)), POLYGON ((15 30, 15 20, 20 25, 15 30)), POLYGON ((15 30, 20 25, 25 35, 15 30)), POLYGON ((25 35, 20 25, 30 20, 25 35)), POLYGON ((25 35, 30 20, 40 30, 25 35)), POLYGON ((40 30, 30 20, 35 15, 40 30)), POLYGON ((40 30, 35 15, 50 10, 40 30)), POLYGON ((50 10, 35 15, 45 5, 50 10)), POLYGON ((30 5, 45 5, 35 15, 30 5)), POLYGON ((30 5, 35 15, 25 15, 30 5)), POLYGON ((30 5, 25 15, 20 10, 30 5)), POLYGON ((30 5, 20 10, 10 10, 30 5)), POLYGON ((10 10, 20 10, 15 20, 10 10)), POLYGON ((15 20, 20 10, 25 15, 15 20)), POLYGON ((15 20, 25 15, 20 25, 15 20)), POLYGON ((20 25, 25 15, 30 20, 20 25)), POLYGON ((30 20, 25 15, 35 15, 30 20)))
```

## ST_Difference

Introduction: Return the difference between geometry A and B (return part of geometry A that does not intersect geometry B)
Expand Down
33 changes: 33 additions & 0 deletions docs/api/sql/Function.md
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,39 @@ Output:
11.309932474020195
```

## ST_DelaunayTriangles

Introduction: This function computes the [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) for the set of vertices in the input geometry. An optional `tolerance` parameter allows snapping nearby input vertices together prior to triangulation and can improve robustness in certain scenarios by handling near-coincident vertices. The default for `tolerance` is 0. The Delaunay triangulation geometry is bounded by the convex hull of the input vertex set.

The output geometry representation depends on the provided `flag`:

- `0` - a GeometryCollection of triangular Polygons (default option)
- `1` - a MultiLinestring of the edges of the triangulation

Format:

`ST_DelaunayTriangles(geometry: Geometry)`

`ST_DelaunayTriangles(geometry: Geometry, tolerance: Double)`

`ST_DelaunayTriangles(geometry: Geometry, tolerance: Double, flag: Integer)`

Since: `v1.6.1`

SQL Example

```sql
SELECT ST_DelaunayTriangles(
ST_GeomFromWKT('POLYGON ((10 10, 15 30, 20 25, 25 35, 30 20, 40 30, 50 10, 45 5, 35 15, 30 5, 25 15, 20 10, 15 20, 10 10))')
)
```

Output:

```
GEOMETRYCOLLECTION (POLYGON ((15 30, 10 10, 15 20, 15 30)), POLYGON ((15 30, 15 20, 20 25, 15 30)), POLYGON ((15 30, 20 25, 25 35, 15 30)), POLYGON ((25 35, 20 25, 30 20, 25 35)), POLYGON ((25 35, 30 20, 40 30, 25 35)), POLYGON ((40 30, 30 20, 35 15, 40 30)), POLYGON ((40 30, 35 15, 50 10, 40 30)), POLYGON ((50 10, 35 15, 45 5, 50 10)), POLYGON ((30 5, 45 5, 35 15, 30 5)), POLYGON ((30 5, 35 15, 25 15, 30 5)), POLYGON ((30 5, 25 15, 20 10, 30 5)), POLYGON ((30 5, 20 10, 10 10, 30 5)), POLYGON ((10 10, 20 10, 15 20, 10 10)), POLYGON ((15 20, 20 10, 25 15, 15 20)), POLYGON ((15 20, 25 15, 20 25, 15 20)), POLYGON ((20 25, 25 15, 30 20, 20 25)), POLYGON ((30 20, 25 15, 35 15, 30 20)))
```

## ST_Difference

Introduction: Return the difference between geometry A and B (return part of geometry A that does not intersect geometry B)
Expand Down
1 change: 1 addition & 0 deletions flink/src/main/java/org/apache/sedona/flink/Catalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public static UserDefinedFunction[] getFuncs() {
new Functions.ST_H3ToGeom(),
new Functions.ST_Dump(),
new Functions.ST_DumpPoints(),
new Functions.ST_DelaunayTriangles(),
new Functions.ST_EndPoint(),
new Functions.ST_GeometryType(),
new Functions.ST_Intersection(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,29 @@ public Double eval(@DataTypeHint("Double") Double angleInRadian) {
}
}

public static class ST_DelaunayTriangles 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(value = "Double") Double tolerance,
@DataTypeHint(value = "Integer") Integer flag) {
Geometry geometry = (Geometry) o;
return org.apache.sedona.common.Functions.delaunayTriangle(geometry, tolerance, flag);
}

@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(value = "Double") Double tolerance) {
Geometry geometry = (Geometry) o;
return org.apache.sedona.common.Functions.delaunayTriangle(geometry, tolerance);
}

@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) {
Geometry geometry = (Geometry) o;
return org.apache.sedona.common.Functions.delaunayTriangle(geometry);
}
}

public static class ST_IsValidReason extends ScalarFunction {
@DataTypeHint("String")
public String eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object o) {
Expand Down
16 changes: 16 additions & 0 deletions flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,22 @@ public void testAngle() {

}

@Test
public void testDelaunayTriangle() {
Table polyTable = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('MULTIPOLYGON (((10 10, 10 20, 20 20, 20 10, 10 10)),((25 10, 25 20, 35 20, 35 10, 25 10)))') AS geom");
String actual = ((Geometry) first(polyTable.select(call(Functions.ST_DelaunayTriangles.class.getSimpleName(), $("geom")))).getField(0)).toText();
String expected = "GEOMETRYCOLLECTION (POLYGON ((10 20, 10 10, 20 10, 10 20)), POLYGON ((10 20, 20 10, 20 20, 10 20)), POLYGON ((20 20, 20 10, 25 10, 20 20)), POLYGON ((20 20, 25 10, 25 20, 20 20)), POLYGON ((25 20, 25 10, 35 10, 25 20)), POLYGON ((25 20, 35 10, 35 20, 25 20)))";
assertEquals(expected, actual);

actual = ((Geometry) first(polyTable.select(call(Functions.ST_DelaunayTriangles.class.getSimpleName(), $("geom"), 20))).getField(0)).toText();
expected = "GEOMETRYCOLLECTION (POLYGON ((10 20, 10 10, 35 10, 10 20)))";
assertEquals(expected, actual);

actual = ((Geometry) first(polyTable.select(call(Functions.ST_DelaunayTriangles.class.getSimpleName(), $("geom"), 20, 1))).getField(0)).toText();
expected = "MULTILINESTRING ((10 20, 35 10), (10 10, 10 20), (10 10, 35 10))";
assertEquals(expected, actual);
}

@Test
public void testHausdorffDistance() {
Table polyTable = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POINT (0.0 1.0)') AS g1, ST_GeomFromWKT('LINESTRING (0 0, 1 0, 2 0, 3 0, 4 0, 5 0)') AS g2");
Expand Down
24 changes: 24 additions & 0 deletions python/sedona/sql/st_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,30 @@ def ST_Degrees(angleInRadian: Union[ColumnOrName, float]) -> Column:
:return: Angle in Degrees
"""
return _call_st_function("ST_Degrees", angleInRadian)

@validate_argument_types
def ST_DelaunayTriangles(geometry: ColumnOrName, tolerance: Optional[Union[ColumnOrName, float]] = None, flag: Optional[Union[ColumnOrName, int]] = None) -> Column:
"""
Computes the Delaunay Triangles of the vertices of the input geometry.
:param geometry: Input geometry
:type geometry: ColumnOrName
:param tolerance:
:type tolerance: ColumnOrName or float
:param flag: Selects the output type
:type flag: ColumnOrName or int
:return: Delaunay triangles of the input geometry
:rtype: ColumnOrName
"""

if flag is None and tolerance is None:
args = (geometry)
elif flag is None:
args = (geometry, tolerance)
else:
args = (geometry, tolerance, flag)
return _call_st_function("ST_DelaunayTriangles", args)

@validate_argument_types
def ST_HausdorffDistance(g1: ColumnOrName, g2: ColumnOrName, densityFrac: Optional[Union[ColumnOrName, float]] = -1) -> Column:
"""
Expand Down
2 changes: 2 additions & 0 deletions python/tests/sql/test_dataframe_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
(stf.ST_DistanceSpheroid, ("point", "point"), "point_geom", "", 0.0),
(stf.ST_DistanceSphere, ("point", "point"), "point_geom", "", 0.0),
(stf.ST_DistanceSphere, ("point", "point", 6378137.0), "point_geom", "", 0.0),
(stf.ST_DelaunayTriangles, ("multipoint", ), "multipoint_geom", "", "GEOMETRYCOLLECTION (POLYGON ((10 40, 20 20, 40 30, 10 40)), POLYGON ((40 30, 20 20, 30 10, 40 30)))"),
(stf.ST_Dump, ("geom",), "multipoint", "", ["POINT (0 0)", "POINT (1 1)"]),
(stf.ST_DumpPoints, ("line",), "linestring_geom", "", ["POINT (0 0)", "POINT (1 0)", "POINT (2 0)", "POINT (3 0)", "POINT (4 0)", "POINT (5 0)"]),
(stf.ST_EndPoint, ("line",), "linestring_geom", "", "POINT (5 0)"),
Expand Down Expand Up @@ -320,6 +321,7 @@
(stf.ST_Distance, ("", None)),
(stf.ST_Dump, (None,)),
(stf.ST_DumpPoints, (None,)),
(stf.ST_DelaunayTriangles, (None,)),
(stf.ST_EndPoint, (None,)),
(stf.ST_Envelope, (None,)),
(stf.ST_ExteriorRing, (None,)),
Expand Down
6 changes: 6 additions & 0 deletions python/tests/sql/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,12 @@ def test_st_difference_right_not_overlaps_left(self):
diff = self.spark.sql("select ST_Difference(a,b) from test_diff")
assert diff.take(1)[0][0].wkt == "POLYGON EMPTY"

def test_st_delaunay_triangles(self):
baseDf = self.spark.sql("SELECT ST_GeomFromWKT('MULTIPOLYGON (((10 10, 10 20, 20 20, 20 10, 10 10)),((25 10, 25 20, 35 20, 35 10, 25 10)))') AS geom")
actual = baseDf.selectExpr("ST_DelaunayTriangles(geom)").take(1)[0][0].wkt
expected = "GEOMETRYCOLLECTION (POLYGON ((10 20, 10 10, 20 10, 10 20)), POLYGON ((10 20, 20 10, 20 20, 10 20)), POLYGON ((20 20, 20 10, 25 10, 20 20)), POLYGON ((20 20, 25 10, 25 20, 20 20)), POLYGON ((25 20, 25 10, 35 10, 25 20)), POLYGON ((25 20, 35 10, 35 20, 25 20)))"
assert expected == actual

def test_st_sym_difference_part_of_right_overlaps_left(self):
test_table = self.spark.sql(
"select ST_GeomFromWKT('POLYGON ((-1 -1, 1 -1, 1 1, -1 1, -1 -1))') as a,ST_GeomFromWKT('POLYGON ((0 -2, 2 -2, 2 0, 0 0, 0 -2))') as b")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,15 @@ public void test_ST_Difference() {
);
}

@Test
public void test_ST_DelaunayTriangles() {
registerUDF("ST_DelaunayTriangles", byte[].class);
verifySqlSingleRes(
"select sedona.ST_AsText(sedona.ST_DelaunayTriangles(sedona.ST_GeomFromText('POLYGON ((10 10, 15 30, 20 25, 25 35, 30 20, 40 30, 50 10, 45 5, 35 15, 30 5, 25 15, 20 10, 15 20, 10 10))')))",
"GEOMETRYCOLLECTION (POLYGON ((15 30, 10 10, 15 20, 15 30)), POLYGON ((15 30, 15 20, 20 25, 15 30)), POLYGON ((15 30, 20 25, 25 35, 15 30)), POLYGON ((25 35, 20 25, 30 20, 25 35)), POLYGON ((25 35, 30 20, 40 30, 25 35)), POLYGON ((40 30, 30 20, 35 15, 40 30)), POLYGON ((40 30, 35 15, 50 10, 40 30)), POLYGON ((50 10, 35 15, 45 5, 50 10)), POLYGON ((30 5, 45 5, 35 15, 30 5)), POLYGON ((30 5, 35 15, 25 15, 30 5)), POLYGON ((30 5, 25 15, 20 10, 30 5)), POLYGON ((30 5, 20 10, 10 10, 30 5)), POLYGON ((10 10, 20 10, 15 20, 10 10)), POLYGON ((15 20, 20 10, 25 15, 15 20)), POLYGON ((15 20, 25 15, 20 25, 15 20)), POLYGON ((20 25, 25 15, 30 20, 20 25)), POLYGON ((30 20, 25 15, 35 15, 30 20)))"
);
}

@Test
public void test_ST_Degrees() {
registerUDF("ST_Degrees", double.class);
Expand Down
Loading

0 comments on commit 3fe212f

Please sign in to comment.