private static Envelope2D rasterizeGeomExtent()

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;
  }