You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sedona.apache.org by ji...@apache.org on 2023/11/17 00:36:29 UTC
(sedona) branch master updated: [SEDONA-427] Add RS_RasterToWorldCoord (#1123)
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 1ed05805e [SEDONA-427] Add RS_RasterToWorldCoord (#1123)
1ed05805e is described below
commit 1ed05805e0374fc7be37ba67c0d9aed0ac7de0b8
Author: Pranav Toggi <pr...@gmail.com>
AuthorDate: Thu Nov 16 19:36:24 2023 -0500
[SEDONA-427] Add RS_RasterToWorldCoord (#1123)
---
.../sedona/common/raster/RasterAccessors.java | 8 +++++-
.../sedona/common/raster/RasterAccessorsTest.java | 32 ++++++++++++++++++++++
docs/api/sql/Raster-operators.md | 20 ++++++++++++++
.../scala/org/apache/sedona/sql/UDF/Catalog.scala | 1 +
.../expressions/raster/RasterAccessors.scala | 7 +++++
.../org/apache/sedona/sql/rasteralgebraTest.scala | 8 ++++++
6 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterAccessors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterAccessors.java
index 20062d425..4d04bd0a5 100644
--- a/common/src/main/java/org/apache/sedona/common/raster/RasterAccessors.java
+++ b/common/src/main/java/org/apache/sedona/common/raster/RasterAccessors.java
@@ -32,7 +32,7 @@ import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
-import java.awt.image.RenderedImage;
+import java.awt.geom.Point2D;
import java.util.Arrays;
import java.util.Set;
@@ -106,6 +106,12 @@ public class RasterAccessors
return RasterUtils.getWorldCornerCoordinates(raster, colX, rowY).getY();
}
+ public static Geometry getWorldCoord(GridCoverage2D raster, int colX, int rowY) throws TransformException {
+ Point2D worldCoords = RasterUtils.getWorldCornerCoordinates(raster, colX, rowY);
+ Geometry point = new GeometryFactory().createPoint(new Coordinate(worldCoords.getX(), worldCoords.getY()));
+ return point;
+ }
+
public static String getGeoReference(GridCoverage2D raster) {
return getGeoReference(raster, "GDAL");
}
diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterAccessorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterAccessorsTest.java
index 2193225f0..5dac999c9 100644
--- a/common/src/test/java/org/apache/sedona/common/raster/RasterAccessorsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/raster/RasterAccessorsTest.java
@@ -155,6 +155,38 @@ public class RasterAccessorsTest extends RasterTestBase
assertEquals(expectedY, actualY, 0.1d);
}
+ @Test
+ public void testWorldCoord() throws FactoryException, TransformException {
+ int colX = 1, rowY = 1;
+ GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 5, 10, -123, 54, 5, -10, 0, 0, 4326);
+
+ Coordinate actual = RasterAccessors.getWorldCoord(emptyRaster, colX, rowY).getCoordinate();
+ double expectedX = -123, expectedY = 54;
+
+ assertEquals(expectedX, actual.getX(), 0.1d);
+ assertEquals(expectedY, actual.getY(), 0.1d);
+
+ rowY = 2;
+ actual = RasterAccessors.getWorldCoord(emptyRaster, colX, rowY).getCoordinate();
+ expectedY = 44;
+
+ assertEquals(expectedX, actual.getX(), 0.1d);
+ assertEquals(expectedY, actual.getY(), 0.1d);
+ }
+
+ @Test
+ public void testWorldCoordOutOfBounds() throws FactoryException, TransformException{
+ int colX = 4;
+ int rowY = 11;
+ GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 5, 10, -123, 54, 5, -10, 0, 0, 4326);
+
+ double expectedX = -108, expectedY = -46;
+ Coordinate actual = RasterAccessors.getWorldCoord(emptyRaster, colX, rowY).getCoordinate();
+
+ assertEquals(expectedX, actual.getX(), 0.1d);
+ assertEquals(expectedY, actual.getY(), 0.1d);
+ }
+
@Test
public void testGridCoordLatLon() throws TransformException, FactoryException {
double longitude = -123, latitude = 54;
diff --git a/docs/api/sql/Raster-operators.md b/docs/api/sql/Raster-operators.md
index 697c21af0..55d0a8d57 100644
--- a/docs/api/sql/Raster-operators.md
+++ b/docs/api/sql/Raster-operators.md
@@ -384,6 +384,26 @@ Output:
54
```
+### RS_RasterToWorldCoord
+
+Introduction: Returns the upper left X and Y coordinates of the given row and column of the given raster geometric units of the geo-referenced raster as a Point geometry. If any out of bounds values are given, the X and Y coordinates of the assumed point considering existing raster pixel size and skew values will be returned.
+
+Format: `RS_RasterToWorldCoord(raster: Raster, colX: Integer, rowY: Integer)`
+
+Since: `v1.5.1`
+
+Spark SQL Example:
+
+```sql
+SELECT RS_RasterToWorldCoord(ST_MakeEmptyRaster(1, 5, 10, -123, 54, 5, -10, 0, 0, 4326), 1, 1) from rasters
+```
+
+Output:
+
+```
+POINT (-123 54)
+```
+
### RS_Rotation
Introduction: Returns the uniform rotation of the raster in radian.
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 75f30016c..3a176db8d 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
@@ -240,6 +240,7 @@ object Catalog {
function[RS_ConvexHull](),
function[RS_RasterToWorldCoordX](),
function[RS_RasterToWorldCoordY](),
+ function[RS_RasterToWorldCoord](),
function[RS_Within](),
function[RS_Contains](),
function[RS_WorldToRasterCoord](),
diff --git a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterAccessors.scala b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterAccessors.scala
index e6f13eb3f..f0039c6af 100644
--- a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterAccessors.scala
+++ b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterAccessors.scala
@@ -121,6 +121,13 @@ case class RS_RasterToWorldCoordY(inputExpressions: Seq[Expression]) extends Inf
copy(inputExpressions = newChildren)
}
}
+
+case class RS_RasterToWorldCoord(inputExpressions: Seq[Expression]) extends InferredExpression(RasterAccessors.getWorldCoord _) {
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = {
+ copy(inputExpressions = newChildren)
+ }
+}
+
case class RS_WorldToRasterCoord(inputExpressions: Seq[Expression]) extends InferredExpression(inferrableFunction3(RasterAccessors.getGridCoord), inferrableFunction2(RasterAccessors.getGridCoord)) {
protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = {
copy(inputExpressions = newChildren)
diff --git a/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala b/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala
index d855e145d..018ed42f6 100644
--- a/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala
+++ b/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala
@@ -969,6 +969,14 @@ class rasteralgebraTest extends TestBaseScala with BeforeAndAfter with GivenWhen
assertEquals(4021262.7487925636, result, 0.5d)
}
+ it("Passed RS_RasterToWorldCoord with raster") {
+ var df = sparkSession.read.format("binaryFile").load(resourceFolder + "raster/test1.tiff")
+ df = df.selectExpr("RS_FromGeoTiff(content) as raster")
+ val result = df.selectExpr("RS_RasterToWorldCoord(raster, 1, 1)").first().get(0).toString
+ val expected = "POINT (-13095818 4021262.75)"
+ assertEquals(expected, result)
+ }
+
it("Passed RS_WorldToRasterCoord with raster") {
var df = sparkSession.read.format("binaryFile").load(resourceFolder + "raster/test1.tiff")
df = df.selectExpr("RS_FromGeoTiff(content) as raster")