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 354b55d896 [SEDONA-735] Fix RS_Clip bug caused by AOI geometries 
smaller than pixel size (#1952)
354b55d896 is described below

commit 354b55d896cb02dc4fd29b7b8b85e3a68ec30c7f
Author: Pranav Toggi <[email protected]>
AuthorDate: Wed May 21 12:02:17 2025 -0700

    [SEDONA-735] Fix RS_Clip bug caused by AOI geometries smaller than pixel 
size (#1952)
    
    * profiling1
    
    * profiling4
    
    * profiling...
    
    * profiling 8
    
    * remove redundant cropping
    
    * fix lenient mode
    
    * Use rasterizeGeomExtent from Rasterization class
    
    * add comment
    
    * add test for small AOI geometries
    
    * make rasterizeGeomExtent a protected method
    
    * add test geotif
    
    * undo pom changes
    
    * Address comments
    
    * spotless fix
---
 .../sedona/common/raster/RasterBandEditors.java    | 11 +++++++++-
 .../apache/sedona/common/raster/Rasterization.java |  2 +-
 .../common/raster/RasterBandEditorsTest.java       | 24 +++++++++++++++++++++-
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git 
a/common/src/main/java/org/apache/sedona/common/raster/RasterBandEditors.java 
b/common/src/main/java/org/apache/sedona/common/raster/RasterBandEditors.java
index a05872722b..3abd56869e 100644
--- 
a/common/src/main/java/org/apache/sedona/common/raster/RasterBandEditors.java
+++ 
b/common/src/main/java/org/apache/sedona/common/raster/RasterBandEditors.java
@@ -31,7 +31,10 @@ import org.geotools.coverage.GridSampleDimension;
 import org.geotools.coverage.grid.GridCoverage2D;
 import org.geotools.coverage.processing.CannotCropException;
 import org.geotools.coverage.processing.operation.Crop;
+import org.geotools.geometry.Envelope2D;
+import org.geotools.geometry.jts.JTS;
 import org.locationtech.jts.geom.Geometry;
+import org.opengis.geometry.BoundingBox;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.FactoryException;
 import org.opengis.referencing.operation.TransformException;
@@ -298,13 +301,19 @@ public class RasterBandEditors {
     singleBandRaster = pair.getLeft();
     geometry = pair.getRight();
 
+    // Use rasterizeGeomExtent for AOI geometries smaller than a pixel
+    double[] metadata = RasterAccessors.metadata(singleBandRaster);
+    Envelope2D geomEnvelope =
+        Rasterization.rasterizeGeomExtent(geometry, singleBandRaster, 
metadata, allTouched);
+    Geometry geomExtent = JTS.toGeometry((BoundingBox) geomEnvelope);
+
     // Crop the raster
     // this will shrink the extent of the raster to the geometry
     Crop cropObject = new Crop();
     ParameterValueGroup parameters = cropObject.getParameters();
     parameters.parameter("Source").setValue(singleBandRaster);
     parameters.parameter(Crop.PARAMNAME_DEST_NODATA).setValue(new double[] 
{noDataValue});
-    parameters.parameter(Crop.PARAMNAME_ROI).setValue(geometry);
+    parameters.parameter(Crop.PARAMNAME_ROI).setValue(geomExtent);
 
     GridCoverage2D newRaster;
     try {
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 19530441bb..5d15990d6f 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
@@ -303,7 +303,7 @@ public class Rasterization {
     return x >= minX && x <= maxX && y >= minY && y <= maxY;
   }
 
-  private static Envelope2D rasterizeGeomExtent(
+  protected static Envelope2D rasterizeGeomExtent(
       Geometry geom, GridCoverage2D raster, double[] metadata, boolean 
allTouched) {
 
     if (Objects.equals(geom.getGeometryType(), "MultiLineString")) {
diff --git 
a/common/src/test/java/org/apache/sedona/common/raster/RasterBandEditorsTest.java
 
b/common/src/test/java/org/apache/sedona/common/raster/RasterBandEditorsTest.java
index 73f81e8ed1..45de7c7e30 100644
--- 
a/common/src/test/java/org/apache/sedona/common/raster/RasterBandEditorsTest.java
+++ 
b/common/src/test/java/org/apache/sedona/common/raster/RasterBandEditorsTest.java
@@ -201,6 +201,28 @@ public class RasterBandEditorsTest extends RasterTestBase {
     assertTrue(Arrays.equals(expectedValues, actualValues));
   }
 
+  @Test
+  public void testClip_smallAOI() throws FactoryException, TransformException, 
ParseException {
+    // Test for AOI geometries smaller than a pixel
+    GridCoverage2D raster =
+        RasterConstructors.makeEmptyRaster(1, "F", 4, 4, 401805.039562261, 
2095852.150947876, 30);
+    raster = RasterEditors.setSrid(raster, 5070);
+    double[] bandValues = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16};
+    raster = MapAlgebra.addBandFromArray(raster, bandValues, 1);
+    String polygon =
+        "POLYGON ((401866.1071465613 2095803.8989834636, 401850.9983055725 
2095803.1375789386, 401850.039562261 2095822.150947876, 401865.14840359957 
2095822.9124532426, 401880.2572475523 2095823.6738547424, 401881.2159852499 
2095804.6604855175, 401866.1071465613 2095803.8989834636))";
+    Geometry geom = Constructors.geomFromWKT(polygon, 5070);
+
+    GridCoverage2D clippedRaster = RasterBandEditors.clip(raster, 1, geom, 
false, 0, true);
+    double bandNoDataValue = 
RasterBandAccessors.getBandNoDataValue(clippedRaster);
+    double expectedBandNoDataValue = 0.0;
+    double[] actualValues = MapAlgebra.bandAsArray(clippedRaster, 1);
+    double[] expectedValues = {2.0, 3.0, 6.0, 7.0};
+
+    assertEquals(expectedBandNoDataValue, bandNoDataValue, FP_TOLERANCE);
+    assertTrue(Arrays.equals(expectedValues, actualValues));
+  }
+
   @Test
   public void testClip()
       throws IOException, FactoryException, TransformException, ParseException,
@@ -244,7 +266,7 @@ public class RasterBandEditorsTest extends RasterTestBase {
     points.add(Constructors.geomFromWKT("POINT(237919 4.20357e+06)", 26918));
     points.add(Constructors.geomFromWKT("POINT(223802 4.20465e+06)", 26918));
     actualValues = PixelFunctions.values(croppedRaster, points, 1).toArray(new 
Double[0]);
-    expectedValues = new Double[] {0.0, 0.0, 0.0, 0.0, null};
+    expectedValues = new Double[] {0.0, 0.0, 0.0, 0.0, 255.0};
     assertTrue(Arrays.equals(expectedValues, actualValues));
   }
 

Reply via email to