[geos-commits] [SCM] GEOS branch master updated. dddda853c784296ba9f3742e1659e8140c0e8a33

git at osgeo.org git at osgeo.org
Tue Nov 27 15:38:44 PST 2018


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, master has been updated
       via  dddda853c784296ba9f3742e1659e8140c0e8a33 (commit)
      from  a1d4d13b81f340bfebe80a9891353b04029b3c4a (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 dddda853c784296ba9f3742e1659e8140c0e8a33
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Tue Nov 27 15:37:45 2018 -0800

    Harmonize with JTS isSimple behaviour for GeometryCollection
    and Polygons, which is that an area with non-simple rings
    is itself non-simple, and a collection with a non-simple
    component is non-simple.

diff --git a/include/geos/geom/LinearRing.h b/include/geos/geom/LinearRing.h
index 0b1cebf..085b3ea 100644
--- a/include/geos/geom/LinearRing.h
+++ b/include/geos/geom/LinearRing.h
@@ -97,16 +97,6 @@ public:
 	 */
 	int getBoundaryDimension() const override;
 
-	/** \brief
-	 * Returns <code>true</code>, since by definition LinearRings
-	 * are always simple.
-	 *
-	 * @return <code>true</code>
-	 *
-	 * @see Geometry::isSimple
-	 */
-	bool isSimple() const override;
-
 	bool isClosed() const override;
 
 	std::string getGeometryType() const override;
diff --git a/include/geos/geom/MultiPolygon.h b/include/geos/geom/MultiPolygon.h
index 9aaae1a..9f91393 100644
--- a/include/geos/geom/MultiPolygon.h
+++ b/include/geos/geom/MultiPolygon.h
@@ -83,8 +83,6 @@ public:
 
 	GeometryTypeId getGeometryTypeId() const override;
 
-	bool isSimple() const override;
-
 	bool equalsExact(const Geometry *other, double tolerance=0) const override;
 
 	Geometry *clone() const override;
diff --git a/include/geos/geom/Polygon.h b/include/geos/geom/Polygon.h
index eb15715..a62bd47 100644
--- a/include/geos/geom/Polygon.h
+++ b/include/geos/geom/Polygon.h
@@ -106,14 +106,6 @@ public:
 
 	bool isEmpty() const override;
 
-	/** \brief
-	 * Tests if a valid polygon is simple.
-	 * This method always returns true, since a valid polygon is always simple
-	 *
-	 * @return <code>true</code>
-	 */
-	bool isSimple() const override;
-
 	/// Returns the exterior ring (shell)
 	const LineString* getExteriorRing() const;
 
@@ -132,6 +124,8 @@ public:
 	void apply_ro(GeometryFilter *filter) const override;
 	void apply_rw(CoordinateSequenceFilter& filter) override;
 	void apply_ro(CoordinateSequenceFilter& filter) const override;
+	void apply_rw(GeometryComponentFilter *filter) override;
+	void apply_ro(GeometryComponentFilter *filter) const override;
 
 	Geometry* convexHull() const override;
 
@@ -148,10 +142,6 @@ public:
  	/// Returns the perimeter of this <code>Polygon</code>
 	double getLength() const override;
 
-	void apply_rw(GeometryComponentFilter *filter) override;
-
-	void apply_ro(GeometryComponentFilter *filter) const override;
-
 	bool isRectangle() const override;
 
 protected:
diff --git a/include/geos/operation/IsSimpleOp.h b/include/geos/operation/IsSimpleOp.h
index 8375e25..ccc2bca 100644
--- a/include/geos/operation/IsSimpleOp.h
+++ b/include/geos/operation/IsSimpleOp.h
@@ -39,9 +39,12 @@ namespace geos {
 	}
 	namespace geom {
 		class LineString;
+		class LinearRing;
 		class MultiLineString;
 		class MultiPoint;
 		class Geometry;
+		class Polygon;
+		class GeometryCollection;
 		struct CoordinateLessThen;
 	}
 	namespace geomgraph {
@@ -193,6 +196,10 @@ private:
 	 */
 	bool hasClosedEndpointIntersection(geomgraph::GeometryGraph &graph);
 
+	bool computeSimple(const geom::Geometry *geom);
+  bool isSimplePolygonal(const geom::Geometry *geom);
+	bool isSimpleGeometryCollection(const geom::GeometryCollection *col);
+
 	/**
 	 * Add an endpoint to the map, creating an entry for it if none exists
 	 */
diff --git a/src/geom/Geometry.cpp b/src/geom/Geometry.cpp
index 1ceb813..571520a 100644
--- a/src/geom/Geometry.cpp
+++ b/src/geom/Geometry.cpp
@@ -861,7 +861,6 @@ Geometry::apply_rw(GeometryComponentFilter *filter)
 bool
 Geometry::isSimple() const
 {
-	checkNotGeometryCollection(this);
 	operation::IsSimpleOp op(*this);
 	return op.isSimple();
 }
diff --git a/src/geom/LinearRing.cpp b/src/geom/LinearRing.cpp
index e74e795..01e10f3 100644
--- a/src/geom/LinearRing.cpp
+++ b/src/geom/LinearRing.cpp
@@ -92,12 +92,6 @@ LinearRing::getBoundaryDimension() const
 }
 
 bool
-LinearRing::isSimple() const
-{
-	return true;
-}
-
-bool
 LinearRing::isClosed() const
 {
 	if ( points->isEmpty() ) {
diff --git a/src/geom/MultiPolygon.cpp b/src/geom/MultiPolygon.cpp
index 5ed93a5..84fce6a 100644
--- a/src/geom/MultiPolygon.cpp
+++ b/src/geom/MultiPolygon.cpp
@@ -60,10 +60,6 @@ string MultiPolygon::getGeometryType() const {
 	return "MultiPolygon";
 }
 
-bool MultiPolygon::isSimple() const {
-	return true;
-}
-
 Geometry* MultiPolygon::getBoundary() const {
 	if (isEmpty()) {
 		return getFactory()->createMultiLineString();
diff --git a/src/geom/Polygon.cpp b/src/geom/Polygon.cpp
index 90028fe..85082c7 100644
--- a/src/geom/Polygon.cpp
+++ b/src/geom/Polygon.cpp
@@ -175,12 +175,6 @@ Polygon::isEmpty() const
 	return shell->isEmpty();
 }
 
-bool
-Polygon::isSimple() const
-{
-	return true;
-}
-
 const LineString*
 Polygon::getExteriorRing() const
 {
diff --git a/src/operation/IsSimpleOp.cpp b/src/operation/IsSimpleOp.cpp
index c279636..614a6dc 100644
--- a/src/operation/IsSimpleOp.cpp
+++ b/src/operation/IsSimpleOp.cpp
@@ -29,8 +29,12 @@
 #include <geos/geom/Geometry.h>
 #include <geos/geom/MultiPoint.h>
 #include <geos/geom/MultiLineString.h>
+#include <geos/geom/Polygon.h>
+#include <geos/geom/LinearRing.h>
 #include <geos/geom/Point.h>
+#include <geos/geom/GeometryCollection.h>
 #include <geos/geom/Coordinate.h>
+#include <geos/geom/util/LinearComponentExtracter.h>
 
 #include <set>
 #include <cassert>
@@ -40,6 +44,7 @@ using namespace geos::algorithm;
 using namespace geos::geomgraph;
 using namespace geos::geomgraph::index;
 using namespace geos::geom;
+using namespace geos::geom::util;
 
 namespace geos {
 namespace operation { // geos.operation
@@ -107,18 +112,7 @@ bool
 IsSimpleOp::isSimple()
 {
 	nonSimpleLocation.reset();
-
-	if ( dynamic_cast<const LineString*>(geom) )
-		return isSimpleLinearGeometry(geom);
-
-	if ( dynamic_cast<const MultiLineString*>(geom) )
-		return isSimpleLinearGeometry(geom);
-
-	const MultiPoint* mp = dynamic_cast<const MultiPoint*>(geom);
-	if ( mp ) return isSimpleMultiPoint(*mp);
-
-	// all other geometry types are simple by definition
-	return true;
+	return computeSimple(geom);
 }
 
 
@@ -171,7 +165,7 @@ IsSimpleOp::isSimpleLinearGeometry(const Geometry *p_geom)
 	if (p_geom->isEmpty()) return true;
 	GeometryGraph graph(0,p_geom);
 	LineIntersector li;
-	std::unique_ptr<SegmentIntersector> si (graph.computeSelfNodes(&li,true));
+	std::unique_ptr<SegmentIntersector> si(graph.computeSelfNodes(&li,true));
 
 	// if no self-intersection, must be simple
 	if (!si->hasIntersection()) return true;
@@ -220,6 +214,65 @@ IsSimpleOp::hasNonEndpointIntersection(GeometryGraph &graph)
 
 /*private*/
 bool
+IsSimpleOp::computeSimple(const geom::Geometry *geom)
+{
+	nonSimpleLocation.reset();
+
+	if (dynamic_cast<const LineString*>(geom))
+		return isSimpleLinearGeometry(geom);
+
+	if (dynamic_cast<const LinearRing*>(geom))
+		return isSimpleLinearGeometry(geom);
+
+	if (dynamic_cast<const MultiLineString*>(geom))
+		return isSimpleLinearGeometry(geom);
+
+	if (dynamic_cast<const Polygon*>(geom))
+		return isSimplePolygonal(geom);
+
+	const MultiPoint* mp = dynamic_cast<const MultiPoint*>(geom);
+	if (mp) return isSimpleMultiPoint(*mp);
+
+	// This must be after MultiPoint test, as MultiPoint can
+	// cast cleanly into GeometryCollection
+	const GeometryCollection* gc = dynamic_cast<const GeometryCollection*>(geom);
+	if (gc)
+		return isSimpleGeometryCollection(gc);
+
+	// all other geometry types are simple by definition
+	return true;
+}
+
+/*private*/
+bool
+IsSimpleOp::isSimpleGeometryCollection(const geom::GeometryCollection *col)
+{
+	GeometryCollection::const_iterator it;
+	for (it = col->begin(); it < col->end(); ++it)
+	{
+		const geom::Geometry *geom = *it;
+		if (!computeSimple(geom)) return false;
+	}
+	return true;
+}
+
+/*private*/
+bool
+IsSimpleOp::isSimplePolygonal(const geom::Geometry *geom)
+{
+
+	LineString::ConstVect rings;
+	LinearComponentExtracter::getLines(*geom, rings);
+	for (const geom::LineString *ring : rings)
+	{
+			if(!isSimpleLinearGeometry(ring))
+				return false;
+	}
+	return true;
+}
+
+/*private*/
+bool
 IsSimpleOp::hasClosedEndpointIntersection(GeometryGraph &graph)
 {
 	map<const Coordinate*,EndpointInfo*,CoordinateLessThen> endPoints;
diff --git a/tests/unit/geom/GeometryFactoryTest.cpp b/tests/unit/geom/GeometryFactoryTest.cpp
index bc83067..bb127d8 100644
--- a/tests/unit/geom/GeometryFactoryTest.cpp
+++ b/tests/unit/geom/GeometryFactoryTest.cpp
@@ -811,18 +811,6 @@ reader_(factory_.get())
 		ensure( "createGeometryCollection() returned null pointer.", col != nullptr );
 		ensure( col->isEmpty() );
 		ensure( col->isValid() );
-
-		try
-		{
-			ensure( !col->isSimple() );
-			fail("IllegalArgumentException expected");
-		}
-		catch ( geos::util::IllegalArgumentException const& e )
-		{
-			const char* msg = e.what(); // ok
-			ensure( msg != nullptr );
-		}
-
 		ensure( col->getCentroid() == nullptr );
 		ensure_equals( col->getGeometryTypeId(), geos::geom::GEOS_GEOMETRYCOLLECTION );
 		ensure_equals( col->getDimension(), geos::geom::Dimension::False );
diff --git a/tests/xmltester/tests/general/TestSimple.xml b/tests/xmltester/tests/general/TestSimple.xml
index eca2f4b..a21bbbd 100644
--- a/tests/xmltester/tests/general/TestSimple.xml
+++ b/tests/xmltester/tests/general/TestSimple.xml
@@ -242,9 +242,9 @@
 </case>
 
 <case>
-  <desc>A</desc>
+  <desc>LR - valid ring</desc>
   <a>
-    POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260))
+    LINEARRING (100 300, 200 300, 200 200, 100 200, 100 300)
   </a>
 <test>
   <op name="isSimple" arg1="A">
@@ -254,28 +254,57 @@
 </case>
 
 <case>
-  <desc>A - empty</desc>
+  <desc>LR - ring with self-intersection</desc>
   <a>
-    POLYGON EMPTY
+    LINEARRING (100 300, 200 300, 100 200, 200 200, 100 300)
   </a>
 <test>
   <op name="isSimple" arg1="A">
-    true
+    false
   </op>
 </test>
 </case>
 
 <case>
-  <desc>mA</desc>
+  <desc>A - valid polygon</desc>
+  <a>
+    POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260))
+  </a>
+<test>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>A - invalid bowtie polygon</desc>
+  <a>
+    POLYGON ((100 100, 100 200, 200 100, 200 200, 100 100))
+  </a>
+<test>
+  <op name="isSimple" arg1="A"> false </op>
+</test>
+</case>
+
+
+<case>
+  <desc>A - empty</desc>
+  <a>
+    POLYGON EMPTY
+  </a>
+<test>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>mA - valid polygon</desc>
   <a>
     MULTIPOLYGON (((240 160, 140 220, 80 60, 220 40, 240 160)), 
   ((160 380, 100 240, 20 380, 160 380), 
     (120 340, 60 360, 80 320, 120 340)))
   </a>
 <test>
-  <op name="isSimple" arg1="A">
-    true
-  </op>
+  <op name="isSimple" arg1="A"> true </op>
 </test>
 </case>
 
@@ -287,9 +316,41 @@
     (120 340, 60 360, 80 320, 120 340)))
   </a>
 <test>
-  <op name="isSimple" arg1="A">
-    true
-  </op>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>mA - with an invalid bowtie element</desc>
+  <a>
+MULTIPOLYGON (((100 100, 100 200, 200 100, 200 200, 100 100)), ((100 400, 200 400, 200 300, 100 300, 100 400)))
+</a>
+<test>
+  <op name="isSimple" arg1="A"> false </op>
+</test>
+</case>
+
+<case>
+  <desc>GC - all components simple</desc>
+  <a>
+GEOMETRYCOLLECTION (POLYGON ((100 200, 200 200, 200 100, 100 100, 100 200)), 
+  LINESTRING (100 300, 200 250), 
+  POINT (250 250), 
+  POINT (250 150))</a>
+<test>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>GC - one non-simple component</desc>
+  <a>
+GEOMETRYCOLLECTION (POLYGON ((100 100, 100 200, 200 100, 200 200, 100 100)), 
+  LINESTRING (100 300, 200 250), 
+  POINT (250 250), 
+  POINT (250 150))</a>
+<test>
+  <op name="isSimple" arg1="A"> false </op>
 </test>
 </case>
 

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

Summary of changes:
 include/geos/geom/LinearRing.h               | 10 ----
 include/geos/geom/MultiPolygon.h             |  2 -
 include/geos/geom/Polygon.h                  | 14 +----
 include/geos/operation/IsSimpleOp.h          |  7 +++
 src/geom/Geometry.cpp                        |  1 -
 src/geom/LinearRing.cpp                      |  6 --
 src/geom/MultiPolygon.cpp                    |  4 --
 src/geom/Polygon.cpp                         |  6 --
 src/operation/IsSimpleOp.cpp                 | 79 +++++++++++++++++++++-----
 tests/unit/geom/GeometryFactoryTest.cpp      | 12 ----
 tests/xmltester/tests/general/TestSimple.xml | 85 ++++++++++++++++++++++++----
 11 files changed, 148 insertions(+), 78 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list