[geos-commits] [SCM] GEOS branch 3.11 updated. 3ab7bb4309ac22b36ee0a1e6219b0c969d45087e

git at osgeo.org git at osgeo.org
Thu Nov 9 00:25:49 PST 2023


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.11 has been updated
       via  3ab7bb4309ac22b36ee0a1e6219b0c969d45087e (commit)
       via  2ec7bc32a7114f9f03e057593d4ad604604602bc (commit)
       via  5a9389e29aeea306c5af3f67f2a010657b393e1e (commit)
       via  43809f000a84970a4db445d245d4827331d8862e (commit)
       via  b376f0f4d81503574803e55aa7856759af7c44d7 (commit)
      from  7d568c481663b2db08255d51eed4a619b320e2ec (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 3ab7bb4309ac22b36ee0a1e6219b0c969d45087e
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Thu Nov 2 14:48:26 2023 -0700

    News entry for #979

diff --git a/NEWS.md b/NEWS.md
index 375dfbcaa..af43f0988 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -13,6 +13,7 @@
   - Remove undefined behaviour in use of null PrecisionModel (GH-931, Jeff Walton)
   - Fix InteriorPointPoint to handle empty elements (GH-977, Martin Davis)
   - PreparedLineStringIntersects: Fix incorrect result with mixed-dim collection with points (GH-774, Dan Baston)
+  - Skip over testing empty distances for mixed collections (GH-979, Paul Ramsey)
 
 ## Changes in 3.11.2
 2023-03-16

commit 2ec7bc32a7114f9f03e057593d4ad604604602bc
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Thu Nov 2 14:45:36 2023 -0700

    Skip over testing empty distances for mixed collections. Closes #979

diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp
index d65cc5897..9c8888dd0 100644
--- a/src/operation/distance/DistanceOp.cpp
+++ b/src/operation/distance/DistanceOp.cpp
@@ -358,6 +358,10 @@ DistanceOp::computeMinDistanceLines(
 {
     for(const LineString* line0 : lines0) {
         for(const LineString* line1 : lines1) {
+
+            if (line0->isEmpty() || line1->isEmpty())
+                continue;
+
             computeMinDistance(line0, line1, locGeom);
             if(minDistance <= terminateDistance) {
                 return;
@@ -374,13 +378,11 @@ DistanceOp::computeMinDistancePoints(
     std::array<std::unique_ptr<GeometryLocation>, 2> & locGeom)
 {
     for(const Point* pt0 : points0) {
-        if (pt0->isEmpty()) {
-            continue;
-        }
         for(const Point* pt1 : points1) {
-            if (pt1->isEmpty()) {
+
+            if (pt1->isEmpty() || pt0->isEmpty())
                 continue;
-            }
+
             double dist = pt0->getCoordinate()->distance(*(pt1->getCoordinate()));
 
 #if GEOS_DEBUG
@@ -414,6 +416,10 @@ DistanceOp::computeMinDistanceLinesPoints(
 {
     for(const LineString* line : lines) {
         for(const Point* pt : points) {
+
+            if (line->isEmpty() || pt->isEmpty())
+                continue;
+
             computeMinDistance(line, pt, locGeom);
             if(minDistance <= terminateDistance) {
                 return;
diff --git a/tests/unit/operation/distance/DistanceOpTest.cpp b/tests/unit/operation/distance/DistanceOpTest.cpp
index e80a0e143..16414a8bb 100644
--- a/tests/unit/operation/distance/DistanceOpTest.cpp
+++ b/tests/unit/operation/distance/DistanceOpTest.cpp
@@ -565,6 +565,11 @@ void object::test<21>()
     ensure_equals(g1->distance(g2.get()), 1.9996999774966246);
 }
 
+//
+// Variations on a theme: testing EMPTY and collections with EMPTY
+//
+
+// Ignoring empty component
 template<>
 template<>
 void object::test<22>()
@@ -576,6 +581,69 @@ void object::test<22>()
     ensure_equals(g2->distance(g1.get()), 1);
 }
 
+// Empty is same as empty so zero...?
+template<>
+template<>
+void object::test<23>()
+{
+    auto g1 = wktreader.read("POINT EMPTY");
+    auto g2 = wktreader.read("LINESTRING EMPTY");
+
+    ensure(g1 != nullptr && g2 != nullptr);
+    ensure_equals(g1->distance(g2.get()), 0);
+    ensure_equals(g2->distance(g1.get()), 0);
+}
+
+template<>
+template<>
+void object::test<24>()
+{
+    auto g1 = wktreader.read("GEOMETRYCOLLECTION(POINT EMPTY, LINESTRING EMPTY)");
+    auto g2 = wktreader.read("LINESTRING EMPTY");
+
+    ensure(g1 != nullptr && g2 != nullptr);
+    ensure_equals(g1->distance(g2.get()), 0);
+    ensure_equals(g2->distance(g1.get()), 0);
+}
+
+// But ignore empty if there's a real distance?
+template<>
+template<>
+void object::test<25>()
+{
+    auto g1 = wktreader.read("GEOMETRYCOLLECTION(LINESTRING EMPTY, POINT(2 1))");
+    auto g2 = wktreader.read("POINT(1 1)");
+
+    ensure(g1 != nullptr && g2 != nullptr);
+    ensure_equals(g1->distance(g2.get()), 1);
+    ensure_equals(g2->distance(g1.get()), 1);
+}
+
+template<>
+template<>
+void object::test<26>()
+{
+    auto g1 = wktreader.read("GEOMETRYCOLLECTION(POINT(-2 0), POINT EMPTY)");
+    auto g2 = wktreader.read("GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,1 0))");
+
+    ensure(g1 != nullptr && g2 != nullptr);
+    ensure_equals(g1->distance(g2.get()), 2);
+    ensure_equals(g2->distance(g1.get()), 2);
+}
+
+template<>
+template<>
+void object::test<27>()
+{
+    auto g1 = wktreader.read("GEOMETRYCOLLECTION(POINT EMPTY)");
+    auto g2 = wktreader.read("GEOMETRYCOLLECTION(POINT(1 0))");
+
+    ensure(g1 != nullptr && g2 != nullptr);
+    ensure_equals(g1->distance(g2.get()), 0);
+    ensure_equals(g2->distance(g1.get()), 0);
+}
+
+
 // TODO: finish the tests by adding:
 // 	LINESTRING - *all*
 // 	MULTILINESTRING - *all*
diff --git a/tests/xmltester/tests/general/TestDistance.xml b/tests/xmltester/tests/general/TestDistance.xml
index 4ce6d0fed..3835c919d 100644
--- a/tests/xmltester/tests/general/TestDistance.xml
+++ b/tests/xmltester/tests/general/TestDistance.xml
@@ -6,6 +6,7 @@
   <a>    POINT(10 10)  </a>
   <b>    POINT EMPTY  </b>
 <test><op name="distance" arg1="A" arg2="B">    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    0.0   </op></test>
 </case>
 
 <case>
@@ -13,6 +14,31 @@
   <a>    POINT(10 10)  </a>
   <b>    POINT (10 0)  </b>
 <test><op name="distance" arg1="A" arg2="B">    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    10.0   </op></test>
+</case>
+
+<case>
+  <desc>PP - point to multipoint</desc>
+  <a>    POINT(10 10)  </a>
+  <b>    MULTIPOINT ((10 0), (30 30))  </b>
+<test><op name="distance" arg1="A" arg2="B">    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    10.0   </op></test>
+</case>
+
+<case>
+  <desc>PP - point to multipoint with empty element</desc>
+  <a>    POINT(10 10)  </a>
+  <b>    MULTIPOINT ((10 0), EMPTY)  </b>
+<test><op name="distance" arg1="A" arg2="B">    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    10.0   </op></test>
+</case>
+
+<case>
+  <desc>LL - line to empty line</desc>
+  <a>    LINESTRING (0 0, 0 10)  </a>
+  <b>    LINESTRING EMPTY  </b>
+<test><op name="distance" arg1="A" arg2="B">    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    0.0   </op></test>
 </case>
 
 <case>
@@ -20,6 +46,31 @@
   <a>    LINESTRING (0 0, 0 10)  </a>
   <b>    LINESTRING (10 0, 10 10)  </b>
 <test><op name="distance" arg1="A" arg2="B">    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    10.0   </op></test>
+</case>
+
+<case>
+  <desc>LL - line to multiline</desc>
+  <a>    LINESTRING (0 0, 0 10)  </a>
+  <b>    MULTILINESTRING ((10 0, 10 10), (50 50, 60 60))  </b>
+<test><op name="distance" arg1="A" arg2="B">    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    10.0   </op></test>
+</case>
+
+<case>
+  <desc>LL - line to multiline with empty element</desc>
+  <a>    LINESTRING (0 0, 0 10)  </a>
+  <b>    MULTILINESTRING ((10 0, 10 10), EMPTY)  </b>
+<test><op name="distance" arg1="A" arg2="B">    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A">    10.0   </op></test>
+</case>
+
+<case>
+  <desc>PA - point to empty polygon</desc>
+  <a>    POINT (240 160)  </a>
+  <b>    POLYGON EMPTY  </b>
+<test><op name="distance" arg1="A" arg2="B" >    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    0.0   </op></test>
 </case>
 
 <case>
@@ -27,6 +78,7 @@
   <a>    POINT (240 160)  </a>
   <b>    POLYGON ((100 260, 340 180, 100 60, 180 160, 100 260))  </b>
 <test><op name="distance" arg1="A" arg2="B" >    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    0.0   </op></test>
 </case>
 
 <case>
@@ -34,6 +86,7 @@
   <a>    LINESTRING (40 300, 280 220, 60 160, 140 60)  </a>
   <b>    LINESTRING (140 360, 260 280, 240 120, 120 160)  </b>
 <test><op name="distance" arg1="A" arg2="B" >    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    0.0   </op></test>
 </case>
 
 <case>
@@ -41,6 +94,7 @@
   <a>    POLYGON ((60 260, 260 180, 100 60, 60 160, 60 260))  </a>
   <b>    POLYGON ((220 280, 120 160, 300 60, 360 220, 220 280))  </b>
 <test><op name="distance" arg1="A" arg2="B" >    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    0.0   </op></test>
 </case>
 
 <case>
@@ -48,6 +102,7 @@
   <a>    POLYGON ((100 320, 60 120, 240 180, 200 260, 100 320))  </a>
   <b>    POLYGON ((420 320, 280 260, 400 100, 420 320))  </b>
 <test><op name="distance" arg1="A" arg2="B" >   71.55417527999327  </op></test>
+<test><op name="distance" arg1="B" arg2="A" >   71.55417527999327  </op></test>
 </case>
 
 <case>
@@ -55,13 +110,23 @@
   <a>    MULTIPOLYGON (((40 240, 160 320, 40 380, 40 240)),   ((100 240, 240 60, 40 40, 100 240)))  </a>
   <b>    MULTIPOLYGON (((220 280, 120 160, 300 60, 360 220, 220 280)),   ((240 380, 280 300, 420 340, 240 380)))  </b>
 <test><op name="distance" arg1="A" arg2="B" >    0.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    0.0   </op></test>
 </case>
 
 <case>
-  <desc>mAmA - multipolygon with empty component</desc>
+  <desc>mAmA - multipolygon with empty element</desc>
   <a> MULTIPOLYGON (EMPTY, ((98 200, 200 200, 200 99, 98 99, 98 200))) </a>
   <b> POLYGON ((300 200, 400 200, 400 100, 300 100, 300 200)) </b>
 <test><op name="distance" arg1="A" arg2="B" >    100.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    100.0   </op></test>
+</case>
+
+<case>
+  <desc>GCGC - geometry collections with mixed dimensions</desc>
+  <a> GEOMETRYCOLLECTION (LINESTRING (10 10, 50 10), POINT (90 10)) </a>
+  <b> GEOMETRYCOLLECTION (POLYGON ((90 20, 60 20, 60 50, 90 50, 90 20)), LINESTRING (10 50, 30 70)) </b>
+<test><op name="distance" arg1="A" arg2="B" >    10.0   </op></test>
+<test><op name="distance" arg1="B" arg2="A" >    10.0   </op></test>
 </case>
 
 </run>

commit 5a9389e29aeea306c5af3f67f2a010657b393e1e
Author: Dan Baston <dbaston at gmail.com>
Date:   Mon Dec 12 19:00:48 2022 -0500

    PreparedLineStringIntersects: Fix incorrect result for mixed-dim GC with points (#774)

diff --git a/NEWS.md b/NEWS.md
index b137b3e8f..375dfbcaa 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -12,6 +12,7 @@
   - GEOSClipByRect: Fix case with POINT EMPTY (GH-913, Mike Taves)
   - Remove undefined behaviour in use of null PrecisionModel (GH-931, Jeff Walton)
   - Fix InteriorPointPoint to handle empty elements (GH-977, Martin Davis)
+  - PreparedLineStringIntersects: Fix incorrect result with mixed-dim collection with points (GH-774, Dan Baston)
 
 ## Changes in 3.11.2
 2023-03-16
diff --git a/include/geos/geom/Geometry.h b/include/geos/geom/Geometry.h
index 807ecbbe2..f225a802d 100644
--- a/include/geos/geom/Geometry.h
+++ b/include/geos/geom/Geometry.h
@@ -342,6 +342,11 @@ public:
     /// Returns the dimension of this Geometry (0=point, 1=line, 2=surface)
     virtual Dimension::DimensionType getDimension() const = 0; //Abstract
 
+    /// Checks whether any component of this geometry has dimension d
+    virtual bool hasDimension(Dimension::DimensionType d) const {
+        return getDimension() == d;
+    }
+
     /// Checks whether this Geometry consists only of components having dimension d.
     virtual bool isDimensionStrict(Dimension::DimensionType d) const {
         return d == getDimension();
diff --git a/include/geos/geom/GeometryCollection.h b/include/geos/geom/GeometryCollection.h
index b6cf4df8d..59c146018 100644
--- a/include/geos/geom/GeometryCollection.h
+++ b/include/geos/geom/GeometryCollection.h
@@ -109,6 +109,8 @@ public:
      */
     Dimension::DimensionType getDimension() const override;
 
+    bool hasDimension(Dimension::DimensionType d) const override;
+
     bool isDimensionStrict(Dimension::DimensionType d) const override;
 
     /// Returns coordinate dimension.
diff --git a/include/geos/geom/MultiLineString.h b/include/geos/geom/MultiLineString.h
index ec04b0745..81aa0805f 100644
--- a/include/geos/geom/MultiLineString.h
+++ b/include/geos/geom/MultiLineString.h
@@ -58,6 +58,10 @@ public:
     /// Returns line dimension (1)
     Dimension::DimensionType getDimension() const override;
 
+    bool hasDimension(Dimension::DimensionType d) const override {
+        return d == Dimension::L;
+    }
+
     bool isDimensionStrict(Dimension::DimensionType d) const override {
         return d == Dimension::L;
     }
diff --git a/include/geos/geom/MultiPoint.h b/include/geos/geom/MultiPoint.h
index 8bfaf9386..c586ca76b 100644
--- a/include/geos/geom/MultiPoint.h
+++ b/include/geos/geom/MultiPoint.h
@@ -63,6 +63,10 @@ public:
         return d == Dimension::P;
     }
 
+    bool hasDimension(Dimension::DimensionType d) const override {
+        return d == Dimension::P;
+    }
+
     /// Returns Dimension::False (Point has no boundary)
     int getBoundaryDimension() const override;
 
diff --git a/include/geos/geom/MultiPolygon.h b/include/geos/geom/MultiPolygon.h
index 365a4da50..6cdc0eb15 100644
--- a/include/geos/geom/MultiPolygon.h
+++ b/include/geos/geom/MultiPolygon.h
@@ -66,6 +66,10 @@ public:
     /// Returns surface dimension (2)
     Dimension::DimensionType getDimension() const override;
 
+    bool hasDimension(Dimension::DimensionType d) const override {
+        return d == Dimension::A;
+    }
+
     bool isDimensionStrict(Dimension::DimensionType d) const override {
         return d == Dimension::A;
     }
diff --git a/src/geom/GeometryCollection.cpp b/src/geom/GeometryCollection.cpp
index c278eea99..8675cef36 100644
--- a/src/geom/GeometryCollection.cpp
+++ b/src/geom/GeometryCollection.cpp
@@ -137,6 +137,15 @@ GeometryCollection::isDimensionStrict(Dimension::DimensionType d) const {
             });
 }
 
+bool
+GeometryCollection::hasDimension(Dimension::DimensionType d) const {
+    return std::any_of(geometries.begin(),
+                       geometries.end(),
+                       [&d](const std::unique_ptr<Geometry>& g) {
+        return g->hasDimension(d);
+    });
+}
+
 int
 GeometryCollection::getBoundaryDimension() const
 {
diff --git a/src/geom/prep/PreparedLineStringIntersects.cpp b/src/geom/prep/PreparedLineStringIntersects.cpp
index 810bb5f61..8933cf7d5 100644
--- a/src/geom/prep/PreparedLineStringIntersects.cpp
+++ b/src/geom/prep/PreparedLineStringIntersects.cpp
@@ -70,11 +70,6 @@ PreparedLineStringIntersects::intersects(const geom::Geometry* g) const
         return true;
     }
 
-    // For L/L case we are done
-    if(g->getDimension() == 1) {
-        return false;
-    }
-
     // For L/A case, need to check for proper inclusion of the target in the test
     if(g->getDimension() == 2
             &&	prepLine.isAnyTargetComponentInTest(g)) {
@@ -82,7 +77,7 @@ PreparedLineStringIntersects::intersects(const geom::Geometry* g) const
     }
 
     // For L/P case, need to check if any points lie on line(s)
-    if(g->getDimension() == 0) {
+    if(g->hasDimension(Dimension::P)) {
         return isAnyTestPointInTarget(g);
     }
 
diff --git a/tests/unit/geom/GeometryCollectionTest.cpp b/tests/unit/geom/GeometryCollectionTest.cpp
index 934af2d30..41477bb2f 100644
--- a/tests/unit/geom/GeometryCollectionTest.cpp
+++ b/tests/unit/geom/GeometryCollectionTest.cpp
@@ -154,4 +154,31 @@ void object::test<7>()
     ensure_equals(components.size(), 2u);
 }
 
+// Test of hasDimension()
+template<>
+template<>
+void object::test<8>
+()
+{
+    auto gc = readWKT("GEOMETRYCOLLECTION(POINT (1 1), LINESTRING (1 1, 2 2))");
+
+    ensure(gc->hasDimension(geos::geom::Dimension::P));
+    ensure(gc->hasDimension(geos::geom::Dimension::L));
+    ensure(!gc->hasDimension(geos::geom::Dimension::A));
+}
+
+
+// Test of hasDimension() for nested collection
+template<>
+template<>
+void object::test<9>
+()
+{
+    auto gc = readWKT("GEOMETRYCOLLECTION(POINT (1 1), GEOMETRYCOLLECTION(LINESTRING (1 1, 2 2), POLYGON((0 0, 0 1, 1 1, 0 0))))");
+
+    ensure(gc->hasDimension(geos::geom::Dimension::P));
+    ensure(gc->hasDimension(geos::geom::Dimension::L));
+    ensure(gc->hasDimension(geos::geom::Dimension::A));
+}
+
 } // namespace tut
diff --git a/tests/unit/geom/LineStringTest.cpp b/tests/unit/geom/LineStringTest.cpp
index 992188762..f94c37c03 100644
--- a/tests/unit/geom/LineStringTest.cpp
+++ b/tests/unit/geom/LineStringTest.cpp
@@ -573,6 +573,18 @@ void object::test<31>
 
 }
 
+// Test of hasDimension()
+template<>
+template<>
+void object::test<32>
+()
+{
+    auto line = reader_.read<geos::geom::LineString>("LINESTRING (0 0, 10 10)");
+
+    ensure(!line->hasDimension(geos::geom::Dimension::P));
+    ensure(line->hasDimension(geos::geom::Dimension::L));
+    ensure(!line->hasDimension(geos::geom::Dimension::A));
+}
 
 } // namespace tut
 
diff --git a/tests/unit/geom/MultiLineStringTest.cpp b/tests/unit/geom/MultiLineStringTest.cpp
index 9e238be25..7e7433a9d 100644
--- a/tests/unit/geom/MultiLineStringTest.cpp
+++ b/tests/unit/geom/MultiLineStringTest.cpp
@@ -63,5 +63,18 @@ void object::test<3>
     ensure(!mls_->isDimensionStrict(geos::geom::Dimension::A));
 }
 
+
+// Test of hasDimension()
+template<>
+template<>
+void object::test<4>
+()
+{
+    ensure(!mls_->hasDimension(geos::geom::Dimension::P));
+    ensure(mls_->hasDimension(geos::geom::Dimension::L));
+    ensure(!mls_->hasDimension(geos::geom::Dimension::A));
+}
+
+
 } // namespace tut
 
diff --git a/tests/unit/geom/MultiPointTest.cpp b/tests/unit/geom/MultiPointTest.cpp
index 24fae37f8..3f5c10373 100644
--- a/tests/unit/geom/MultiPointTest.cpp
+++ b/tests/unit/geom/MultiPointTest.cpp
@@ -417,5 +417,16 @@ void object::test<31>
     ensure(!empty_mp_->isDimensionStrict(geos::geom::Dimension::L));
 }
 
+// Test of hasDimension()
+template<>
+template<>
+void object::test<32>
+()
+{
+    ensure(mp_->hasDimension(geos::geom::Dimension::P));
+    ensure(!mp_->hasDimension(geos::geom::Dimension::L));
+    ensure(!mp_->hasDimension(geos::geom::Dimension::A));
+}
+
 } // namespace tut
 
diff --git a/tests/unit/geom/MultiPolygonTest.cpp b/tests/unit/geom/MultiPolygonTest.cpp
index 1ff9f8cd3..efe46919c 100644
--- a/tests/unit/geom/MultiPolygonTest.cpp
+++ b/tests/unit/geom/MultiPolygonTest.cpp
@@ -62,4 +62,15 @@ void object::test<3>
     ensure(!empty_mp_->isDimensionStrict(geos::geom::Dimension::L));
 }
 
+// Test of hasDimension()
+template<>
+template<>
+void object::test<4>
+()
+{
+    ensure(!mp_->hasDimension(geos::geom::Dimension::P));
+    ensure(!mp_->hasDimension(geos::geom::Dimension::L));
+    ensure(mp_->hasDimension(geos::geom::Dimension::A));
+}
+
 } // namespace tut
diff --git a/tests/unit/geom/PointTest.cpp b/tests/unit/geom/PointTest.cpp
index 75ed26259..140cfed57 100644
--- a/tests/unit/geom/PointTest.cpp
+++ b/tests/unit/geom/PointTest.cpp
@@ -17,6 +17,7 @@
 #include <memory>
 #include <string>
 
+constexpr int MAX_TESTS = 100;
 
 namespace tut {
 //
@@ -58,7 +59,7 @@ struct test_point_data {
     }
 };
 
-typedef test_group<test_point_data> group;
+typedef test_group<test_point_data, MAX_TESTS> group;
 typedef group::object object;
 
 group test_point_group("geos::geom::Point");
@@ -600,5 +601,16 @@ void object::test<46>
     ensure("point->getCoordinateDimension() == 2", point->getCoordinateDimension() == 2);
 }
 
+// Test of hasDimension()
+template<>
+template<>
+void object::test<47>
+()
+{
+    ensure(point_->hasDimension(geos::geom::Dimension::P));
+    ensure(!point_->hasDimension(geos::geom::Dimension::L));
+    ensure(!point_->hasDimension(geos::geom::Dimension::A));
+}
+
 } // namespace tut
 
diff --git a/tests/unit/geom/PolygonTest.cpp b/tests/unit/geom/PolygonTest.cpp
index f3b4ae20b..ab1fdc501 100644
--- a/tests/unit/geom/PolygonTest.cpp
+++ b/tests/unit/geom/PolygonTest.cpp
@@ -652,4 +652,15 @@ void object::test<44>()
     ensure_equals(holes.size(), 1u);
 }
 
+// Test of hasDimension()
+template<>
+template<>
+void object::test<45>
+()
+{
+    ensure(!poly_->hasDimension(geos::geom::Dimension::P));
+    ensure(!poly_->hasDimension(geos::geom::Dimension::L));
+    ensure(poly_->hasDimension(geos::geom::Dimension::A));
+}
+
 } // namespace tut
diff --git a/tests/xmltester/tests/general/TestPreparedPredicatesWithGeometryCollection.xml b/tests/xmltester/tests/general/TestPreparedPredicatesWithGeometryCollection.xml
index 9ea382193..a1092a0da 100644
--- a/tests/xmltester/tests/general/TestPreparedPredicatesWithGeometryCollection.xml
+++ b/tests/xmltester/tests/general/TestPreparedPredicatesWithGeometryCollection.xml
@@ -76,6 +76,17 @@
 <test>  <op name="intersects"     arg1="A" arg2="B">   true  </op> </test>
 </case>
 
+<case>
+  <desc>LineString against GC, with point at endpoint
+  </desc>
+  <a>
+  LINESTRING (0 0, 1 1)
+  </a>
+  <b>
+    GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (2 2, 3 3))
+  </b>
+<test>  <op name="intersects"     arg1="A" arg2="B">   true  </op> </test>
+</case>
 
 
 </run>

commit 43809f000a84970a4db445d245d4827331d8862e
Author: Martin Davis <mtnclimb at gmail.com>
Date:   Sun Oct 29 08:34:38 2023 -0700

    UIpdate NEWS

diff --git a/NEWS.md b/NEWS.md
index 9bc02788d..b137b3e8f 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -11,6 +11,7 @@
   - OffsetCurve: add minimum threshold for quadsegs (GH-897, Martin Davis, Paul Ramsey)
   - GEOSClipByRect: Fix case with POINT EMPTY (GH-913, Mike Taves)
   - Remove undefined behaviour in use of null PrecisionModel (GH-931, Jeff Walton)
+  - Fix InteriorPointPoint to handle empty elements (GH-977, Martin Davis)
 
 ## Changes in 3.11.2
 2023-03-16

commit b376f0f4d81503574803e55aa7856759af7c44d7
Author: Martin Davis <mtnclimb at gmail.com>
Date:   Sun Oct 29 08:26:44 2023 -0700

    Fix InteriorPointPoint to handle empty elements (#977)

diff --git a/src/algorithm/InteriorPointPoint.cpp b/src/algorithm/InteriorPointPoint.cpp
index 6e52fb5b1..2fc90e0c5 100644
--- a/src/algorithm/InteriorPointPoint.cpp
+++ b/src/algorithm/InteriorPointPoint.cpp
@@ -47,6 +47,9 @@ InteriorPointPoint::InteriorPointPoint(const Geometry* g)
 void
 InteriorPointPoint::add(const Geometry* geom)
 {
+    if (geom->isEmpty())
+        return;
+
     const Point* po = dynamic_cast<const Point*>(geom);
     if (po) {
         add(po->getCoordinate());
diff --git a/tests/xmltester/tests/general/TestInteriorPoint.xml b/tests/xmltester/tests/general/TestInteriorPoint.xml
index 0d765caca..23b4a8705 100644
--- a/tests/xmltester/tests/general/TestInteriorPoint.xml
+++ b/tests/xmltester/tests/general/TestInteriorPoint.xml
@@ -14,12 +14,19 @@
 </case>
 
 <case>
-  <desc>P - single point</desc>
+  <desc>P - multipoint</desc>
   <a>    MULTIPOINT ((60 300), (200 200), (240 240), (200 300), (40 140), (80 240), (140 240), (100 160), (140 200), (60 200))
 	</a>
 <test><op name="getInteriorPoint" arg1="A" >    POINT (140 240)   </op></test>
 </case>
 
+<case>
+  <desc>P - multipoint with EMPTY</desc>
+  <a>    MULTIPOINT((0 0), EMPTY)
+	</a>
+<test><op name="getInteriorPoint" arg1="A" >    POINT (0 0)   </op></test>
+</case>
+
 <case>
   <desc>L - linestring with single segment</desc>
   <a>    LINESTRING (0 0, 7 14)

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

Summary of changes:
 NEWS.md                                            |  3 +
 include/geos/geom/Geometry.h                       |  5 ++
 include/geos/geom/GeometryCollection.h             |  2 +
 include/geos/geom/MultiLineString.h                |  4 ++
 include/geos/geom/MultiPoint.h                     |  4 ++
 include/geos/geom/MultiPolygon.h                   |  4 ++
 src/algorithm/InteriorPointPoint.cpp               |  3 +
 src/geom/GeometryCollection.cpp                    |  9 +++
 src/geom/prep/PreparedLineStringIntersects.cpp     |  7 +--
 src/operation/distance/DistanceOp.cpp              | 16 +++--
 tests/unit/geom/GeometryCollectionTest.cpp         | 27 +++++++++
 tests/unit/geom/LineStringTest.cpp                 | 12 ++++
 tests/unit/geom/MultiLineStringTest.cpp            | 13 +++++
 tests/unit/geom/MultiPointTest.cpp                 | 11 ++++
 tests/unit/geom/MultiPolygonTest.cpp               | 11 ++++
 tests/unit/geom/PointTest.cpp                      | 14 ++++-
 tests/unit/geom/PolygonTest.cpp                    | 11 ++++
 tests/unit/operation/distance/DistanceOpTest.cpp   | 68 ++++++++++++++++++++++
 tests/xmltester/tests/general/TestDistance.xml     | 67 ++++++++++++++++++++-
 .../xmltester/tests/general/TestInteriorPoint.xml  |  9 ++-
 ...estPreparedPredicatesWithGeometryCollection.xml | 11 ++++
 21 files changed, 297 insertions(+), 14 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list