[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