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

git at osgeo.org git at osgeo.org
Thu Apr 30 07:26:45 PDT 2020


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  ebae359519ddb33ff9e7ccfc40d36a412a83ac56 (commit)
       via  526bfae4b3411748eadf05b767ca98dc66794e34 (commit)
       via  ba81ee7ef3e6947cf09ccb4b855e1ffa680ad99f (commit)
       via  7c68d1400cb18fd612a4c84edde740a6156c2804 (commit)
       via  0ee0a4a2aea90d36afb41d9a3859365eaa7b6e4e (commit)
       via  d954041ac8ca6add66428cfc6383e294b3b5a847 (commit)
       via  0fca42d6e18445373ba40a46874f96b11221a5ba (commit)
       via  b0af7d7cee7fb097774c2508f76d43d5581c1c2e (commit)
      from  1357b728c30c6008d6d4fafba158f0cee71f3e9d (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 ebae359519ddb33ff9e7ccfc40d36a412a83ac56
Merge: 1357b72 526bfae
Author: Daniel Baston <dbaston at gmail.com>
Date:   Thu Apr 30 10:26:17 2020 -0400

    Merge branch 'distanceop-perf'


commit 526bfae4b3411748eadf05b767ca98dc66794e34
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed Apr 29 22:07:48 2020 -0400

    Add some tests for Envelope::distance

diff --git a/tests/unit/geom/EnvelopeTest.cpp b/tests/unit/geom/EnvelopeTest.cpp
index bd98f6e..a0744c3 100644
--- a/tests/unit/geom/EnvelopeTest.cpp
+++ b/tests/unit/geom/EnvelopeTest.cpp
@@ -304,5 +304,57 @@ void object::test<10>
 
 }
 
+// Test envelope distance
+template<>
+template<>
+void object::test<11>
+()
+{
+    using geos::geom::Coordinate;
+    using geos::geom::Envelope;
+
+    // b touches a
+    Envelope a{{0, 0}, {5, 5}};
+    Envelope b({5, 5}, {10, 10});
+    ensure_equals(a.distance(b), 0);
+    ensure_equals(a.distance(b), b.distance(a));
+
+    // b within a
+    a = Envelope({0, 0}, {10, 10});
+    b = Envelope({3, 3}, {3, 3});
+    ensure_equals(a.distance(b), 0);
+    ensure_equals(a.distance(b), b.distance(a));
+
+    // b overlaps a
+    a = Envelope({0, 0}, {5, 5});
+    b = Envelope({2, 2}, {8, 8});
+    ensure_equals(a.distance(b), 0);
+    ensure_equals(a.distance(b), b.distance(a));
+
+    // b above a
+    a = Envelope({2, 3}, {5, 7});
+    b = Envelope({0, 10}, {10, 20});
+    ensure_equals(a.distance(b), 3);
+    ensure_equals(a.distance(b), b.distance(a));
+
+    // b right of a
+    a = Envelope({2, 3}, {5, 7});
+    b = Envelope({9, 4}, {11, 12});
+    ensure_equals(a.distance(b), 4);
+    ensure_equals(a.distance(b), b.distance(a));
+
+    // b above and right of a
+    a = Envelope({0, 0}, {5, 7});
+    b = Envelope({9, 13}, {12, 28});
+    ensure_equals(a.distance(b), Coordinate(5, 7).distance(Coordinate(9, 13)));
+    ensure_equals(a.distance(b), b.distance(a));
+
+    // b below and right of a
+    a = Envelope({10, 11}, {13, 28});
+    b = Envelope({17, 3}, {20, 5});
+    ensure_equals(a.distance(b), Coordinate(13, 11).distance(Coordinate(17, 5)));
+    ensure_equals(a.distance(b), b.distance(a));
+}
+
 } // namespace tut
 

commit ba81ee7ef3e6947cf09ccb4b855e1ffa680ad99f
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed Apr 29 22:07:32 2020 -0400

    Use reference in Envelope::distance signature

diff --git a/include/geos/geom/Envelope.h b/include/geos/geom/Envelope.h
index 6392807..e743c38 100644
--- a/include/geos/geom/Envelope.h
+++ b/include/geos/geom/Envelope.h
@@ -451,7 +451,7 @@ public:
      * The distance between overlapping Envelopes is 0. Otherwise, the
      * distance is the Euclidean distance between the closest points.
      */
-    double distance(const Envelope* env) const;
+    double distance(const Envelope& env) const;
 
     /** \brief
      * Computes the square of the distance between this and another Envelope.
@@ -459,7 +459,7 @@ public:
      * The distance between overlapping Envelopes is 0. Otherwise, the
      * distance is the Euclidean distance between the closest points.
      */
-    double distanceSquared(const Envelope* env) const;
+    double distanceSquared(const Envelope& env) const;
 
     /** \brief
      * Computes the distance between one Coordinate and an Envelope
diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index a69e541..955a59a 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -265,19 +265,19 @@ Envelope::setToNull()
 }
 
 INLINE double
-Envelope::distanceSquared(const Envelope* env) const {
+Envelope::distanceSquared(const Envelope& env) const {
     double dx = std::max(0.0,
-                         std::max(maxx, env->maxx) - std::min(minx, env->minx) - (maxx - minx) -
-                         (env->maxx - env->minx));
+                         std::max(maxx, env.maxx) - std::min(minx, env.minx) - (maxx - minx) -
+                         (env.maxx - env.minx));
     double dy = std::max(0.0,
-                         std::max(maxy, env->maxy) - std::min(miny, env->miny) - (maxy - miny) -
-                         (env->maxy - env->miny));
+                         std::max(maxy, env.maxy) - std::min(miny, env.miny) - (maxy - miny) -
+                         (env.maxy - env.miny));
 
     return dx * dx + dy * dy;
 }
 
 INLINE double
-Envelope::distance(const Envelope* env) const {
+Envelope::distance(const Envelope& env) const {
     return std::sqrt(distanceSquared(env));
 }
 
diff --git a/src/geom/Geometry.cpp b/src/geom/Geometry.cpp
index b583f6e..b0f09be 100644
--- a/src/geom/Geometry.cpp
+++ b/src/geom/Geometry.cpp
@@ -153,7 +153,7 @@ Geometry::isWithinDistance(const Geometry* geom, double cDistance) const
 {
     const Envelope* env0 = getEnvelopeInternal();
     const Envelope* env1 = geom->getEnvelopeInternal();
-    double envDist = env0->distance(env1);
+    double envDist = env0->distance(*env1);
 
     if(envDist > cDistance) {
         return false;
diff --git a/src/index/strtree/BoundablePair.cpp b/src/index/strtree/BoundablePair.cpp
index 60409b7..1372e97 100644
--- a/src/index/strtree/BoundablePair.cpp
+++ b/src/index/strtree/BoundablePair.cpp
@@ -59,7 +59,7 @@ BoundablePair::distance() const
     if (!e1 || !e2) {
         throw util::GEOSException("Can't compute envelope of item in BoundablePair");
     }
-    return e1->distance(e2);
+    return e1->distance(*e2);
 }
 
 double
diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp
index 485a90a..82b27d2 100644
--- a/src/operation/distance/DistanceOp.cpp
+++ b/src/operation/distance/DistanceOp.cpp
@@ -431,7 +431,7 @@ DistanceOp::computeMinDistance(
 
     const Envelope* lineEnv0 = line0->getEnvelopeInternal();
     const Envelope* lineEnv1 = line1->getEnvelopeInternal();
-    if(lineEnv0->distance(lineEnv1) > minDistance) {
+    if(lineEnv0->distance(*lineEnv1) > minDistance) {
         return;
     }
 
@@ -442,22 +442,22 @@ DistanceOp::computeMinDistance(
 
     // brute force approach!
     for(size_t i = 0; i < npts0 - 1; ++i) {
-        auto& p00 = coord0->getAt(i);
-        auto& p01 = coord0->getAt(i+1);
+        const Coordinate& p00 = coord0->getAt(i);
+        const Coordinate& p01 = coord0->getAt(i+1);
 
         Envelope segEnv0(p00, p01);
 
-        if (segEnv0.distanceSquared(lineEnv1) > minDistance*minDistance) {
+        if (segEnv0.distanceSquared(*lineEnv1) > minDistance*minDistance) {
             continue;
         }
 
         for(size_t j = 0; j < npts1 - 1; ++j) {
-            auto& p10 = coord1->getAt(j);
-            auto& p11 = coord1->getAt(j+1);
+            const Coordinate& p10 = coord1->getAt(j);
+            const Coordinate& p11 = coord1->getAt(j+1);
 
             Envelope segEnv1(p10, p11);
 
-            if (segEnv0.distanceSquared(&segEnv1) > minDistance*minDistance) {
+            if (segEnv0.distanceSquared(segEnv1) > minDistance*minDistance) {
                 continue;
             }
 
@@ -492,7 +492,7 @@ DistanceOp::computeMinDistance(const LineString* line,
 
     const Envelope* env0 = line->getEnvelopeInternal();
     const Envelope* env1 = pt->getEnvelopeInternal();
-    if(env0->distance(env1) > minDistance) {
+    if(env0->distance(*env1) > minDistance) {
         return;
     }
     const CoordinateSequence* coord0 = line->getCoordinatesRO();

commit 7c68d1400cb18fd612a4c84edde740a6156c2804
Author: Daniel Baston <dbaston at gmail.com>
Date:   Tue Apr 28 14:59:01 2020 -0400

    Add Envelope::distanceSquared

diff --git a/include/geos/geom/Envelope.h b/include/geos/geom/Envelope.h
index 9ecca80..6392807 100644
--- a/include/geos/geom/Envelope.h
+++ b/include/geos/geom/Envelope.h
@@ -454,6 +454,14 @@ public:
     double distance(const Envelope* env) const;
 
     /** \brief
+     * Computes the square of the distance between this and another Envelope.
+     *
+     * The distance between overlapping Envelopes is 0. Otherwise, the
+     * distance is the Euclidean distance between the closest points.
+     */
+    double distanceSquared(const Envelope* env) const;
+
+    /** \brief
      * Computes the distance between one Coordinate and an Envelope
      * defined by two other Coordinates. The order of the Coordinates
      * used to define the envelope is not significant.
diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index 6f30dac..a69e541 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -265,7 +265,7 @@ Envelope::setToNull()
 }
 
 INLINE double
-Envelope::distance(const Envelope* env) const {
+Envelope::distanceSquared(const Envelope* env) const {
     double dx = std::max(0.0,
                          std::max(maxx, env->maxx) - std::min(minx, env->minx) - (maxx - minx) -
                          (env->maxx - env->minx));
@@ -273,7 +273,12 @@ Envelope::distance(const Envelope* env) const {
                          std::max(maxy, env->maxy) - std::min(miny, env->miny) - (maxy - miny) -
                          (env->maxy - env->miny));
 
-    return std::sqrt(dx * dx + dy * dy);
+    return dx * dx + dy * dy;
+}
+
+INLINE double
+Envelope::distance(const Envelope* env) const {
+    return std::sqrt(distanceSquared(env));
 }
 
 INLINE double
diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp
index dc75fc4..485a90a 100644
--- a/src/operation/distance/DistanceOp.cpp
+++ b/src/operation/distance/DistanceOp.cpp
@@ -447,7 +447,7 @@ DistanceOp::computeMinDistance(
 
         Envelope segEnv0(p00, p01);
 
-        if (segEnv0.distance(lineEnv1) > minDistance) {
+        if (segEnv0.distanceSquared(lineEnv1) > minDistance*minDistance) {
             continue;
         }
 
@@ -457,7 +457,7 @@ DistanceOp::computeMinDistance(
 
             Envelope segEnv1(p10, p11);
 
-            if (segEnv0.distance(&segEnv1) > minDistance) {
+            if (segEnv0.distanceSquared(&segEnv1) > minDistance*minDistance) {
                 continue;
             }
 

commit 0ee0a4a2aea90d36afb41d9a3859365eaa7b6e4e
Author: Daniel Baston <dbaston at gmail.com>
Date:   Tue Apr 28 14:49:55 2020 -0400

    Clarify variable names

diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp
index 097a8d5..dc75fc4 100644
--- a/src/operation/distance/DistanceOp.cpp
+++ b/src/operation/distance/DistanceOp.cpp
@@ -429,9 +429,9 @@ DistanceOp::computeMinDistance(
 {
     using geos::algorithm::Distance;
 
-    const Envelope* env0 = line0->getEnvelopeInternal();
-    const Envelope* env1 = line1->getEnvelopeInternal();
-    if(env0->distance(env1) > minDistance) {
+    const Envelope* lineEnv0 = line0->getEnvelopeInternal();
+    const Envelope* lineEnv1 = line1->getEnvelopeInternal();
+    if(lineEnv0->distance(lineEnv1) > minDistance) {
         return;
     }
 
@@ -445,9 +445,9 @@ DistanceOp::computeMinDistance(
         auto& p00 = coord0->getAt(i);
         auto& p01 = coord0->getAt(i+1);
 
-        Envelope e0(p00, p01);
+        Envelope segEnv0(p00, p01);
 
-        if (e0.distance(env1) > minDistance) {
+        if (segEnv0.distance(lineEnv1) > minDistance) {
             continue;
         }
 
@@ -455,9 +455,9 @@ DistanceOp::computeMinDistance(
             auto& p10 = coord1->getAt(j);
             auto& p11 = coord1->getAt(j+1);
 
-            Envelope e1(p10, p11);
+            Envelope segEnv1(p10, p11);
 
-            if (e0.distance(&e1) > minDistance) {
+            if (segEnv0.distance(&segEnv1) > minDistance) {
                 continue;
             }
 

commit d954041ac8ca6add66428cfc6383e294b3b5a847
Author: Daniel Baston <dbaston at gmail.com>
Date:   Tue Apr 28 14:46:53 2020 -0400

    Add additional envelope test to DistanceOp::computeMinDistance

diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp
index daecb40..097a8d5 100644
--- a/src/operation/distance/DistanceOp.cpp
+++ b/src/operation/distance/DistanceOp.cpp
@@ -447,6 +447,10 @@ DistanceOp::computeMinDistance(
 
         Envelope e0(p00, p01);
 
+        if (e0.distance(env1) > minDistance) {
+            continue;
+        }
+
         for(size_t j = 0; j < npts1 - 1; ++j) {
             auto& p10 = coord1->getAt(j);
             auto& p11 = coord1->getAt(j+1);

commit 0fca42d6e18445373ba40a46874f96b11221a5ba
Author: Daniel Baston <dbaston at gmail.com>
Date:   Tue Apr 28 14:44:59 2020 -0400

    Optimize and inline Envelope::distance

diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index 7942cb6..6f30dac 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -265,6 +265,18 @@ Envelope::setToNull()
 }
 
 INLINE double
+Envelope::distance(const Envelope* env) const {
+    double dx = std::max(0.0,
+                         std::max(maxx, env->maxx) - std::min(minx, env->minx) - (maxx - minx) -
+                         (env->maxx - env->minx));
+    double dy = std::max(0.0,
+                         std::max(maxy, env->maxy) - std::min(miny, env->miny) - (maxy - miny) -
+                         (env->maxy - env->miny));
+
+    return std::sqrt(dx * dx + dy * dy);
+}
+
+INLINE double
 Envelope::distanceToCoordinate(const Coordinate & c, const Coordinate & p0, const Coordinate & p1) {
     return std::sqrt(distanceSquaredToCoordinate(c, p0, p1));
 }
diff --git a/src/geom/Envelope.cpp b/src/geom/Envelope.cpp
index 2c8cc69..8624741 100644
--- a/src/geom/Envelope.cpp
+++ b/src/geom/Envelope.cpp
@@ -235,37 +235,6 @@ Envelope::toString() const
 }
 
 /*public*/
-double
-Envelope::distance(const Envelope* env) const
-{
-    if(intersects(env)) {
-        return 0;
-    }
-    double dx = 0.0;
-    if(maxx < env->minx) {
-        dx = env->minx - maxx;
-    }
-    if(minx > env->maxx) {
-        dx = minx - env->maxx;
-    }
-    double dy = 0.0;
-    if(maxy < env->miny) {
-        dy = env->miny - maxy;
-    }
-    if(miny > env->maxy) {
-        dy = miny - env->maxy;
-    }
-    // if either is zero, the envelopes overlap either vertically or horizontally
-    if(dx == 0.0) {
-        return dy;
-    }
-    if(dy == 0.0) {
-        return dx;
-    }
-    return sqrt(dx * dx + dy * dy);
-}
-
-/*public*/
 bool
 operator==(const Envelope& a, const Envelope& b)
 {

commit b0af7d7cee7fb097774c2508f76d43d5581c1c2e
Author: Daniel Baston <dbaston at gmail.com>
Date:   Tue Apr 28 09:39:47 2020 -0400

    Add envelope check to DistanceOp::computeMinDistance
    
    Also reduce virtual method calls.

diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp
index 7cbbaf7..daecb40 100644
--- a/src/operation/distance/DistanceOp.cpp
+++ b/src/operation/distance/DistanceOp.cpp
@@ -442,17 +442,30 @@ DistanceOp::computeMinDistance(
 
     // brute force approach!
     for(size_t i = 0; i < npts0 - 1; ++i) {
+        auto& p00 = coord0->getAt(i);
+        auto& p01 = coord0->getAt(i+1);
+
+        Envelope e0(p00, p01);
+
         for(size_t j = 0; j < npts1 - 1; ++j) {
-            double dist = Distance::segmentToSegment(coord0->getAt(i), coord0->getAt(i + 1),
-                          coord1->getAt(j), coord1->getAt(j + 1));
+            auto& p10 = coord1->getAt(j);
+            auto& p11 = coord1->getAt(j+1);
+
+            Envelope e1(p10, p11);
+
+            if (e0.distance(&e1) > minDistance) {
+                continue;
+            }
+
+            double dist = Distance::segmentToSegment(p00, p01, p10, p11);
             if(dist < minDistance) {
                 minDistance = dist;
 
                 // TODO avoid copy from constructing segs, maybe
                 // by making a static closestPoints that takes four
                 // coordinate references
-                LineSegment seg0(coord0->getAt(i), coord0->getAt(i + 1));
-                LineSegment seg1(coord1->getAt(j), coord1->getAt(j + 1));
+                LineSegment seg0(p00, p01);
+                LineSegment seg1(p10, p11);
                 auto closestPt = seg0.closestPoints(seg1);
 
                 locGeom[0].reset(new GeometryLocation(line0, i, closestPt[0]));

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

Summary of changes:
 include/geos/geom/Envelope.h          | 10 ++++++-
 include/geos/geom/Envelope.inl        | 17 ++++++++++++
 src/geom/Envelope.cpp                 | 31 ---------------------
 src/geom/Geometry.cpp                 |  2 +-
 src/index/strtree/BoundablePair.cpp   |  2 +-
 src/operation/distance/DistanceOp.cpp | 33 ++++++++++++++++------
 tests/unit/geom/EnvelopeTest.cpp      | 52 +++++++++++++++++++++++++++++++++++
 7 files changed, 105 insertions(+), 42 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list