This is an automated email from the ASF dual-hosted git repository. jiayu pushed a commit to branch prepare-1.7.2 in repository https://gitbox.apache.org/repos/asf/sedona.git
commit 64d2ffbaa2c6d95787e0f811d8a2e725fa1e97fe Author: Pranav Toggi <[email protected]> AuthorDate: Mon Mar 31 11:57:08 2025 -0700 [SEDONA-728] Fix Rasterization clamping bug (#1897) * profiling1 * profiling4 * profiling... * profiling 8 * [BUG-918] Fix clamping issue in Rasterization (#403) ## Did you read the Contributor Guide? - Yes, I have read the [Contributor Rules](https://sedona.apache.org/latest/community/rule/) and [Contributor Development Guide](https://sedona.apache.org/latest/community/develop/) ## Is this PR related to a ticket? - Yes, and the PR name follows the format `[SEDONA-XXX] my subject`. ## What changes were proposed in this PR? - Fixes clamping issue in scanLine intersection calculation ## How was this patch tested? - Passes new and existing tests ## Did this PR include necessary documentation updates? - Yes, I am adding a new API. I am using the [current SNAPSHOT version number](https://github.com/apache/sedona/blob/99239524f17389fc4ae9548ea88756f8ea538bb9/pom.xml#L29) in `vX.Y.Z` format. - Yes, I have updated the documentation. - No, this PR does not affect any public API so no need to change the documentation. * undo pom changes --- .../apache/sedona/common/raster/Rasterization.java | 4 ++-- .../sedona/common/raster/FunctionEditorsTest.java | 6 +++--- .../sedona/common/raster/RasterBandAccessorsTest.java | 19 +++++++++++++++++-- .../org/apache/sedona/sql/rasteralgebraTest.scala | 9 +++++---- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/raster/Rasterization.java b/common/src/main/java/org/apache/sedona/common/raster/Rasterization.java index 652e822e92..19530441bb 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/Rasterization.java +++ b/common/src/main/java/org/apache/sedona/common/raster/Rasterization.java @@ -574,7 +574,7 @@ public class Rasterization { // calculating slope for (double y = yStart; y >= yEnd; y--) { double xIntercept = p1X; // Vertical line, xIntercept is constant - if (xIntercept < 0 || xIntercept > params.writableRaster.getWidth()) { + if (xIntercept < 0 || xIntercept >= params.writableRaster.getWidth()) { continue; // Skip xIntercepts outside geomExtent } scanlineIntersections.computeIfAbsent(y, k -> new TreeSet<>()).add(xIntercept); @@ -585,7 +585,7 @@ public class Rasterization { for (double y = yStart; y >= yEnd; y--) { double xIntercept = p1X + ((p1Y - y) / slope); - if ((xIntercept < 0) || (xIntercept > params.writableRaster.getWidth())) { + if ((xIntercept < 0) || (xIntercept >= params.writableRaster.getWidth())) { continue; // skip xIntercepts outside geomExtent } if (!scanlineIntersections.containsKey(y)) { 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 ef34a5060d..93aa474588 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 @@ -68,8 +68,8 @@ public class FunctionEditorsTest extends RasterTestBase { expected = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, - 10.0, 0.0, 0.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, - 10.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 10.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 10.0, 0.0, 0.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, + 10.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 10.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 @@ -239,7 +239,7 @@ public class FunctionEditorsTest extends RasterTestBase { actual = MapAlgebra.bandAsArray(raster, 1); expected = new double[] { - 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 0.0, 0.0, 0.0, + 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 255.0, 255.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; assertArrayEquals(expected, actual, 0.1d); diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterBandAccessorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterBandAccessorsTest.java index 21f4e446ae..e0efb21897 100644 --- a/common/src/test/java/org/apache/sedona/common/raster/RasterBandAccessorsTest.java +++ b/common/src/test/java/org/apache/sedona/common/raster/RasterBandAccessorsTest.java @@ -100,14 +100,29 @@ public class RasterBandAccessorsTest extends RasterTestBase { 0); Double actualZonalStats = RasterBandAccessors.getZonalStats(raster, extent, "mode"); - assertNull(actualZonalStats); + assertEquals(10.0, actualZonalStats, FP_TOLERANCE); String actualZonalStatsAll = Arrays.toString(RasterBandAccessors.getZonalStatsAll(raster, extent)); - String expectedZonalStatsAll = "[0.0, null, null, null, null, null, null, null, null]"; + String expectedZonalStatsAll = "[1.0, 10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 10.0]"; assertEquals(expectedZonalStatsAll, actualZonalStatsAll); } + @Test + public void testZonalStatsForVerticalLineBug() throws Exception { + String wkt = + "POLYGON ((989675.3 221207.04013636176, 989675.3 221109.675, 989435.2175433404 221109.675, 989433.6550697018 221110.53743814293, 989419.3 221118.46099022447, 989419.3 221137.08165200218, 989449.9606422258 221192.9473339209, 989465.7613533186 221221.73707975633, 989508.9887178271 221300.49928501665, 989630.3976442496 221232.27312269452, 989639.3630089872 221227.23492283348, 989675.3 221207.04013636176))"; + + Geometry geom = Constructors.geomFromWKT(wkt, 2263); + + GridCoverage2D raster = + RasterConstructors.makeEmptyRaster(1, 256, 256, 989419.3, 221365.675, 1, -1, 0, 0, 2263); + + Double actual = RasterBandAccessors.getZonalStats(raster, geom, 1, "mean", true); + Double expected = 0.0; + assertEquals(expected, actual, FP_TOLERANCE); + } + @Test public void testZonalStats() throws FactoryException, ParseException, IOException { GridCoverage2D raster = 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 5832e54077..ff5dc7109b 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 @@ -1633,12 +1633,13 @@ class rasteralgebraTest extends TestBaseScala with BeforeAndAfter with GivenWhen |SELECT RS_SetSRID(RS_AddBandFromArray(RS_MakeEmptyRaster(1, "D", 5, 5, 1, -1, 1), pixels, 1), 4326) as raster, geom FROM data |""".stripMargin) - val actual = df.selectExpr("RS_ZonalStats(raster, geom, 1, 'mode')").first().get(0) - assertNull(actual) + var actual = df.selectExpr("RS_ZonalStats(raster, geom, 1, 'mode')").first().get(0) + assertEquals(10.0, actual) val statsDf = df.selectExpr("RS_ZonalStatsAll(raster, geom) as stats") - val actualBoolean = statsDf.selectExpr("isNull(stats.mode)").first().getAs[Boolean](0) - assertTrue(actualBoolean) + actual = statsDf.first().getStruct(0).toSeq.slice(0, 9) + val expected = Seq(1.0, 10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 10.0) + assertTrue(expected.equals(actual)) } it("Passed RS_ZonalStats") {
