[geos-commits] [SCM] GEOS branch main updated. cc1d2bc2d31a4056b38dc829c0e1a9c0320888c9

git at osgeo.org git at osgeo.org
Mon Sep 21 09:42:50 PDT 2026


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, main has been updated
       via  cc1d2bc2d31a4056b38dc829c0e1a9c0320888c9 (commit)
      from  ee23efdfd0acf5e0bfd10158930a825628c41389 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit cc1d2bc2d31a4056b38dc829c0e1a9c0320888c9
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 21 12:42:23 2026 -0400

    GEOSGridIntersectionFractions: Set cells outside geometry bounding box to zero (#1532)

diff --git a/include/geos/operation/grid/Matrix.h b/include/geos/operation/grid/Matrix.h
index 67d49d9cc..1d1a1bccd 100644
--- a/include/geos/operation/grid/Matrix.h
+++ b/include/geos/operation/grid/Matrix.h
@@ -141,6 +141,10 @@ class Matrix
         return m_data.get() + m_rows * m_cols;
     }
 
+    void fill(const T& val) {
+        std::fill(m_data.get(), m_data.get() + m_rows * m_cols, val);
+    }
+
 #ifdef MATRIX_CHECK_BOUNDS
     void check(size_t row, size_t col) const
     {
diff --git a/src/operation/grid/GridIntersection.cpp b/src/operation/grid/GridIntersection.cpp
index 7c4815b75..c60c3aaec 100644
--- a/src/operation/grid/GridIntersection.cpp
+++ b/src/operation/grid/GridIntersection.cpp
@@ -60,6 +60,31 @@ get_cell(Matrix<std::unique_ptr<Cell>>& cells, const Grid<infinite_extent>& ex,
     return cells(row, col).get();
 }
 
+static Grid<infinite_extent>
+getSubgrid(const Envelope& box, const Grid<infinite_extent>& geometry_grid)
+{
+    Envelope cropped_ring_extent = geometry_grid.getExtent().intersection(box);
+    return geometry_grid.shrinkToFit(cropped_ring_extent);
+}
+
+static Grid<infinite_extent>
+getSubgrid(const Geometry& ls, const Grid<infinite_extent>& geometry_grid)
+{
+    return getSubgrid(*ls.getEnvelopeInternal(), geometry_grid);
+}
+
+
+template<typename T>
+static void
+initialize(const T& geom, const Grid<infinite_extent> geom_grid, Matrix<float>* cov)
+{
+    const auto subgrid = getSubgrid(geom, geom_grid);
+
+    if (subgrid.getNumRows() < geom_grid.getNumRows() || subgrid.getNumCols() < geom_grid.getNumCols()) {
+        cov->fill(0);
+    }
+}
+
 Envelope
 GridIntersection::processingRegion(const Envelope& raster_extent, const Geometry& g)
 {
@@ -96,6 +121,10 @@ GridIntersection::GridIntersection(const Grid<bounded_extent>& raster_grid, cons
     }
 
     if (!m_geometry_grid.isEmpty()) {
+        if (cov) {
+            initialize(g, m_geometry_grid, cov.get());
+        }
+
         process(g);
     }
 }
@@ -107,6 +136,10 @@ GridIntersection::GridIntersection(const Grid<bounded_extent>& raster_grid, cons
   , m_areal{ false }
 {
     if (!m_geometry_grid.isEmpty()) {
+        if (cov) {
+            initialize(box, m_geometry_grid, cov.get());
+        }
+
         processRectangularRing(box, true);
     }
 }
@@ -140,19 +173,6 @@ GridIntersection::process(const Geometry& g)
     }
 }
 
-static Grid<infinite_extent>
-get_box_grid(const Envelope& box, const Grid<infinite_extent>& geometry_grid)
-{
-    Envelope cropped_ring_extent = geometry_grid.getExtent().intersection(box);
-    return geometry_grid.shrinkToFit(cropped_ring_extent);
-}
-
-static Grid<infinite_extent>
-get_ring_grid(const Geometry& ls, const Grid<infinite_extent>& geometry_grid)
-{
-    return get_box_grid(*ls.getEnvelopeInternal(), geometry_grid);
-}
-
 void
 GridIntersection::processRectangularRing(const Envelope& box, bool exterior_ring)
 {
@@ -160,7 +180,7 @@ GridIntersection::processRectangularRing(const Envelope& box, bool exterior_ring
         return;
     }
 
-    auto ring_grid = get_box_grid(box, m_geometry_grid);
+    auto ring_grid = getSubgrid(box, m_geometry_grid);
 
     auto row_min = ring_grid.getRow(box.getMaxY());
     auto row_max = ring_grid.getRow(box.getMinY());
@@ -406,7 +426,7 @@ GridIntersection::processLine(const LineString& ls, bool exterior_ring)
         }
     }
 
-    Grid<infinite_extent> ring_grid = get_ring_grid(ls, m_geometry_grid);
+    Grid<infinite_extent> ring_grid = getSubgrid(ls, m_geometry_grid);
 
     size_t rows = ring_grid.getNumRows();
     size_t cols = ring_grid.getNumCols();
diff --git a/tests/unit/capi/GEOSGridIntersectionFractionsTest.cpp b/tests/unit/capi/GEOSGridIntersectionFractionsTest.cpp
index 5dacbf175..59d0c9eaa 100644
--- a/tests/unit/capi/GEOSGridIntersectionFractionsTest.cpp
+++ b/tests/unit/capi/GEOSGridIntersectionFractionsTest.cpp
@@ -64,4 +64,31 @@ void object::test<3>()
     ensure_equals(result, 0);
 }
 
+template<>
+template<>
+void object::test<4>()
+{
+    set_test_name("values outside the geometry bounding box are set to zero");
+
+    input_ = fromWKT("POLYGON ((0.5 0.5, 2.5 0.5, 2.5 2.5, 0.5 2.5, 0.5 0.5))");
+
+    const unsigned nx = 5;
+    const unsigned ny = 5;
+    const float init_value = 99999;
+
+    std::vector<float> result_vec(nx * ny, init_value);
+    int result = GEOSGridIntersectionFractions(input_, 0, 0, nx, ny, nx, ny, result_vec.data());
+    ensure_equals(result, 1);
+
+    std::vector<float> expected = {
+        0,      0,    0, 0, 0,
+        0,      0,    0, 0, 0,
+        0.25, 0.5, 0.25, 0, 0,
+        0.5,  1.0,  0.5, 0, 0,
+        0.25, 0.5, 0.25, 0, 0
+    };
+
+    ensure(result_vec == expected);
+}
+
 }

-----------------------------------------------------------------------

Summary of changes:
 include/geos/operation/grid/Matrix.h               |  4 ++
 src/operation/grid/GridIntersection.cpp            | 50 +++++++++++++++-------
 .../capi/GEOSGridIntersectionFractionsTest.cpp     | 27 ++++++++++++
 3 files changed, 66 insertions(+), 15 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list