[geos-commits] [SCM] GEOS branch master updated. 3a5fd40eddfdb8bb6be2cfa1a3166e53577c8242

git at osgeo.org git at osgeo.org
Mon Feb 8 15:15:36 PST 2021


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  3a5fd40eddfdb8bb6be2cfa1a3166e53577c8242 (commit)
       via  f16218f1b13b1268be72788928ca1be037244a74 (commit)
      from  4b6ccd37d457db83e1c26d2dc051dfe29f83b0d0 (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 3a5fd40eddfdb8bb6be2cfa1a3166e53577c8242
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Feb 7 19:56:04 2021 -0500

    Guard against use of meaningless null Envelope bounds

diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index c513441..c3661e4 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -88,10 +88,10 @@ INLINE void
 Envelope::expandToInclude(const Envelope* other)
 {
     if(isNull()) {
-        minx = other->getMinX();
-        maxx = other->getMaxX();
-        miny = other->getMinY();
-        maxy = other->getMaxY();
+        minx = other->minx;
+        maxx = other->maxx;
+        miny = other->miny;
+        maxy = other->maxy;
     }
     else {
         if(other->minx < minx) {
@@ -139,6 +139,7 @@ Envelope::expandToInclude(double x, double y)
 INLINE double
 Envelope::getMaxY() const
 {
+    assert(!isNull());
     return maxy;
 }
 
@@ -146,6 +147,7 @@ Envelope::getMaxY() const
 INLINE double
 Envelope::getMaxX() const
 {
+    assert(!isNull());
     return maxx;
 }
 
@@ -153,6 +155,7 @@ Envelope::getMaxX() const
 INLINE double
 Envelope::getMinY() const
 {
+    assert(!isNull());
     return miny;
 }
 
@@ -160,6 +163,7 @@ Envelope::getMinY() const
 INLINE double
 Envelope::getMinX() const
 {
+    assert(!isNull());
     return minx;
 }
 
diff --git a/include/geos/operation/overlayng/RingClipper.h b/include/geos/operation/overlayng/RingClipper.h
index 85d5c84..c81bed4 100644
--- a/include/geos/operation/overlayng/RingClipper.h
+++ b/include/geos/operation/overlayng/RingClipper.h
@@ -74,11 +74,7 @@ private:
     static constexpr int BOX_BOTTOM = 0;
 
     // Members
-    // const Envelope* clipEnv;
-    double clipEnvMinY;
-    double clipEnvMaxY;
-    double clipEnvMinX;
-    double clipEnvMaxX;
+    const Envelope clipEnv;
 
     // Methods
 
@@ -101,10 +97,7 @@ private:
 public:
 
     RingClipper(const Envelope* env)
-        : clipEnvMinY(env->getMinY())
-        , clipEnvMaxY(env->getMaxY())
-        , clipEnvMinX(env->getMinX())
-        , clipEnvMaxX(env->getMaxX())
+        : clipEnv(*env)
         {};
 
     /**
diff --git a/src/geom/Envelope.cpp b/src/geom/Envelope.cpp
index 65202d9..6288a7b 100644
--- a/src/geom/Envelope.cpp
+++ b/src/geom/Envelope.cpp
@@ -161,10 +161,10 @@ bool
 Envelope::covers(const Envelope& other) const
 {
     return
-        other.getMinX() >= minx &&
-        other.getMaxX() <= maxx &&
-        other.getMinY() >= miny &&
-        other.getMaxY() <= maxy;
+        other.minx >= minx &&
+        other.maxx <= maxx &&
+        other.miny >= miny &&
+        other.maxy <= maxy;
 }
 
 /*public*/
@@ -174,10 +174,10 @@ Envelope::equals(const Envelope* other) const
     if(isNull()) {
         return other->isNull();
     }
-    return  other->getMinX() == minx &&
-            other->getMaxX() == maxx &&
-            other->getMinY() == miny &&
-            other->getMaxY() == maxy;
+    return  other->minx == minx &&
+            other->maxx == maxx &&
+            other->miny == miny &&
+            other->maxy == maxy;
 }
 
 /* public */
diff --git a/src/operation/overlayng/OverlayNGRobust.cpp b/src/operation/overlayng/OverlayNGRobust.cpp
index b8ee6bf..32b817f 100644
--- a/src/operation/overlayng/OverlayNGRobust.cpp
+++ b/src/operation/overlayng/OverlayNGRobust.cpp
@@ -265,7 +265,7 @@ OverlayNGRobust::snapTolerance(const Geometry* geom)
 double
 OverlayNGRobust::ordinateMagnitude(const Geometry* geom)
 {
-    if (geom == nullptr) return 0;
+    if (geom == nullptr || geom->isEmpty()) return 0;
     const Envelope* env = geom->getEnvelopeInternal();
     double magMax = std::max(
         std::abs(env->getMaxX()),
diff --git a/src/operation/overlayng/RingClipper.cpp b/src/operation/overlayng/RingClipper.cpp
index b042332..c311dd9 100644
--- a/src/operation/overlayng/RingClipper.cpp
+++ b/src/operation/overlayng/RingClipper.cpp
@@ -83,17 +83,17 @@ RingClipper::intersection(const Coordinate& a, const Coordinate& b, int edgeInde
 {
     switch (edgeIndex) {
     case BOX_BOTTOM:
-        rsltPt = Coordinate(intersectionLineY(a, b, clipEnvMinY), clipEnvMinY);
+        rsltPt = Coordinate(intersectionLineY(a, b, clipEnv.getMinY()), clipEnv.getMinY());
         break;
     case BOX_RIGHT:
-        rsltPt = Coordinate(clipEnvMaxX, intersectionLineX(a, b, clipEnvMaxX));
+        rsltPt = Coordinate(clipEnv.getMaxX(), intersectionLineX(a, b, clipEnv.getMaxX()));
         break;
     case BOX_TOP:
-        rsltPt = Coordinate(intersectionLineY(a, b, clipEnvMaxY), clipEnvMaxY);
+        rsltPt = Coordinate(intersectionLineY(a, b, clipEnv.getMaxY()), clipEnv.getMaxY());
         break;
     case BOX_LEFT:
     default:
-        rsltPt = Coordinate(clipEnvMinX, intersectionLineX(a, b, clipEnvMinX));
+        rsltPt = Coordinate(clipEnv.getMinX(), intersectionLineX(a, b, clipEnv.getMinX()));
     }
     return;
 }
@@ -120,20 +120,24 @@ RingClipper::intersectionLineX(const Coordinate& a, const Coordinate& b, double
 bool
 RingClipper::isInsideEdge(const Coordinate& p, int edgeIndex) const
 {
+    if (clipEnv.isNull()) {
+        return false;
+    }
+
     bool isInside = false;
     switch (edgeIndex) {
     case BOX_BOTTOM: // bottom
-        isInside = p.y > clipEnvMinY;
+        isInside = p.y > clipEnv.getMinY();
         break;
     case BOX_RIGHT: // right
-        isInside = p.x < clipEnvMaxX;
+        isInside = p.x < clipEnv.getMaxX();
         break;
     case BOX_TOP: // top
-        isInside = p.y < clipEnvMaxY;
+        isInside = p.y < clipEnv.getMaxY();
         break;
     case BOX_LEFT:
     default: // left
-        isInside = p.x > clipEnvMinX;
+        isInside = p.x > clipEnv.getMinX();
     }
     return isInside;
 }

commit f16218f1b13b1268be72788928ca1be037244a74
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Feb 7 09:56:49 2021 -0500

    Represent empty envelope with NaN
    
    This allows explicit isNull() checks to be avoided in some of the
    envelope operations, since NaN semantics make the affected conversions
    false for null envelopes.
    
    Improves performance of watershed union operation by 1%.

diff --git a/include/geos/geom/Envelope.h b/include/geos/geom/Envelope.h
index b61ab57..ed01723 100644
--- a/include/geos/geom/Envelope.h
+++ b/include/geos/geom/Envelope.h
@@ -91,13 +91,13 @@ public:
      *
      * @param  p  the Coordinate
      */
-    Envelope(const Coordinate& p);
+    explicit Envelope(const Coordinate& p);
 
     /** \brief
      * Create an Envelope from an Envelope string representation produced
      * by Envelope::toString()
      */
-    Envelope(const std::string& str);
+    explicit Envelope(const std::string& str);
 
     /** \brief
      * Test the point `q` to see whether it intersects the Envelope
@@ -138,7 +138,7 @@ public:
     /** \brief
      *  Initialize to a null Envelope.
      */
-    void init(void);
+    void init();
 
     /** \brief
      * Initialize an Envelope for a region defined by maximum and minimum values.
@@ -172,7 +172,7 @@ public:
      * Makes this `Envelope` a "null" envelope, that is, the envelope
      * of the empty geometry.
      */
-    void setToNull(void);
+    void setToNull();
 
     /** \brief
      * Returns `true` if this Envelope is a "null" envelope.
@@ -180,21 +180,21 @@ public:
      * @return `true` if this Envelope is uninitialized or is the
      *                envelope of the empty geometry.
      */
-    bool isNull(void) const;
+    bool isNull() const;
 
     /** \brief
      * Returns the difference between the maximum and minimum x values.
      *
      * @return  `max x - min x`, or 0 if this is a null Envelope
      */
-    double getWidth(void) const;
+    double getWidth() const;
 
     /** \brief
      * Returns the difference between the maximum and minimum y values.
      *
      * @return `max y - min y`, or 0 if this is a null Envelope
      */
-    double getHeight(void) const;
+    double getHeight() const;
 
     /** \brief
      * Gets the area of this envelope.
@@ -449,7 +449,7 @@ public:
      *
      * @return a `string` of the form `Env[minx:maxx,miny:maxy]`
      */
-    std::string toString(void) const;
+    std::string toString() const;
 
     /** \brief
      * Computes the distance between this and another Envelope.
@@ -499,7 +499,7 @@ private:
      * This is a generic function that really belongs in a utility
      * file somewhere
      */
-    std::vector<std::string> split(const std::string& str,
+    static std::vector<std::string> split(const std::string& str,
                                    const std::string& delimiters = " ");
 
     static double distance(double x0, double y0, double x1, double y1);
diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index a1b5ec3..c513441 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -34,10 +34,12 @@ namespace geom { // geos::geom
 
 /*public*/
 INLINE
-Envelope::Envelope()
-{
-    init();
-}
+Envelope::Envelope() :
+    minx(std::numeric_limits<double>::quiet_NaN()),
+    maxx(std::numeric_limits<double>::quiet_NaN()),
+    miny(std::numeric_limits<double>::quiet_NaN()),
+    maxy(std::numeric_limits<double>::quiet_NaN())
+{}
 
 /*public*/
 INLINE
@@ -85,9 +87,6 @@ Envelope::expandToInclude(const Envelope& other)
 INLINE void
 Envelope::expandToInclude(const Envelope* other)
 {
-    if(other->isNull()) {
-        return;
-    }
     if(isNull()) {
         minx = other->getMinX();
         maxx = other->getMaxX();
@@ -246,21 +245,17 @@ Envelope::intersects(const Envelope& other) const
 INLINE bool
 Envelope::isNull(void) const
 {
-    return maxx < minx;
+    return std::isnan(maxx);
 }
 
 /*public*/
 INLINE bool
 Envelope::intersects(const Envelope* other) const
 {
-    // Optimized to reduce function calls
-    if(isNull() || other->isNull()) {
-        return false;
-    }
-    return !(other->minx > maxx ||
-             other->maxx < minx ||
-             other->miny > maxy ||
-             other->maxy < miny);
+    return other->minx <= maxx &&
+           other->maxx >= minx &&
+           other->miny <= maxy &&
+           other->maxy >= miny;
 }
 
 /*public*/
@@ -281,13 +276,10 @@ Envelope::disjoint(const Envelope& other) const
 INLINE bool
 Envelope::disjoint(const Envelope* other) const
 {
-    if (isNull() || other->isNull()) {
-        return true;
-    }
-    return other->minx > maxx ||
-        other->maxx < minx ||
-        other->miny > maxy ||
-        other->maxy < miny;
+    return !(other->minx <= maxx ||
+             other->maxx >= minx ||
+             other->miny <= maxy ||
+             other->maxy >= miny);
 }
 
 
@@ -302,10 +294,7 @@ Envelope::covers(const Coordinate* p) const
 INLINE void
 Envelope::setToNull()
 {
-    minx = 0;
-    maxx = -1;
-    miny = 0;
-    maxy = -1;
+    minx = maxx = miny = maxy = std::numeric_limits<double>::quiet_NaN();
 }
 
 INLINE double
diff --git a/include/geos/triangulate/quadedge/Vertex.h b/include/geos/triangulate/quadedge/Vertex.h
index 808bf0e..7be420f 100644
--- a/include/geos/triangulate/quadedge/Vertex.h
+++ b/include/geos/triangulate/quadedge/Vertex.h
@@ -21,6 +21,7 @@
 
 #include <math.h>
 #include <memory>
+#include <cstring>
 
 #include <geos/geom/Coordinate.h>
 #include <geos/algorithm/HCoordinate.h>
@@ -112,10 +113,7 @@ public:
     inline bool
     equals(const Vertex& _x) const
     {
-        if(p.x == _x.getX() && p.y == _x.getY()) {
-            return true;
-        }
-        return false;
+        return p.equals2D(_x.p);
     }
 
     inline bool
diff --git a/src/geom/Envelope.cpp b/src/geom/Envelope.cpp
index c821fd9..65202d9 100644
--- a/src/geom/Envelope.cpp
+++ b/src/geom/Envelope.cpp
@@ -85,9 +85,11 @@ Envelope::intersects(const Coordinate& p1, const Coordinate& p2,
 bool
 Envelope::intersects(const Coordinate& a, const Coordinate& b) const
 {
-
+    // These comparisons look redundant, but an alternative using
+    // std::minmax performs no better and compiles down to more
+    // instructions.
     double envminx = (a.x < b.x) ? a.x : b.x;
-    if(envminx > maxx) {
+    if(!(maxx >= envminx)) { // awkward comparison catches cases where this->isNull()
         return false;
     }
 
@@ -116,7 +118,7 @@ Envelope::Envelope(const std::string& str)
     // Env[7.2:2.3,7.1:8.2]
 
     // extract out the values between the [ and ] characters
-    std::string::size_type index = str.find("[");
+    std::string::size_type index = str.find('[');
     std::string coordString = str.substr(index + 1, str.size() - 1 - 1);
 
     // now split apart the string on : and , characters
@@ -147,9 +149,6 @@ Envelope::init(Envelope env)
 bool
 Envelope::covers(double x, double y) const
 {
-    if(isNull()) {
-        return false;
-    }
     return x >= minx &&
            x <= maxx &&
            y >= miny &&
@@ -161,10 +160,6 @@ Envelope::covers(double x, double y) const
 bool
 Envelope::covers(const Envelope& other) const
 {
-    if(isNull() || other.isNull()) {
-        return false;
-    }
-
     return
         other.getMinX() >= minx &&
         other.getMaxX() <= maxx &&
@@ -208,16 +203,7 @@ Envelope::toString() const
 bool
 operator==(const Envelope& a, const Envelope& b)
 {
-    if(a.isNull()) {
-        return b.isNull();
-    }
-    if(b.isNull()) {
-        return a.isNull();
-    }
-    return a.getMaxX() == b.getMaxX() &&
-           a.getMaxY() == b.getMaxY() &&
-           a.getMinX() == b.getMinX() &&
-           a.getMinY() == b.getMinY();
+    return a.equals(&b);
 }
 
 /*public*/
@@ -303,10 +289,6 @@ Envelope::translate(double transX, double transY)
 void
 Envelope::expandBy(double deltaX, double deltaY)
 {
-    if(isNull()) {
-        return;
-    }
-
     minx -= deltaX;
     maxx += deltaX;
     miny -= deltaY;
diff --git a/src/operation/overlay/OverlayOp.cpp b/src/operation/overlay/OverlayOp.cpp
index a046e45..543a00e 100644
--- a/src/operation/overlay/OverlayOp.cpp
+++ b/src/operation/overlay/OverlayOp.cpp
@@ -252,7 +252,7 @@ OverlayOp::copyPoints(uint8_t argIndex, const Envelope* env)
         assert(graphNode);
         const Coordinate& coord = graphNode->getCoordinate();
 
-        if(env && ! env->covers(coord)) {
+        if(env && ! env->covers(&coord)) {
             continue;
         }
 
diff --git a/src/triangulate/DelaunayTriangulationBuilder.cpp b/src/triangulate/DelaunayTriangulationBuilder.cpp
index 19b84cd..2385487 100644
--- a/src/triangulate/DelaunayTriangulationBuilder.cpp
+++ b/src/triangulate/DelaunayTriangulationBuilder.cpp
@@ -101,10 +101,15 @@ DelaunayTriangulationBuilder::create()
         return;
     }
 
-    Envelope siteEnv;
-    siteCoords ->expandEnvelope(siteEnv);
+    if (siteCoords->isEmpty()) {
+        return;
+
+    }
+
+    Envelope siteEnv = siteCoords->getEnvelope();
     auto vertices = toVertices(*siteCoords);
-    std::sort(vertices.begin(), vertices.end()); // Best performance from locator when inserting points near each other
+    std::sort(vertices.begin(),
+              vertices.end()); // Best performance from locator when inserting points near each other
 
     subdiv.reset(new quadedge::QuadEdgeSubdivision(siteEnv, tolerance));
     IncrementalDelaunayTriangulator triangulator = IncrementalDelaunayTriangulator(subdiv.get());
@@ -123,6 +128,10 @@ DelaunayTriangulationBuilder::getEdges(
     const GeometryFactory& geomFact)
 {
     create();
+    if (!subdiv) {
+        return geomFact.createMultiLineString();
+    }
+
     return subdiv->getEdges(geomFact);
 }
 
@@ -131,15 +140,17 @@ DelaunayTriangulationBuilder::getTriangles(
     const geom::GeometryFactory& geomFact)
 {
     create();
+    if (!subdiv) {
+        return geomFact.createGeometryCollection();
+    }
+
     return subdiv->getTriangles(geomFact);
 }
 
 geom::Envelope
 DelaunayTriangulationBuilder::envelope(const geom::CoordinateSequence& coords)
 {
-    Envelope env;
-    coords.expandEnvelope(env);
-    return env;
+    return coords.getEnvelope();
 }
 
 
diff --git a/src/triangulate/VoronoiDiagramBuilder.cpp b/src/triangulate/VoronoiDiagramBuilder.cpp
index b3a0db5..5adfbd6 100644
--- a/src/triangulate/VoronoiDiagramBuilder.cpp
+++ b/src/triangulate/VoronoiDiagramBuilder.cpp
@@ -77,7 +77,11 @@ VoronoiDiagramBuilder::create()
         return;
     }
 
-    diagramEnv = DelaunayTriangulationBuilder::envelope(*siteCoords);
+    if (siteCoords->isEmpty()) {
+        return;
+    }
+
+    diagramEnv = siteCoords->getEnvelope();
     //adding buffer around the final envelope
     double expandBy = std::max(diagramEnv.getWidth(), diagramEnv.getHeight());
     diagramEnv.expandBy(expandBy);
@@ -106,8 +110,11 @@ VoronoiDiagramBuilder::getDiagram(const geom::GeometryFactory& geomFact)
 {
     create();
 
-    auto polys = subdiv->getVoronoiCellPolygons(geomFact);
-    auto ret = clipGeometryCollection(polys, diagramEnv);
+    std::unique_ptr<GeometryCollection> ret;
+    if (subdiv) {
+        auto polys = subdiv->getVoronoiCellPolygons(geomFact);
+        ret = clipGeometryCollection(polys, diagramEnv);
+    }
 
     if (ret == nullptr) {
         return std::unique_ptr<geom::GeometryCollection>(geomFact.createGeometryCollection());
@@ -120,6 +127,11 @@ std::unique_ptr<geom::Geometry>
 VoronoiDiagramBuilder::getDiagramEdges(const geom::GeometryFactory& geomFact)
 {
     create();
+
+    if (!subdiv) {
+        return geomFact.createMultiLineString();
+    }
+
     std::unique_ptr<geom::MultiLineString> edges = subdiv->getVoronoiDiagramEdges(geomFact);
     if(edges->isEmpty()) {
         return std::unique_ptr<Geometry>(edges.release());
diff --git a/src/triangulate/quadedge/QuadEdgeSubdivision.cpp b/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
index 4917f87..36492a4 100644
--- a/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
+++ b/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
@@ -74,6 +74,10 @@ QuadEdgeSubdivision::QuadEdgeSubdivision(const geom::Envelope& env, double p_tol
 void
 QuadEdgeSubdivision::createFrame(const geom::Envelope& env)
 {
+    if (env.isNull()) {
+        throw util::IllegalArgumentException("Cannot create frame from empty Envelope.");
+    }
+
     double deltaX = env.getWidth();
     double deltaY = env.getHeight();
     double offset = 0.0;
diff --git a/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp b/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp
index 317cb1a..9ef1215 100644
--- a/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp
+++ b/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp
@@ -44,6 +44,7 @@ void object::test<1>
     ensure_equals(GEOSisEmpty(geom1_), 1);
 
     geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
+    ensure (geom2_ != nullptr);
     ensure_equals(GEOSisEmpty(geom2_), 1);
     ensure_equals(GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION);
 
diff --git a/tests/unit/geom/EnvelopeTest.cpp b/tests/unit/geom/EnvelopeTest.cpp
index 1c7b46a..6e3409b 100644
--- a/tests/unit/geom/EnvelopeTest.cpp
+++ b/tests/unit/geom/EnvelopeTest.cpp
@@ -38,7 +38,7 @@ void object::test<1>
     ensure_equals(empty.getHeight(), 0);
 }
 
-// 2 - Test of overriden constructor
+// 2 - Test of overridden constructor
 template<>
 template<>
 void object::test<2>
@@ -107,7 +107,7 @@ void object::test<5>
     ensure(!box.isNull());
 
     /* See http://trac.osgeo.org/geos/ticket/703 */
-    ensure(empty.equals(&empty));
+    ensure("empty envelopes are equal", empty.equals(&empty));
 
     ensure(!empty.equals(&zero));
     ensure(!zero.equals(&empty));
@@ -134,16 +134,19 @@ void object::test<6>
     ensure(!big.isNull());
 
     // Test empty envelope by reference
-    ensure("empty envelope is not empty!", !empty.contains(small));
-    ensure("empty envelope is not empty!", !small.contains(empty));
+    ensure("empty envelope does not contain non-empty envelope", !empty.contains(small));
+    ensure("non-empty envelope does not contain empty envelope", !small.contains(empty));
+    ensure("empty envelope does not contain self", !empty.contains(empty));
 
     // Test empty envelope by pointer
-    ensure("empty envelope is not empty!", !empty.contains(&small));
-    ensure("empty envelope is not empty!", !small.contains(&empty));
+    ensure("empty envelope does not contain non-empty envelope", !empty.contains(&small));
+    ensure("non-empty envelope does not contain empty envelope", !small.contains(&empty));
+    ensure("empty envelope does not contain self", !empty.contains(&empty));
 
     // Test non-empty envelope by reference
-    ensure(!small.contains(big));
-    ensure(big.contains(small));
+    ensure("small envelope does not contain big envelope", !small.contains(big));
+    ensure("big envelope contains small envelope", big.contains(small));
+    ensure("non-empty envelope contains itself", big.contains(big));
 
     // Test raw point
     ensure(small.contains(0, 0));
@@ -159,7 +162,7 @@ void object::test<6>
     ensure(small.contains(origin));
 }
 
-// Test of intersects()
+// Test of intersects() and disjoint()
 template<>
 template<>
 void object::test<7>
@@ -174,16 +177,27 @@ void object::test<7>
     ensure(!moved.isNull());
 
     // Test empty envelope by reference
-    ensure("empty envelope seems not empty!", !empty.intersects(with_origin));
-    ensure("empty envelope seems not empty!", !with_origin.intersects(empty));
+    ensure("empty envelope does not intersect non-empty envelope", !empty.intersects(with_origin));
+    ensure("non-empty envelope does not intersect empty envelope", !with_origin.intersects(empty));
+    ensure("empty envelope is disjoint with non-empty envelope", empty.disjoint(with_origin));
+    ensure("non-empty envelope is disjoint with empty envelope", with_origin.disjoint(empty));
 
     // Test empty envelope by pointer
-    ensure("empty envelope seems not empty!", !empty.intersects(&with_origin));
-    ensure("empty envelope seems not empty!", !with_origin.intersects(&empty));
+    ensure("empty envelope does not intersect non-empty envelope", !empty.intersects(&with_origin));
+    ensure("non-empty envelope does not intersect empty envelope", !with_origin.intersects(&empty));
+    ensure("empty envelope is disjoint with non-empty envelope", empty.disjoint(&with_origin));
+    ensure("non-empty envelope is disjoint with empty envelope", with_origin.disjoint(&empty));
+
+    // Test empty envelope does not intersect self
+    ensure("empty envelope does not intersect self", !empty.intersects(empty));
+    ensure("empty envelope is disjoint with self", empty.disjoint(empty));
 
     // Test non-empty envelope by reference
     ensure(with_origin.intersects(moved));
+    ensure(!with_origin.disjoint(moved));
+
     ensure(moved.intersects(with_origin));
+    ensure(!moved.disjoint(with_origin));
 
     // Test intersection with raw point
     ensure(with_origin.intersects(0, 0));
@@ -198,6 +212,7 @@ void object::test<7>
     ensure_equals(origin.z, 0);
     ensure(with_origin.intersects(origin));
 
+    ensure("empty envelope does not intersect coordinate", !empty.intersects(origin));
 }
 
 // Test of expand()
@@ -216,11 +231,13 @@ void object::test<8>
 
     // Expand box envelope to include null envelope
     box.expandToInclude(&empty);
-    ensure(box == exemplar);   // no change expected
+    ensure("expanding envelope to include null envelope has no effect",
+           box == exemplar);   // no change expected
 
     // Expand null envelope to include box envelope
     empty.expandToInclude(&box);
-    ensure(empty == exemplar);
+    ensure("expanding null envelope to include non-null envelope makes null envelope not null",
+           empty == exemplar);
 }
 
 // Second test of expand()

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

Summary of changes:
 include/geos/geom/Envelope.h                      | 18 ++++----
 include/geos/geom/Envelope.inl                    | 55 ++++++++++-------------
 include/geos/operation/overlayng/RingClipper.h    | 11 +----
 include/geos/triangulate/quadedge/Vertex.h        |  6 +--
 src/geom/Envelope.cpp                             | 46 ++++++-------------
 src/operation/overlay/OverlayOp.cpp               |  2 +-
 src/operation/overlayng/OverlayNGRobust.cpp       |  2 +-
 src/operation/overlayng/RingClipper.cpp           | 20 +++++----
 src/triangulate/DelaunayTriangulationBuilder.cpp  | 23 +++++++---
 src/triangulate/VoronoiDiagramBuilder.cpp         | 18 ++++++--
 src/triangulate/quadedge/QuadEdgeSubdivision.cpp  |  4 ++
 tests/unit/capi/GEOSDelaunayTriangulationTest.cpp |  1 +
 tests/unit/geom/EnvelopeTest.cpp                  | 47 ++++++++++++-------
 13 files changed, 134 insertions(+), 119 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list