in common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java [619:713]
public static GridCoverage2D interpolate(
GridCoverage2D inputRaster,
Double power,
String mode,
Double numPointsOrRadius,
Double maxRadiusOrMinPoints,
Integer band)
throws IllegalArgumentException {
if (!mode.equalsIgnoreCase("variable") && !mode.equalsIgnoreCase("fixed")) {
throw new IllegalArgumentException(
"Invalid 'mode': '" + mode + "'. Expected one of: 'Variable', 'Fixed'.");
}
Raster rasterData = inputRaster.getRenderedImage().getData();
WritableRaster raster =
rasterData.createCompatibleWritableRaster(
RasterAccessors.getWidth(inputRaster), RasterAccessors.getHeight(inputRaster));
int width = raster.getWidth();
int height = raster.getHeight();
int numBands = raster.getNumBands();
GridSampleDimension[] gridSampleDimensions = inputRaster.getSampleDimensions();
if (band != null && (band < 1 || band > numBands)) {
throw new IllegalArgumentException("Band index out of range.");
}
// Interpolation for each band
for (int bandIndex = 0; bandIndex < numBands; bandIndex++) {
if (band == null || bandIndex == band - 1) {
// Generate STRtree
STRtree strtree = RasterInterpolate.generateSTRtree(inputRaster, bandIndex);
Double noDataValue = RasterUtils.getNoDataValue(inputRaster.getSampleDimension(bandIndex));
int countNoDataValues = 0;
// Skip band if STRtree is empty or has all valid data pixels
if (strtree.isEmpty() || strtree.size() == width * height) {
continue;
}
if (mode.equalsIgnoreCase("variable") && strtree.size() < numPointsOrRadius) {
throw new IllegalArgumentException(
"Parameter 'numPoints' is larger than no. of valid pixels in band "
+ bandIndex
+ ". Please choose an appropriate value");
}
// Perform interpolation
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
double value = rasterData.getSampleDouble(x, y, bandIndex);
if (Double.isNaN(value) || value == noDataValue) {
countNoDataValues++;
double interpolatedValue =
RasterInterpolate.interpolateIDW(
x,
y,
strtree,
width,
height,
power,
mode,
numPointsOrRadius,
maxRadiusOrMinPoints);
interpolatedValue =
(Double.isNaN(interpolatedValue)) ? noDataValue : interpolatedValue;
if (interpolatedValue != noDataValue) {
countNoDataValues--;
}
raster.setSample(x, y, bandIndex, interpolatedValue);
} else {
raster.setSample(x, y, bandIndex, value);
}
}
}
// If all noDataValues are interpolated, update band metadata (remove nodatavalue)
if (countNoDataValues == 0) {
gridSampleDimensions[bandIndex] =
RasterUtils.removeNoDataValue(inputRaster.getSampleDimension(bandIndex));
}
} else {
raster.setSamples(
0,
0,
raster.getWidth(),
raster.getHeight(),
band,
rasterData.getSamples(
0, 0, raster.getWidth(), raster.getHeight(), band, (double[]) null));
}
}
return RasterUtils.clone(
raster, inputRaster.getGridGeometry(), gridSampleDimensions, inputRaster, null, true);
}