From 866c6ac76881cea36f3effc7359019ce9218918a Mon Sep 17 00:00:00 2001 From: Junhao Liu <992364620@qq.com> Date: Fri, 11 Aug 2023 09:09:55 +0800 Subject: [PATCH] [SEDONA-351] Support XYZM coordinate (#956) --- .../apache/sedona/common/utils/GeomUtils.java | 5 +- .../apache/sedona/common/FunctionsTest.java | 76 +++++++++++++++++++ docs/api/flink/Function.md | 53 ++++++++++++- docs/api/sql/Function.md | 53 ++++++++++++- .../sedona/flink/expressions/Functions.java | 2 +- 5 files changed, 183 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/utils/GeomUtils.java b/common/src/main/java/org/apache/sedona/common/utils/GeomUtils.java index cb26309f04..7ccb6da30c 100644 --- a/common/src/main/java/org/apache/sedona/common/utils/GeomUtils.java +++ b/common/src/main/java/org/apache/sedona/common/utils/GeomUtils.java @@ -173,15 +173,14 @@ public static String getEWKT(Geometry geometry) { if (srid != 0) { sridString = "SRID=" + String.valueOf(srid) + ";"; } - - return sridString + new WKTWriter(GeomUtils.getDimension(geometry)).write(geometry); + return sridString + new WKTWriter(4).write(geometry); } public static String getWKT(Geometry geometry) { if (geometry == null) { return null; } - return new WKTWriter(GeomUtils.getDimension(geometry)).write(geometry); + return new WKTWriter(4).write(geometry); } public static byte[] getEWKB(Geometry geometry) { 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 b9cc27dea8..987a89fe82 100644 --- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java +++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java @@ -65,6 +65,82 @@ private Coordinate[] coordArray3d(double... coordValues) { return coords; } + @Test + public void asEWKT() throws Exception{ + GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4236); + Geometry geometry = geometryFactory.createPoint(new Coordinate(1.0, 2.0)); + String actualResult = Functions.asEWKT(geometry); + String expectedResult = "SRID=4236;POINT (1 2)"; + Geometry acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + + geometry = geometryFactory.createPoint(new Coordinate(1.0, 2.0, 3.0)); + actualResult = Functions.asEWKT(geometry); + expectedResult = "SRID=4236;POINT Z(1 2 3)"; + acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + + geometry = geometryFactory.createPoint(new CoordinateXYM(1.0, 2.0, 3.0)); + actualResult = Functions.asEWKT(geometry); + expectedResult = "SRID=4236;POINT M(1 2 3)"; + acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + + geometry = geometryFactory.createPoint(new CoordinateXYZM(1.0, 2.0, 3.0, 4.0)); + actualResult = Functions.asEWKT(geometry); + expectedResult = "SRID=4236;POINT ZM(1 2 3 4)"; + acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + } + + @Test + public void asWKT() throws Exception { + Geometry geometry = GEOMETRY_FACTORY.createPoint(new Coordinate(1.0, 2.0)); + String actualResult = Functions.asWKT(geometry); + String expectedResult = "POINT (1 2)"; + Geometry acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + + geometry = GEOMETRY_FACTORY.createPoint(new Coordinate(1.0, 2.0, 3.0)); + actualResult = Functions.asWKT(geometry); + expectedResult = "POINT Z(1 2 3)"; + acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + + geometry = GEOMETRY_FACTORY.createPoint(new CoordinateXYM(1.0, 2.0, 3.0)); + actualResult = Functions.asWKT(geometry); + expectedResult = "POINT M(1 2 3)"; + acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + + geometry = GEOMETRY_FACTORY.createPoint(new CoordinateXYZM(1.0, 2.0, 3.0, 4.0)); + actualResult = Functions.asWKT(geometry); + expectedResult = "POINT ZM(1 2 3 4)"; + acutal = Constructors.geomFromEWKT(expectedResult); + assertEquals(geometry, acutal); + assertEquals(expectedResult, actualResult); + } + + @Test + public void asWKB() throws Exception{ + Geometry geometry = GEOMETRY_FACTORY.createPoint(new Coordinate(1.0, 2.0)); + byte[] actualResult = Functions.asWKB(geometry); + Geometry expected = Constructors.geomFromWKB(actualResult); + assertEquals(expected, geometry); + + geometry = GEOMETRY_FACTORY.createPoint(new Coordinate(1.0, 2.0, 3.0)); + actualResult = Functions.asWKB(geometry); + expected = Constructors.geomFromWKB(actualResult); + assertEquals(expected, geometry); + } + @Test public void splitLineStringByMultipoint() { LineString lineString = GEOMETRY_FACTORY.createLineString(coordArray(0.0, 0.0, 1.5, 1.5, 2.0, 2.0)); diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md index 3fa0083bd7..3122e1611a 100644 --- a/docs/api/flink/Function.md +++ b/docs/api/flink/Function.md @@ -269,6 +269,7 @@ Introduction: Return the Extended Well-Known Binary representation of a geometry EWKB is an extended version of WKB which includes the SRID of the geometry. The format originated in PostGIS but is supported by many GIS tools. If the geometry is lacking SRID a WKB format is produced. +It will ignore the M coordinate if present. Format: `ST_AsEWKB (A:geometry)` @@ -293,6 +294,7 @@ EWKT is an extended version of WKT which includes the SRID of the geometry. The format originated in PostGIS but is supported by many GIS tools. If the geometry is lacking SRID a WKT format is produced. [See ST_SetSRID](#ST_SetSRID) +It will support M coodinate if present since v1.5.0. Format: `ST_AsEWKT (A:geometry)` @@ -309,6 +311,30 @@ Output: SRID=4326;POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0)) ``` +Example: + +```sql +SELECT ST_AsEWKT(ST_MakePointM(1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT M(1 1 1) +``` + +Example: + +```sql +SELECT ST_AsEWKT(ST_MakePoint(1.0, 1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT ZM(1 1 1 1) +``` + ## ST_AsGeoJSON Introduction: Return the [GeoJSON](https://geojson.org/) string representation of a geometry @@ -379,7 +405,8 @@ Output: ## ST_AsText -Introduction: Return the Well-Known Text string representation of a geometry +Introduction: Return the Well-Known Text string representation of a geometry. +It will support M coodinate if present since v1.5.0. Format: `ST_AsText (A:geometry)` @@ -397,6 +424,30 @@ Output: POINT (1 1) ``` +Example: + +```sql +SELECT ST_AsText(ST_MakePointM(1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT M(1 1 1) +``` + +Example: + +```sql +SELECT ST_AsText(ST_MakePoint(1.0, 1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT ZM(1 1 1 1) +``` + ## ST_Azimuth Introduction: Returns Azimuth for two given points in radians null otherwise. diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md index 69a109fb05..e947c61534 100644 --- a/docs/api/sql/Function.md +++ b/docs/api/sql/Function.md @@ -264,6 +264,7 @@ EWKB is an extended version of WKB which includes the SRID of the geometry. The format originated in PostGIS but is supported by many GIS tools. If the geometry is lacking SRID a WKB format is produced. [Se ST_SetSRID](#ST_SetSRID) +It will ignore the M coordinate if present. Format: `ST_AsEWKB (A:geometry)` @@ -288,6 +289,7 @@ EWKT is an extended version of WKT which includes the SRID of the geometry. The format originated in PostGIS but is supported by many GIS tools. If the geometry is lacking SRID a WKT format is produced. [See ST_SetSRID](#ST_SetSRID) +It will support M coodinate if present since v1.5.0. Format: `ST_AsEWKT (A:geometry)` @@ -305,6 +307,30 @@ Output: SRID=4326;POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0)) ``` +Example: + +```sql +SELECT ST_AsEWKT(ST_MakePointM(1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT M(1 1 1) +``` + +Example: + +```sql +SELECT ST_AsEWKT(ST_MakePoint(1.0, 1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT ZM(1 1 1 1) +``` + ## ST_AsGeoJSON Introduction: Return the [GeoJSON](https://geojson.org/) string representation of a geometry @@ -376,7 +402,8 @@ Output: ## ST_AsText -Introduction: Return the Well-Known Text string representation of a geometry +Introduction: Return the Well-Known Text string representation of a geometry. +It will support M coodinate if present since v1.5.0. Format: `ST_AsText (A:geometry)` @@ -394,6 +421,30 @@ Output: POINT (1 1) ``` +Example: + +```sql +SELECT ST_AsText(ST_MakePointM(1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT M(1 1 1) +``` + +Example: + +```sql +SELECT ST_AsText(ST_MakePoint(1.0, 1.0, 1.0, 1.0)) +``` + +Output: + +``` +POINT ZM(1 1 1 1) +``` + ## ST_Azimuth Introduction: Returns Azimuth for two given points in radians null otherwise. 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 2d96d87bda..7c6c713771 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 @@ -455,7 +455,7 @@ public static class ST_AsText extends ScalarFunction { @DataTypeHint("String") public String eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object o) { Geometry geom = (Geometry) o; - return org.apache.sedona.common.Functions.asEWKT(geom); + return org.apache.sedona.common.Functions.asWKT(geom); } }