[geos-commits] [SCM] GEOS branch 3.15 updated. 86a4af483db99dc3f8914cd6a16cbfddd9961130

git at osgeo.org git at osgeo.org
Mon Sep 21 09:48:40 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, 3.15 has been updated
       via  86a4af483db99dc3f8914cd6a16cbfddd9961130 (commit)
      from  ba13c5a0329ee8b0edd5d2562286f220e55866fe (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 86a4af483db99dc3f8914cd6a16cbfddd9961130
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/NEWS.md b/NEWS.md
index 7ba8f81b8..e5a2885ef 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -4,6 +4,7 @@
 - Fixes/Improvements:
   - Fix arc noding failure with endpoint intersections (GH-1513, Dan Baston)
   - Make GeometrySplitter able to split MultiSurface inputs (GH-1518, Dan Baston)
+  - GEOSGridIntersectionFractions: Set cells outside geometry bounding box to zero (GH-1532, Dan Baston)
 
 ## Changes in 3.15.0
 2026-09-01
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:
 NEWS.md                                            |  1 +
 include/geos/operation/grid/Matrix.h               |  4 ++
 src/operation/grid/GridIntersection.cpp            | 50 +++++++++++++++-------
 .../capi/GEOSGridIntersectionFractionsTest.cpp     | 27 ++++++++++++
 4 files changed, 67 insertions(+), 15 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list