Skip to content

Commit

Permalink
[SEDONA-659] Upgrade JTS version to 1.20.0 (#1655)
Browse files Browse the repository at this point in the history
* bump jts to 1.20.0

* Fix tests for jts 1.20.0

* Fix python tests for jts 1.20.0, removed unnecessary print statements from the python test code.

* Fix test failures

* Fix type annotation for ST_Rotate

---------

Co-authored-by: jameswillis <[email protected]>
  • Loading branch information
Kontinuation and jameswillis authored Oct 25, 2024
1 parent a56cbc5 commit 3a73733
Show file tree
Hide file tree
Showing 25 changed files with 259 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ public static InscribedCircle maximumInscribedCircle(Geometry geometry) {
// All non-polygonal geometries use LargestEmptyCircle
if (!geometry.getClass().getSimpleName().equals("Polygon")
&& !geometry.getClass().getSimpleName().equals("MultiPolygon")) {
LargestEmptyCircle largestEmptyCircle = new LargestEmptyCircle(geometry, tolerance);
LargestEmptyCircle largestEmptyCircle = new LargestEmptyCircle(geometry, null, tolerance);
center = largestEmptyCircle.getCenter();
nearest = largestEmptyCircle.getRadiusPoint();
radius = largestEmptyCircle.getRadiusLine().getLength();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,15 @@ public boolean equals(InscribedCircle other) {
&& this.nearest.equals(other.nearest)
&& Math.abs(this.radius - other.radius) < epsilon;
}

public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
InscribedCircle other = (InscribedCircle) obj;
return this.equals(other);
}
}
45 changes: 21 additions & 24 deletions common/src/test/java/org/apache/sedona/common/FunctionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ public void delaunayTriangles() throws ParseException {
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);
assertGeometryEquals(expected, actual);

poly =
Constructors.geomFromEWKT(
Expand All @@ -1610,7 +1610,7 @@ public void delaunayTriangles() throws ParseException {
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);
assertGeometryEquals(expected, actual);
}

@Test
Expand Down Expand Up @@ -1802,14 +1802,11 @@ public void simplify() throws ParseException {
expectedPoints = 17;
assertEquals(expectedPoints, actualPoints);

actualPoints = Functions.nPoints(Functions.simplify(geom, 1));
Geometry actual = Functions.simplify(geom, 1);
actualPoints = Functions.nPoints(actual);
expectedPoints = 9;
assertEquals(expectedPoints, actualPoints);

Geometry actual = Functions.simplify(geom, 10);
actualPoints = Functions.nPoints(actual);
expectedPoints = 4;
assertEquals(expectedPoints, actualPoints);
assertEquals(1111, actual.getSRID());
}

Expand Down Expand Up @@ -3733,22 +3730,22 @@ public void testAddMeasure() throws ParseException {
public void voronoiPolygons() {
MultiPoint multiPoint = GEOMETRY_FACTORY.createMultiPointFromCoords(coordArray(0, 0, 2, 2));
Geometry actual1 = FunctionsGeoTools.voronoiPolygons(multiPoint, 0, null);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-2 -2, -2 4, 4 -2, -2 -2)), POLYGON ((-2 4, 4 4, 4 -2, -2 4)))",
actual1.toText());

Geometry actual2 = FunctionsGeoTools.voronoiPolygons(multiPoint, 30, null);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-2 -2, -2 4, 4 4, 4 -2, -2 -2)))", actual2.toText());

Geometry buf = Functions.buffer(GEOMETRY_FACTORY.createPoint(new Coordinate(1, 1)), 10);
Geometry actual3 = FunctionsGeoTools.voronoiPolygons(multiPoint, 0, buf);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-9 -9, -9 11, 11 -9, -9 -9)), POLYGON ((-9 11, 11 11, 11 -9, -9 11)))",
actual3.toText());

Geometry actual4 = FunctionsGeoTools.voronoiPolygons(multiPoint, 30, buf);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-9 -9, -9 11, 11 11, 11 -9, -9 -9)))", actual4.toText());

Geometry actual5 = FunctionsGeoTools.voronoiPolygons(null, 0, null);
Expand Down Expand Up @@ -3827,20 +3824,20 @@ public void maximumInscribedCircle() throws ParseException {
InscribedCircle actual = Functions.maximumInscribedCircle(geom);
InscribedCircle expected =
new InscribedCircle(
Constructors.geomFromEWKT("POINT (96.953125 76.328125)"),
Constructors.geomFromEWKT("POINT (140 90)"),
45.165846);
assertTrue(expected.equals(actual));
Constructors.geomFromEWKT("POINT (96.9287109375 76.3232421875)"),
Constructors.geomFromEWKT("POINT (61.64205411585366 104.55256764481707)"),
45.18896951053177);
assertEquals(expected, actual);

geom =
Constructors.geomFromEWKT(
"MULTILINESTRING ((59.5 17, 65 17), (60 16.5, 66 12), (65 12, 69 17))");
actual = Functions.maximumInscribedCircle(geom);
expected =
new InscribedCircle(
Constructors.geomFromEWKT("POINT (65.0419921875 15.1005859375)"),
Constructors.geomFromEWKT("POINT (65 17)"),
1.8998781);
Constructors.geomFromEWKT("POINT (65.043212890625 15.098388671875)"),
Constructors.geomFromEWKT("POINT (66.52827267530488 13.910340844131097)"),
1.9018044602641058);
assertTrue(expected.equals(actual));

geom =
Expand All @@ -3849,9 +3846,9 @@ public void maximumInscribedCircle() throws ParseException {
actual = Functions.maximumInscribedCircle(geom);
expected =
new InscribedCircle(
Constructors.geomFromEWKT("POINT (65.44062499999998 15.953124999999998)"),
Constructors.geomFromEWKT("POINT (67.5 16.9)"),
2.2666269);
Constructors.geomFromEWKT("POINT (65.44223632812499 15.945361328125001)"),
Constructors.geomFromEWKT("POINT (67.4 14.8)"),
2.2681911662992174);
assertTrue(expected.equals(actual));

geom = Constructors.geomFromEWKT("MULTIPOINT ((60.8 15.5), (63.2 16.3))");
Expand All @@ -3869,9 +3866,9 @@ public void maximumInscribedCircle() throws ParseException {
actual = Functions.maximumInscribedCircle(geom);
expected =
new InscribedCircle(
Constructors.geomFromEWKT("POINT (65.44062499999998 15.953124999999998)"),
Constructors.geomFromEWKT("POINT (67.5 16.9)"),
2.2666269);
Constructors.geomFromEWKT("POINT (65.44223632812499 15.945361328125001)"),
Constructors.geomFromEWKT("POINT (67.4 14.8)"),
2.2681911662992174);
assertTrue(expected.equals(actual));
}

Expand Down
24 changes: 24 additions & 0 deletions common/src/test/java/org/apache/sedona/common/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
*/
package org.apache.sedona.common;

import static org.junit.Assert.fail;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;

public class TestBase {
public Coordinate[] coordArray(double... coordValues) {
Expand All @@ -37,4 +41,24 @@ public Coordinate[] coordArray3d(double... coordValues) {
}
return coords;
}

public void assertGeometryEquals(String expectedWkt, String actualWkt, double tolerance) {
WKTReader reader = new WKTReader();
try {
Geometry expectedGeom = reader.read(expectedWkt);
Geometry actualGeom = reader.read(actualWkt);
if (!expectedGeom.equals(actualGeom)) {
if (!expectedGeom.buffer(tolerance).contains(actualGeom)
|| !actualGeom.buffer(tolerance).contains(expectedGeom)) {
fail(String.format("Geometry %s should equal to %s", actualWkt, expectedWkt));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void assertGeometryEquals(String expectedWkt, String actualWkt) {
assertGeometryEquals(expectedWkt, actualWkt, 1e-6);
}
}
12 changes: 6 additions & 6 deletions flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,14 @@ public void testConcaveHull() {
polygonTable.select(
call(Functions.ST_ConcaveHull.class.getSimpleName(), $("geom"), 1.0, true));
Geometry result = (Geometry) first(concaveHullPolygonTable).getField(0);
assertEquals("POLYGON ((1 2, 2 2, 3 2, 5 0, 4 0, 1 0, 0 0, 1 2))", result.toString());
assertGeometryEquals("POLYGON ((1 2, 2 2, 3 2, 5 0, 4 0, 1 0, 0 0, 1 2))", result.toString());

Table polygonTable2 =
tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POLYGON ((0 0, 1 0, 1 1, 0 0))') as geom");
Table concaveHullPolygonTable2 =
polygonTable2.select(call(Functions.ST_ConcaveHull.class.getSimpleName(), $("geom"), 1.0));
Geometry result2 = (Geometry) first(concaveHullPolygonTable2).getField(0);
assertEquals("POLYGON ((0 0, 1 1, 1 0, 0 0))", result2.toString());
assertGeometryEquals("POLYGON ((0 0, 1 1, 1 0, 0 0))", result2.toString());
}

@Test
Expand Down Expand Up @@ -2358,30 +2358,30 @@ public void testVoronoiPolygons() {
Table polyTable1 =
tableEnv.sqlQuery("SELECT ST_VoronoiPolygons(ST_GeomFromWKT('MULTIPOINT ((0 0), (2 2))'))");
Geometry result = (Geometry) first(polyTable1).getField(0);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-2 -2, -2 4, 4 -2, -2 -2)), POLYGON ((-2 4, 4 4, 4 -2, -2 4)))",
result.toString());

Table polyTable2 =
tableEnv.sqlQuery(
"SELECT ST_VoronoiPolygons(ST_GeomFromWKT('MULTIPOINT ((0 0), (2 2))'), 0, ST_Buffer(ST_GeomFromWKT('POINT(1 1)'), 10.0) )");
result = (Geometry) first(polyTable2).getField(0);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-9 -9, -9 11, 11 -9, -9 -9)), POLYGON ((-9 11, 11 11, 11 -9, -9 11)))",
result.toString());

Table polyTable3 =
tableEnv.sqlQuery(
"SELECT ST_VoronoiPolygons(ST_GeomFromWKT('MULTIPOINT ((0 0), (2 2))'), 30)");
result = (Geometry) first(polyTable3).getField(0);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-2 -2, -2 4, 4 4, 4 -2, -2 -2)))", result.toString());

Table polyTable4 =
tableEnv.sqlQuery(
"SELECT ST_VoronoiPolygons(ST_GeomFromWKT('MULTIPOINT ((0 0), (2 2))'), 30, ST_Buffer(ST_GeomFromWKT('POINT(1 1)'), 10) )");
result = (Geometry) first(polyTable4).getField(0);
assertEquals(
assertGeometryEquals(
"GEOMETRYCOLLECTION (POLYGON ((-9 -9, -9 11, 11 11, 11 -9, -9 -9)))", result.toString());

Table polyTable5 =
Expand Down
21 changes: 21 additions & 0 deletions flink/src/test/java/org/apache/sedona/flink/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.apache.sedona.flink;

import static org.apache.flink.table.api.Expressions.*;
import static org.junit.Assert.fail;

import com.google.common.math.DoubleMath;
import java.sql.Timestamp;
Expand Down Expand Up @@ -483,4 +484,24 @@ static long count(Table table) {
}
return count;
}

public void assertGeometryEquals(String expectedWkt, String actualWkt, double tolerance) {
WKTReader reader = new WKTReader();
try {
Geometry expectedGeom = reader.read(expectedWkt);
Geometry actualGeom = reader.read(actualWkt);
if (!expectedGeom.equals(actualGeom)) {
if (!expectedGeom.buffer(tolerance).contains(actualGeom)
|| !actualGeom.buffer(tolerance).contains(expectedGeom)) {
fail(String.format("Geometry %s should equal to %s", actualWkt, expectedWkt));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void assertGeometryEquals(String expectedWkt, String actualWkt) {
assertGeometryEquals(expectedWkt, actualWkt, 1e-6);
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<geotools.version>28.2</geotools.version>
<hadoop.version>3.2.4</hadoop.version>
<jackson.version>2.13.4</jackson.version>
<jts.version>1.19.0</jts.version>
<jts.version>1.20.0</jts.version>
<jts2geojson.version>0.16.1</jts2geojson.version>
<spatial4j.version>0.8</spatial4j.version>

Expand Down
6 changes: 3 additions & 3 deletions python/sedona/sql/st_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2364,9 +2364,9 @@ def ST_RotateY(geometry: ColumnOrName, angle: Union[ColumnOrName, float]) -> Col
def ST_Rotate(
geometry: ColumnOrName,
angle: Union[ColumnOrName, float],
originX: Union[ColumnOrName, float] = None,
originY: Union[ColumnOrName, float] = None,
pointOrigin: ColumnOrName = None,
originX: Optional[Union[ColumnOrName, float]] = None,
originY: Optional[Union[ColumnOrName, float]] = None,
pointOrigin: Optional[ColumnOrName] = None,
) -> Column:
"""Return a counter-clockwise rotated geometry along the specified origin.
Expand Down
5 changes: 0 additions & 5 deletions python/tests/core/test_spatial_rdd_from_disc.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ def test_loading_spatial_rdd_from_disc(self):
assert point_rdd.indexedRawRDD is not None
assert isinstance(point_rdd, PointRDD)
point_rdd.analyze()
print(point_rdd.boundaryEnvelope)

polygon_rdd = load_spatial_rdd_from_disc(
self.sc, os.path.join(disc_location, "polygon"), GeoType.POLYGON
Expand All @@ -158,8 +157,6 @@ def test_loading_spatial_rdd_from_disc(self):
polygon_rdd.indexedRawRDD = polygon_index_rdd
polygon_rdd.analyze()

print(polygon_rdd.boundaryEnvelope)

assert polygon_rdd.indexedRawRDD is not None
assert isinstance(polygon_rdd, PolygonRDD)

Expand All @@ -175,7 +172,6 @@ def test_loading_spatial_rdd_from_disc(self):
assert isinstance(linestring_rdd, LineStringRDD)

linestring_rdd.analyze()
print(linestring_rdd.boundaryEnvelope)

linestring_rdd.spatialPartitioning(GridType.KDBTREE)
polygon_rdd.spatialPartitioning(linestring_rdd.getPartitioner())
Expand All @@ -186,5 +182,4 @@ def test_loading_spatial_rdd_from_disc(self):
linestring_rdd, polygon_rdd, True, True
).collect()

print(result)
remove_directory(disc_location)
1 change: 0 additions & 1 deletion python/tests/format_mapper/test_wkt_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ def test_read_to_geometry_rdd(self):
wkt_geometries = os.path.join(tests_resource, "county_small.tsv")
wkt_rdd = WktReader.readToGeometryRDD(self.sc, wkt_geometries, 0, True, False)
assert wkt_rdd.rawSpatialRDD.count() == 103
print(wkt_rdd.rawSpatialRDD.collect())
4 changes: 2 additions & 2 deletions python/tests/spatial_operator/test_rectangle_knn.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def test_spatial_knn_using_polygon(self):
rectangle_rdd, self.query_polygon, self.top_k, False
)

print(result_no_index)
assert len(result_no_index) > 0

def test_spatial_knn_using_linestring(self):
rectangle_rdd = RectangleRDD(self.sc, inputLocation, offset, splitter, True)
Expand All @@ -128,4 +128,4 @@ def test_spatial_knn_using_linestring(self):
rectangle_rdd, self.query_line, self.top_k, False
)

print(result_no_index)
assert len(result_no_index) > 0
3 changes: 0 additions & 3 deletions python/tests/spatial_rdd/test_linestring_rdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,4 @@ def test_mbr(self):
rectangle_rdd = linestring_rdd.MinimumBoundingRectangle()
result = rectangle_rdd.rawSpatialRDD.collect()

for el in result:
print(el)

assert result.__len__() > -1
3 changes: 0 additions & 3 deletions python/tests/spatial_rdd/test_polygon_rdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,4 @@ def test_mbr(self):

result = rectangle_rdd.rawSpatialRDD.collect()

for el in result:
print(el.geom.wkt)
print(result)
assert result.__len__() > -1
3 changes: 2 additions & 1 deletion python/tests/sql/test_dataframe_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1653,7 +1653,8 @@ def test_dataframe_function(
actual_result = df.collect()[0][0]

if isinstance(actual_result, BaseGeometry):
actual_result = actual_result.wkt
self.assert_geometry_almost_equal(expected_result, actual_result)
return
elif isinstance(actual_result, bytearray):
actual_result = actual_result.hex()
elif isinstance(actual_result, Row):
Expand Down
Loading

0 comments on commit 3a73733

Please sign in to comment.