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/08/29 00:08:56 UTC
[sedona] branch master updated: [SEDONA-378] Add RS_SetValue (#990)
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 43c53707b [SEDONA-378] Add RS_SetValue (#990)
43c53707b is described below
commit 43c53707bd87221c9f8a1c925d6167d2322f105d
Author: Furqaanahmed Khan <46...@users.noreply.github.com>
AuthorDate: Mon Aug 28 20:08:51 2023 -0400
[SEDONA-378] Add RS_SetValue (#990)
---
.../sedona/common/raster/PixelFunctionEditors.java | 12 ++++++++
.../sedona/common/raster/FunctionEditorsTest.java | 26 +++++++++++++----
docs/api/sql/Raster-operators.md | 34 +++++++++++++++++++++-
.../scala/org/apache/sedona/sql/UDF/Catalog.scala | 1 +
.../expressions/raster/PixelFunctionEditors.scala | 9 ++++++
.../org/apache/sedona/sql/rasteralgebraTest.scala | 17 +++++++++--
6 files changed, 91 insertions(+), 8 deletions(-)
diff --git a/common/src/main/java/org/apache/sedona/common/raster/PixelFunctionEditors.java b/common/src/main/java/org/apache/sedona/common/raster/PixelFunctionEditors.java
index 66db6fe13..cd4a687d1 100644
--- a/common/src/main/java/org/apache/sedona/common/raster/PixelFunctionEditors.java
+++ b/common/src/main/java/org/apache/sedona/common/raster/PixelFunctionEditors.java
@@ -46,6 +46,10 @@ public class PixelFunctionEditors {
if (keepNoData) {
noDataValue = RasterBandAccessors.getBandNoDataValue(raster, band);
}
+
+ // making them 0-indexed
+ colX--; rowY--;
+
int iterator = 0;
for (int j = rowY; j < rowY + height; j++) {
for (int i = colX; i < colX + width; i++) {
@@ -66,4 +70,12 @@ public class PixelFunctionEditors {
public static GridCoverage2D setValues(GridCoverage2D raster, int band, int colX, int rowY, int width, int height, double[] values) {
return setValues(raster, band, colX, rowY, width, height, values, false);
}
+
+ public static GridCoverage2D setValue(GridCoverage2D raster, int band, int colX, int rowY, double newValue) {
+ return setValues(raster, band, colX, rowY, 1, 1, new double[]{newValue}, false);
+ }
+
+ public static GridCoverage2D setValue(GridCoverage2D raster, int colX, int rowY, double newValue) {
+ return setValues(raster, 1, colX, rowY, 1, 1, new double[]{newValue}, false);
+ }
}
diff --git a/common/src/test/java/org/apache/sedona/common/raster/FunctionEditorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/FunctionEditorsTest.java
index 516f07e62..c5292dd39 100644
--- a/common/src/test/java/org/apache/sedona/common/raster/FunctionEditorsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/raster/FunctionEditorsTest.java
@@ -22,26 +22,42 @@ import org.geotools.coverage.grid.GridCoverage2D;
import org.junit.Test;
import org.opengis.referencing.FactoryException;
-import java.util.Arrays;
-
import static org.junit.Assert.*;
public class FunctionEditorsTest extends RasterTestBase {
@Test
- public void testSetValueWithEmptyRaster() throws FactoryException {
+ public void testSetValuesWithEmptyRaster() throws FactoryException {
GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 5, 5, 0, 0, 1, -1, 0, 0, 0);
double[] values = new double[] {1,1,1,0,0,0,1,2,3,3,5,6,7,0,0,3,0,0,3,0,0,0,0,0,0};
emptyRaster = MapAlgebra.addBandFromArray(emptyRaster, values, 1, 0d);
double[] newValues = new double[] {11,12,13,14,15,16,17,18,19};
GridCoverage2D raster = PixelFunctionEditors.setValues(emptyRaster, 1, 2, 2, 3, 3, newValues, true);
double[] actual = MapAlgebra.bandAsArray(raster, 1);
- double[] expected = new double[] {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 5.0, 6.0, 11.0, 0.0, 0.0, 3.0, 0.0, 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+ double[] expected = new double[] {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 11.0, 12.0, 13.0, 3.0, 5.0, 14.0, 15.0, 0.0, 0.0, 3.0, 0.0, 0.0, 19.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
assertArrayEquals(actual, expected, 0.0);
raster = PixelFunctionEditors.setValues(emptyRaster, 1, 2, 2, 3, 3, newValues);
actual = MapAlgebra.bandAsArray(raster, 1);
- expected = new double[] {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 5.0, 6.0, 11.0, 12.0, 13.0, 3.0, 0.0, 14.0, 15.0, 16.0, 0.0, 0.0, 17.0, 18.0, 19.0};
+ expected = new double[] {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 11.0, 12.0, 13.0, 3.0, 5.0, 14.0, 15.0, 16.0, 0.0, 3.0, 17.0, 18.0, 19.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
assertArrayEquals(actual, expected, 0.0);
}
+
+ @Test
+ public void testSetValueWithEmptyRaster() throws FactoryException {
+ GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 5, 5, 0, 0, 1, -1, 0, 0, 0);
+ double[] values = new double[] {1,1,1,0,0,0,1,2,3,3,5,6,7,0,0,3,0,0,3,0,0,0,0,0,0};
+ emptyRaster = MapAlgebra.addBandFromArray(emptyRaster, values, 1, 0d);
+ double newValue = 1777;
+ GridCoverage2D raster = PixelFunctionEditors.setValue(emptyRaster, 1, 2, 2, newValue);
+ double[] actual = MapAlgebra.bandAsArray(raster, 1);
+ double[] expected = new double[]{1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1777.0, 2.0, 3.0, 3.0, 5.0, 6.0, 7.0, 0.0, 0.0, 3.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+ assertArrayEquals(expected, actual, 0.1d);
+
+ newValue = 8723;
+ raster = PixelFunctionEditors.setValue(emptyRaster, 2, 2, newValue);
+ actual = MapAlgebra.bandAsArray(raster, 1);
+ expected = new double[]{1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 8723.0, 2.0, 3.0, 3.0, 5.0, 6.0, 7.0, 0.0, 0.0, 3.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+ assertArrayEquals(expected, actual, 0.1d);
+ }
}
diff --git a/docs/api/sql/Raster-operators.md b/docs/api/sql/Raster-operators.md
index 3fe33532b..16ff2a806 100644
--- a/docs/api/sql/Raster-operators.md
+++ b/docs/api/sql/Raster-operators.md
@@ -963,6 +963,38 @@ Output:
-3.000000
```
+### RS_SetValue
+
+Introduction: Returns a raster by replacing the value of pixel specified by `colX` and `rowY`.
+
+Format:
+
+```
+RS_SetValue(raster: Raster, bandIndex: Integer = 1, colX: Integer, rowY: Integer, newValue: Double)
+```
+
+Since: `v1.5.0`
+
+Spark SQL Example:
+
+```sql
+SELECT RS_BandAsArray(
+ RS_SetValue(
+ RS_AddBandFromArray(
+ RS_MakeEmptyRaster(1, 5, 5, 0, 0, 1, -1, 0, 0, 0),
+ [1,1,1,0,0,0,1,2,3,3,5,6,7,0,0,3,0,0,3,0,0,0,0,0,0], 1, 0d
+ ),
+ 1, 2, 2, 255
+ )
+ )
+```
+
+Output:
+
+```
+[1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 255.0, 2.0, 3.0, 3.0, 5.0, 6.0, 7.0, 0.0, 0.0, 3.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+```
+
### RS_SetValues
Introduction: Returns a raster by replacing the values of pixels in a specified rectangular region. The top left
@@ -1004,7 +1036,7 @@ SELECT RS_BandAsArray(
Output:
```
-[1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 5.0, 6.0, 11.0, 12.0, 13.0, 3.0, 0.0, 14.0, 15.0, 16.0, 0.0, 0.0, 17.0, 18.0, 19.0]
+[1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 11.0, 12.0, 13.0, 3.0, 5.0, 14.0, 15.0, 16.0, 0.0, 3.0, 17.0, 18.0, 19.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
```
### RS_SetSRID
diff --git a/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala b/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
index fd8a62611..ee104a411 100644
--- a/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
+++ b/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
@@ -205,6 +205,7 @@ object Catalog {
function[RS_SetGeoReference](),
function[RS_SetBandNoDataValue](),
function[RS_SetValues](),
+ function[RS_SetValue](),
function[RS_SRID](),
function[RS_Value](1),
function[RS_Values](1),
diff --git a/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/PixelFunctionEditors.scala b/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/PixelFunctionEditors.scala
index 94fdf8de3..824f9a7b2 100644
--- a/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/PixelFunctionEditors.scala
+++ b/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/PixelFunctionEditors.scala
@@ -30,4 +30,13 @@ case class RS_SetValues(inputExpressions: Seq[Expression]) extends InferredExpre
protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = {
copy(inputExpressions = newChildren)
}
+}
+
+case class RS_SetValue(inputExpressions: Seq[Expression]) extends InferredExpression(
+ inferrableFunction5(PixelFunctionEditors.setValue),
+ inferrableFunction4(PixelFunctionEditors.setValue)
+) {
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = {
+ copy(inputExpressions = newChildren)
+ }
}
\ No newline at end of file
diff --git a/sql/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala b/sql/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala
index 1704b081c..581c66223 100644
--- a/sql/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala
+++ b/sql/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala
@@ -345,11 +345,24 @@ class rasteralgebraTest extends TestBaseScala with BeforeAndAfter with GivenWhen
var inputDf = Seq((Seq(1, 1, 1, 0, 0, 0, 1, 2, 3, 3, 5, 6, 7, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0), Seq(11, 12, 13, 14, 15, 16, 17, 18, 19))).toDF("band","newValues")
var df = inputDf.selectExpr("RS_AddBandFromArray(RS_MakeEmptyRaster(1, 5, 5, 0, 0, 1, -1, 0, 0, 0), band, 1, 0d) as raster", "newValues")
var actual = df.selectExpr("RS_BandAsArray(RS_SetValues(raster, 1, 2, 2, 3, 3, newValues, true), 1)").first().getSeq(0)
- var expected = Seq(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 5.0, 6.0, 11.0, 0.0, 0.0, 3.0, 0.0, 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
+ var expected = Seq(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 11.0, 12.0, 13.0, 3.0, 5.0, 14.0, 15.0, 0.0, 0.0, 3.0, 0.0, 0.0, 19.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
assert(expected.equals(actual))
actual = df.selectExpr("RS_BandAsArray(RS_SetValues(raster, 1, 2, 2, 3, 3, newValues), 1)").first().getSeq(0)
- expected = Seq(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 5.0, 6.0, 11.0, 12.0, 13.0, 3.0, 0.0, 14.0, 15.0, 16.0, 0.0, 0.0, 17.0, 18.0, 19.0)
+ expected = Seq(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 11.0, 12.0, 13.0, 3.0, 5.0, 14.0, 15.0, 16.0, 0.0, 3.0, 17.0, 18.0, 19.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
+ assert(expected.equals(actual))
+ }
+
+ it("Passed RS_SetValue with empty raster") {
+ var inputDF = Seq((Seq(1, 1, 1, 0, 0, 0, 1, 2, 3, 3, 5, 6, 7, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0))).toDF("band")
+ var df = inputDF.selectExpr("RS_AddBandFromArray(RS_MakeEmptyRaster(1, 5, 5, 0, 0, 1, -1, 0, 0, 0), " +
+ "band, 1, 0d) as raster")
+ var actual = df.selectExpr("RS_BandAsArray(RS_SetValue(raster, 1, 2, 2, 255), 1)").first().getSeq(0)
+ var expected = Seq(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 255.0, 2.0, 3.0, 3.0, 5.0, 6.0, 7.0, 0.0, 0.0, 3.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
+ assert(expected.equals(actual))
+
+ actual = df.selectExpr("RS_BandAsArray(RS_SetValue(raster, 2, 2, 156), 1)").first().getSeq(0)
+ expected = Seq(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 156.0, 2.0, 3.0, 3.0, 5.0, 6.0, 7.0, 0.0, 0.0, 3.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
assert(expected.equals(actual))
}