[geos-commits] r3534 - in trunk: include/geos/operation/union src/operation/union tests/xmltester tests/xmltester/tests/general

svn_geos at osgeo.org svn_geos at osgeo.org
Fri Dec 9 03:48:04 EST 2011


Author: strk
Date: 2011-12-09 00:48:04 -0800 (Fri, 09 Dec 2011)
New Revision: 3534

Added:
   trunk/tests/xmltester/tests/general/TestUnaryUnionFloating.xml
Modified:
   trunk/include/geos/operation/union/CascadedPolygonUnion.h
   trunk/src/operation/union/CascadedPolygonUnion.cpp
   trunk/tests/xmltester/Makefile.am
   trunk/tests/xmltester/tests/general/TestUnaryUnion.xml
Log:
Fix CascadedPolygonUnion to discard non-polygonal components created during unioning

This is to avoid failures and provide more desirable behaviour.
Includes automated testing. Closes ticket #499.

Modified: trunk/include/geos/operation/union/CascadedPolygonUnion.h
===================================================================
--- trunk/include/geos/operation/union/CascadedPolygonUnion.h	2011-12-09 08:47:27 UTC (rev 3533)
+++ trunk/include/geos/operation/union/CascadedPolygonUnion.h	2011-12-09 08:48:04 UTC (rev 3534)
@@ -13,7 +13,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/union/CascadedPolygonUnion.java r320 (JTS-1.12)
+ * Last port: operation/union/CascadedPolygonUnion.java r487 (JTS-1.12+)
  *
  **********************************************************************/
 
@@ -24,6 +24,7 @@
 
 #include <vector>
 #include <algorithm>
+#include <memory>
 
 #include "GeometryListHolder.h"
 
@@ -81,6 +82,22 @@
      */
     static int const STRTREE_NODE_CAPACITY = 4;
 
+    /**
+     * Computes a {@link Geometry} containing only {@link Polygonal} components.
+     *
+     * Extracts the {@link Polygon}s from the input
+     * and returns them as an appropriate {@link Polygonal} geometry.
+     * 
+     * If the input is already <tt>Polygonal</tt>, it is returned unchanged.
+     *
+     * A particular use case is to filter out non-polygonal components
+     * returned from an overlay operation.
+     *
+     * @param g the geometry to filter
+     * @return a Polygonal geometry
+     */
+    static std::auto_ptr<geom::Geometry> restrictToPolygons(std::auto_ptr<geom::Geometry> g);
+
 public:
     CascadedPolygonUnion();
 
@@ -154,9 +171,9 @@
      * Unions a section of a list using a recursive binary union on each half
      * of the section.
      * 
-     * @param geoms
-     * @param start
-     * @param end
+     * @param geoms the list of geometries containing the section to union
+     * @param start the start index of the section
+     * @param end the index after the end of the section
      * @return the union of the list section
      */
     geom::Geometry* binaryUnion(GeometryListHolder* geoms, std::size_t start, 
@@ -185,7 +202,10 @@
     geom::Geometry* unionOptimized(geom::Geometry* g0, geom::Geometry* g1);
 
     /**
-     * Unions two polygonal geometries.
+     * \brief
+     * Unions two polygonal geometries, restricting computation
+     * to the envelope intersection where possible.
+     *
      * The case of MultiPolygons is optimized to union only 
      * the polygons which lie in the intersection of the two geometry's
      * envelopes.

Modified: trunk/src/operation/union/CascadedPolygonUnion.cpp
===================================================================
--- trunk/src/operation/union/CascadedPolygonUnion.cpp	2011-12-09 08:47:27 UTC (rev 3533)
+++ trunk/src/operation/union/CascadedPolygonUnion.cpp	2011-12-09 08:48:04 UTC (rev 3534)
@@ -13,7 +13,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/union/CascadedPolygonUnion.java r320 (JTS-1.12)
+ * Last port: operation/union/CascadedPolygonUnion.java r487 (JTS-1.12+)
  *
  **********************************************************************/
 
@@ -23,6 +23,7 @@
 #include <geos/geom/Polygon.h>
 #include <geos/geom/MultiPolygon.h>
 #include <geos/geom/util/GeometryCombiner.h>
+#include <geos/geom/util/PolygonExtracter.h>
 #include <geos/index/strtree/STRtree.h>
 // std
 #include <cassert>
@@ -211,9 +212,38 @@
 geom::Geometry* 
 CascadedPolygonUnion::unionActual(geom::Geometry* g0, geom::Geometry* g1)
 {
-    return g0->Union(g1);
+    return restrictToPolygons(std::auto_ptr<geom::Geometry>(g0->Union(g1))).release();
 }
 
+std::auto_ptr<geom::Geometry>
+CascadedPolygonUnion::restrictToPolygons(std::auto_ptr<geom::Geometry> g)
+{
+    using namespace geom;
+    using namespace std;
+
+    if ( dynamic_cast<Polygonal*>(g.get()) ) {
+      return g;
+    }
+
+    Polygon::ConstVect polygons;
+    util::PolygonExtracter::getPolygons(*g, polygons);
+
+    if (polygons.size() == 1)
+      return std::auto_ptr<Geometry>(polygons[0]->clone());
+
+    typedef vector<Geometry *> GeomVect;
+
+    Polygon::ConstVect::size_type n = polygons.size();
+    GeomVect* newpolys = new GeomVect(n);
+    for (Polygon::ConstVect::size_type i=0; i<n; ++i) {
+        (*newpolys)[i] = polygons[i]->clone();
+    }
+    return auto_ptr<Geometry>(
+      g->getFactory()->createMultiPolygon(newpolys)
+    );
+
+}
+
 } // namespace geos.operation.union
 } // namespace geos.operation
 } // namespace geos

Modified: trunk/tests/xmltester/Makefile.am
===================================================================
--- trunk/tests/xmltester/Makefile.am	2011-12-09 08:47:27 UTC (rev 3533)
+++ trunk/tests/xmltester/Makefile.am	2011-12-09 08:48:04 UTC (rev 3534)
@@ -61,6 +61,7 @@
 	$(srcdir)/tests/general/TestRelatePP.xml \
 	$(srcdir)/tests/general/TestSimple.xml \
 	$(srcdir)/tests/general/TestUnaryUnion.xml \
+	$(srcdir)/tests/general/TestUnaryUnionFloating.xml \
 	$(srcdir)/tests/general/TestValid.xml \
 	$(srcdir)/tests/general/TestValid2.xml \
 	$(srcdir)/tests/general/TestValid2-big.xml \

Modified: trunk/tests/xmltester/tests/general/TestUnaryUnion.xml
===================================================================
--- trunk/tests/xmltester/tests/general/TestUnaryUnion.xml	2011-12-09 08:47:27 UTC (rev 3533)
+++ trunk/tests/xmltester/tests/general/TestUnaryUnion.xml	2011-12-09 08:48:04 UTC (rev 3534)
@@ -151,8 +151,7 @@
   </a>
   <test>
     <op name="union" arg1="A">
-    	GEOMETRYCOLLECTION (LINESTRING (0 0, 20 0), 
-  POLYGON ((150 0, 20 0, 20 100, 180 100, 180 0, 150 0)))
+  POLYGON ((150 0, 20 0, 20 100, 180 100, 180 0, 150 0))
     </op>
   </test>
 </case>

Added: trunk/tests/xmltester/tests/general/TestUnaryUnionFloating.xml
===================================================================
--- trunk/tests/xmltester/tests/general/TestUnaryUnionFloating.xml	                        (rev 0)
+++ trunk/tests/xmltester/tests/general/TestUnaryUnionFloating.xml	2011-12-09 08:48:04 UTC (rev 3534)
@@ -0,0 +1,20 @@
+<run>
+  <desc>Tests for Geometry.union() method (unary union) with floating precision</desc>
+
+<case>
+  <desc>mP - showing that non-polygonal components are discarded correctly</desc>
+  <a>
+  GEOMETRYCOLLECTION (
+    POLYGON ((-3 -2, 700 900, -6 900, -3 -2)),
+    POLYGON((700 900, -1.6859349853697 899.55, 0.3 -0.4, 700 900)),
+    POLYGON ((700 860, 700 899.5, -1.68593498537 899.55, 700 860))
+    )
+  </a>
+<test>
+  <op name="union" arg1="A">
+    POLYGON ((0.2942036115049298 2.226702215615205, -3 -2, -6 900, 700 900, 699.6114719806972 899.5000276853219, 700 899.5, 700 860, 670.2204017222961 861.6785046602191, 0.3 -0.4, 0.2942036115049298 2.226702215615205))
+  </op>
+</test>
+</case>
+
+</run>



More information about the geos-commits mailing list