[geos-commits] [SCM] GEOS branch master updated. 1b24aed3c5ef4f972dd46ca46b6b389d02f38136

git at osgeo.org git at osgeo.org
Fri Apr 12 14:23:36 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, master has been updated
       via  1b24aed3c5ef4f972dd46ca46b6b389d02f38136 (commit)
      from  74bff6762298909e96af591bf3199113b1f4facc (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 1b24aed3c5ef4f972dd46ca46b6b389d02f38136
Author: Martin Davis <mtnclimb at gmail.co>
Date:   Fri Apr 12 14:23:24 2019 -0700

    Rework the logic to cope with unsafe unions by envelope
    (for cases where union snapping alters the result envelope)
    This fixes the performance regression in 3.6.2.
    
    Fixes #867

diff --git a/src/operation/union/CascadedPolygonUnion.cpp b/src/operation/union/CascadedPolygonUnion.cpp
index a456095..70572d6 100644
--- a/src/operation/union/CascadedPolygonUnion.cpp
+++ b/src/operation/union/CascadedPolygonUnion.cpp
@@ -273,7 +273,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")) {
@@ -291,7 +291,7 @@ CascadedPolygonUnion::unionUsingEnvelopeIntersection(geom::Geometry* g0,
 #endif
 
     if(disjointPolys.empty()) {
-        return u.release();
+        return unionCommon.release();
     }
 
 #if GEOS_DEBUG_CASCADED_UNION
@@ -302,30 +302,39 @@ 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:
 src/operation/union/CascadedPolygonUnion.cpp | 31 ++++++++++++++++++----------
 1 file changed, 20 insertions(+), 11 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list