[geos-commits] [SCM] GEOS branch master updated. 47c50306157577e9a923ab532a9361eb65bd2074

git at osgeo.org git at osgeo.org
Mon Jun 3 05:24:29 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  47c50306157577e9a923ab532a9361eb65bd2074 (commit)
       via  73851a3508f759c6692577862ab54fc762900d33 (commit)
       via  62a875357de7b971debc7e7f85a5a7ed462dc649 (commit)
      from  09ca35b403759c07a98aec829add26364f08a156 (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 47c50306157577e9a923ab532a9361eb65bd2074
Merge: 09ca35b 73851a3
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Jun 3 08:23:26 2019 -0400

    Merge branch 'voronoi-perf'

diff --cc include/geos/triangulate/DelaunayTriangulationBuilder.h
index 38379d2,e42d967..3f79bd6
--- a/include/geos/triangulate/DelaunayTriangulationBuilder.h
+++ b/include/geos/triangulate/DelaunayTriangulationBuilder.h
@@@ -64,13 -62,11 +64,13 @@@ public
      static std::unique_ptr<geom::CoordinateSequence> extractUniqueCoordinates(const geom::Geometry& geom);
  
      /**
 -     * Converts all {@link Coordinate}s in a collection to {@link Vertex}es.
 +     * Converts all {@link geom::Coordinate}s in a collection to
 +     * {@link quadedge::Vertex}es.
 +     *
       * @param coords the coordinates to convert
-      * @return a List of Vertex objects. Call takes ownership of returned object.
+      * @return a List of Vertex objects.
       */
-     static IncrementalDelaunayTriangulator::VertexList* toVertices(const geom::CoordinateSequence& coords);
+     static IncrementalDelaunayTriangulator::VertexList toVertices(const geom::CoordinateSequence& coords);
  
      /**
       * Returns a CoordinateSequence containing only the unique coordinates of its input.

commit 73851a3508f759c6692577862ab54fc762900d33
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed May 29 21:30:58 2019 -0400

    Improve performance of VoronoiDiagramBuilder
    
    - Ensure vertices are inserted in sorted order
    - Reduce manual memory allocation
    - Remove some unnecessary copying
    - Use unordered_set instead of set
    
    Overall performance improvement is about 20-30% using the random points
    benchmark for the case of a Geometry input. The improvement is > 5x for
    the case of a CoordinateSequence input due to a performance bug
    (vertices not sorted) that may have been recently introduced.

diff --git a/include/geos/triangulate/DelaunayTriangulationBuilder.h b/include/geos/triangulate/DelaunayTriangulationBuilder.h
index e39e9bf..e42d967 100644
--- a/include/geos/triangulate/DelaunayTriangulationBuilder.h
+++ b/include/geos/triangulate/DelaunayTriangulationBuilder.h
@@ -64,9 +64,9 @@ public:
     /**
      * Converts all {@link Coordinate}s in a collection to {@link Vertex}es.
      * @param coords the coordinates to convert
-     * @return a List of Vertex objects. Call takes ownership of returned object.
+     * @return a List of Vertex objects.
      */
-    static IncrementalDelaunayTriangulator::VertexList* toVertices(const geom::CoordinateSequence& coords);
+    static IncrementalDelaunayTriangulator::VertexList toVertices(const geom::CoordinateSequence& coords);
 
     /**
      * Returns a CoordinateSequence containing only the unique coordinates of its input.
@@ -78,7 +78,7 @@ public:
 private:
     std::unique_ptr<geom::CoordinateSequence> siteCoords;
     double tolerance;
-    quadedge::QuadEdgeSubdivision* subdiv;
+    std::unique_ptr<quadedge::QuadEdgeSubdivision> subdiv;
 
 public:
     /**
@@ -87,7 +87,7 @@ public:
      */
     DelaunayTriangulationBuilder();
 
-    ~DelaunayTriangulationBuilder();
+    ~DelaunayTriangulationBuilder() = default;
 
     /**
      * Sets the sites (vertices) which will be triangulated.
diff --git a/include/geos/triangulate/IncrementalDelaunayTriangulator.h b/include/geos/triangulate/IncrementalDelaunayTriangulator.h
index b4ad5fc..058ec2b 100644
--- a/include/geos/triangulate/IncrementalDelaunayTriangulator.h
+++ b/include/geos/triangulate/IncrementalDelaunayTriangulator.h
@@ -54,7 +54,7 @@ public:
      */
     IncrementalDelaunayTriangulator(quadedge::QuadEdgeSubdivision* subdiv);
 
-    typedef std::list<quadedge::Vertex> VertexList;
+    typedef std::vector<quadedge::Vertex> VertexList;
 
     /**
      * Inserts all sites in a collection. The inserted vertices <b>MUST</b> be
diff --git a/include/geos/triangulate/VoronoiDiagramBuilder.h b/include/geos/triangulate/VoronoiDiagramBuilder.h
index 37df492..81f47f4 100644
--- a/include/geos/triangulate/VoronoiDiagramBuilder.h
+++ b/include/geos/triangulate/VoronoiDiagramBuilder.h
@@ -125,7 +125,7 @@ private:
     void create();
 
     static std::unique_ptr<geom::GeometryCollection>
-    clipGeometryCollection(const geom::GeometryCollection& geom, const geom::Envelope& clipEnv);
+    clipGeometryCollection(std::vector<std::unique_ptr<geom::Geometry>> & geoms, const geom::Envelope& clipEnv);
 
 };
 
diff --git a/include/geos/triangulate/quadedge/QuadEdgeSubdivision.h b/include/geos/triangulate/quadedge/QuadEdgeSubdivision.h
index ce5a49c..eb16295 100644
--- a/include/geos/triangulate/quadedge/QuadEdgeSubdivision.h
+++ b/include/geos/triangulate/quadedge/QuadEdgeSubdivision.h
@@ -22,7 +22,7 @@
 #include <memory>
 #include <list>
 #include <stack>
-#include <set>
+#include <unordered_set>
 #include <vector>
 
 #include <geos/geom/MultiLineString.h>
@@ -353,8 +353,8 @@ public:
 
 private:
     typedef std::stack<QuadEdge*> QuadEdgeStack;
-    typedef std::set<QuadEdge*> QuadEdgeSet;
-    typedef std::list< geom::CoordinateSequence*> TriList;
+    typedef std::unordered_set<QuadEdge*> QuadEdgeSet;
+    typedef std::vector<geom::CoordinateSequence*> TriList;
 
     /**
      * The quadedges forming a single triangle.
@@ -443,7 +443,7 @@ public:
      * @param geomFact a geometry factory
      * @return a List of Polygons
      */
-    std::unique_ptr< std::vector<geom::Geometry*> > getVoronoiCellPolygons(const geom::GeometryFactory& geomFact);
+    std::vector<std::unique_ptr<geom::Geometry>> getVoronoiCellPolygons(const geom::GeometryFactory& geomFact);
 
     /**
      * Gets a List of {@link LineString}s for the Voronoi cells
@@ -486,7 +486,7 @@ public:
      * @param geomFact a factory for building the polygon
      * @return a polygon indicating the cell extent
      */
-    std::unique_ptr<geom::Geometry> getVoronoiCellPolygon(QuadEdge* qe, const geom::GeometryFactory& geomFact);
+    std::unique_ptr<geom::Geometry> getVoronoiCellPolygon(const QuadEdge* qe, const geom::GeometryFactory& geomFact);
 
     /**
      * Gets the Voronoi cell edge around a site specified
@@ -499,7 +499,7 @@ public:
      * @param geomFact a factory for building the polygon
      * @return a polygon indicating the cell extent
      */
-    std::unique_ptr<geom::Geometry> getVoronoiCellEdge(QuadEdge* qe, const geom::GeometryFactory& geomFact);
+    std::unique_ptr<geom::Geometry> getVoronoiCellEdge(const QuadEdge* qe, const geom::GeometryFactory& geomFact);
 
 };
 
diff --git a/src/triangulate/DelaunayTriangulationBuilder.cpp b/src/triangulate/DelaunayTriangulationBuilder.cpp
index 389aa9e..684a4e9 100644
--- a/src/triangulate/DelaunayTriangulationBuilder.cpp
+++ b/src/triangulate/DelaunayTriangulationBuilder.cpp
@@ -62,15 +62,14 @@ DelaunayTriangulationBuilder::unique(const CoordinateSequence* seq) {
     }
 }
 
-IncrementalDelaunayTriangulator::VertexList*
+IncrementalDelaunayTriangulator::VertexList
 DelaunayTriangulationBuilder::toVertices(
     const CoordinateSequence& coords)
 {
-    IncrementalDelaunayTriangulator::VertexList* vertexList =
-        new IncrementalDelaunayTriangulator::VertexList();
+    IncrementalDelaunayTriangulator::VertexList vertexList(coords.size());
 
-    for(size_t iter = 0; iter < coords.size(); ++iter) {
-        vertexList->push_back(quadedge::Vertex(coords.getAt(iter)));
+    for(size_t i = 0; i < coords.size(); i++) {
+        vertexList[i] = quadedge::Vertex(coords.getAt(i));
     }
     return vertexList;
 }
@@ -80,13 +79,6 @@ DelaunayTriangulationBuilder::DelaunayTriangulationBuilder() :
 {
 }
 
-DelaunayTriangulationBuilder::~DelaunayTriangulationBuilder()
-{
-    if(subdiv) {
-        delete subdiv;
-    }
-}
-
 void
 DelaunayTriangulationBuilder::setSites(const Geometry& geom)
 {
@@ -110,11 +102,12 @@ DelaunayTriangulationBuilder::create()
 
     Envelope siteEnv;
     siteCoords ->expandEnvelope(siteEnv);
-    IncrementalDelaunayTriangulator::VertexList* vertices = toVertices(*siteCoords);
-    subdiv = new quadedge::QuadEdgeSubdivision(siteEnv, tolerance);
-    IncrementalDelaunayTriangulator triangulator = IncrementalDelaunayTriangulator(subdiv);
-    triangulator.insertSites(*vertices);
-    delete vertices;
+    auto vertices = toVertices(*siteCoords);
+    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());
+    triangulator.insertSites(vertices);
 }
 
 quadedge::QuadEdgeSubdivision&
@@ -144,12 +137,7 @@ geom::Envelope
 DelaunayTriangulationBuilder::envelope(const geom::CoordinateSequence& coords)
 {
     Envelope env;
-    std::vector<Coordinate> coord_vector;
-    coords.toVector(coord_vector);
-    for(std::vector<Coordinate>::iterator it = coord_vector.begin() ; it != coord_vector.end() ; ++it) {
-        const Coordinate& coord = *it;
-        env.expandToInclude(coord);
-    }
+    coords.expandEnvelope(env);
     return env;
 }
 
diff --git a/src/triangulate/IncrementalDelaunayTriangulator.cpp b/src/triangulate/IncrementalDelaunayTriangulator.cpp
index 8ca0d0b..7becab8 100644
--- a/src/triangulate/IncrementalDelaunayTriangulator.cpp
+++ b/src/triangulate/IncrementalDelaunayTriangulator.cpp
@@ -36,9 +36,8 @@ IncrementalDelaunayTriangulator::IncrementalDelaunayTriangulator(
 void
 IncrementalDelaunayTriangulator::insertSites(const VertexList& vertices)
 {
-    for(VertexList::const_iterator x = vertices.begin();
-            x != vertices.end(); ++x) {
-        insertSite(*x);
+    for(const auto& vertex : vertices) {
+        insertSite(vertex);
     }
 }
 
diff --git a/src/triangulate/VoronoiDiagramBuilder.cpp b/src/triangulate/VoronoiDiagramBuilder.cpp
index a65b7c8..702e43c 100644
--- a/src/triangulate/VoronoiDiagramBuilder.cpp
+++ b/src/triangulate/VoronoiDiagramBuilder.cpp
@@ -86,13 +86,12 @@ VoronoiDiagramBuilder::create()
         diagramEnv.expandToInclude(clipEnv);
     }
 
-    std::unique_ptr<IncrementalDelaunayTriangulator::VertexList> vertices(
-        DelaunayTriangulationBuilder::toVertices(*siteCoords)
-    );
+    auto vertices = DelaunayTriangulationBuilder::toVertices(*siteCoords);
+    std::sort(vertices.begin(), vertices.end()); // Best performance from locator when inserting points near each other
 
     subdiv.reset(new quadedge::QuadEdgeSubdivision(diagramEnv, tolerance));
     IncrementalDelaunayTriangulator triangulator(subdiv.get());
-    triangulator.insertSites(*vertices);
+    triangulator.insertSites(vertices);
 }
 
 std::unique_ptr<quadedge::QuadEdgeSubdivision>
@@ -107,8 +106,15 @@ std::unique_ptr<geom::GeometryCollection>
 VoronoiDiagramBuilder::getDiagram(const geom::GeometryFactory& geomFact)
 {
     create();
-    std::unique_ptr<geom::GeometryCollection> polys = subdiv->getVoronoiDiagram(geomFact);
-    return clipGeometryCollection(*polys, diagramEnv);
+
+    auto polys = subdiv->getVoronoiCellPolygons(geomFact);
+    auto ret = clipGeometryCollection(polys, diagramEnv);
+
+    if (ret == nullptr) {
+        return std::unique_ptr<geom::GeometryCollection>(geomFact.createGeometryCollection());
+    }
+
+    return ret;
 }
 
 std::unique_ptr<geom::Geometry>
@@ -125,28 +131,36 @@ VoronoiDiagramBuilder::getDiagramEdges(const geom::GeometryFactory& geomFact)
 }
 
 std::unique_ptr<geom::GeometryCollection>
-VoronoiDiagramBuilder::clipGeometryCollection(const geom::GeometryCollection& geom, const geom::Envelope& clipEnv)
+VoronoiDiagramBuilder::clipGeometryCollection(std::vector<std::unique_ptr<Geometry>> & geoms, const geom::Envelope& clipEnv)
 {
-    std::unique_ptr<geom::Geometry> clipPoly(geom.getFactory()->toGeometry(&clipEnv));
+    if (geoms.empty()) {
+        return nullptr;
+    }
+
+    auto gfact = geoms[0]->getFactory();
+
+    std::unique_ptr<geom::Geometry> clipPoly(gfact->toGeometry(&clipEnv));
     std::unique_ptr< std::vector<Geometry*> >clipped(new std::vector<Geometry*>);
-    for(std::size_t i = 0 ; i < geom.getNumGeometries() ; i++) {
-        const Geometry* g = geom.getGeometryN(i);
+
+    for(auto& g : geoms) {
         std::unique_ptr<Geometry> result;
+
         // don't clip unless necessary
         if(clipEnv.contains(g->getEnvelopeInternal())) {
-            result = g->clone();
+            result = std::move(g);
             // TODO: check if userData is correctly cloned here?
         }
         else if(clipEnv.intersects(g->getEnvelopeInternal())) {
-            result = clipPoly->intersection(g);
-            result->setUserData(((Geometry*)g)->getUserData()); // TODO: needed ?
+            result = clipPoly->intersection(g.get());
+            result->setUserData(g->getUserData()); // TODO: needed ?
         }
 
         if(result.get() && !result->isEmpty()) {
             clipped->push_back(result.release());
         }
     }
-    return std::unique_ptr<GeometryCollection>(geom.getFactory()->createGeometryCollection(clipped.release()));
+
+    return std::unique_ptr<GeometryCollection>(gfact->createGeometryCollection(clipped.release()));
 }
 
 } //namespace geos.triangulate
diff --git a/src/triangulate/quadedge/QuadEdgeSubdivision.cpp b/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
index 62cd765..75fd1bb 100644
--- a/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
+++ b/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
@@ -517,8 +517,15 @@ QuadEdgeSubdivision::getTriangles(const GeometryFactory& geomFact)
 std::unique_ptr<geom::GeometryCollection>
 QuadEdgeSubdivision::getVoronoiDiagram(const geom::GeometryFactory& geomFact)
 {
-    std::unique_ptr< std::vector<geom::Geometry*> > vorCells = getVoronoiCellPolygons(geomFact);
-    return std::unique_ptr<GeometryCollection>(geomFact.createGeometryCollection(vorCells.release()));
+    auto vorCells = getVoronoiCellPolygons(geomFact);
+
+    // TODO remove loop when GeometryFactory API handles unique_ptr
+    std::unique_ptr<std::vector<Geometry*>> rawCells(new std::vector<Geometry*>(vorCells.size()));
+    for (size_t i = 0; i < rawCells->size(); i++) {
+        (*rawCells)[i] = vorCells[i].release();
+    }
+
+    return std::unique_ptr<GeometryCollection>(geomFact.createGeometryCollection(rawCells.release()));
 }
 
 std::unique_ptr<geom::MultiLineString>
@@ -528,22 +535,20 @@ QuadEdgeSubdivision::getVoronoiDiagramEdges(const geom::GeometryFactory& geomFac
     return std::unique_ptr<MultiLineString>(geomFact.createMultiLineString(vorCells.release()));
 }
 
-std::unique_ptr< std::vector<geom::Geometry*> >
+std::vector<std::unique_ptr<geom::Geometry>>
 QuadEdgeSubdivision::getVoronoiCellPolygons(const geom::GeometryFactory& geomFact)
 {
-    std::unique_ptr< std::vector<geom::Geometry*> > cells(new std::vector<geom::Geometry*>);
-    TriangleCircumcentreVisitor* tricircumVisitor = new TriangleCircumcentreVisitor();
-    visitTriangles((TriangleVisitor*)tricircumVisitor, true);
+    std::vector<std::unique_ptr<geom::Geometry>> cells;
+    TriangleCircumcentreVisitor tricircumVisitor;
 
-    std::unique_ptr<QuadEdgeSubdivision::QuadEdgeList> edges = getVertexUniqueEdges(false);
+    visitTriangles((TriangleVisitor*) &tricircumVisitor, true);
 
-    for(QuadEdgeSubdivision::QuadEdgeList::iterator it = edges->begin() ; it != edges->end() ; ++it) {
-        QuadEdge* qe = *it;
-        std::unique_ptr<geom::Geometry> poly = getVoronoiCellPolygon(qe, geomFact);
+    std::unique_ptr<QuadEdgeSubdivision::QuadEdgeList> edges = getVertexUniqueEdges(false);
 
-        cells->push_back(poly.release());
+    for(const QuadEdge* qe : *edges) {
+        cells.push_back(getVoronoiCellPolygon(qe, geomFact));
     }
-    delete tricircumVisitor;
+
     return cells;
 }
 
@@ -551,50 +556,48 @@ std::unique_ptr< std::vector<geom::Geometry*> >
 QuadEdgeSubdivision::getVoronoiCellEdges(const geom::GeometryFactory& geomFact)
 {
     std::unique_ptr< std::vector<geom::Geometry*> > cells(new std::vector<geom::Geometry*>);
-    TriangleCircumcentreVisitor* tricircumVisitor = new TriangleCircumcentreVisitor();
-    visitTriangles((TriangleVisitor*)tricircumVisitor, true);
+    TriangleCircumcentreVisitor tricircumVisitor;
+
+    visitTriangles((TriangleVisitor*) &tricircumVisitor, true);
 
     std::unique_ptr<QuadEdgeSubdivision::QuadEdgeList> edges = getVertexUniqueEdges(false);
 
-    for(QuadEdgeSubdivision::QuadEdgeList::iterator it = edges->begin() ; it != edges->end() ; ++it) {
-        QuadEdge* qe = *it;
+    for(const QuadEdge* qe : *edges) {
         std::unique_ptr<geom::Geometry> poly = getVoronoiCellEdge(qe, geomFact);
 
         cells->push_back(poly.release());
     }
-    delete tricircumVisitor;
+
     return cells;
 }
 
 std::unique_ptr<geom::Geometry>
-QuadEdgeSubdivision::getVoronoiCellPolygon(QuadEdge* qe, const geom::GeometryFactory& geomFact)
+QuadEdgeSubdivision::getVoronoiCellPolygon(const QuadEdge* qe, const geom::GeometryFactory& geomFact)
 {
-    std::vector<Coordinate> cellPts;
-    QuadEdge* startQE = qe;
+    std::unique_ptr<std::vector<Coordinate>> cellPts(new std::vector<Coordinate>());
+    const QuadEdge* startQE = qe;
     do {
-        Coordinate cc = qe->rot().orig().getCoordinate();
-        if(cellPts.empty() || cellPts.back() != cc) {  // no duplicates
-            cellPts.push_back(cc);
+        const Coordinate& cc = qe->rot().orig().getCoordinate();
+        if(cellPts->empty() || cellPts->back() != cc) {  // no duplicates
+            cellPts->push_back(cc);
         }
         qe = &qe->oPrev();
 
     }
     while(qe != startQE);
 
-
-    //CoordList from a vector of Coordinates.
-    geom::CoordinateList coordList(cellPts);
-    //for checking close ring in CoordList class:
-    coordList.closeRing();
-
-    if(coordList.size() < 4) {
-        coordList.insert(coordList.end(), *(coordList.end()), true);
+    // Close the ring
+    if (cellPts->front() != cellPts->back()) {
+        cellPts->push_back(cellPts->front());
+    }
+    if (cellPts->size() < 4) {
+        cellPts->push_back(cellPts->back());
     }
 
-    std::unique_ptr<Coordinate::Vect> pts = coordList.toCoordinateArray();
     std::unique_ptr<geom::Geometry> cellPoly(
-        geomFact.createPolygon(geomFact.createLinearRing(new geom::CoordinateArraySequence(pts.release())), nullptr));
+        geomFact.createPolygon(geomFact.createLinearRing(new geom::CoordinateArraySequence(cellPts.release())), nullptr));
 
+    // FIXME why is this returning a pointer to a local variable?
     Vertex v = startQE->orig();
     Coordinate c(0, 0);
     c = v.getCoordinate();
@@ -603,30 +606,29 @@ QuadEdgeSubdivision::getVoronoiCellPolygon(QuadEdge* qe, const geom::GeometryFac
 }
 
 std::unique_ptr<geom::Geometry>
-QuadEdgeSubdivision::getVoronoiCellEdge(QuadEdge* qe, const geom::GeometryFactory& geomFact)
+QuadEdgeSubdivision::getVoronoiCellEdge(const QuadEdge* qe, const geom::GeometryFactory& geomFact)
 {
-    std::vector<Coordinate> cellPts;
-    QuadEdge* startQE = qe;
+    std::unique_ptr<std::vector<Coordinate>> cellPts(new std::vector<Coordinate>());
+    const QuadEdge* startQE = qe;
     do {
-        Coordinate cc = qe->rot().orig().getCoordinate();
-        if(cellPts.empty() || cellPts.back() != cc) {  // no duplicates
-            cellPts.push_back(cc);
+        const Coordinate& cc = qe->rot().orig().getCoordinate();
+        if(cellPts->empty() || cellPts->back() != cc) {  // no duplicates
+            cellPts->push_back(cc);
         }
         qe = &qe->oPrev();
 
     }
     while(qe != startQE);
 
+    // Close the ring
+    if (cellPts->front() != cellPts->back()) {
+        cellPts->push_back(cellPts->front());
+    }
 
-    //CoordList from a vector of Coordinates.
-    geom::CoordinateList coordList(cellPts);
-    //for checking close ring in CoordList class:
-    coordList.closeRing();
-
-    std::unique_ptr<Coordinate::Vect> pts = coordList.toCoordinateArray();
     std::unique_ptr<geom::Geometry> cellEdge(
-        geomFact.createLineString(new geom::CoordinateArraySequence(pts.release())));
+        geomFact.createLineString(new geom::CoordinateArraySequence(cellPts.release())));
 
+    // FIXME why is this returning a pointer to a local variable?
     Vertex v = startQE->orig();
     Coordinate c(0, 0);
     c = v.getCoordinate();
@@ -638,21 +640,20 @@ std::unique_ptr<QuadEdgeSubdivision::QuadEdgeList>
 QuadEdgeSubdivision::getVertexUniqueEdges(bool includeFrame)
 {
     std::unique_ptr<QuadEdgeSubdivision::QuadEdgeList> edges(new QuadEdgeList());
-    std::set<Vertex> visitedVertices;
-    for(QuadEdgeSubdivision::QuadEdgeList::iterator it = quadEdges.begin() ; it != quadEdges.end() ; ++it) {
-        QuadEdge* qe = (QuadEdge*)(*it);
-        Vertex v = qe->orig();
+    std::set<Vertex> visitedVertices; // TODO unordered_set of Vertex* ?
 
+    for(QuadEdge* qe : quadEdges) {
+        const Vertex& v = qe->orig();
 
         if(visitedVertices.find(v) == visitedVertices.end()) {	//if v not found
             visitedVertices.insert(v);
+
             if(includeFrame || ! QuadEdgeSubdivision::isFrameVertex(v)) {
                 edges->push_back(qe);
             }
         }
         QuadEdge* qd = &(qe->sym());
-        Vertex vd = qd->orig();
-
+        const Vertex& vd = qd->orig();
 
         if(visitedVertices.find(vd) == visitedVertices.end()) {
             visitedVertices.insert(vd);
diff --git a/tests/unit/triangulate/quadedge/QuadEdgeSubdivisionTest.cpp b/tests/unit/triangulate/quadedge/QuadEdgeSubdivisionTest.cpp
index 2506747..79f53cd 100644
--- a/tests/unit/triangulate/quadedge/QuadEdgeSubdivisionTest.cpp
+++ b/tests/unit/triangulate/quadedge/QuadEdgeSubdivisionTest.cpp
@@ -94,10 +94,10 @@ void object::test<2>
     double expandBy = std::max(Env.getWidth(), Env.getHeight());
     Env.expandBy(expandBy);
 
-    IncrementalDelaunayTriangulator::VertexList* vertices = DelaunayTriangulationBuilder::toVertices(*siteCoords);
+    IncrementalDelaunayTriangulator::VertexList vertices = DelaunayTriangulationBuilder::toVertices(*siteCoords);
     subdiv = new quadedge::QuadEdgeSubdivision(Env, 0);
     IncrementalDelaunayTriangulator triangulator(subdiv);
-    triangulator.insertSites(*vertices);
+    triangulator.insertSites(vertices);
 
     //Test for getVoronoiDiagram::
     const GeometryFactory& geomFact(*GeometryFactory::getDefaultInstance());
@@ -112,7 +112,6 @@ void object::test<2>
     ensure(polys->equalsExact(expected, 1e-7));
     delete sites;
     delete subdiv;
-    delete vertices;
     delete expected;
 //		ensure(polys->getCoordinateDimension() == expected->getCoordinateDimension());
 }
@@ -141,12 +140,10 @@ template<> template<> void object::test<3>
         new quadedge::QuadEdgeSubdivision(env, 10)
     );
 
-    std::unique_ptr<IncrementalDelaunayTriangulator::VertexList> vertices(
-        DelaunayTriangulationBuilder::toVertices(*siteCoords)
-    );
+    auto vertices(DelaunayTriangulationBuilder::toVertices(*siteCoords));
 
     IncrementalDelaunayTriangulator triangulator(subdiv.get());
-    triangulator.insertSites(*vertices);
+    triangulator.insertSites(vertices);
 
     //Test for getVoronoiDiagram::
     const GeometryFactory& geomFact(*GeometryFactory::getDefaultInstance());

commit 62a875357de7b971debc7e7f85a5a7ed462dc649
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed May 29 21:26:18 2019 -0400

    Add Voronoi perf test

diff --git a/benchmarks/algorithm/CMakeLists.txt b/benchmarks/algorithm/CMakeLists.txt
index 5a0703e..2aad3ab 100644
--- a/benchmarks/algorithm/CMakeLists.txt
+++ b/benchmarks/algorithm/CMakeLists.txt
@@ -12,3 +12,6 @@
 #################################################################################
 add_executable(perf_interiorpoint_area InteriorPointAreaPerfTest.cpp)
 target_link_libraries(perf_interiorpoint_area geos)
+
+add_executable(perf_voronoi VoronoiPerfTest.cpp)
+target_link_libraries(perf_voronoi geos)
diff --git a/benchmarks/algorithm/VoronoiPerfTest.cpp b/benchmarks/algorithm/VoronoiPerfTest.cpp
new file mode 100644
index 0000000..9ab6789
--- /dev/null
+++ b/benchmarks/algorithm/VoronoiPerfTest.cpp
@@ -0,0 +1,91 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2019 Daniel Baston <dbaston at gmail.com>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************/
+
+#include <geos/triangulate/DelaunayTriangulationBuilder.h>
+#include <geos/triangulate/VoronoiDiagramBuilder.h>
+#include <geos/geom/CoordinateArraySequence.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/profiler.h>
+
+#include <algorithm>
+#include <random>
+#include <vector>
+#include <memory>
+
+class VoronoiPerfTest {
+
+public:
+    void test(size_t num_points) {
+        using namespace geos::geom;
+
+        std::default_random_engine e(12345);
+        std::uniform_real_distribution<> dis(0, 100);
+
+        std::unique_ptr<std::vector<Coordinate>> coords(new std::vector<Coordinate>(num_points));
+        std::generate(coords->begin(), coords->end(), [&dis, &e]() {
+            return Coordinate(dis(e), dis(e));
+        });
+        CoordinateArraySequence seq(coords.release());
+        auto geom = gfact->createLineString(seq.clone());
+
+        voronoi(seq);
+        voronoi(*geom);
+
+        delaunay(seq);
+        delaunay(*geom);
+
+        std::cout << std::endl;
+    }
+private:
+    decltype(geos::geom::GeometryFactory::create()) gfact = geos::geom::GeometryFactory::create();
+
+    template<typename T>
+    void voronoi(const T & sites) {
+        geos::util::Profile sw(std::string("Voronoi from ") + typeid(T).name());
+        sw.start();
+
+        geos::triangulate::VoronoiDiagramBuilder vdb;
+        vdb.setSites(sites);
+
+        auto result = vdb.getDiagram(*gfact);
+        sw.stop();
+
+        std::cout << sw.name << ": " << result->getNumGeometries() << ": " << sw.getTotFormatted() << std::endl;
+    }
+
+    template<typename T>
+    void delaunay(const T & seq) {
+        geos::util::Profile sw(std::string("Delaunay from ") + typeid(T).name());
+        sw.start();
+
+        geos::triangulate::DelaunayTriangulationBuilder dtb;
+        dtb.setSites(seq);
+
+        auto result = dtb.getTriangles(*gfact);
+
+        sw.stop();
+        std::cout << sw.name << ": " << result->getNumGeometries() << ": " << sw.getTotFormatted() << std::endl;
+    }
+};
+
+int main() {
+    VoronoiPerfTest tester;
+
+    //tester.test(100);
+    //tester.test(1000);
+    //tester.test(10000);
+    for (auto i = 0; i < 5; i++) {
+        tester.test(100000);
+    }
+}
\ No newline at end of file

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

Summary of changes:
 benchmarks/algorithm/CMakeLists.txt                |   3 +
 benchmarks/algorithm/VoronoiPerfTest.cpp           |  91 ++++++++++++++++++
 .../triangulate/DelaunayTriangulationBuilder.h     |   8 +-
 .../triangulate/IncrementalDelaunayTriangulator.h  |   2 +-
 include/geos/triangulate/VoronoiDiagramBuilder.h   |   2 +-
 .../triangulate/quadedge/QuadEdgeSubdivision.h     |  12 +--
 src/triangulate/DelaunayTriangulationBuilder.cpp   |  34 +++----
 .../IncrementalDelaunayTriangulator.cpp            |   5 +-
 src/triangulate/VoronoiDiagramBuilder.cpp          |  42 ++++++---
 src/triangulate/quadedge/QuadEdgeSubdivision.cpp   | 105 +++++++++++----------
 .../quadedge/QuadEdgeSubdivisionTest.cpp           |  11 +--
 11 files changed, 204 insertions(+), 111 deletions(-)
 create mode 100644 benchmarks/algorithm/VoronoiPerfTest.cpp


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list