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/incubator-sedona.git
The following commit(s) were added to refs/heads/master by this push:
new d71b5604 [SEDONA-116] Add ST_YMax and ST_YMin function (#620)
d71b5604 is described below
commit d71b5604b0e6e9f91be6ec342e4cfe13bdd548ed
Author: naharon2210 <[email protected]>
AuthorDate: Sat Apr 23 01:22:20 2022 -0700
[SEDONA-116] Add ST_YMax and ST_YMin function (#620)
---
docs/api/flink/Function.md | 28 +++++++++++++
docs/api/sql/Function.md | 31 +++++++++++++++
.../main/java/org/apache/sedona/flink/Catalog.java | 4 +-
.../apache/sedona/flink/expressions/Functions.java | 28 +++++++++++++
.../java/org/apache/sedona/flink/FunctionTest.java | 19 +++++++++
.../scala/org/apache/sedona/sql/UDF/Catalog.scala | 4 +-
.../sql/sedona_sql/expressions/Functions.scala | 46 ++++++++++++++++++++++
.../org/apache/sedona/sql/functionTestScala.scala | 10 +++++
8 files changed, 168 insertions(+), 2 deletions(-)
diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index 8c613c1a..8d2ba930 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -56,7 +56,35 @@ Spark SQL example:
SELECT ST_Buffer(polygondf.countyshape, 1)
FROM polygondf
```
+## ST_YMin
+Introduction: Return the minimum Y coordinate of A
+
+Format: `ST_Y_Min (A:geometry)`
+
+Since: `v1.2.1`
+
+Spark SQL example:
+```SQL
+SELECT ST_YMin(ST_GeomFromText('POLYGON((0 0 1, 1 1 1, 1 2 1, 1 1 1, 0 0 1))'))
+```
+
+Output : 0
+
+## ST_YMax
+
+Introduction: Return the minimum Y coordinate of A
+
+Format: `ST_YMax (A:geometry)`
+
+Since: `v1.2.1`
+
+Spark SQL example:
+```SQL
+SELECT ST_YMax(ST_GeomFromText('POLYGON((0 0 1, 1 1 1, 1 2 1, 1 1 1, 0 0 1))'))
+```
+
+Output : 2
## ST_FlipCoordinates
Introduction: Returns a version of the given geometry with X and Y axis
flipped.
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 1adfa515..1080f1d7 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -12,6 +12,37 @@ SELECT ST_Distance(polygondf.countyshape,
polygondf.countyshape)
FROM polygondf
```
+## ST_YMin
+
+Introduction: Return the minimum Y coordinate of A
+
+Format: `ST_Y_Min (A:geometry)`
+
+Since: `v1.2.1`
+
+Spark SQL example:
+```SQL
+SELECT ST_YMin(ST_GeomFromText('POLYGON((0 0 1, 1 1 1, 1 2 1, 1 1 1, 0 0 1))'))
+```
+
+Output : 0
+
+## ST_YMax
+
+Introduction: Return the minimum Y coordinate of A
+
+Format: `ST_YMax (A:geometry)`
+
+Since: `v1.2.1`
+
+Spark SQL example:
+```SQL
+SELECT ST_YMax(ST_GeomFromText('POLYGON((0 0 1, 1 1 1, 1 2 1, 1 1 1, 0 0 1))'))
+```
+
+Output: 2
+
+
## ST_3DDistance
Introduction: Return the 3-dimensional minimum cartesian distance between A
and B
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 d0c207ea..6fe3ab43 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -35,7 +35,9 @@ public class Catalog {
new Functions.ST_Reverse(),
new Functions.ST_AsEWKT(),
new Functions.ST_Force_2D(),
- new Functions.ST_IsEmpty()
+ new Functions.ST_IsEmpty(),
+ new Functions.ST_YMax(),
+ new Functions.ST_YMin()
};
}
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 9dd46016..46b4c713 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
@@ -25,6 +25,7 @@ import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateSequence;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.Coordinate;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
@@ -54,6 +55,33 @@ public class Functions {
}
}
+ public static class ST_YMin extends ScalarFunction {
+ @DataTypeHint("Double")
+ public Double eval(@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o){
+ Geometry geom = (Geometry) o;
+ Coordinate[] points= geom.getCoordinates();
+ double min=Double.MAX_VALUE;
+ for(int i=0;i<points.length;i++){
+ min=Math.min(points[i].getY(),min);
+ }
+ return min;
+ }
+ }
+
+ public static class ST_YMax extends ScalarFunction {
+ @DataTypeHint("Double")
+ public Double eval(@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o){
+ Geometry geom = (Geometry) o;
+ Coordinate[] points= geom.getCoordinates();
+ double max=Double.MIN_VALUE;
+ for(int i=0;i<points.length;i++){
+ max=Math.max(points[i].getY(),max);
+ }
+ return max;
+ }
+ }
+
+
public static class ST_Transform 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("String")
String sourceCRS, @DataTypeHint("String") String targetCRS) {
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 0a1cc84b..f4901e69 100644
--- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
@@ -61,6 +61,25 @@ public class FunctionTest extends TestBase{
assertEquals(0.0, first(pointTable).getField(0));
}
+ @Test
+ public void testYMax() {
+ Table polygonTable = createPolygonTable(1);
+ Table ResultTable =
polygonTable.select(call(Functions.ST_YMax.class.getSimpleName(),
$(polygonColNames[0])));
+ assert(first(ResultTable).getField(0)!=null);
+ double result = (double) first(ResultTable).getField(0);
+ assertEquals(0.5, result,0);
+ }
+
+ @Test
+ public void testYMin() {
+ Table polygonTable = createPolygonTable(1);
+ Table ResultTable =
polygonTable.select(call(Functions.ST_YMin.class.getSimpleName(),
$(polygonColNames[0])));
+ assert(first(ResultTable).getField(0)!=null);
+ double result = (double) first(ResultTable).getField(0);
+ assertEquals(-0.5, result, 0);
+ }
+
+
@Test
public void testGeomToGeoHash() {
Table pointTable = createPointTable(testDataSize);
diff --git a/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
b/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
index df9d7c0b..882ed307 100644
--- a/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
+++ b/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
@@ -20,7 +20,7 @@ package org.apache.sedona.sql.UDF
import org.apache.spark.sql.catalyst.analysis.FunctionRegistry.FunctionBuilder
import org.apache.spark.sql.expressions.{Aggregator,
UserDefinedAggregateFunction}
-import org.apache.spark.sql.sedona_sql.expressions._
+import org.apache.spark.sql.sedona_sql.expressions.{ST_YMax, ST_YMin, _}
import org.apache.spark.sql.sedona_sql.expressions.collect.ST_Collect
import org.apache.spark.sql.sedona_sql.expressions.raster.{RS_Add, RS_Append,
RS_Array, RS_Base64, RS_BitwiseAnd, RS_BitwiseOr, RS_Count, RS_Divide,
RS_FetchRegion, RS_GetBand, RS_GreaterThan, RS_GreaterThanEqual, RS_HTML,
RS_LessThan, RS_LessThanEqual, RS_LogicalDifference, RS_LogicalOver, RS_Mean,
RS_Mode, RS_Modulo, RS_Multiply, RS_MultiplyFactor, RS_Normalize,
RS_NormalizedDifference, RS_SquareRoot, RS_Subtract}
import org.locationtech.jts.geom.Geometry
@@ -108,6 +108,8 @@ object Catalog {
ST_Reverse,
ST_AsEWKT,
ST_Force_2D,
+ ST_YMax,
+ ST_YMin,
// Expression for rasters
RS_NormalizedDifference,
RS_Mean,
diff --git
a/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
b/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
index a24a549e..ffc33275 100644
---
a/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
+++
b/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
@@ -49,6 +49,8 @@ import org.locationtech.jts.precision.GeometryPrecisionReducer
import org.locationtech.jts.simplify.TopologyPreservingSimplifier
import org.opengis.referencing.operation.MathTransform
import org.wololo.jts2geojson.GeoJSONWriter
+import org.locationtech.jts.geom.Geometry
+import org.locationtech.jts.geom.Coordinate
import java.nio.ByteOrder
import scala.util.{Failure, Success, Try}
@@ -77,6 +79,50 @@ case class ST_Distance(inputExpressions: Seq[Expression])
}
}
+
+case class ST_YMax(inputExpressions: Seq[Expression])
+ extends UnaryGeometryExpression with CodegenFallback {
+ assert(inputExpressions.length == 1)
+
+ override protected def nullSafeEval(geometry: Geometry): Any = {
+ val seqRev : Array[Coordinate] = geometry.getCoordinates()
+ var maxVal:Double = Double.MinValue
+ for(x <- seqRev ){
+ maxVal=Math.max(maxVal,x.getY())
+ }
+ maxVal
+ }
+
+ override def dataType: DataType = DoubleType
+
+ override def children: Seq[Expression] = inputExpressions
+
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
{
+ copy(inputExpressions = newChildren)
+ }
+}
+
+case class ST_YMin(inputExpressions: Seq[Expression])
+ extends UnaryGeometryExpression with CodegenFallback {
+ assert(inputExpressions.length == 1)
+
+ override protected def nullSafeEval(geometry: Geometry): Any = {
+ val seqRev : Array[Coordinate] = geometry.getCoordinates()
+ var minVal:Double = Double.MaxValue
+ for(x <- seqRev){
+ minVal=Math.min(minVal,x.getY())
+ }
+ minVal
+ }
+
+ override def dataType: DataType = DoubleType
+
+ override def children: Seq[Expression] = inputExpressions
+
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
{
+ copy(inputExpressions = newChildren)
+ }
+}
case class ST_3DDistance(inputExpressions: Seq[Expression])
extends BinaryGeometryExpression with CodegenFallback {
assert(inputExpressions.length == 2)
diff --git a/sql/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
b/sql/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
index 71411cc0..ff6bce37 100644
--- a/sql/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
+++ b/sql/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
@@ -65,6 +65,16 @@ class functionTestScala extends TestBaseScala with Matchers
with GeometrySample
assert(functionDf.count() > 0);
}
+ it("Passed ST_YMax") {
+ var test = sparkSession.sql("SELECT ST_YMax(ST_GeomFromWKT('POLYGON ((-3
-3, 3 -3, 3 3, -3 3, -3 -3))'))")
+ assert(test.take(1)(0).get(0).asInstanceOf[Double] == 3.0)
+ }
+
+ it("Passed ST_YMin") {
+ var test = sparkSession.sql("SELECT ST_YMin(ST_GeomFromWKT('POLYGON ((-3
-3, 3 -3, 3 3, -3 3, -3 -3))'))")
+ assert(test.take(1)(0).get(0).asInstanceOf[Double] == -3.0)
+ }
+
it("Passed ST_Centroid") {
var polygonWktDf = sparkSession.read.format("csv").option("delimiter",
"\t").option("header", "false").load(mixedWktGeometryInputLocation)
polygonWktDf.createOrReplaceTempView("polygontable")