Skip to content

Commit 3f16ee4

Browse files
prantoggjiayuasu
authored andcommitted
[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
1 parent 9831713 commit 3f16ee4

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

common/src/main/java/org/apache/sedona/common/raster/RasterBandEditors.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
import org.geotools.coverage.grid.GridCoverage2D;
3232
import org.geotools.coverage.processing.CannotCropException;
3333
import org.geotools.coverage.processing.operation.Crop;
34+
import org.geotools.geometry.Envelope2D;
35+
import org.geotools.geometry.jts.JTS;
3436
import org.locationtech.jts.geom.Geometry;
37+
import org.opengis.geometry.BoundingBox;
3538
import org.opengis.parameter.ParameterValueGroup;
3639
import org.opengis.referencing.FactoryException;
3740
import org.opengis.referencing.operation.TransformException;
@@ -298,13 +301,19 @@ public static GridCoverage2D clip(
298301
singleBandRaster = pair.getLeft();
299302
geometry = pair.getRight();
300303

304+
// Use rasterizeGeomExtent for AOI geometries smaller than a pixel
305+
double[] metadata = RasterAccessors.metadata(singleBandRaster);
306+
Envelope2D geomEnvelope =
307+
Rasterization.rasterizeGeomExtent(geometry, singleBandRaster, metadata, allTouched);
308+
Geometry geomExtent = JTS.toGeometry((BoundingBox) geomEnvelope);
309+
301310
// Crop the raster
302311
// this will shrink the extent of the raster to the geometry
303312
Crop cropObject = new Crop();
304313
ParameterValueGroup parameters = cropObject.getParameters();
305314
parameters.parameter("Source").setValue(singleBandRaster);
306315
parameters.parameter(Crop.PARAMNAME_DEST_NODATA).setValue(new double[] {noDataValue});
307-
parameters.parameter(Crop.PARAMNAME_ROI).setValue(geometry);
316+
parameters.parameter(Crop.PARAMNAME_ROI).setValue(geomExtent);
308317

309318
GridCoverage2D newRaster;
310319
try {

common/src/main/java/org/apache/sedona/common/raster/Rasterization.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ private static boolean isInsideBounds(
303303
return x >= minX && x <= maxX && y >= minY && y <= maxY;
304304
}
305305

306-
private static Envelope2D rasterizeGeomExtent(
306+
protected static Envelope2D rasterizeGeomExtent(
307307
Geometry geom, GridCoverage2D raster, double[] metadata, boolean allTouched) {
308308

309309
if (Objects.equals(geom.getGeometryType(), "MultiLineString")) {

common/src/test/java/org/apache/sedona/common/raster/RasterBandEditorsTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,28 @@ public void testClipWithGeometryTransform()
201201
assertTrue(Arrays.equals(expectedValues, actualValues));
202202
}
203203

204+
@Test
205+
public void testClip_smallAOI() throws FactoryException, TransformException, ParseException {
206+
// Test for AOI geometries smaller than a pixel
207+
GridCoverage2D raster =
208+
RasterConstructors.makeEmptyRaster(1, "F", 4, 4, 401805.039562261, 2095852.150947876, 30);
209+
raster = RasterEditors.setSrid(raster, 5070);
210+
double[] bandValues = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
211+
raster = MapAlgebra.addBandFromArray(raster, bandValues, 1);
212+
String polygon =
213+
"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))";
214+
Geometry geom = Constructors.geomFromWKT(polygon, 5070);
215+
216+
GridCoverage2D clippedRaster = RasterBandEditors.clip(raster, 1, geom, false, 0, true);
217+
double bandNoDataValue = RasterBandAccessors.getBandNoDataValue(clippedRaster);
218+
double expectedBandNoDataValue = 0.0;
219+
double[] actualValues = MapAlgebra.bandAsArray(clippedRaster, 1);
220+
double[] expectedValues = {2.0, 3.0, 6.0, 7.0};
221+
222+
assertEquals(expectedBandNoDataValue, bandNoDataValue, FP_TOLERANCE);
223+
assertTrue(Arrays.equals(expectedValues, actualValues));
224+
}
225+
204226
@Test
205227
public void testClip()
206228
throws IOException, FactoryException, TransformException, ParseException,
@@ -244,7 +266,7 @@ public void testClip()
244266
points.add(Constructors.geomFromWKT("POINT(237919 4.20357e+06)", 26918));
245267
points.add(Constructors.geomFromWKT("POINT(223802 4.20465e+06)", 26918));
246268
actualValues = PixelFunctions.values(croppedRaster, points, 1).toArray(new Double[0]);
247-
expectedValues = new Double[] {0.0, 0.0, 0.0, 0.0, null};
269+
expectedValues = new Double[] {0.0, 0.0, 0.0, 0.0, 255.0};
248270
assertTrue(Arrays.equals(expectedValues, actualValues));
249271
}
250272

0 commit comments

Comments
 (0)