From 5d3b80ec1e5c800ef87503316b676b1d4b7267e0 Mon Sep 17 00:00:00 2001 From: Pranav Toggi Date: Thu, 22 Feb 2024 15:02:10 -0500 Subject: [PATCH 1/6] init --- .../sedona/common/raster/RasterEditors.java | 59 +++++++++++++++++++ .../common/raster/RasterEditorsTest.java | 21 +++++++ 2 files changed, 80 insertions(+) diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java index 27b77f529b..6fd509a1ca 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java +++ b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java @@ -51,6 +51,65 @@ public class RasterEditors { + + public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String bandDataType) { + return setBandPixelType(raster, bandDataType, null); + } + + /** + * Changes the pixel type of a specified band or all bands in a raster. + * + * @param raster The raster whose band pixel type is to be changed. + * @param bandDataType The target data type for the band ("D", "F", "I", "S", "US", "B"). + * @param bandIndex The index of the band to be modified (1-based index), or null to modify all bands. + * @return The raster with the modified band pixel type. + */ + public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String bandDataType, Integer bandIndex) { + int numBands = raster.getNumSampleDimensions(); + + if (bandIndex == null) { + for (int i = 1; i <= numBands; i++) { + double[] bandValues = bandAsArray(raster, i); + bandValues = changeBandDataType(bandValues, bandDataType); + raster = addBandFromArray(raster, bandValues, i); + } + } else { + double[] bandValues = bandAsArray(raster, bandIndex); + bandValues = changeBandDataType(bandValues, bandDataType); + raster = addBandFromArray(raster, bandValues, bandIndex); + } + + return raster; + } + + private static double[] changeBandDataType(double[] bandValues, String bandDataType) { + int dataType = mapBandDataTypeToDataBufferType(bandDataType); + + for (int i = 0; i < bandValues.length; i++) { + bandValues[i] = castRasterDataType(bandValues[i], dataType); + } + return bandValues; + } + + private static int mapBandDataTypeToDataBufferType(String bandDataType) { + switch (bandDataType) { + case "D": + return DataBuffer.TYPE_DOUBLE; + case "F": + return DataBuffer.TYPE_FLOAT; + case "I": + return DataBuffer.TYPE_INT; + case "S": + return DataBuffer.TYPE_SHORT; + case "US": + return DataBuffer.TYPE_USHORT; // Assuming this maps to TYPE_USHORT + case "B": + return DataBuffer.TYPE_BYTE; + default: + throw new IllegalArgumentException("Invalid Band Data Type"); + } + } + public static GridCoverage2D setSrid(GridCoverage2D raster, int srid) { CoordinateReferenceSystem crs; diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java index 2c3b99a4f4..4f59d0edde 100644 --- a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java +++ b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java @@ -32,6 +32,27 @@ import static org.junit.Assert.assertThrows; public class RasterEditorsTest extends RasterTestBase { + + @Test + public void testSetBandPixelType() throws FactoryException { + // Create a test raster using makeEmptyRaster + GridCoverage2D testRaster = RasterConstructors.makeEmptyRaster(3, "I", 10, 10, 0, 0, 1); + + // Change the pixel type of a specific band + GridCoverage2D modifiedRaster = RasterEditors.setBandPixelType(testRaster, "F", 1); // Changing to Float type for band 1 + // Verify the change in data type for the specified band + assertEquals(DataBuffer.TYPE_FLOAT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + + // Change the pixel type of all bands + modifiedRaster = RasterEditors.setBandPixelType(testRaster, "B", null); // Changing to Byte type for all bands + // Verify the change in data type for all bands + assertEquals(DataBuffer.TYPE_BYTE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + + // Additional verification: Check if the raster dimensions remain unchanged + assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); + assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); + } + @Test public void testSetGeoReferenceWithRaster() throws IOException { GridCoverage2D raster = rasterFromGeoTiff(resourceFolder + "raster/test1.tiff"); From 24bc0925ddbc8c247f6923a50307d1241434bd2f Mon Sep 17 00:00:00 2001 From: Pranav Toggi Date: Thu, 7 Mar 2024 13:14:03 -0500 Subject: [PATCH 2/6] test --- .../sedona/common/raster/RasterEditors.java | 284 +++++++++++++++--- .../common/raster/RasterEditorsTest.java | 24 +- 2 files changed, 255 insertions(+), 53 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java index 6fd509a1ca..4528597384 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java +++ b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java @@ -21,6 +21,7 @@ import org.apache.sedona.common.FunctionsGeoTools; import org.apache.sedona.common.utils.RasterUtils; import org.geotools.coverage.CoverageFactoryFinder; +import org.geotools.coverage.GridSampleDimension; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; import org.geotools.coverage.grid.GridEnvelope2D; @@ -29,7 +30,9 @@ import org.geotools.geometry.Envelope2D; import org.geotools.referencing.crs.DefaultEngineeringCRS; import org.geotools.referencing.operation.transform.AffineTransform2D; +import org.opengis.coverage.SampleDimensionType; import org.opengis.coverage.grid.GridCoverage; +import org.opengis.geometry.Envelope; import org.opengis.metadata.spatial.PixelOrientation; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; @@ -39,9 +42,10 @@ import org.opengis.referencing.operation.TransformException; import javax.media.jai.Interpolation; +import javax.media.jai.RasterFactory; +import java.awt.*; import java.awt.geom.Point2D; -import java.awt.image.DataBuffer; -import java.awt.image.RenderedImage; +import java.awt.image.*; import java.util.Arrays; import java.util.Map; import java.util.Objects; @@ -52,64 +56,248 @@ public class RasterEditors { - public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String bandDataType) { - return setBandPixelType(raster, bandDataType, null); - } - /** - * Changes the pixel type of a specified band or all bands in a raster. + * Changes the band pixel type of a specific band of a raster. * - * @param raster The raster whose band pixel type is to be changed. - * @param bandDataType The target data type for the band ("D", "F", "I", "S", "US", "B"). - * @param bandIndex The index of the band to be modified (1-based index), or null to modify all bands. - * @return The raster with the modified band pixel type. + * @param raster The input raster. + * @param BandDataType The desired data type of the band(s). + * @param bandID The specific band to change. If null, all bands are changed. + * @return The modified raster with updated band pixel type. */ - public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String bandDataType, Integer bandIndex) { - int numBands = raster.getNumSampleDimensions(); - - if (bandIndex == null) { - for (int i = 1; i <= numBands; i++) { - double[] bandValues = bandAsArray(raster, i); - bandValues = changeBandDataType(bandValues, bandDataType); - raster = addBandFromArray(raster, bandValues, i); +// public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { +// int newDataType = RasterUtils.getDataTypeCode(BandDataType); +// System.out.println("Original raster band 1: "+Arrays.toString(MapAlgebra.bandAsArray(raster, 1))); +// System.out.println("Original raster band 1: "+Arrays.toString(MapAlgebra.bandAsArray(raster, 2))); +// +// // Extracting the WritableRaster from the original GridCoverage2D +// RenderedImage originalImage = raster.getRenderedImage(); +// WritableRaster originalRaster = RasterUtils.getRaster(originalImage).createCompatibleWritableRaster(); +// System.out.println("originalRaster minX: "+originalRaster.getMinX()); +// System.out.println("originalRaster minY: "+originalRaster.getMinY()); +// +// // Create a new raster with modified data type for the specified band +// WritableRaster modifiedRaster = null; +// if (bandID == null) { +// modifiedRaster = modifyRasterBandType(originalRaster, 0, newDataType); +// for (int band = 1; band < raster.getNumSampleDimensions(); band++) { +// modifiedRaster = modifyRasterBandType(modifiedRaster, band, newDataType); +// } +// } else { +// modifiedRaster = modifyRasterBandType(originalRaster, bandID-1, newDataType); +// } +// +// // Update GridSampleDimension for the modified band +// GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); +//// GridSampleDimension modifiedDimension; +//// if (bandID == null) { +//// for (int band = 0; band < raster.getNumSampleDimensions(); band++) { +//// modifiedDimension = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], RasterUtils.getNoDataValue(sampleDimensions[band])); +//// sampleDimensions[band] = modifiedDimension; +//// } +//// } else { +//// modifiedDimension = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[bandID - 1], RasterUtils.getNoDataValue(sampleDimensions[bandID - 1])); +//// sampleDimensions[bandID - 1] = modifiedDimension; +//// } +// +// // Clone the original GridCoverage2D with the modified raster and sample dimensions +// System.out.println(modifiedRaster.getMinX()); +// System.out.println(modifiedRaster.getMinY()); +// return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); +// } + + public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { + int newDataType = RasterUtils.getDataTypeCode(BandDataType); + + // Extracting the original data + RenderedImage originalImage = raster.getRenderedImage(); + Raster originalData = RasterUtils.getRaster(originalImage); + + int width = originalImage.getWidth(); + int height = originalImage.getHeight(); + int numBands = originalImage.getSampleModel().getNumBands(); + + // Create a new writable raster with the specified data type + WritableRaster modifiedRaster = RasterFactory.createBandedRaster(newDataType, width, height, numBands, null); + + // Copy data to the new raster, converting type as necessary + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + for (int band = 0; band < numBands; band++) { + double originalValue = originalData.getSampleDouble(x, y, band); + if (bandID == null || band == bandID - 1) { + double convertedValue = castRasterDataType(originalValue, newDataType); + modifiedRaster.setSample(x, y, band, convertedValue); + } else { + modifiedRaster.setSample(x, y, band, originalValue); + } + } } - } else { - double[] bandValues = bandAsArray(raster, bandIndex); - bandValues = changeBandDataType(bandValues, bandDataType); - raster = addBandFromArray(raster, bandValues, bandIndex); } - return raster; - } - - private static double[] changeBandDataType(double[] bandValues, String bandDataType) { - int dataType = mapBandDataTypeToDataBufferType(bandDataType); + // Re-create sample dimensions if necessary + GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); +// if (bandID != null) { +// sampleDimensions[bandID - 1] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[bandID - 1], RasterUtils.getNoDataValue(sampleDimensions[bandID - 1])); +// } - for (int i = 0; i < bandValues.length; i++) { - bandValues[i] = castRasterDataType(bandValues[i], dataType); - } - return bandValues; + // Clone the original GridCoverage2D with the modified raster + return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); } - private static int mapBandDataTypeToDataBufferType(String bandDataType) { - switch (bandDataType) { - case "D": - return DataBuffer.TYPE_DOUBLE; - case "F": - return DataBuffer.TYPE_FLOAT; - case "I": - return DataBuffer.TYPE_INT; - case "S": - return DataBuffer.TYPE_SHORT; - case "US": - return DataBuffer.TYPE_USHORT; // Assuming this maps to TYPE_USHORT - case "B": - return DataBuffer.TYPE_BYTE; - default: - throw new IllegalArgumentException("Invalid Band Data Type"); +// public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { +// int numBands = raster.getNumSampleDimensions(); +// double[] bandValues; +// if (bandID == null) { +// for (int band = 0; band < numBands; band++) { +// bandValues = bandAsArray(raster, band + 1); +// double bandNoDataValue = RasterUtils.getNoDataValue(raster.getSampleDimension(band)); +// +// for (int i = 0; i < bandValues.length; i++) { +// bandValues[i] = castRasterDataType(bandValues[i], RasterUtils.getDataTypeCode(BandDataType)); +// } +// +// raster = addBandFromArray(raster, bandValues, band+1); +// } +// } else { +// bandValues = bandAsArray(raster, bandID); +// +// for (int i = 0; i < bandValues.length; i++) { +// bandValues[i] = castRasterDataType(bandValues[i], RasterUtils.getDataTypeCode(BandDataType)); +// } +// +// raster = addBandFromArray(raster, bandValues, bandID); +// } +// +// return raster; +// } + + private static WritableRaster modifyRasterBandType(WritableRaster raster, int bandIndex, int newDataType) { + int width = raster.getWidth(); + int height = raster.getHeight(); + int numBands = raster.getNumBands(); + + WritableRaster modifiedRaster = RasterFactory.createBandedRaster(newDataType, width, height, numBands, null); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + for (int band = 0; band < numBands; band++) { + double originalValue = raster.getSampleDouble(x, y, band); + if (band == bandIndex) { + double convertedValue = castRasterDataType(originalValue, newDataType); + modifiedRaster.setSample(x, y, band, convertedValue); + System.out.println("Original Value: " + originalValue + ", Converted Value: " + convertedValue); + } else { + modifiedRaster.setSample(x, y, band, originalValue); + } + } + } } + return modifiedRaster; } + + + + +// private static WritableRaster modifyRasterBandType(WritableRaster raster, int bandIndex, int newDataType) { +// int width = raster.getWidth(); +// int height = raster.getHeight(); +// WritableRaster modifiedRaster = raster.createCompatibleWritableRaster(width, height); +// +// // Iterate over each pixel to convert the data type of the specified band +// for (int y = 0; y < height; y++) { +// for (int x = 0; x < width; x++) { +// // Handle the conversion based on the data type +// switch (newDataType) { +// case DataBuffer.TYPE_BYTE: +// byte byteValue = (byte) raster.getSample(x, y, bandIndex); +// modifiedRaster.setSample(x, y, bandIndex, byteValue); +// break; +// case DataBuffer.TYPE_SHORT: +// case DataBuffer.TYPE_USHORT: +// short shortValue = (short) raster.getSample(x, y, bandIndex); +// modifiedRaster.setSample(x, y, bandIndex, shortValue); +// break; +// case DataBuffer.TYPE_INT: +// int intValue = (int) raster.getSample(x, y, bandIndex); +// modifiedRaster.setSample(x, y, bandIndex, intValue); +// break; +// case DataBuffer.TYPE_FLOAT: +// float floatValue = raster.getSampleFloat(x, y, bandIndex); +// modifiedRaster.setSample(x, y, bandIndex, floatValue); +// break; +// case DataBuffer.TYPE_DOUBLE: +// double doubleValue = raster.getSampleDouble(x, y, bandIndex); +// modifiedRaster.setSample(x, y, bandIndex, doubleValue); +// break; +// default: +// throw new IllegalArgumentException("Unsupported data type: " + newDataType); +// } +// } +// } +// return modifiedRaster; +// } + +// private static RenderedImage createNewRenderedImageWithBandType(RenderedImage image, int newDataType, Integer bandID) { +// // This is a placeholder logic, real implementation can be significantly more complex. +// // This example only changes the data type and copies data for a single band. +// +// if (bandID == null) { +// throw new IllegalArgumentException("Band ID cannot be null"); +// } +// +// // Assuming we are changing the data type of a single band. +// // A more complex implementation would be needed for multi-band images. +// int band = bandID - 1; // Adjusting for 0-based index +// +// // Get the data from the specified band +// Raster raster = image.getData(); +// int width = image.getWidth(); +// int height = image.getHeight(); +// double[] samples = raster.getSamples(0, 0, width, height, band, (double[]) null); +// +// // Create a new writable raster with the new data type +// WritableRaster newRaster = Raster.createBandedRaster(newDataType, width, height, 1, new Point(0, 0)); +// +// // Set the samples to the new raster +// for (int y = 0; y < height; y++) { +// for (int x = 0; x < width; x++) { +// double value = samples[y * width + x]; +// newRaster.setSample(x, y, 0, value); // Casts are applied here based on newDataType +// } +// } +// +// // Return a new RenderedImage +// return new BufferedImage(image.getColorModel(), newRaster, image.getColorModel().isAlphaPremultiplied(), null); +// } + +// private static GridSampleDimension[] updateSampleDimensions(GridSampleDimension[] sampleDimensions, int newDataType, Integer bandID) { +// if (bandID == null) { +// throw new IllegalArgumentException("Band ID cannot be null"); +// } +// +// int band = bandID - 1; // Adjusting for 0-based index +// GridSampleDimension[] newSampleDimensions = new GridSampleDimension[sampleDimensions.length]; +// +// for (int i = 0; i < sampleDimensions.length; i++) { +// if (i == band) { +// // Update the sample dimension for the specified band. +// // This example just updates the data type; you might want to modify other properties. +// GridSampleDimension sd = sampleDimensions[i]; +// // Sample code to recreate the sample dimension with a new data type +// // The specifics of this operation depend on your data and requirements +// newSampleDimensions[i] = new GridSampleDimension(sd.getDescription().toString(), +// SampleDimensionType.valueOf(newDataType), sd.getNoDataValues()); +// } else { +// // Keep other bands as is +// newSampleDimensions[i] = sampleDimensions[i]; +// } +// } +// +// return newSampleDimensions; +// } + + public static GridCoverage2D setSrid(GridCoverage2D raster, int srid) { CoordinateReferenceSystem crs; diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java index 4f59d0edde..64425671ff 100644 --- a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java +++ b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java @@ -36,17 +36,31 @@ public class RasterEditorsTest extends RasterTestBase { @Test public void testSetBandPixelType() throws FactoryException { // Create a test raster using makeEmptyRaster - GridCoverage2D testRaster = RasterConstructors.makeEmptyRaster(3, "I", 10, 10, 0, 0, 1); + GridCoverage2D testRaster = RasterConstructors.makeEmptyRaster(3, "F", 4, 4, 0, 0, 1); + double[] bandValues1 = {1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1,11.1,12.1,13.1,14.1,15.1,16.1}; + double[] bandValues2 = {17.9, 18.9, 19.9, 20.9, 21.9, 22.9, 23.9, 24.9, 25.9, 26.9, 27.9, 28.9, 29.9, 30.9, 31.9, 32.9}; + double[] bandValues3 = {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}; + + testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues1, 1); + testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues2, 2); + testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues3, 3); // Change the pixel type of a specific band - GridCoverage2D modifiedRaster = RasterEditors.setBandPixelType(testRaster, "F", 1); // Changing to Float type for band 1 +// GridCoverage2D modifiedRaster = RasterEditors.setBandPixelType(testRaster, "F", 1); // Changing to Float type for band 1 // Verify the change in data type for the specified band - assertEquals(DataBuffer.TYPE_FLOAT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); +// assertEquals(DataBuffer.TYPE_FLOAT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); // Change the pixel type of all bands - modifiedRaster = RasterEditors.setBandPixelType(testRaster, "B", null); // Changing to Byte type for all bands + GridCoverage2D modifiedRaster = RasterEditors.setBandPixelType(testRaster, "I", null); // Changing to Byte type for all bands // Verify the change in data type for all bands - assertEquals(DataBuffer.TYPE_BYTE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + System.out.println(Arrays.toString(MapAlgebra.bandAsArray(testRaster, 1))); + System.out.println(Arrays.toString(MapAlgebra.bandAsArray(testRaster, 2))); + System.out.println(Arrays.toString(MapAlgebra.bandAsArray(testRaster, 3))); + System.out.println(); + System.out.println(Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 1))); + System.out.println(Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 2))); + System.out.println(Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))); + assertEquals(DataBuffer.TYPE_INT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); // Additional verification: Check if the raster dimensions remain unchanged assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); From 5923552427645f7756ab01c8ee7452d5af9d14c3 Mon Sep 17 00:00:00 2001 From: Pranav Toggi Date: Fri, 8 Mar 2024 18:47:36 -0500 Subject: [PATCH 3/6] test2 --- .../sedona/common/raster/RasterEditors.java | 96 +++++++++++++++---- .../common/raster/RasterEditorsTest.java | 82 ++++++++++++---- 2 files changed, 144 insertions(+), 34 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java index 4528597384..d081b37e79 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java +++ b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java @@ -50,6 +50,7 @@ import java.util.Map; import java.util.Objects; +import static java.lang.Double.NaN; import static org.apache.sedona.common.raster.MapAlgebra.addBandFromArray; import static org.apache.sedona.common.raster.MapAlgebra.bandAsArray; @@ -61,7 +62,6 @@ public class RasterEditors * * @param raster The input raster. * @param BandDataType The desired data type of the band(s). - * @param bandID The specific band to change. If null, all bands are changed. * @return The modified raster with updated band pixel type. */ // public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { @@ -105,7 +105,9 @@ public class RasterEditors // return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); // } - public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { +// + + public static GridCoverage2D setRasterPixelType(GridCoverage2D raster, String BandDataType) { int newDataType = RasterUtils.getDataTypeCode(BandDataType); // Extracting the original data @@ -119,31 +121,93 @@ public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String Band // Create a new writable raster with the specified data type WritableRaster modifiedRaster = RasterFactory.createBandedRaster(newDataType, width, height, numBands, null); - // Copy data to the new raster, converting type as necessary - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - for (int band = 0; band < numBands; band++) { + // Populate modified raster and recreate sample dimensions + GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); +// for (int band = 0; band < numBands; band++) { +// double[] samples = originalData.getSamples(0, 0, width, height, band, (double[]) null); +// modifiedRaster.setSamples(0, 0, width, height, band, samples); +//// double newNoDataValue = (RasterUtils.getNoDataValue(raster.getSampleDimension(band)) == NaN) ? NaN : castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType); +// if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { +// System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); +// sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); +// } +// } + for (int band = 0; band < numBands; band++) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { double originalValue = originalData.getSampleDouble(x, y, band); - if (bandID == null || band == bandID - 1) { - double convertedValue = castRasterDataType(originalValue, newDataType); - modifiedRaster.setSample(x, y, band, convertedValue); - } else { - modifiedRaster.setSample(x, y, band, originalValue); - } + double convertedValue = castRasterDataType(originalValue, newDataType); + modifiedRaster.setSample(x, y, band, convertedValue); } } + if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { + System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); + sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); + } } - // Re-create sample dimensions if necessary - GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); + // Clone the original GridCoverage2D with the modified raster + return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); + } + + +// public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { +// int newDataType = RasterUtils.getDataTypeCode(BandDataType); +// +// RenderedImage originalImage = raster.getRenderedImage(); +// int numBands = originalImage.getSampleModel().getNumBands(); +// int width = originalImage.getWidth(); +// int height = originalImage.getHeight(); +// +// // Create separate rasters for each band +// WritableRaster[] bandRasters = new WritableRaster[numBands]; +// for (int band = 0; band < numBands; band++) { +// int dataType = (bandID != null && band == bandID - 1) ? newDataType : originalImage.getSampleModel().getDataType(band); +// bandRasters[band] = RasterFactory.createBandedRaster(dataType, width, height, 1, null); +// copyBandData(originalImage, bandRasters[band], band, dataType); +// } +// +// // Combine the separate rasters into a single raster +// WritableRaster modifiedRaster = combineBandRasters(bandRasters, width, height); +// +// // Re-create sample dimensions if necessary +// GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); // if (bandID != null) { // sampleDimensions[bandID - 1] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[bandID - 1], RasterUtils.getNoDataValue(sampleDimensions[bandID - 1])); // } +// +// // Clone the original GridCoverage2D with the modified raster +// return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); +// } +// +// private static void copyBandData(RenderedImage originalImage, WritableRaster bandRaster, int bandIndex, int dataType) { +// Raster originalData = originalImage.getData(); +// System.out.println("\nBand: "+bandIndex); +// for (int y = 0; y < originalImage.getHeight(); y++) { +// for (int x = 0; x < originalImage.getWidth(); x++) { +// double value = originalData.getSampleDouble(x, y, bandIndex); +// double convertedValue = castRasterDataType(value, dataType); +// bandRaster.setSample(x, y, 0, convertedValue); +// System.out.println("Original value: "+value+", Converted value: "+convertedValue); +// } +// } +// } - // Clone the original GridCoverage2D with the modified raster - return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); + private static WritableRaster combineBandRasters(WritableRaster[] bandRasters, int width, int height) { + WritableRaster combinedRaster = RasterFactory.createBandedRaster(DataBuffer.TYPE_DOUBLE, width, height, bandRasters.length, null); + for (int band = 0; band < bandRasters.length; band++) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + combinedRaster.setSample(x, y, band, bandRasters[band].getSampleDouble(x, y, 0)); + } + } + } + return combinedRaster; } +// castRasterDataType method remains unchanged + + // public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { // int numBands = raster.getNumSampleDimensions(); // double[] bandValues; diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java index 64425671ff..926ae95074 100644 --- a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java +++ b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java @@ -36,33 +36,79 @@ public class RasterEditorsTest extends RasterTestBase { @Test public void testSetBandPixelType() throws FactoryException { // Create a test raster using makeEmptyRaster - GridCoverage2D testRaster = RasterConstructors.makeEmptyRaster(3, "F", 4, 4, 0, 0, 1); - double[] bandValues1 = {1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1,11.1,12.1,13.1,14.1,15.1,16.1}; + GridCoverage2D testRaster = RasterConstructors.makeEmptyRaster(4, "F", 4, 4, 0, 0, 1); + double[] bandValues1 = {1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1,11.1,12.1,13.1,14.1,15.1,99.2}; double[] bandValues2 = {17.9, 18.9, 19.9, 20.9, 21.9, 22.9, 23.9, 24.9, 25.9, 26.9, 27.9, 28.9, 29.9, 30.9, 31.9, 32.9}; double[] bandValues3 = {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}; + double[] bandValues4 = {65535, 65536, 65537, 65538, 65539, 65540, 65541, 65542, 65543, 65544, 65545, 65546, 65547, 65548, 65549, -9999}; testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues1, 1); testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues2, 2); testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues3, 3); + testRaster = MapAlgebra.addBandFromArray(testRaster, bandValues4, 4); + testRaster = RasterBandEditors.setBandNoDataValue(testRaster, 1, 99.2); + testRaster = RasterBandEditors.setBandNoDataValue(testRaster, 4, -9999.0); + + GridCoverage2D modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "D"); + + assertEquals(DataBuffer.TYPE_DOUBLE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + assertEquals(99.19999694824219, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); + assertEquals(-9999, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); + assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); + assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); + + modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "F"); + + assertEquals(DataBuffer.TYPE_FLOAT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + assertEquals(99.19999694824219, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); + assertEquals(-9999, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); + assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); + assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); + + + modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "I"); - // Change the pixel type of a specific band -// GridCoverage2D modifiedRaster = RasterEditors.setBandPixelType(testRaster, "F", 1); // Changing to Float type for band 1 - // Verify the change in data type for the specified band -// assertEquals(DataBuffer.TYPE_FLOAT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); - - // Change the pixel type of all bands - GridCoverage2D modifiedRaster = RasterEditors.setBandPixelType(testRaster, "I", null); // Changing to Byte type for all bands - // Verify the change in data type for all bands - System.out.println(Arrays.toString(MapAlgebra.bandAsArray(testRaster, 1))); - System.out.println(Arrays.toString(MapAlgebra.bandAsArray(testRaster, 2))); - System.out.println(Arrays.toString(MapAlgebra.bandAsArray(testRaster, 3))); - System.out.println(); - System.out.println(Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 1))); - System.out.println(Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 2))); - System.out.println(Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))); assertEquals(DataBuffer.TYPE_INT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); + assertEquals(-9999, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); + assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); + assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); + + modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "S"); + double[] expected = {-1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, -9999.0}; + + assertEquals(DataBuffer.TYPE_SHORT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); + assertEquals(-9999, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); + assertEquals(Arrays.toString(expected), Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 4))); + assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); + assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); + + modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "US"); + expected = new double[]{65526.0, 65527.0, 65528.0, 65529.0, 65530.0, 65531.0, 65532.0, 65533.0, 65534.0, 65535.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0}; + + assertEquals(DataBuffer.TYPE_USHORT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); + assertEquals(55537, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); + assertEquals(Arrays.toString(expected), Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))); + assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); + assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); + + modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "B"); + + System.out.println("\nOriginal Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(0))); + System.out.println("Original Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(1))); + System.out.println("Original Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(2))); + System.out.println("Original Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(3))); + + System.out.println("\nModified Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0))); + System.out.println("Modified Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(1))); + System.out.println("Modified Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(2))); + System.out.println("Modified Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3))); - // Additional verification: Check if the raster dimensions remain unchanged + assertEquals(DataBuffer.TYPE_BYTE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); + assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); + assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); } From afec99c5b4abdd9b0cafee3503a632279c6d458c Mon Sep 17 00:00:00 2001 From: Pranav Toggi Date: Mon, 11 Mar 2024 16:35:21 -0400 Subject: [PATCH 4/6] Implement RS_SetPixelType --- .../sedona/common/raster/RasterEditors.java | 311 +++--------------- .../common/raster/RasterEditorsTest.java | 33 +- docs/api/sql/Raster-loader.md | 2 +- docs/api/sql/Raster-operators.md | 29 ++ .../org/apache/sedona/sql/UDF/Catalog.scala | 1 + .../expressions/raster/RasterEditors.scala | 6 + .../apache/sedona/sql/rasteralgebraTest.scala | 29 ++ 7 files changed, 122 insertions(+), 289 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java index d081b37e79..c202c9540c 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java +++ b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java @@ -61,54 +61,12 @@ public class RasterEditors * Changes the band pixel type of a specific band of a raster. * * @param raster The input raster. - * @param BandDataType The desired data type of the band(s). + * @param dataType The desired data type of the pixel. * @return The modified raster with updated band pixel type. */ -// public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { -// int newDataType = RasterUtils.getDataTypeCode(BandDataType); -// System.out.println("Original raster band 1: "+Arrays.toString(MapAlgebra.bandAsArray(raster, 1))); -// System.out.println("Original raster band 1: "+Arrays.toString(MapAlgebra.bandAsArray(raster, 2))); -// -// // Extracting the WritableRaster from the original GridCoverage2D -// RenderedImage originalImage = raster.getRenderedImage(); -// WritableRaster originalRaster = RasterUtils.getRaster(originalImage).createCompatibleWritableRaster(); -// System.out.println("originalRaster minX: "+originalRaster.getMinX()); -// System.out.println("originalRaster minY: "+originalRaster.getMinY()); -// -// // Create a new raster with modified data type for the specified band -// WritableRaster modifiedRaster = null; -// if (bandID == null) { -// modifiedRaster = modifyRasterBandType(originalRaster, 0, newDataType); -// for (int band = 1; band < raster.getNumSampleDimensions(); band++) { -// modifiedRaster = modifyRasterBandType(modifiedRaster, band, newDataType); -// } -// } else { -// modifiedRaster = modifyRasterBandType(originalRaster, bandID-1, newDataType); -// } -// -// // Update GridSampleDimension for the modified band -// GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); -//// GridSampleDimension modifiedDimension; -//// if (bandID == null) { -//// for (int band = 0; band < raster.getNumSampleDimensions(); band++) { -//// modifiedDimension = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], RasterUtils.getNoDataValue(sampleDimensions[band])); -//// sampleDimensions[band] = modifiedDimension; -//// } -//// } else { -//// modifiedDimension = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[bandID - 1], RasterUtils.getNoDataValue(sampleDimensions[bandID - 1])); -//// sampleDimensions[bandID - 1] = modifiedDimension; -//// } -// -// // Clone the original GridCoverage2D with the modified raster and sample dimensions -// System.out.println(modifiedRaster.getMinX()); -// System.out.println(modifiedRaster.getMinY()); -// return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); -// } -// - - public static GridCoverage2D setRasterPixelType(GridCoverage2D raster, String BandDataType) { - int newDataType = RasterUtils.getDataTypeCode(BandDataType); + public static GridCoverage2D setPixelType(GridCoverage2D raster, String dataType) { + int newDataType = RasterUtils.getDataTypeCode(dataType); // Extracting the original data RenderedImage originalImage = raster.getRenderedImage(); @@ -123,245 +81,32 @@ public static GridCoverage2D setRasterPixelType(GridCoverage2D raster, String Ba // Populate modified raster and recreate sample dimensions GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); -// for (int band = 0; band < numBands; band++) { -// double[] samples = originalData.getSamples(0, 0, width, height, band, (double[]) null); -// modifiedRaster.setSamples(0, 0, width, height, band, samples); -//// double newNoDataValue = (RasterUtils.getNoDataValue(raster.getSampleDimension(band)) == NaN) ? NaN : castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType); -// if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { -// System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); -// sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); -// } -// } for (int band = 0; band < numBands; band++) { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - double originalValue = originalData.getSampleDouble(x, y, band); - double convertedValue = castRasterDataType(originalValue, newDataType); - modifiedRaster.setSample(x, y, band, convertedValue); - } - } + double[] samples = originalData.getSamples(0, 0, width, height, band, (double[]) null); + modifiedRaster.setSamples(0, 0, width, height, band, samples); if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); } } - - // Clone the original GridCoverage2D with the modified raster - return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); - } - - -// public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { -// int newDataType = RasterUtils.getDataTypeCode(BandDataType); -// -// RenderedImage originalImage = raster.getRenderedImage(); -// int numBands = originalImage.getSampleModel().getNumBands(); -// int width = originalImage.getWidth(); -// int height = originalImage.getHeight(); -// -// // Create separate rasters for each band -// WritableRaster[] bandRasters = new WritableRaster[numBands]; // for (int band = 0; band < numBands; band++) { -// int dataType = (bandID != null && band == bandID - 1) ? newDataType : originalImage.getSampleModel().getDataType(band); -// bandRasters[band] = RasterFactory.createBandedRaster(dataType, width, height, 1, null); -// copyBandData(originalImage, bandRasters[band], band, dataType); -// } -// -// // Combine the separate rasters into a single raster -// WritableRaster modifiedRaster = combineBandRasters(bandRasters, width, height); -// -// // Re-create sample dimensions if necessary -// GridSampleDimension[] sampleDimensions = raster.getSampleDimensions(); -// if (bandID != null) { -// sampleDimensions[bandID - 1] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[bandID - 1], RasterUtils.getNoDataValue(sampleDimensions[bandID - 1])); -// } -// -// // Clone the original GridCoverage2D with the modified raster -// return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); -// } -// -// private static void copyBandData(RenderedImage originalImage, WritableRaster bandRaster, int bandIndex, int dataType) { -// Raster originalData = originalImage.getData(); -// System.out.println("\nBand: "+bandIndex); -// for (int y = 0; y < originalImage.getHeight(); y++) { -// for (int x = 0; x < originalImage.getWidth(); x++) { -// double value = originalData.getSampleDouble(x, y, bandIndex); -// double convertedValue = castRasterDataType(value, dataType); -// bandRaster.setSample(x, y, 0, convertedValue); -// System.out.println("Original value: "+value+", Converted value: "+convertedValue); -// } -// } -// } - - private static WritableRaster combineBandRasters(WritableRaster[] bandRasters, int width, int height) { - WritableRaster combinedRaster = RasterFactory.createBandedRaster(DataBuffer.TYPE_DOUBLE, width, height, bandRasters.length, null); - for (int band = 0; band < bandRasters.length; band++) { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - combinedRaster.setSample(x, y, band, bandRasters[band].getSampleDouble(x, y, 0)); - } - } - } - return combinedRaster; - } - -// castRasterDataType method remains unchanged - - -// public static GridCoverage2D setBandPixelType(GridCoverage2D raster, String BandDataType, Integer bandID) { -// int numBands = raster.getNumSampleDimensions(); -// double[] bandValues; -// if (bandID == null) { -// for (int band = 0; band < numBands; band++) { -// bandValues = bandAsArray(raster, band + 1); -// double bandNoDataValue = RasterUtils.getNoDataValue(raster.getSampleDimension(band)); -// -// for (int i = 0; i < bandValues.length; i++) { -// bandValues[i] = castRasterDataType(bandValues[i], RasterUtils.getDataTypeCode(BandDataType)); +// for (int y = 0; y < height; y++) { +// for (int x = 0; x < width; x++) { +// double originalValue = originalData.getSampleDouble(x, y, band); +// double convertedValue = castRasterDataType(originalValue, newDataType); +// modifiedRaster.setSample(x, y, band, convertedValue); // } -// -// raster = addBandFromArray(raster, bandValues, band+1); // } -// } else { -// bandValues = bandAsArray(raster, bandID); -// -// for (int i = 0; i < bandValues.length; i++) { -// bandValues[i] = castRasterDataType(bandValues[i], RasterUtils.getDataTypeCode(BandDataType)); +// if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { +// System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); +// sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); // } -// -// raster = addBandFromArray(raster, bandValues, bandID); // } -// -// return raster; -// } - - private static WritableRaster modifyRasterBandType(WritableRaster raster, int bandIndex, int newDataType) { - int width = raster.getWidth(); - int height = raster.getHeight(); - int numBands = raster.getNumBands(); - WritableRaster modifiedRaster = RasterFactory.createBandedRaster(newDataType, width, height, numBands, null); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - for (int band = 0; band < numBands; band++) { - double originalValue = raster.getSampleDouble(x, y, band); - if (band == bandIndex) { - double convertedValue = castRasterDataType(originalValue, newDataType); - modifiedRaster.setSample(x, y, band, convertedValue); - System.out.println("Original Value: " + originalValue + ", Converted Value: " + convertedValue); - } else { - modifiedRaster.setSample(x, y, band, originalValue); - } - } - } - } - return modifiedRaster; + // Clone the original GridCoverage2D with the modified raster + return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); } - - - - -// private static WritableRaster modifyRasterBandType(WritableRaster raster, int bandIndex, int newDataType) { -// int width = raster.getWidth(); -// int height = raster.getHeight(); -// WritableRaster modifiedRaster = raster.createCompatibleWritableRaster(width, height); -// -// // Iterate over each pixel to convert the data type of the specified band -// for (int y = 0; y < height; y++) { -// for (int x = 0; x < width; x++) { -// // Handle the conversion based on the data type -// switch (newDataType) { -// case DataBuffer.TYPE_BYTE: -// byte byteValue = (byte) raster.getSample(x, y, bandIndex); -// modifiedRaster.setSample(x, y, bandIndex, byteValue); -// break; -// case DataBuffer.TYPE_SHORT: -// case DataBuffer.TYPE_USHORT: -// short shortValue = (short) raster.getSample(x, y, bandIndex); -// modifiedRaster.setSample(x, y, bandIndex, shortValue); -// break; -// case DataBuffer.TYPE_INT: -// int intValue = (int) raster.getSample(x, y, bandIndex); -// modifiedRaster.setSample(x, y, bandIndex, intValue); -// break; -// case DataBuffer.TYPE_FLOAT: -// float floatValue = raster.getSampleFloat(x, y, bandIndex); -// modifiedRaster.setSample(x, y, bandIndex, floatValue); -// break; -// case DataBuffer.TYPE_DOUBLE: -// double doubleValue = raster.getSampleDouble(x, y, bandIndex); -// modifiedRaster.setSample(x, y, bandIndex, doubleValue); -// break; -// default: -// throw new IllegalArgumentException("Unsupported data type: " + newDataType); -// } -// } -// } -// return modifiedRaster; -// } - -// private static RenderedImage createNewRenderedImageWithBandType(RenderedImage image, int newDataType, Integer bandID) { -// // This is a placeholder logic, real implementation can be significantly more complex. -// // This example only changes the data type and copies data for a single band. -// -// if (bandID == null) { -// throw new IllegalArgumentException("Band ID cannot be null"); -// } -// -// // Assuming we are changing the data type of a single band. -// // A more complex implementation would be needed for multi-band images. -// int band = bandID - 1; // Adjusting for 0-based index -// -// // Get the data from the specified band -// Raster raster = image.getData(); -// int width = image.getWidth(); -// int height = image.getHeight(); -// double[] samples = raster.getSamples(0, 0, width, height, band, (double[]) null); -// -// // Create a new writable raster with the new data type -// WritableRaster newRaster = Raster.createBandedRaster(newDataType, width, height, 1, new Point(0, 0)); -// -// // Set the samples to the new raster -// for (int y = 0; y < height; y++) { -// for (int x = 0; x < width; x++) { -// double value = samples[y * width + x]; -// newRaster.setSample(x, y, 0, value); // Casts are applied here based on newDataType -// } -// } -// -// // Return a new RenderedImage -// return new BufferedImage(image.getColorModel(), newRaster, image.getColorModel().isAlphaPremultiplied(), null); -// } - -// private static GridSampleDimension[] updateSampleDimensions(GridSampleDimension[] sampleDimensions, int newDataType, Integer bandID) { -// if (bandID == null) { -// throw new IllegalArgumentException("Band ID cannot be null"); -// } -// -// int band = bandID - 1; // Adjusting for 0-based index -// GridSampleDimension[] newSampleDimensions = new GridSampleDimension[sampleDimensions.length]; -// -// for (int i = 0; i < sampleDimensions.length; i++) { -// if (i == band) { -// // Update the sample dimension for the specified band. -// // This example just updates the data type; you might want to modify other properties. -// GridSampleDimension sd = sampleDimensions[i]; -// // Sample code to recreate the sample dimension with a new data type -// // The specifics of this operation depend on your data and requirements -// newSampleDimensions[i] = new GridSampleDimension(sd.getDescription().toString(), -// SampleDimensionType.valueOf(newDataType), sd.getNoDataValues()); -// } else { -// // Keep other bands as is -// newSampleDimensions[i] = sampleDimensions[i]; -// } -// } -// -// return newSampleDimensions; -// } - - public static GridCoverage2D setSrid(GridCoverage2D raster, int srid) { CoordinateReferenceSystem crs; @@ -656,7 +401,10 @@ public static GridCoverage2D normalizeAll(GridCoverage2D rasterGeom, double minL private static double castRasterDataType(double value, int dataType) { switch (dataType) { case DataBuffer.TYPE_BYTE: - return (byte) value; + // Cast to unsigned byte (0-255) + double remainder = value%256; + double v = (remainder < 0) ? remainder+256 : remainder; + return (int) v; case DataBuffer.TYPE_SHORT: return (short) value; case DataBuffer.TYPE_INT: @@ -671,4 +419,25 @@ private static double castRasterDataType(double value, int dataType) { } } +// private static double castRasterDataType(double value, int dataType) { +// switch (dataType) { +// case DataBuffer.TYPE_BYTE: +// // Cast to byte and clamp values to byte range +// return (byte) Math.max(Math.min(value, 255), 0); +// case DataBuffer.TYPE_USHORT: +// // Cast to unsigned short (0-65535) range +// return (int) Math.max(Math.min(value, 65535), 0); +// case DataBuffer.TYPE_SHORT: +// return (short) value; +// case DataBuffer.TYPE_INT: +// return (int) value; +// case DataBuffer.TYPE_FLOAT: +// return (float) value; +// case DataBuffer.TYPE_DOUBLE: +// default: +// return value; +// } +// } + + } diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java index 926ae95074..1cd084b126 100644 --- a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java +++ b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java @@ -49,7 +49,7 @@ public void testSetBandPixelType() throws FactoryException { testRaster = RasterBandEditors.setBandNoDataValue(testRaster, 1, 99.2); testRaster = RasterBandEditors.setBandNoDataValue(testRaster, 4, -9999.0); - GridCoverage2D modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "D"); + GridCoverage2D modifiedRaster = RasterEditors.setPixelType(testRaster, "D"); assertEquals(DataBuffer.TYPE_DOUBLE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); assertEquals(99.19999694824219, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); @@ -57,7 +57,7 @@ public void testSetBandPixelType() throws FactoryException { assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); - modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "F"); + modifiedRaster = RasterEditors.setPixelType(testRaster, "F"); assertEquals(DataBuffer.TYPE_FLOAT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); assertEquals(99.19999694824219, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); @@ -66,7 +66,7 @@ public void testSetBandPixelType() throws FactoryException { assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); - modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "I"); + modifiedRaster = RasterEditors.setPixelType(testRaster, "I"); assertEquals(DataBuffer.TYPE_INT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); @@ -74,7 +74,7 @@ public void testSetBandPixelType() throws FactoryException { assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); - modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "S"); + modifiedRaster = RasterEditors.setPixelType(testRaster, "S"); double[] expected = {-1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, -9999.0}; assertEquals(DataBuffer.TYPE_SHORT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); @@ -84,7 +84,7 @@ public void testSetBandPixelType() throws FactoryException { assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); - modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "US"); + modifiedRaster = RasterEditors.setPixelType(testRaster, "US"); expected = new double[]{65526.0, 65527.0, 65528.0, 65529.0, 65530.0, 65531.0, 65532.0, 65533.0, 65534.0, 65535.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0}; assertEquals(DataBuffer.TYPE_USHORT, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); @@ -94,21 +94,20 @@ public void testSetBandPixelType() throws FactoryException { assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); - modifiedRaster = RasterEditors.setRasterPixelType(testRaster, "B"); - - System.out.println("\nOriginal Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(0))); - System.out.println("Original Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(1))); - System.out.println("Original Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(2))); - System.out.println("Original Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(3))); - - System.out.println("\nModified Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0))); - System.out.println("Modified Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(1))); - System.out.println("Modified Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(2))); - System.out.println("Modified Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3))); + modifiedRaster = RasterEditors.setPixelType(testRaster, "B"); +// System.out.println("\nOriginal Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(0))); +// System.out.println("Original Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(1))); +// System.out.println("Original Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(2))); +// System.out.println("Original Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(3))); +// +// System.out.println("\nModified Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0))); +// System.out.println("Modified Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(1))); +// System.out.println("Modified Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(2))); +// System.out.println("Modified Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3))); assertEquals(DataBuffer.TYPE_BYTE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); - assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); + assertEquals(241, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3)), 0.01); assertEquals(testRaster.getRenderedImage().getWidth(), modifiedRaster.getRenderedImage().getWidth()); assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); } diff --git a/docs/api/sql/Raster-loader.md b/docs/api/sql/Raster-loader.md index ef648838e1..4f5a5137f8 100644 --- a/docs/api/sql/Raster-loader.md +++ b/docs/api/sql/Raster-loader.md @@ -65,7 +65,7 @@ Accepts one of: 3. "I" - 32 bits signed Integer 4. "S" - 16 bits signed Short 5. "US" - 16 bits unsigned Short - 6. "B" - 8 bits Byte + 6. "B" - 8 bits unsigned Byte * Width: The width of the raster in pixels. * Height: The height of the raster in pixels. * UpperleftX: The X coordinate of the upper left corner of the raster, in terms of the CRS units. diff --git a/docs/api/sql/Raster-operators.md b/docs/api/sql/Raster-operators.md index a3b75dbd86..27899f2a9f 100644 --- a/docs/api/sql/Raster-operators.md +++ b/docs/api/sql/Raster-operators.md @@ -1767,6 +1767,35 @@ Output: -3.000000 ``` +### RS_SetPixelType + +Introduction: Returns a modified raster with the desired pixel data type. + +The `dataType` parameter accepts one of the following strings. + +- "D" - 64 bits Double +- "F" - 32 bits Float +- "I" - 32 bits signed Integer +- "S" - 16 bits signed Short +- "US" - 16 bits unsigned Short +- "B" - 8 bits unsigned Byte + +!!!note + If the specified `dataType` is narrower than the original data type, the function will truncate the pixel values to fit the new data type range. + +Format: +``` +RS_SetPixelType(raster: Raster, dataType: String) +``` + +Since: `v1.6.0` + +SQL Example: + +```sql +RS_SetPixelType(raster, "I") +``` + ### RS_SetValue Introduction: Returns a raster by replacing the value of pixel specified by `colX` and `rowY`. diff --git a/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala b/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala index db9fe9d099..e0adb53938 100644 --- a/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala +++ b/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala @@ -217,6 +217,7 @@ object Catalog { function[RS_SetSRID](), function[RS_SetGeoReference](), function[RS_SetBandNoDataValue](), + function[RS_SetPixelType](), function[RS_SetValues](), function[RS_SetValue](), function[RS_SRID](), diff --git a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterEditors.scala b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterEditors.scala index 5ccf34ccb5..673e59911a 100644 --- a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterEditors.scala +++ b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/raster/RasterEditors.scala @@ -37,6 +37,12 @@ case class RS_SetGeoReference(inputExpressions: Seq[Expression]) extends Inferre } } +case class RS_SetPixelType(inputExpressions: Seq[Expression]) extends InferredExpression(RasterEditors.setPixelType _) { + protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = { + copy(inputExpressions = newChildren) + } +} + case class RS_Resample(inputExpressions: Seq[Expression]) extends InferredExpression( nullTolerantInferrableFunction4(RasterEditors.resample), nullTolerantInferrableFunction5(RasterEditors.resample), nullTolerantInferrableFunction7(RasterEditors.resample)) { diff --git a/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala b/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala index 6d7a9cf512..4fc41a67b1 100644 --- a/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala +++ b/spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala @@ -229,6 +229,35 @@ class rasteralgebraTest extends TestBaseScala with BeforeAndAfter with GivenWhen assert(result4.isInstanceOf[GridCoverage2D]) } + it("should pass RS_SetPixelType") { + var df = sparkSession.read.format("binaryFile").load(resourceFolder + "raster/test1.tiff") + df = df.selectExpr("RS_FromGeoTiff(content) as raster") + + val df1 = df.selectExpr("RS_SetPixelType(raster, 'D') as modifiedRaster") + val result1 = df1.selectExpr("RS_BandPixelType(modifiedRaster)").first().get(0).toString + assert(result1 == "REAL_64BITS") + + val df2 = df.selectExpr("RS_SetPixelType(raster, 'F') as modifiedRaster") + val result2 = df2.selectExpr("RS_BandPixelType(modifiedRaster)").first().get(0).toString + assert(result2 == "REAL_32BITS") + + val df3 = df.selectExpr("RS_SetPixelType(raster, 'I') as modifiedRaster") + val result3 = df3.selectExpr("RS_BandPixelType(modifiedRaster)").first().get(0).toString + assert(result3 == "SIGNED_32BITS") + + val df4 = df.selectExpr("RS_SetPixelType(raster, 'S') as modifiedRaster") + val result4 = df4.selectExpr("RS_BandPixelType(modifiedRaster)").first().get(0).toString + assert(result4 == "SIGNED_16BITS") + + val df5 = df.selectExpr("RS_SetPixelType(raster, 'US') as modifiedRaster") + val result5 = df5.selectExpr("RS_BandPixelType(modifiedRaster)").first().get(0).toString + assert(result5 == "UNSIGNED_16BITS") + + val df6 = df.selectExpr("RS_SetPixelType(raster, 'B') as modifiedRaster") + val result6 = df6.selectExpr("RS_BandPixelType(modifiedRaster)").first().get(0).toString + assert(result6 == "UNSIGNED_8BITS") + } + it("should pass RS_Array") { val df = sparkSession.sql("SELECT RS_Array(6, 1e-6) as band") val result = df.first().getAs[mutable.WrappedArray[Double]](0) From 2efed56c4068b592f925bcc7db2422ff042d3536 Mon Sep 17 00:00:00 2001 From: Pranav Toggi Date: Mon, 11 Mar 2024 16:42:36 -0400 Subject: [PATCH 5/6] Update comments --- .../sedona/common/raster/RasterEditors.java | 36 +------------------ .../common/raster/RasterEditorsTest.java | 10 ------ 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java index c202c9540c..d1a77804ac 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java +++ b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java @@ -85,23 +85,10 @@ public static GridCoverage2D setPixelType(GridCoverage2D raster, String dataType double[] samples = originalData.getSamples(0, 0, width, height, band, (double[]) null); modifiedRaster.setSamples(0, 0, width, height, band, samples); if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { - System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); +// System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); } } -// for (int band = 0; band < numBands; band++) { -// for (int y = 0; y < height; y++) { -// for (int x = 0; x < width; x++) { -// double originalValue = originalData.getSampleDouble(x, y, band); -// double convertedValue = castRasterDataType(originalValue, newDataType); -// modifiedRaster.setSample(x, y, band, convertedValue); -// } -// } -// if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { -// System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); -// sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); -// } -// } // Clone the original GridCoverage2D with the modified raster return RasterUtils.clone(modifiedRaster, raster.getGridGeometry(), sampleDimensions, raster, null, true); @@ -419,25 +406,4 @@ private static double castRasterDataType(double value, int dataType) { } } -// private static double castRasterDataType(double value, int dataType) { -// switch (dataType) { -// case DataBuffer.TYPE_BYTE: -// // Cast to byte and clamp values to byte range -// return (byte) Math.max(Math.min(value, 255), 0); -// case DataBuffer.TYPE_USHORT: -// // Cast to unsigned short (0-65535) range -// return (int) Math.max(Math.min(value, 65535), 0); -// case DataBuffer.TYPE_SHORT: -// return (short) value; -// case DataBuffer.TYPE_INT: -// return (int) value; -// case DataBuffer.TYPE_FLOAT: -// return (float) value; -// case DataBuffer.TYPE_DOUBLE: -// default: -// return value; -// } -// } - - } diff --git a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java index 1cd084b126..895127525f 100644 --- a/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java +++ b/common/src/test/java/org/apache/sedona/common/raster/RasterEditorsTest.java @@ -35,7 +35,6 @@ public class RasterEditorsTest extends RasterTestBase { @Test public void testSetBandPixelType() throws FactoryException { - // Create a test raster using makeEmptyRaster GridCoverage2D testRaster = RasterConstructors.makeEmptyRaster(4, "F", 4, 4, 0, 0, 1); double[] bandValues1 = {1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1,11.1,12.1,13.1,14.1,15.1,99.2}; double[] bandValues2 = {17.9, 18.9, 19.9, 20.9, 21.9, 22.9, 23.9, 24.9, 25.9, 26.9, 27.9, 28.9, 29.9, 30.9, 31.9, 32.9}; @@ -95,15 +94,6 @@ public void testSetBandPixelType() throws FactoryException { assertEquals(testRaster.getRenderedImage().getHeight(), modifiedRaster.getRenderedImage().getHeight()); modifiedRaster = RasterEditors.setPixelType(testRaster, "B"); -// System.out.println("\nOriginal Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(0))); -// System.out.println("Original Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(1))); -// System.out.println("Original Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(2))); -// System.out.println("Original Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(testRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(testRaster.getSampleDimension(3))); -// -// System.out.println("\nModified Band 1: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 1))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0))); -// System.out.println("Modified Band 2: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 2))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(1))); -// System.out.println("Modified Band 3: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 3))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(2))); -// System.out.println("Modified Band 4: "+Arrays.toString(MapAlgebra.bandAsArray(modifiedRaster, 4))+", noDataValue: "+ RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(3))); assertEquals(DataBuffer.TYPE_BYTE, modifiedRaster.getRenderedImage().getSampleModel().getDataType()); assertEquals(99, RasterUtils.getNoDataValue(modifiedRaster.getSampleDimension(0)), 0.01); From 11da1c10b36501d2099f6f066a10470dda0058c3 Mon Sep 17 00:00:00 2001 From: Pranav Toggi Date: Mon, 11 Mar 2024 16:44:31 -0400 Subject: [PATCH 6/6] Update comments --- .../java/org/apache/sedona/common/raster/RasterEditors.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java index d1a77804ac..eb0db1eab4 100644 --- a/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java +++ b/common/src/main/java/org/apache/sedona/common/raster/RasterEditors.java @@ -60,9 +60,9 @@ public class RasterEditors /** * Changes the band pixel type of a specific band of a raster. * - * @param raster The input raster. + * @param raster The input raster. * @param dataType The desired data type of the pixel. - * @return The modified raster with updated band pixel type. + * @return The modified raster with updated pixel type. */ public static GridCoverage2D setPixelType(GridCoverage2D raster, String dataType) { @@ -85,7 +85,6 @@ public static GridCoverage2D setPixelType(GridCoverage2D raster, String dataType double[] samples = originalData.getSamples(0, 0, width, height, band, (double[]) null); modifiedRaster.setSamples(0, 0, width, height, band, samples); if (!Double.isNaN(RasterUtils.getNoDataValue(sampleDimensions[band]))) { -// System.out.println("NoDataValue: "+ RasterUtils.getNoDataValue(sampleDimensions[band])+", newNoDataValue: "+castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); sampleDimensions[band] = RasterUtils.createSampleDimensionWithNoDataValue(sampleDimensions[band], castRasterDataType(RasterUtils.getNoDataValue(sampleDimensions[band]), newDataType)); } }