You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sedona.apache.org by "prantogg (via GitHub)" <gi...@apache.org> on 2023/11/20 22:29:26 UTC

[PR] [SEDONA-431] Add RS_PixelAsPoints [sedona]

prantogg opened a new pull request, #1125:
URL: https://github.com/apache/sedona/pull/1125

   
   ## Did you read the Contributor Guide?
   
   - Yes, I have read [Contributor Rules](https://sedona.apache.org/latest-snapshot/community/rule/) and [Contributor Development Guide](https://sedona.apache.org/latest-snapshot/community/develop/)
   
   ## Is this PR related to a JIRA ticket?
   
   - Yes, the URL of the associated JIRA ticket is https://issues.apache.org/jira/browse/SEDONA-431. The PR name follows the format `[SEDONA-XXX] my subject`.
   
   ## What changes were proposed in this PR?
   
   - Implements Raster operator RS_PixelAsPoints
   
   ## How was this patch tested?
   
   - Passes new and existing tests
   
   ## Did this PR include necessary documentation updates?
   
   - Yes, I am adding a new API. I am using the [current SNAPSHOT version number](https://github.com/apache/sedona/blob/a64972027aa4c0fea354898da67a2dd4e6cde46b/pom.xml#L29) in since `vX.Y.Z` format.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@sedona.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [SEDONA-431] Add RS_PixelAsPoints [sedona]

Posted by "jiayuasu (via GitHub)" <gi...@apache.org>.
jiayuasu merged PR #1125:
URL: https://github.com/apache/sedona/pull/1125


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@sedona.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [SEDONA-431] Add RS_PixelAsPoints [sedona]

Posted by "jiayuasu (via GitHub)" <gi...@apache.org>.
jiayuasu commented on code in PR #1125:
URL: https://github.com/apache/sedona/pull/1125#discussion_r1401390351


##########
spark/common/src/test/scala/org/apache/sedona/sql/rasteralgebraTest.scala:
##########
@@ -931,6 +931,25 @@ class rasteralgebraTest extends TestBaseScala with BeforeAndAfter with GivenWhen
       assertEquals(expectedY, actualCoordinates.y, 1e-5)
     }
 
+    it("Passed RS_PixelAsPoints with empty raster") {

Review Comment:
   Please add a test with Spark explode function and make sure the output of this function can work seamlessly with explode.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@sedona.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [SEDONA-431] Add RS_PixelAsPoints [sedona]

Posted by "prantogg (via GitHub)" <gi...@apache.org>.
prantogg commented on code in PR #1125:
URL: https://github.com/apache/sedona/pull/1125#discussion_r1400874342


##########
common/src/main/java/org/apache/sedona/common/raster/PixelFunctions.java:
##########
@@ -91,6 +92,45 @@ public static Geometry getPixelAsPoint(GridCoverage2D raster, int colX, int rowY
         return GEOMETRY_FACTORY.createPoint(pointCoord);
     }
 
+    public static List<PixelRecord> getPixelAsPoints(GridCoverage2D rasterGeom, int band) throws TransformException, FactoryException {
+        RasterUtils.ensureBand(rasterGeom, band);
+
+        int width = RasterAccessors.getWidth(rasterGeom);
+        int height = RasterAccessors.getHeight(rasterGeom);
+
+        Raster r = RasterUtils.getRaster(rasterGeom.getRenderedImage());
+        double[] pixels = r.getSamples(0, 0, width, height, band - 1, (double[]) null);
+
+        AffineTransform2D gridToCRS = RasterUtils.getGDALAffineTransform(rasterGeom);
+        double cellSizeX = gridToCRS.getScaleX();
+        double cellSizeY = gridToCRS.getScaleY();
+        double shearX = gridToCRS.getShearX();
+        double shearY = gridToCRS.getShearY();
+
+        int srid = RasterAccessors.srid(rasterGeom);
+        GeometryFactory geometryFactory = srid != 0 ? new GeometryFactory(new PrecisionModel(), srid) : GEOMETRY_FACTORY;
+
+        Point2D upperLeft = RasterUtils.getWorldCornerCoordinates(rasterGeom, 1, 1);
+        List<PixelRecord> pointRecords = new ArrayList<>();
+
+        for (int y = 1; y <= height; y++) {

Review Comment:
   It shares the same logic as RS_PixelAsPoint to retrieve upper left world coordinates of first pixel in the raster. 
   For all other pixels, upper left world coordinates are calculated based on pixel size and skew of raster. This eliminates the need to do transformations from grid coords to world coords for every pixel. 
   I tested it against results of RS_PixelAsPoint to make sure the calculations are accurate. 



##########
common/src/main/java/org/apache/sedona/common/raster/PixelFunctions.java:
##########
@@ -91,6 +92,45 @@ public static Geometry getPixelAsPoint(GridCoverage2D raster, int colX, int rowY
         return GEOMETRY_FACTORY.createPoint(pointCoord);
     }
 
+    public static List<PixelRecord> getPixelAsPoints(GridCoverage2D rasterGeom, int band) throws TransformException, FactoryException {
+        RasterUtils.ensureBand(rasterGeom, band);
+
+        int width = RasterAccessors.getWidth(rasterGeom);
+        int height = RasterAccessors.getHeight(rasterGeom);
+
+        Raster r = RasterUtils.getRaster(rasterGeom.getRenderedImage());
+        double[] pixels = r.getSamples(0, 0, width, height, band - 1, (double[]) null);
+
+        AffineTransform2D gridToCRS = RasterUtils.getGDALAffineTransform(rasterGeom);
+        double cellSizeX = gridToCRS.getScaleX();
+        double cellSizeY = gridToCRS.getScaleY();
+        double shearX = gridToCRS.getShearX();
+        double shearY = gridToCRS.getShearY();
+
+        int srid = RasterAccessors.srid(rasterGeom);
+        GeometryFactory geometryFactory = srid != 0 ? new GeometryFactory(new PrecisionModel(), srid) : GEOMETRY_FACTORY;
+
+        Point2D upperLeft = RasterUtils.getWorldCornerCoordinates(rasterGeom, 1, 1);
+        List<PixelRecord> pointRecords = new ArrayList<>();
+
+        for (int y = 1; y <= height; y++) {

Review Comment:
   @jiayuasu It shares the same logic as RS_PixelAsPoint to retrieve upper left world coordinates of first pixel in the raster. 
   For all other pixels, upper left world coordinates are calculated based on pixel size and skew of raster. This eliminates the need to do transformations from grid coords to world coords for every pixel. 
   I tested it against results of RS_PixelAsPoint to make sure the calculations are accurate. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@sedona.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [SEDONA-431] Add RS_PixelAsPoints [sedona]

Posted by "jiayuasu (via GitHub)" <gi...@apache.org>.
jiayuasu commented on code in PR #1125:
URL: https://github.com/apache/sedona/pull/1125#discussion_r1400850714


##########
common/src/main/java/org/apache/sedona/common/raster/PixelFunctions.java:
##########
@@ -91,6 +92,45 @@ public static Geometry getPixelAsPoint(GridCoverage2D raster, int colX, int rowY
         return GEOMETRY_FACTORY.createPoint(pointCoord);
     }
 
+    public static List<PixelRecord> getPixelAsPoints(GridCoverage2D rasterGeom, int band) throws TransformException, FactoryException {
+        RasterUtils.ensureBand(rasterGeom, band);
+
+        int width = RasterAccessors.getWidth(rasterGeom);
+        int height = RasterAccessors.getHeight(rasterGeom);
+
+        Raster r = RasterUtils.getRaster(rasterGeom.getRenderedImage());
+        double[] pixels = r.getSamples(0, 0, width, height, band - 1, (double[]) null);
+
+        AffineTransform2D gridToCRS = RasterUtils.getGDALAffineTransform(rasterGeom);
+        double cellSizeX = gridToCRS.getScaleX();
+        double cellSizeY = gridToCRS.getScaleY();
+        double shearX = gridToCRS.getShearX();
+        double shearY = gridToCRS.getShearY();
+
+        int srid = RasterAccessors.srid(rasterGeom);
+        GeometryFactory geometryFactory = srid != 0 ? new GeometryFactory(new PrecisionModel(), srid) : GEOMETRY_FACTORY;
+
+        Point2D upperLeft = RasterUtils.getWorldCornerCoordinates(rasterGeom, 1, 1);
+        List<PixelRecord> pointRecords = new ArrayList<>();
+
+        for (int y = 1; y <= height; y++) {

Review Comment:
   Should this share the same logic of RS_PixelAsPoint?



##########
common/src/test/java/org/apache/sedona/common/raster/FunctionsTest.java:
##########
@@ -183,6 +183,93 @@ public void testPixelAsPointFromRasterFile() throws IOException, TransformExcept
         assertEquals(expectedY, coordinate.getY(), 0.2d);
     }
 
+    @Test
+    public void testPixelAsPointSkewedRaster() throws FactoryException, TransformException {
+        // Testing with skewed raster
+        GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 12, 13, 240, -193, 2, 1.5, 3, 2, 0);
+        String actual = Functions.asWKT(PixelFunctions.getPixelAsPoint(emptyRaster, 3, 3));
+        String expected = "POINT (250 -186)";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testPixelAsPointsOutputSize() throws FactoryException, TransformException {
+        GridCoverage2D raster = RasterConstructors.makeEmptyRaster(1, 5, 10, 123, -230, 8);
+        List<PixelRecord> points = PixelFunctions.getPixelAsPoints(raster, 1);
+        assertEquals(50, points.size());
+    }
+
+    @Test
+    public void testPixelAsPointsValues() throws FactoryException, TransformException {
+        GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 5, 10, 123, -230, 8);
+        List<PixelRecord> points = PixelFunctions.getPixelAsPoints(emptyRaster, 1);
+
+        PixelRecord point1 = points.get(0);
+        Geometry geom1 = (Geometry) point1.geom;
+        assertEquals(123, geom1.getCoordinate().x, 0.2d);
+        assertEquals(-230, geom1.getCoordinate().y, 0.2d);
+        assertEquals(0.0, point1.value, 0.2d);
+
+        PixelRecord point2 = points.get(22);
+        Geometry geom2 = (Geometry) point2.geom;
+        assertEquals(139, geom2.getCoordinate().x, 0.2d);
+        assertEquals(-262, geom2.getCoordinate().y, 0.2d);
+        assertEquals(0.0, point2.value, 0.2d);
+    }
+
+    @Test
+    public void testPixelAsPointsCustomSRIDPlanar() throws FactoryException, TransformException {
+        int srid = 3857;
+        GridCoverage2D emptyRaster = RasterConstructors.makeEmptyRaster(1, 5, 5, -123, 54, 5, 5, 0, 0, srid);
+        List<PixelRecord> points = PixelFunctions.getPixelAsPoints(emptyRaster, 1);
+        PixelRecord point1 = points.get(0);
+        Geometry geom1 = (Geometry) point1.geom;
+        assertEquals(-123, geom1.getCoordinate().x, 1e-9);

Review Comment:
   Please coordinate with @furqaankhan . If you need a delta value for float comparion, better set up a global value under `RasterTestBase`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@sedona.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org