in common/src/main/java/org/apache/sedona/common/raster/Rasterization.java [306:399]
private static Envelope2D rasterizeGeomExtent(
Geometry geom, GridCoverage2D raster, double[] metadata, boolean allTouched) {
if (Objects.equals(geom.getGeometryType(), "MultiLineString")) {
allTouched = true;
}
if (Objects.equals(geom.getGeometryType(), "MultiPoint")) {
allTouched = true;
}
Envelope2D rasterExtent =
JTS.getEnvelope2D(geom.getEnvelopeInternal(), raster.getCoordinateReferenceSystem2D());
// Using BigDecimal to avoid floating point errors
BigDecimal upperLeftX = BigDecimal.valueOf(metadata[0]);
BigDecimal upperLeftY = BigDecimal.valueOf(metadata[1]);
BigDecimal scaleX = BigDecimal.valueOf(metadata[4]);
BigDecimal scaleY = BigDecimal.valueOf(metadata[5]);
// Compute the aligned min/max values
double alignedMinX =
(scaleX
.multiply(
BigDecimal.valueOf(
Math.floor((rasterExtent.getMinX() + metadata[0]) / metadata[4])))
.subtract(upperLeftX))
.doubleValue();
double alignedMinY =
(scaleY
.multiply(
BigDecimal.valueOf(
Math.ceil((rasterExtent.getMinY() + metadata[1]) / metadata[5])))
.subtract(upperLeftY))
.doubleValue();
double alignedMaxX =
(scaleX
.multiply(
BigDecimal.valueOf(
Math.ceil((rasterExtent.getMaxX() + metadata[0]) / metadata[4])))
.subtract(upperLeftX))
.doubleValue();
double alignedMaxY =
(scaleY
.multiply(
BigDecimal.valueOf(
Math.floor((rasterExtent.getMaxY() + metadata[1]) / metadata[5])))
.subtract(upperLeftY))
.doubleValue();
// For points and LineStrings at intersection of 2 or more pixels,
// extend search grid by 1 pixel in each direction
if (alignedMaxX == alignedMinX) {
alignedMinX -= metadata[4];
alignedMaxX += metadata[4];
}
if (alignedMaxY == alignedMinY) {
alignedMinY += metadata[5];
alignedMaxY -= metadata[5];
}
// Get the extent of the original raster
double originalMinX = raster.getEnvelope().getMinimum(0);
double originalMinY = raster.getEnvelope().getMinimum(1);
double originalMaxX = raster.getEnvelope().getMaximum(0);
double originalMaxY = raster.getEnvelope().getMaximum(1);
// Extend the aligned extent by 1 pixel if allTouched is true and if any geometry extent meets
// the aligned extent
if (allTouched) {
alignedMinX -= (rasterExtent.getMinX() == alignedMinX) ? metadata[4] : 0;
alignedMinY += (rasterExtent.getMinY() == alignedMinY) ? metadata[5] : 0;
alignedMaxX += (rasterExtent.getMaxX() == alignedMaxX) ? metadata[4] : 0;
alignedMaxY -= (rasterExtent.getMaxY() == alignedMaxY) ? metadata[5] : 0;
}
alignedMinX = Math.max(alignedMinX, originalMinX);
alignedMinY = Math.max(alignedMinY, originalMinY);
alignedMaxX = Math.min(alignedMaxX, originalMaxX);
alignedMaxY = Math.min(alignedMaxY, originalMaxY);
// Create the aligned raster extent
Envelope2D alignedRasterExtent =
new Envelope2D(
rasterExtent.getCoordinateReferenceSystem(),
alignedMinX,
alignedMinY,
alignedMaxX - alignedMinX,
alignedMaxY - alignedMinY);
return alignedRasterExtent;
}