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

git at osgeo.org git at osgeo.org
Sun Jun 16 17:30:37 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  c897e468c7c0856d241928b95c92883794544f73 (commit)
       via  f53d0bc506f78607850c696e3ca294be3fdf9340 (commit)
      from  67bdb2e1fbdbc8db4d4bc0d21bd6e3ab6ebe71b0 (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 c897e468c7c0856d241928b95c92883794544f73
Merge: 67bdb2e f53d0bc
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Jun 16 20:30:26 2019 -0400

    Merge branch 'polygon-linearring'


commit f53d0bc506f78607850c696e3ca294be3fdf9340
Author: Daniel Baston <dbaston at gmail.com>
Date:   Thu Jun 13 20:27:12 2019 -0400

    Handle Polygon rings as LinearRings
    
    This removes the need for numerous dynamic casts.
    
    Related:
    JTS 992948a3312be5ad9bf97fc50b3c3a0de3acece1
    JTS af8aee0ba345d5f5f8c845c721d9df20fac3bd3d

diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp
index 111dc08..c2c2c3b 100644
--- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -74,6 +74,7 @@
 #include <geos/linearref/LengthIndexedLine.h>
 #include <geos/triangulate/DelaunayTriangulationBuilder.h>
 #include <geos/triangulate/VoronoiDiagramBuilder.h>
+#include <geos/util.h>
 #include <geos/util/IllegalArgumentException.h>
 #include <geos/util/Interrupt.h>
 #include <geos/util/UniqueCoordinateArrayFilter.h>
@@ -4181,17 +4182,24 @@ extern "C" {
         try {
             using geos::geom::LinearRing;
 
-            std::vector<Geometry*>* vholes = new std::vector<Geometry*>(holes, holes + nholes);
+            auto vholes = geos::detail::make_unique<std::vector<LinearRing*>>(nholes);
+
+            for (size_t i = 0; i < nholes; i++) {
+                (*vholes)[i] = dynamic_cast<LinearRing*>(holes[i]);
+                if ((*vholes)[i] == nullptr) {
+                    handle->ERROR_MESSAGE("Hole is not a LinearRing");
+                    return NULL;
+                }
+            }
 
             LinearRing* nshell = dynamic_cast<LinearRing*>(shell);
             if(! nshell) {
                 handle->ERROR_MESSAGE("Shell is not a LinearRing");
-                delete vholes;
                 return NULL;
             }
             const GeometryFactory* gf = handle->geomFactory;
 
-            return gf->createPolygon(nshell, vholes);
+            return gf->createPolygon(nshell, vholes.release());
         }
         catch(const std::exception& e) {
             handle->ERROR_MESSAGE("%s", e.what());
diff --git a/doc/example.cpp b/doc/example.cpp
index c1294ba..68eb354 100644
--- a/doc/example.cpp
+++ b/doc/example.cpp
@@ -295,9 +295,8 @@ create_square_polygon(double xoffset, double yoffset, double side)
                         yoffset + (side / 3), (side / 3));
 
     // If we need to specify any hole, we do it using
-    // a vector of Geometry pointers (I don't know why
-    // not LinearRings)
-    vector<Geometry*>* holes = new vector<Geometry*>;
+    // a vector of LinearRing pointers
+    vector<LinearRing*>* holes = new vector<LinearRing*>;
 
     // We add the newly created geometry to the vector
     // of holes.
diff --git a/include/geos/geom/Geometry.h b/include/geos/geom/Geometry.h
index b7aef91..a3dc7a2 100644
--- a/include/geos/geom/Geometry.h
+++ b/include/geos/geom/Geometry.h
@@ -38,6 +38,7 @@
 #include <geos/geom/GeometryComponentFilter.h> // for inheritance
 #include <geos/geom/IntersectionMatrix.h>
 
+#include <algorithm>
 #include <string>
 #include <iostream>
 #include <vector>
@@ -835,13 +836,19 @@ protected:
     mutable std::unique_ptr<Envelope> envelope;
 
     /// Returns true if the array contains any non-empty Geometrys.
-    static bool hasNonEmptyElements(const std::vector<Geometry*>* geometries);
+    template<typename T>
+    static bool hasNonEmptyElements(const std::vector<T*>* geometries) {
+        return std::any_of(geometries->begin(), geometries->end(), [](const Geometry* g) { return !g->isEmpty(); });
+    }
 
     /// Returns true if the CoordinateSequence contains any null elements.
     static bool hasNullElements(const CoordinateSequence* list);
 
     /// Returns true if the vector contains any null elements.
-    static bool hasNullElements(const std::vector<Geometry*>* lrs);
+    template<typename T>
+    static bool hasNullElements(const std::vector<T*>* geometries) {
+        return std::any_of(geometries->begin(), geometries->end(), [](const Geometry* g) { return g == nullptr; });
+    }
 
 //	static void reversePointOrder(CoordinateSequence* coordinates);
 //	static Coordinate& minCoordinate(CoordinateSequence* coordinates);
diff --git a/include/geos/geom/GeometryFactory.h b/include/geos/geom/GeometryFactory.h
index e90cef9..a44b8f9 100644
--- a/include/geos/geom/GeometryFactory.h
+++ b/include/geos/geom/GeometryFactory.h
@@ -249,11 +249,11 @@ public:
 
     /// Construct a Polygon taking ownership of given arguments
     Polygon* createPolygon(LinearRing* shell,
-                           std::vector<Geometry*>* holes) const;
+                           std::vector<LinearRing*>* holes) const;
 
     /// Construct a Polygon with a deep-copy of given arguments
     Polygon* createPolygon(const LinearRing& shell,
-                           const std::vector<Geometry*>& holes) const;
+                           const std::vector<LinearRing*>& holes) const;
 
     /// Construct an EMPTY LineString
     LineString* createLineString() const;
diff --git a/include/geos/geom/Polygon.h b/include/geos/geom/Polygon.h
index 5013830..ff0fa38 100644
--- a/include/geos/geom/Polygon.h
+++ b/include/geos/geom/Polygon.h
@@ -27,6 +27,7 @@
 #include <geos/geom/Geometry.h> // for inheritance
 #include <geos/geom/Polygonal.h> // for inheritance
 #include <geos/geom/Envelope.h> // for proper use of unique_ptr<>
+#include <geos/geom/LinearRing.h>
 #include <geos/geom/Dimension.h> // for Dimension::DimensionType
 
 #include <geos/inline.h>
@@ -39,7 +40,6 @@ namespace geom { // geos::geom
 class Coordinate;
 class CoordinateArraySequence;
 class CoordinateSequenceFilter;
-class LinearRing;
 class LineString;
 }
 }
@@ -109,13 +109,13 @@ public:
     bool isEmpty() const override;
 
     /// Returns the exterior ring (shell)
-    const LineString* getExteriorRing() const;
+    const LinearRing* getExteriorRing() const;
 
     /// Returns number of interior rings (hole)
     size_t getNumInteriorRing() const;
 
     /// Get nth interior ring (hole)
-    const LineString* getInteriorRingN(std::size_t n) const;
+    const LinearRing* getInteriorRingN(std::size_t n) const;
 
     std::string getGeometryType() const override;
     GeometryTypeId getGeometryTypeId() const override;
@@ -169,12 +169,12 @@ protected:
      *
      * Polygon will take ownership of Shell and Holes LinearRings
      */
-    Polygon(LinearRing* newShell, std::vector<Geometry*>* newHoles,
+    Polygon(LinearRing* newShell, std::vector<LinearRing*>* newHoles,
             const GeometryFactory* newFactory);
 
     LinearRing* shell;
 
-    std::vector<Geometry*>* holes;  //Actually vector<LinearRing *>
+    std::vector<LinearRing*>* holes;
 
     Envelope::Ptr computeEnvelopeInternal() const override;
 
diff --git a/include/geos/operation/polygonize/EdgeRing.h b/include/geos/operation/polygonize/EdgeRing.h
index 5371a19..c218dd2 100644
--- a/include/geos/operation/polygonize/EdgeRing.h
+++ b/include/geos/operation/polygonize/EdgeRing.h
@@ -75,7 +75,7 @@ private:
     std::unique_ptr<geom::CoordinateArraySequence> ringPts;
     std::unique_ptr<algorithm::locate::PointOnGeometryLocator> ringLocator;
 
-    std::unique_ptr<std::vector<geom::Geometry*>> holes;
+    std::unique_ptr<std::vector<geom::LinearRing*>> holes;
 
     EdgeRing* shell = nullptr;
     bool is_hole;
diff --git a/src/algorithm/InteriorPointArea.cpp b/src/algorithm/InteriorPointArea.cpp
index 6239249..379083c 100644
--- a/src/algorithm/InteriorPointArea.cpp
+++ b/src/algorithm/InteriorPointArea.cpp
@@ -160,10 +160,10 @@ public:
          */
         interiorPoint = *polygon.getCoordinate();
 
-        const LinearRing* shell = dynamic_cast<const LinearRing*>(polygon.getExteriorRing());
+        const LinearRing* shell = polygon.getExteriorRing();
         scanRing(*shell, crossings);
         for (size_t i = 0; i < polygon.getNumInteriorRing(); i++) {
-            const LinearRing* hole = dynamic_cast<const LinearRing*>(polygon.getInteriorRingN(i));
+            const LinearRing* hole = polygon.getInteriorRingN(i);
             scanRing(*hole, crossings);
         }
         findBestMidpoint(crossings);
diff --git a/src/algorithm/PointLocator.cpp b/src/algorithm/PointLocator.cpp
index a32143f..6b4ef7c 100644
--- a/src/algorithm/PointLocator.cpp
+++ b/src/algorithm/PointLocator.cpp
@@ -177,7 +177,7 @@ PointLocator::locate(const Coordinate& p, const Polygon* poly)
         return Location::EXTERIOR;
     }
 
-    const LinearRing* shell = dynamic_cast<const LinearRing*>(poly->getExteriorRing());
+    const LinearRing* shell = poly->getExteriorRing();
     assert(shell);
 
     int shellLoc = locateInPolygonRing(p, shell);
@@ -190,7 +190,7 @@ PointLocator::locate(const Coordinate& p, const Polygon* poly)
 
     // now test if the point lies in or on the holes
     for(size_t i = 0, n = poly->getNumInteriorRing(); i < n; ++i) {
-        const LinearRing* hole = dynamic_cast<const LinearRing*>(poly->getInteriorRingN(i));
+        const LinearRing* hole = poly->getInteriorRingN(i);
         int holeLoc = locateInPolygonRing(p, hole);
         if(holeLoc == Location::INTERIOR) {
             return Location::EXTERIOR;
diff --git a/src/geom/Geometry.cpp b/src/geom/Geometry.cpp
index c466552..a050d0e 100644
--- a/src/geom/Geometry.cpp
+++ b/src/geom/Geometry.cpp
@@ -136,17 +136,6 @@ Geometry::Geometry(const Geometry& geom)
 }
 
 bool
-Geometry::hasNonEmptyElements(const vector<Geometry*>* geometries)
-{
-    for(size_t i = 0; i < geometries->size(); i++) {
-        if(!(*geometries)[i]->isEmpty()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
 Geometry::hasNullElements(const CoordinateSequence* list)
 {
     size_t npts = list->getSize();
@@ -158,18 +147,6 @@ Geometry::hasNullElements(const CoordinateSequence* list)
     return false;
 }
 
-bool
-Geometry::hasNullElements(const vector<Geometry*>* lrs)
-{
-    size_t n = lrs->size();
-    for(size_t i = 0; i < n; ++i) {
-        if((*lrs)[i] == nullptr) {
-            return true;
-        }
-    }
-    return false;
-}
-
 /* public */
 bool
 Geometry::isWithinDistance(const Geometry* geom, double cDistance) const
diff --git a/src/geom/GeometryFactory.cpp b/src/geom/GeometryFactory.cpp
index c958227..e7f3d2d 100644
--- a/src/geom/GeometryFactory.cpp
+++ b/src/geom/GeometryFactory.cpp
@@ -598,7 +598,7 @@ GeometryFactory::createPolygon() const
 
 /*public*/
 Polygon*
-GeometryFactory::createPolygon(LinearRing* shell, vector<Geometry*>* holes)
+GeometryFactory::createPolygon(LinearRing* shell, vector<LinearRing*>* holes)
 const
 {
     return new Polygon(shell, holes, this);
@@ -606,13 +606,13 @@ const
 
 /*public*/
 Polygon*
-GeometryFactory::createPolygon(const LinearRing& shell, const vector<Geometry*>& holes)
+GeometryFactory::createPolygon(const LinearRing& shell, const vector<LinearRing*>& holes)
 const
 {
-    LinearRing* newRing = dynamic_cast<LinearRing*>(shell.clone().release());
-    vector<Geometry*>* newHoles = new vector<Geometry*>(holes.size());
+    LinearRing* newRing = new LinearRing(shell);
+    vector<LinearRing*>* newHoles = new vector<LinearRing*>(holes.size());
     for(size_t i = 0; i < holes.size(); i++) {
-        (*newHoles)[i] = holes[i]->clone().release();
+        (*newHoles)[i] = new LinearRing(*(holes[i]));
     }
     Polygon* g = nullptr;
     try {
diff --git a/src/geom/Polygon.cpp b/src/geom/Polygon.cpp
index 2fe58e8..99b0685 100644
--- a/src/geom/Polygon.cpp
+++ b/src/geom/Polygon.cpp
@@ -57,19 +57,15 @@ Polygon::Polygon(const Polygon& p)
 {
     shell = new LinearRing(*p.shell);
     size_t nholes = p.holes->size();
-    holes = new vector<Geometry*>(nholes);
+    holes = new vector<LinearRing*>(nholes);
     for(size_t i = 0; i < nholes; ++i) {
-        // TODO: holes is a vector of Geometry, anyway
-        //       so there's no point in casting here,
-        //       just use ->clone instead !
-        const LinearRing* lr = dynamic_cast<const LinearRing*>((*p.holes)[i]);
-        LinearRing* h = new LinearRing(*lr);
+        LinearRing* h = new LinearRing(*(*p.holes)[i]);
         (*holes)[i] = h;
     }
 }
 
 /*protected*/
-Polygon::Polygon(LinearRing* newShell, vector<Geometry*>* newHoles,
+Polygon::Polygon(LinearRing* newShell, vector<LinearRing*>* newHoles,
                  const GeometryFactory* newFactory):
     Geometry(newFactory)
 {
@@ -84,7 +80,7 @@ Polygon::Polygon(LinearRing* newShell, vector<Geometry*>* newHoles,
     }
 
     if(newHoles == nullptr) {
-        holes = new vector<Geometry*>();
+        holes = new vector<LinearRing*>();
     }
     else {
         if(hasNullElements(newHoles)) {
@@ -117,7 +113,7 @@ Polygon::getCoordinates() const
     // Add holes points
     size_t nholes = holes->size();
     for(size_t i = 0; i < nholes; ++i) {
-        const LinearRing* lr = dynamic_cast<const LinearRing*>((*holes)[i]);
+        const LinearRing* lr = (*holes)[i];
         const CoordinateSequence* childCoords = lr->getCoordinatesRO();
         childCoords->toVector(*cl);
     }
@@ -129,8 +125,7 @@ size_t
 Polygon::getNumPoints() const
 {
     size_t numPoints = shell->getNumPoints();
-    for(size_t i = 0, n = holes->size(); i < n; ++i) {
-        const LinearRing* lr = dynamic_cast<const LinearRing*>((*holes)[i]);
+    for(const LinearRing* lr : *holes) {
         numPoints += lr->getNumPoints();
     }
     return numPoints;
@@ -171,7 +166,7 @@ Polygon::isEmpty() const
     return shell->isEmpty();
 }
 
-const LineString*
+const LinearRing*
 Polygon::getExteriorRing() const
 {
     return shell;
@@ -183,11 +178,10 @@ Polygon::getNumInteriorRing() const
     return holes->size();
 }
 
-const LineString*
+const LinearRing*
 Polygon::getInteriorRingN(size_t n) const
 {
-    const LinearRing* lr = dynamic_cast<const LinearRing*>((*holes)[n]);
-    return lr;
+    return (*holes)[n];
 }
 
 string
@@ -221,7 +215,7 @@ Polygon::getBoundary() const
 
     (*rings)[0] = gf->createLineString(*shell).release();
     for(size_t i = 0, n = holes->size(); i < n; ++i) {
-        const LinearRing* hole = dynamic_cast<const LinearRing*>((*holes)[i]);
+        const LinearRing* hole = (*holes)[i];
         assert(hole);
         LineString* ls = gf->createLineString(*hole).release();
         (*rings)[i + 1] = ls;
@@ -269,8 +263,7 @@ void
 Polygon::apply_ro(CoordinateFilter* filter) const
 {
     shell->apply_ro(filter);
-    for(size_t i = 0, n = holes->size(); i < n; ++i) {
-        const LinearRing* lr = dynamic_cast<const LinearRing*>((*holes)[i]);
+    for(const LinearRing* lr : *holes) {
         lr->apply_ro(filter);
     }
 }
@@ -279,8 +272,7 @@ void
 Polygon::apply_rw(const CoordinateFilter* filter)
 {
     shell->apply_rw(filter);
-    for(size_t i = 0, n = holes->size(); i < n; ++i) {
-        LinearRing* lr = dynamic_cast<LinearRing*>((*holes)[i]);
+    for(LinearRing* lr : *holes) {
         lr->apply_rw(filter);
     }
 }
@@ -307,8 +299,7 @@ void
 Polygon::normalize()
 {
     normalize(shell, true);
-    for(size_t i = 0, n = holes->size(); i < n; ++i) {
-        LinearRing* lr = dynamic_cast<LinearRing*>((*holes)[i]);
+    for(LinearRing* lr : *holes) {
         normalize(lr, false);
     }
     sort(holes->begin(), holes->end(), GeometryGreaterThen());
@@ -364,8 +355,7 @@ Polygon::getArea() const
 {
     double area = 0.0;
     area += fabs(algorithm::Area::ofRing(shell->getCoordinatesRO()));
-    for(size_t i = 0, n = holes->size(); i < n; ++i) {
-        const LinearRing* lr = dynamic_cast<const LinearRing*>((*holes)[i]);
+    for(const LinearRing* lr : *holes) {
         const CoordinateSequence* h = lr->getCoordinatesRO();
         area -= fabs(algorithm::Area::ofRing(h));
     }
@@ -508,13 +498,13 @@ Polygon::reverse() const
     }
 
     auto* exteriorRingReversed = dynamic_cast<LinearRing*>(shell->reverse().release());
-    auto* interiorRingsReversed = new std::vector<Geometry*> {holes->size()};
+    auto* interiorRingsReversed = new std::vector<LinearRing*> {holes->size()};
 
     std::transform(holes->begin(),
                    holes->end(),
                    interiorRingsReversed->begin(),
     [](const Geometry * g) {
-        return g->reverse().release();
+        return dynamic_cast<LinearRing*>(g->reverse().release());
     });
 
     return std::unique_ptr<Geometry>(getFactory()->createPolygon(exteriorRingReversed, interiorRingsReversed));
diff --git a/src/geom/util/GeometryEditor.cpp b/src/geom/util/GeometryEditor.cpp
index 64d0946..320d9b5 100644
--- a/src/geom/util/GeometryEditor.cpp
+++ b/src/geom/util/GeometryEditor.cpp
@@ -130,7 +130,7 @@ GeometryEditor::editPolygon(const Polygon* polygon, GeometryEditorOperation* ope
         return factory->createPolygon(nullptr, nullptr);
     }
 
-    vector<Geometry*>* holes = new vector<Geometry*>;
+    vector<LinearRing*>* holes = new vector<LinearRing*>;
     for(size_t i = 0, n = newPolygon->getNumInteriorRing(); i < n; ++i) {
 
         Geometry* hole_geom = edit(newPolygon->getInteriorRingN(i),
diff --git a/src/geom/util/GeometryTransformer.cpp b/src/geom/util/GeometryTransformer.cpp
index 1bd9637..49f3f08 100644
--- a/src/geom/util/GeometryTransformer.cpp
+++ b/src/geom/util/GeometryTransformer.cpp
@@ -292,10 +292,9 @@ GeometryTransformer::transformPolygon(
         isAllValidLinearRings = false;
     }
 
-    vector<Geometry*>* holes = new vector<Geometry*>();
+    vector<LinearRing*>* holes = new vector<LinearRing*>();
     for(size_t i = 0, n = geom->getNumInteriorRing(); i < n; i++) {
-        const LinearRing* p_lr = dynamic_cast<const LinearRing*>(
-                                     geom->getInteriorRingN(i));
+        const LinearRing* p_lr = geom->getInteriorRingN(i);
         assert(p_lr);
 
         Geometry::Ptr hole(transformLinearRing(p_lr, geom));
@@ -311,7 +310,7 @@ GeometryTransformer::transformPolygon(
             isAllValidLinearRings = false;
         }
 
-        holes->push_back(hole.release());
+        holes->push_back(dynamic_cast<LinearRing*>(hole.release()));
     }
 
     if(isAllValidLinearRings) {
diff --git a/src/geomgraph/EdgeRing.cpp b/src/geomgraph/EdgeRing.cpp
index d24e4c0..89d2749 100644
--- a/src/geomgraph/EdgeRing.cpp
+++ b/src/geomgraph/EdgeRing.cpp
@@ -165,10 +165,9 @@ EdgeRing::toPolygon(const GeometryFactory* p_geometryFactory)
     testInvariant();
 
     size_t nholes = holes.size();
-    vector<Geometry*>* holeLR = new vector<Geometry*>(nholes);
+    vector<LinearRing*>* holeLR = new vector<LinearRing*>(nholes);
     for(size_t i = 0; i < nholes; ++i) {
-        Geometry* hole = holes[i]->getLinearRing()->clone().release();
-        (*holeLR)[i] = hole;
+        (*holeLR)[i] = new LinearRing(*(holes[i]->getLinearRing()));
     }
 
     // We don't use "clone" here because
diff --git a/src/geomgraph/GeometryGraph.cpp b/src/geomgraph/GeometryGraph.cpp
index d18f47d..eaa140b 100644
--- a/src/geomgraph/GeometryGraph.cpp
+++ b/src/geomgraph/GeometryGraph.cpp
@@ -275,20 +275,14 @@ GeometryGraph::addPolygonRing(const LinearRing* lr, int cwLeft, int cwRight)
 void
 GeometryGraph::addPolygon(const Polygon* p)
 {
-    const LineString* ls;
-    const LinearRing* lr;
+    const LinearRing* lr = p->getExteriorRing();
 
-    ls = p->getExteriorRing();
-    assert(dynamic_cast<const LinearRing*>(ls));
-    lr = static_cast<const LinearRing*>(ls);
     addPolygonRing(lr, Location::EXTERIOR, Location::INTERIOR);
     for(size_t i = 0, n = p->getNumInteriorRing(); i < n; ++i) {
         // Holes are topologically labelled opposite to the shell, since
         // the interior of the polygon lies on their opposite side
         // (on the left, if the hole is oriented CW)
-        ls = p->getInteriorRingN(i);
-        assert(dynamic_cast<const LinearRing*>(ls));
-        lr = static_cast<const LinearRing*>(ls);
+        lr = p->getInteriorRingN(i);
         addPolygonRing(lr, Location::INTERIOR, Location::EXTERIOR);
     }
 }
diff --git a/src/io/WKBReader.cpp b/src/io/WKBReader.cpp
index 4b04b6d..6b29aac 100644
--- a/src/io/WKBReader.cpp
+++ b/src/io/WKBReader.cpp
@@ -319,12 +319,12 @@ WKBReader::readPolygon()
         shell = readLinearRing();
     }
 
-    vector<Geometry*>* holes = nullptr;
+    vector<LinearRing*>* holes = nullptr;
     if(numRings > 1) {
         try {
-            holes = new vector<Geometry*>(numRings - 1);
+            holes = new vector<LinearRing*>(numRings - 1);
             for(int i = 0; i < numRings - 1; i++) {
-                (*holes)[i] = (Geometry*)readLinearRing();
+                (*holes)[i] = readLinearRing();
             }
         }
         catch(...) {
diff --git a/src/io/WKTReader.cpp b/src/io/WKTReader.cpp
index b697292..544fd38 100644
--- a/src/io/WKTReader.cpp
+++ b/src/io/WKTReader.cpp
@@ -375,7 +375,7 @@ WKTReader::readPolygonText(StringTokenizer* tokenizer)
         return geometryFactory->createPolygon(nullptr, nullptr);
     }
 
-    vector<Geometry*>* holes = new vector<Geometry*>();
+    vector<LinearRing*>* holes = new vector<LinearRing*>();
     try {
         shell = readLinearRingText(tokenizer);
         nextToken = getNextCloserOrComma(tokenizer);
diff --git a/src/operation/buffer/OffsetCurveSetBuilder.cpp b/src/operation/buffer/OffsetCurveSetBuilder.cpp
index 802cd51..ed3522c 100644
--- a/src/operation/buffer/OffsetCurveSetBuilder.cpp
+++ b/src/operation/buffer/OffsetCurveSetBuilder.cpp
@@ -226,8 +226,7 @@ OffsetCurveSetBuilder::addPolygon(const Polygon* p)
         offsetSide = Position::RIGHT;
     }
 
-    // FIXME: avoid the C-style cast
-    const LinearRing* shell = (const LinearRing*)p->getExteriorRing();
+    const LinearRing* shell = p->getExteriorRing();
 
     // optimization - don't bother computing buffer
     // if the polygon would be completely eroded
diff --git a/src/operation/intersection/RectangleIntersection.cpp b/src/operation/intersection/RectangleIntersection.cpp
index a297b9e..23febb6 100644
--- a/src/operation/intersection/RectangleIntersection.cpp
+++ b/src/operation/intersection/RectangleIntersection.cpp
@@ -421,7 +421,7 @@ RectangleIntersection::clip_polygon_to_linestrings(const geom::Polygon* g,
     for(size_t i = 0, n = g->getNumInteriorRing(); i < n; ++i) {
         if(clip_linestring_parts(g->getInteriorRingN(i), parts, rect)) {
             // clones
-            LinearRing* hole = dynamic_cast<LinearRing*>(g->getInteriorRingN(i)->clone().release());
+            LinearRing* hole = new LinearRing(*(g->getInteriorRingN(i)));
             // becomes exterior
             Polygon* poly = _gf->createPolygon(hole, nullptr);
             toParts.add(poly);
@@ -490,10 +490,10 @@ RectangleIntersection::clip_polygon_to_polygons(const geom::Polygon* g,
 
     for(size_t i = 0, n = g->getNumInteriorRing(); i < n; ++i) {
         RectangleIntersectionBuilder holeparts(*_gf);
-        const LineString* hole = g->getInteriorRingN(i);
+        const LinearRing* hole = g->getInteriorRingN(i);
         if(clip_linestring_parts(hole, holeparts, rect)) {
             // becomes exterior
-            LinearRing* cloned = dynamic_cast<LinearRing*>(hole->clone().release());
+            LinearRing* cloned = new LinearRing(*hole);
             Polygon* poly = _gf->createPolygon(cloned, nullptr);
             parts.add(poly);
         }
diff --git a/src/operation/intersection/RectangleIntersectionBuilder.cpp b/src/operation/intersection/RectangleIntersectionBuilder.cpp
index daf8b6c..ffb52f6 100644
--- a/src/operation/intersection/RectangleIntersectionBuilder.cpp
+++ b/src/operation/intersection/RectangleIntersectionBuilder.cpp
@@ -402,7 +402,7 @@ RectangleIntersectionBuilder::reconnectPolygons(const Rectangle& rect)
 {
     // Build the exterior rings first
 
-    typedef std::vector< geom::Geometry*> LinearRingVect;
+    typedef std::vector< geom::LinearRing*> LinearRingVect;
     typedef std::pair< geom::LinearRing*, LinearRingVect* > ShellAndHoles;
     typedef std::list< ShellAndHoles > ShellAndHolesList;
 
@@ -480,10 +480,10 @@ RectangleIntersectionBuilder::reconnectPolygons(const Rectangle& rect)
 
     for(std::list<geom::Polygon*>::iterator i = polygons.begin(), e = polygons.end(); i != e; ++i) {
         geom::Polygon* poly = *i;
-        const geom::LineString* hole = poly->getExteriorRing();
+        const geom::LinearRing* hole = poly->getExteriorRing();
 
         if(exterior.size() == 1) {
-            exterior.front().second->push_back(hole->clone().release());
+            exterior.front().second->push_back(new LinearRing(*hole));
         }
         else {
             using geos::algorithm::PointLocation;
@@ -493,7 +493,7 @@ RectangleIntersectionBuilder::reconnectPolygons(const Rectangle& rect)
                 const CoordinateSequence* shell_cs = p.first->getCoordinatesRO();
                 if(PointLocation::isInRing(c, shell_cs)) {
                     // add hole to shell
-                    p.second->push_back(hole->clone().release());
+                    p.second->push_back(new LinearRing(*hole));
                     break;
                 }
             }
diff --git a/src/operation/polygonize/EdgeRing.cpp b/src/operation/polygonize/EdgeRing.cpp
index a94f104..437a0e3 100644
--- a/src/operation/polygonize/EdgeRing.cpp
+++ b/src/operation/polygonize/EdgeRing.cpp
@@ -187,7 +187,7 @@ void
 EdgeRing::addHole(LinearRing* hole)
 {
     if(holes == nullptr) {
-        holes.reset(new vector<Geometry*>());
+        holes.reset(new vector<LinearRing*>());
     }
     holes->push_back(hole);
 }
diff --git a/src/operation/valid/IsValidOp.cpp b/src/operation/valid/IsValidOp.cpp
index 387218a..c3c1489 100644
--- a/src/operation/valid/IsValidOp.cpp
+++ b/src/operation/valid/IsValidOp.cpp
@@ -429,24 +429,15 @@ IsValidOp::checkNoSelfIntersectingRing(EdgeIntersectionList& eiList)
 void
 IsValidOp::checkHolesInShell(const Polygon* p, GeometryGraph* graph)
 {
-    assert(dynamic_cast<const LinearRing*>(p->getExteriorRing()));
-
-    const LinearRing* shell = static_cast<const LinearRing*>(
-                                  p->getExteriorRing());
-    const Geometry* shellgeom = static_cast<const Geometry*>(shell);
+    const LinearRing* shell = p->getExteriorRing();
 
     bool isShellEmpty = shell->isEmpty();
 
-    locate::IndexedPointInAreaLocator ipial(*shellgeom);
+    locate::IndexedPointInAreaLocator ipial(*shell);
     auto nholes = p->getNumInteriorRing();
 
     for(size_t i = 0; i < nholes; ++i) {
-
-        assert(dynamic_cast<const LinearRing*>(
-                   p->getInteriorRingN(i)));
-
-        const LinearRing* hole = static_cast<const LinearRing*>(
-                                     p->getInteriorRingN(i));
+        const LinearRing* hole = p->getInteriorRingN(i);
 
         if (hole->isEmpty()) continue;
 
@@ -478,11 +469,7 @@ IsValidOp::checkHolesNotNested(const Polygon* p, GeometryGraph* graph)
 
     auto nholes = p->getNumInteriorRing();
     for (size_t i = 0; i < nholes; ++i) {
-        assert(dynamic_cast<const LinearRing*>(
-                   p->getInteriorRingN(i)));
-
-        const LinearRing* innerHole = static_cast<const LinearRing*>(
-                                          p->getInteriorRingN(i));
+        const LinearRing* innerHole = p->getInteriorRingN(i);
 
         //empty holes always pass
         if (innerHole->isEmpty()) {
@@ -508,8 +495,7 @@ IsValidOp::checkShellsNotNested(const MultiPolygon* mp, GeometryGraph* graph)
         const Polygon* p = dynamic_cast<const Polygon*>(
                                mp->getGeometryN(i));
 
-        const LinearRing* shell = dynamic_cast<const LinearRing*>(
-                                      p->getExteriorRing());
+        const LinearRing* shell = p->getExteriorRing();
 
         if (shell->isEmpty()) return;
 
@@ -542,10 +528,7 @@ IsValidOp::checkShellNotNested(const LinearRing* shell, const Polygon* p,
     const CoordinateSequence* shellPts = shell->getCoordinatesRO();
 
     // test if shell is inside polygon shell
-    assert(dynamic_cast<const LinearRing*>(
-               p->getExteriorRing()));
-    const LinearRing* polyShell = static_cast<const LinearRing*>(
-                                      p->getExteriorRing());
+    const LinearRing* polyShell = p->getExteriorRing();
     const CoordinateSequence* polyPts = polyShell->getCoordinatesRO();
     const Coordinate* shellPt = findPtNotNode(shellPts, polyShell, graph);
 
@@ -578,10 +561,7 @@ IsValidOp::checkShellNotNested(const LinearRing* shell, const Polygon* p,
      */
     const Coordinate* badNestedPt = nullptr;
     for(size_t i = 0; i < nholes; ++i) {
-        assert(dynamic_cast<const LinearRing*>(
-                   p->getInteriorRingN(i)));
-        const LinearRing* hole = static_cast<const LinearRing*>(
-                                     p->getInteriorRingN(i));
+        const LinearRing* hole = p->getInteriorRingN(i);
         badNestedPt = checkShellInsideHole(shell, hole, graph);
         if(badNestedPt == nullptr) {
             return;
@@ -682,7 +662,7 @@ IsValidOp::checkInvalidCoordinates(const Polygon* poly)
 void
 IsValidOp::checkClosedRings(const Polygon* poly)
 {
-    const LinearRing* lr = (const LinearRing*)poly->getExteriorRing();
+    const LinearRing* lr = poly->getExteriorRing();
     checkClosedRing(lr);
     if(validErr) {
         return;
diff --git a/tests/unit/geom/GeometryFactoryTest.cpp b/tests/unit/geom/GeometryFactoryTest.cpp
index 4635239..255d92e 100644
--- a/tests/unit/geom/GeometryFactoryTest.cpp
+++ b/tests/unit/geom/GeometryFactoryTest.cpp
@@ -769,7 +769,7 @@ void object::test<20>
     ensure_equals(hole->getNumPoints(), interiorSize);
 
     // REMEMBER TO DEALLOCATE THIS COLLECTION
-    std::vector<GeometryPtr> holes;
+    std::vector<LinearRingPtr> holes;
     holes.push_back(hole);
 
     // Create polygon using copy ctor
@@ -788,9 +788,8 @@ void object::test<20>
     ensure_equals(poly->getNumInteriorRing(), 1u);
 
     // FREE MEMORY
-    std::vector<GeometryPtr>::const_iterator it;
-    for(it = holes.begin(); it != holes.end(); ++it) {
-        delete(*it);
+    for(auto& h : holes) {
+        delete h;
     }
     holes.clear();
 

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

Summary of changes:
 capi/geos_ts_c.cpp                                 | 14 ++++++--
 doc/example.cpp                                    |  5 ++-
 include/geos/geom/Geometry.h                       | 11 ++++--
 include/geos/geom/GeometryFactory.h                |  4 +--
 include/geos/geom/Polygon.h                        | 10 +++---
 include/geos/operation/polygonize/EdgeRing.h       |  2 +-
 src/algorithm/InteriorPointArea.cpp                |  4 +--
 src/algorithm/PointLocator.cpp                     |  4 +--
 src/geom/Geometry.cpp                              | 23 ------------
 src/geom/GeometryFactory.cpp                       | 10 +++---
 src/geom/Polygon.cpp                               | 42 +++++++++-------------
 src/geom/util/GeometryEditor.cpp                   |  2 +-
 src/geom/util/GeometryTransformer.cpp              |  7 ++--
 src/geomgraph/EdgeRing.cpp                         |  5 ++-
 src/geomgraph/GeometryGraph.cpp                    | 10 ++----
 src/io/WKBReader.cpp                               |  6 ++--
 src/io/WKTReader.cpp                               |  2 +-
 src/operation/buffer/OffsetCurveSetBuilder.cpp     |  3 +-
 .../intersection/RectangleIntersection.cpp         |  6 ++--
 .../intersection/RectangleIntersectionBuilder.cpp  |  8 ++---
 src/operation/polygonize/EdgeRing.cpp              |  2 +-
 src/operation/valid/IsValidOp.cpp                  | 36 +++++--------------
 tests/unit/geom/GeometryFactoryTest.cpp            |  7 ++--
 23 files changed, 87 insertions(+), 136 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list