[geos-commits] [SCM] GEOS branch 3.7 updated. 6f305213fd544d21a09d5c802d8ac82cef576687

git at osgeo.org git at osgeo.org
Wed Aug 21 13:02:02 PDT 2019


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.7 has been updated
       via  6f305213fd544d21a09d5c802d8ac82cef576687 (commit)
      from  e1399c268db52c43b1c55df582e12c6c93cd44b2 (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 6f305213fd544d21a09d5c802d8ac82cef576687
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Wed Aug 21 13:01:28 2019 -0700

    Port fix to regression in union algorithm from master

diff --git a/NEWS b/NEWS
index 59788c3..97cbdd9 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,7 @@ Changes in 3.7.3dev
 2019-XX-XX
 
 - Bug fixes / improvements
-  -
+  - Union performance regression (#867 Paul Ramsey)
 
 
 Changes in 3.7.2
diff --git a/src/operation/union/CascadedPolygonUnion.cpp b/src/operation/union/CascadedPolygonUnion.cpp
index 56b43c4..23a1aaf 100644
--- a/src/operation/union/CascadedPolygonUnion.cpp
+++ b/src/operation/union/CascadedPolygonUnion.cpp
@@ -260,7 +260,7 @@ CascadedPolygonUnion::unionUsingEnvelopeIntersection(geom::Geometry* g0,
     check_valid(*g1Int, "unionUsingEnvelopeIntersection g1Int");
 #endif
 
-    std::unique_ptr<geom::Geometry> u(unionActual(g0Int.get(), g1Int.get()));
+    std::unique_ptr<geom::Geometry> unionCommon(unionActual(g0Int.get(), g1Int.get()));
 
 #if GEOS_DEBUG_CASCADED_UNION
     if ( ! check_valid(*u, "unionUsingEnvelopeIntersection unionActual return") )
@@ -278,7 +278,7 @@ CascadedPolygonUnion::unionUsingEnvelopeIntersection(geom::Geometry* g0,
     }
 #endif
 
-    if ( disjointPolys.empty() ) return u.release();
+    if ( disjointPolys.empty() ) return unionCommon.release();
 
 #if GEOS_DEBUG_CASCADED_UNION
     for ( size_t i=0; i<disjointPolys.size(); ++i )
@@ -288,28 +288,36 @@ CascadedPolygonUnion::unionUsingEnvelopeIntersection(geom::Geometry* g0,
     }
 #endif
 
-    // TODO: find, in disjointPolys, those which now have their
-    // environment intersect the environment of the union "u"
-    // and collect them in another vector to be unioned
+    geom::Envelope const* unionCommonEnv = unionCommon->getEnvelopeInternal(); // TODO: check for EMPTY ?
 
     std::vector<geom::Geometry*> polysOn;
     std::vector<geom::Geometry*> polysOff;
-    geom::Envelope const* uEnv = u->getEnvelopeInternal(); // TODO: check for EMPTY ?
-    extractByEnvelope(*uEnv, disjointPolys, polysOn, polysOff);
+    extractByEnvelope(*unionCommonEnv, disjointPolys, polysOn, polysOff);
 #if GEOS_DEBUG_CASCADED_UNION
     std::cerr << "unionUsingEnvelopeIntersection: " << polysOn.size() << "/" << disjointPolys.size() << " polys intersect union of final thing" << std::endl;
 #endif
 
+    // If the union of the interacting geometries
+    // is contained in the envelope of the inputs
+    // (and this is highly likely unless overlay robustness failure occurs)
+    // it is safe to combine with the disjoint polygons
+    geom::Envelope beforeUnionEnv( *(g0Int->getEnvelopeInternal()) );
+    beforeUnionEnv.expandToInclude( g1Int->getEnvelopeInternal() );
+    bool isUnionSafe = beforeUnionEnv.contains(unionCommonEnv);
+    //if (! isUnionSafe) std::cerr << "Found unsafe union" << std::endl;
+
     std::unique_ptr<geom::Geometry> ret;
-    if ( polysOn.empty() ) {
-      disjointPolys.push_back(u.get());
+    if(polysOn.empty() || isUnionSafe) {
+      disjointPolys.push_back(unionCommon.get());
       ret.reset( geom::util::GeometryCombiner::combine(disjointPolys));
     } else {
+      // The union envelope changed (e.g. due to snapping heuristics)
+      // so to be safe must union everything (which is slow, but infrequent)
       // TODO: could be further tweaked to only union with polysOn
       //       and combine with polysOff, but then it'll need again to
       //       recurse in the check for disjoint/intersecting
-      ret.reset( geom::util::GeometryCombiner::combine(disjointPolys) );
-      ret.reset( unionActual(ret.get(), u.get()) );
+      std::unique_ptr<geom::Geometry> disjointCombined( geom::util::GeometryCombiner::combine(disjointPolys) );
+      ret.reset( unionActual( disjointCombined.get(), unionCommon.get() ) );
     }
 
 #if GEOS_DEBUG_CASCADED_UNION

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

Summary of changes:
 NEWS                                         |  2 +-
 src/operation/union/CascadedPolygonUnion.cpp | 30 ++++++++++++++++++----------
 2 files changed, 20 insertions(+), 12 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list