diff --git a/include/geos/operation/overlay/MaximalEdgeRing.h b/include/geos/operation/overlay/MaximalEdgeRing.h deleted file mode 100644 index ad918dfce6..0000000000 --- a/include/geos/operation/overlay/MaximalEdgeRing.h +++ /dev/null @@ -1,105 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2006 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/MaximalEdgeRing.java rev. 1.15 (JTS-1.10) - * - **********************************************************************/ - -#pragma once - -#include - -#include - -#include // for inheritance - -// Forward declarations -namespace geos { -namespace geom { -class GeometryFactory; -} -namespace geomgraph { -class DirectedEdge; -//class EdgeRing; -} -namespace operation { -namespace overlay { -class MinimalEdgeRing; -} -} -} - -namespace geos { -namespace operation { // geos::operation -namespace overlay { // geos::operation::overlay - -/** \brief - * A ring of [DirectedEdges](@ref geomgraph::DirectedEdge) which may contain nodes of degree > 2. - * - * A MaximalEdgeRing may represent two different spatial entities: - * - * - a single polygon possibly containing inversions (if the ring is oriented CW) - * - a single hole possibly containing exversions (if the ring is oriented CCW) - * - * If the MaximalEdgeRing represents a polygon, - * the interior of the polygon is strongly connected. - * - * These are the form of rings used to define polygons under some spatial data models. - * However, under the OGC SFS model, [MinimalEdgeRings](@ref MinimalEdgeRing) are required. - * A MaximalEdgeRing can be converted to a list of MinimalEdgeRings using the - * {@link #buildMinimalRings() } method. - * - * @see com.vividsolutions.jts.operation.overlay.MinimalEdgeRing - */ -class GEOS_DLL MaximalEdgeRing: public geomgraph::EdgeRing { - -public: - - MaximalEdgeRing(geomgraph::DirectedEdge* start, - const geom::GeometryFactory* geometryFactory); - // throw(const TopologyException &) - - ~MaximalEdgeRing() override = default; - - geomgraph::DirectedEdge* getNext(geomgraph::DirectedEdge* de) override; - - void setEdgeRing(geomgraph::DirectedEdge* de, geomgraph::EdgeRing* er) override; - - /// \brief - /// This function returns a newly allocated vector of - /// pointers to newly allocated MinimalEdgeRing objects. - /// - /// @deprecated pass the vector yourself instead - /// - std::vector* buildMinimalRings(); - - /// \brief - /// This function pushes pointers to newly allocated MinimalEdgeRing - /// objects to the provided vector. - /// - void buildMinimalRings(std::vector& minEdgeRings); - void buildMinimalRings(std::vector& minEdgeRings); - - /// \brief - /// For all nodes in this EdgeRing, - /// link the DirectedEdges at the node to form minimalEdgeRings - /// - void linkDirectedEdgesForMinimalEdgeRings(); -}; - - -} // namespace geos::operation::overlay -} // namespace geos::operation -} // namespace geos - diff --git a/include/geos/operation/overlay/MinimalEdgeRing.h b/include/geos/operation/overlay/MinimalEdgeRing.h deleted file mode 100644 index c2df90eabf..0000000000 --- a/include/geos/operation/overlay/MinimalEdgeRing.h +++ /dev/null @@ -1,80 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2006 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/MinimalEdgeRing.java rev. 1.13 (JTS-1.10) - * - **********************************************************************/ - -#pragma once - - -#include - -#include // for inheritance -#include // for inlines - -#include - -// Forward declarations -namespace geos { -namespace geom { -class GeometryFactory; -} -namespace geomgraph { -class DirectedEdge; -class EdgeRing; -} -} - -namespace geos { -namespace operation { // geos::operation -namespace overlay { // geos::operation::overlay - -/** \brief - * A ring of [Edges](@ref geomgraph::Edge) with the property that no node - * has degree greater than 2. - * - * These are the form of rings required to represent polygons - * under the OGC SFS spatial data model. - * - * @see operation::overlay::MaximalEdgeRing - * - */ -class GEOS_DLL MinimalEdgeRing: public geomgraph::EdgeRing { - -public: - - MinimalEdgeRing(geomgraph::DirectedEdge* start, - const geom::GeometryFactory* geometryFactory); - - ~MinimalEdgeRing() override {}; - - geomgraph::DirectedEdge* getNext(geomgraph::DirectedEdge* de) override - { - return de->getNextMin(); - }; - - void setEdgeRing(geomgraph::DirectedEdge* de, - geomgraph::EdgeRing* er) override - { - de->setMinEdgeRing(er); - }; - -}; - - -} // namespace geos::operation::overlay -} // namespace geos::operation -} // namespace geos - diff --git a/include/geos/operation/overlay/OverlayNodeFactory.h b/include/geos/operation/overlay/OverlayNodeFactory.h deleted file mode 100644 index 74ba8d9552..0000000000 --- a/include/geos/operation/overlay/OverlayNodeFactory.h +++ /dev/null @@ -1,56 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2006 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/OverlayNodeFactory.java rev. 1.11 (JTS-1.10) - * - **********************************************************************/ - -#pragma once - -#include - -#include - -#include // for inheritance - -// Forward declarations -namespace geos { -namespace geom { -class Coordinate; -} -namespace geomgraph { -class Node; -} -} - -namespace geos { -namespace operation { // geos::operation -namespace overlay { // geos::operation::overlay - -/** \brief - * Creates nodes for use in the geomgraph::PlanarGraph constructed during - * overlay operations. NOTE: also used by operation::valid - */ -class GEOS_DLL OverlayNodeFactory: public geomgraph::NodeFactory { -public: - OverlayNodeFactory(): geomgraph::NodeFactory() {} - geomgraph::Node* createNode(const geom::Coordinate& coord) const override; - static const geomgraph::NodeFactory& instance(); -}; - - -} // namespace geos::operation::overlay -} // namespace geos::operation -} // namespace geos - diff --git a/include/geos/operation/overlay/PolygonBuilder.h b/include/geos/operation/overlay/PolygonBuilder.h deleted file mode 100644 index e39e9b6c08..0000000000 --- a/include/geos/operation/overlay/PolygonBuilder.h +++ /dev/null @@ -1,210 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2006 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/PolygonBuilder.java rev. 1.20 (JTS-1.10) - * - **********************************************************************/ - -#pragma once - -#include -#include - -#include - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class -#endif - -// Forward declarations -namespace geos { -namespace geom { -class Geometry; -class Coordinate; -class GeometryFactory; -} -namespace geomgraph { -class EdgeRing; -class Node; -class PlanarGraph; -class DirectedEdge; -} -namespace operation { -namespace overlay { -class MaximalEdgeRing; -class MinimalEdgeRing; -} -} -} - -namespace geos { -namespace operation { // geos::operation -namespace overlay { // geos::operation::overlay - -/** \brief - * Forms Polygon out of a graph of geomgraph::DirectedEdge. - * - * The edges to use are marked as being in the result Area. - */ -class GEOS_DLL PolygonBuilder { -public: - - PolygonBuilder(const geom::GeometryFactory* newGeometryFactory); - - ~PolygonBuilder(); - - /** - * Add a complete graph. - * The graph is assumed to contain one or more polygons, - * possibly with holes. - */ - void add(geomgraph::PlanarGraph* graph); - // throw(const TopologyException &) - - /** - * Add a set of edges and nodes, which form a graph. - * The graph is assumed to contain one or more polygons, - * possibly with holes. - */ - void add(const std::vector* dirEdges, - const std::vector* nodes); - // throw(const TopologyException &) - - std::vector> getPolygons(); - -private: - - const geom::GeometryFactory* geometryFactory; - - std::vector shellList; - - /** - * For all DirectedEdges in result, form them into MaximalEdgeRings - * - * @param maxEdgeRings - * Formed MaximalEdgeRings will be pushed to this vector. - * Ownership of the elements is transferred to caller. - */ - void buildMaximalEdgeRings( - const std::vector* dirEdges, - std::vector& maxEdgeRings); - // throw(const TopologyException &) - - void buildMinimalEdgeRings( - std::vector& maxEdgeRings, - std::vector& newShellList, - std::vector& freeHoleList, - std::vector& edgeRings); - - /** - * This method takes a list of MinimalEdgeRings derived from a - * MaximalEdgeRing, and tests whether they form a Polygon. - * This is the case if there is a single shell - * in the list. In this case the shell is returned. - * The other possibility is that they are a series of connected - * holes, in which case no shell is returned. - * - * @return the shell geomgraph::EdgeRing, if there is one - * @return NULL, if all the rings are holes - */ - geomgraph::EdgeRing* findShell(std::vector* minEdgeRings); - - /** - * This method assigns the holes for a Polygon (formed from a list of - * MinimalEdgeRings) to its shell. - * Determining the holes for a MinimalEdgeRing polygon serves two - * purposes: - * - * - it is faster than using a point-in-polygon check later on. - * - it ensures correctness, since if the PIP test was used the point - * chosen might lie on the shell, which might return an incorrect - * result from the PIP test - */ - void placePolygonHoles(geomgraph::EdgeRing* shell, - std::vector* minEdgeRings); - - /** - * For all rings in the input list, - * determine whether the ring is a shell or a hole - * and add it to the appropriate list. - * Due to the way the DirectedEdges were linked, - * a ring is a shell if it is oriented CW, a hole otherwise. - */ - void sortShellsAndHoles(std::vector& edgeRings, - std::vector& newShellList, - std::vector& freeHoleList); - - struct FastPIPRing { - geomgraph::EdgeRing* edgeRing; - algorithm::locate::IndexedPointInAreaLocator* pipLocator; - }; - - /** \brief - * This method determines finds a containing shell for all holes - * which have not yet been assigned to a shell. - * - * These "free" holes should all be properly contained in - * their parent shells, so it is safe to use the - * findEdgeRingContaining method. - * This is the case because any holes which are NOT - * properly contained (i.e. are connected to their - * parent shell) would have formed part of a MaximalEdgeRing - * and been handled in a previous step. - * - * @throws TopologyException if a hole cannot be assigned to a shell - */ - void placeFreeHoles(std::vector& newShellList, - std::vector& freeHoleList); - // throw(const TopologyException&) - - /** \brief - * Find the innermost enclosing shell geomgraph::EdgeRing containing the - * argument geomgraph::EdgeRing, if any. - * - * The innermost enclosing ring is the smallest enclosing ring. - * The algorithm used depends on the fact that: - * - * ring A contains ring B iff envelope(ring A) - * contains envelope(ring B) - * - * This routine is only safe to use if the chosen point of the hole - * is known to be properly contained in a shell - * (which is guaranteed to be the case if the hole does not touch - * its shell) - * - * @return containing geomgraph::EdgeRing, if there is one - * @return NULL if no containing geomgraph::EdgeRing is found - */ - geomgraph::EdgeRing* findEdgeRingContaining(geomgraph::EdgeRing* testEr, - std::vector& newShellList); - - std::vector> computePolygons( - std::vector& newShellList); - - /** - * Checks the current set of shells (with their associated holes) to - * see if any of them contain the point. - */ - -}; - -} // namespace geos::operation::overlay -} // namespace geos::operation -} // namespace geos - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - diff --git a/src/operation/overlay/MaximalEdgeRing.cpp b/src/operation/overlay/MaximalEdgeRing.cpp deleted file mode 100644 index 6221944e1b..0000000000 --- a/src/operation/overlay/MaximalEdgeRing.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2005-2006 Refractions Research Inc. - * Copyright (C) 2001-2002 Vivid Solutions Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/MaximalEdgeRing.java rev. 1.15 (JTS-1.10) - * - **********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef GEOS_DEBUG -#define GEOS_DEBUG 0 -#endif - -#if GEOS_DEBUG -#include -#endif - - -using namespace geos::geomgraph; -using namespace geos::geom; - -namespace geos { -namespace operation { // geos.operation -namespace overlay { // geos.operation.overlay - -/*public*/ -MaximalEdgeRing::MaximalEdgeRing(DirectedEdge* start, - const GeometryFactory* p_geometryFactory) -// throw(const TopologyException &) - : - EdgeRing(start, p_geometryFactory) -{ - computePoints(start); - computeRing(); -#if GEOS_DEBUG - std::cerr << "MaximalEdgeRing[" << this << "] ctor" << std::endl; -#endif -} - -/*public*/ -DirectedEdge* -MaximalEdgeRing::getNext(DirectedEdge* de) -{ - return de->getNext(); -} - -/*public*/ -void -MaximalEdgeRing::setEdgeRing(DirectedEdge* de, EdgeRing* er) -{ - de->setEdgeRing(er); -} - -/*public*/ -void -MaximalEdgeRing::linkDirectedEdgesForMinimalEdgeRings() -{ - DirectedEdge* de = startDe; - do { - Node* node = de->getNode(); - EdgeEndStar* ees = node->getEdges(); - - DirectedEdgeStar* des = detail::down_cast(ees); - - des->linkMinimalDirectedEdges(this); - - de = de->getNext(); - - } - while(de != startDe); -} - -/*public*/ -std::vector* -MaximalEdgeRing::buildMinimalRings() -{ - std::vector* minEdgeRings = new std::vector; - buildMinimalRings(*minEdgeRings); - return minEdgeRings; -} - -/*public*/ -void -MaximalEdgeRing::buildMinimalRings(std::vector& minEdgeRings) -{ - DirectedEdge* de = startDe; - do { - if(de->getMinEdgeRing() == nullptr) { - MinimalEdgeRing* minEr = new MinimalEdgeRing(de, geometryFactory); - minEdgeRings.push_back(minEr); - } - de = de->getNext(); - } - while(de != startDe); -} - -/*public*/ -void -MaximalEdgeRing::buildMinimalRings(std::vector& minEdgeRings) -{ - DirectedEdge* de = startDe; - do { - if(de->getMinEdgeRing() == nullptr) { - MinimalEdgeRing* minEr = new MinimalEdgeRing(de, geometryFactory); - minEdgeRings.push_back(minEr); - } - de = de->getNext(); - } - while(de != startDe); -} - -} // namespace geos.operation.overlay -} // namespace geos.operation -} // namespace geos diff --git a/src/operation/overlay/MinimalEdgeRing.cpp b/src/operation/overlay/MinimalEdgeRing.cpp deleted file mode 100644 index fd5cc2e72a..0000000000 --- a/src/operation/overlay/MinimalEdgeRing.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2001-2002 Vivid Solutions Inc. - * Copyright (C) 2005 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/MinimalEdgeRing.java rev. 1.13 (JTS-1.10) - * - **********************************************************************/ - -#include -#include - - -namespace geos { -namespace operation { // geos.operation -namespace overlay { // geos.operation.overlay - - -MinimalEdgeRing::MinimalEdgeRing(geomgraph::DirectedEdge* start, - const geom::GeometryFactory* p_geometryFactory) - : - geomgraph::EdgeRing(start, p_geometryFactory) -{ - computePoints(start); - computeRing(); -} - - -} // namespace geos.operation.overlay -} // namespace geos.operation -} // namespace geos - diff --git a/src/operation/overlay/OverlayNodeFactory.cpp b/src/operation/overlay/OverlayNodeFactory.cpp deleted file mode 100644 index 095008da5f..0000000000 --- a/src/operation/overlay/OverlayNodeFactory.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2001-2002 Vivid Solutions Inc. - * Copyright (C) 2005 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/OverlayNodeFactory.java rev. 1.11 (JTS-1.10) - * - **********************************************************************/ - -#include -#include -#include - -using namespace geos::geomgraph; - -namespace geos { -namespace operation { // geos.operation -namespace overlay { // geos.operation.overlay - -Node* -OverlayNodeFactory::createNode(const geom::Coordinate& coord) const -{ - return new Node(coord, new DirectedEdgeStar()); -} - -const NodeFactory& -OverlayNodeFactory::instance() -{ - static OverlayNodeFactory onf; - return onf; -} - -} // namespace geos.operation.overlay -} // namespace geos.operation -} // namespace geos - diff --git a/src/operation/overlay/PolygonBuilder.cpp b/src/operation/overlay/PolygonBuilder.cpp deleted file mode 100644 index e0223b4328..0000000000 --- a/src/operation/overlay/PolygonBuilder.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/********************************************************************** - * - * GEOS - Geometry Engine Open Source - * http://geos.osgeo.org - * - * Copyright (C) 2001-2002 Vivid Solutions Inc. - * Copyright (C) 2005 Refractions Research Inc. - * - * 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. - * - ********************************************************************** - * - * Last port: operation/overlay/PolygonBuilder.java rev. 1.20 (JTS-1.10) - * - **********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include - -#ifndef GEOS_DEBUG -#define GEOS_DEBUG 0 -#endif - -#if GEOS_DEBUG -#include -#endif - -using namespace geos::geomgraph; -using namespace geos::algorithm; -using namespace geos::geom; - -namespace geos { -namespace operation { // geos.operation -namespace overlay { // geos.operation.overlay - -PolygonBuilder::PolygonBuilder(const GeometryFactory* newGeometryFactory) - : - geometryFactory(newGeometryFactory) -{ -} - -PolygonBuilder::~PolygonBuilder() -{ - for(std::size_t i = 0, n = shellList.size(); i < n; ++i) { - delete shellList[i]; - } -} - -/*public*/ -void -PolygonBuilder::add(PlanarGraph* graph) -//throw(TopologyException *) -{ - const std::vector* eeptr = graph->getEdgeEnds(); - assert(eeptr); - const std::vector& ee = *eeptr; - - std::size_t eeSize = ee.size(); - -#if GEOS_DEBUG - std::cerr << __FUNCTION__ << ": PlanarGraph has " << eeSize << " EdgeEnds" << std::endl; -#endif - - std::vector dirEdges(eeSize); - for(std::size_t i = 0; i < eeSize; ++i) { - DirectedEdge* de = detail::down_cast(ee[i]); - dirEdges[i] = de; - } - - const auto& nodeMap = graph->getNodeMap()->nodeMap; - std::vector nodes; - nodes.reserve(nodeMap.size()); - for(const auto& nodeIt: nodeMap) { - Node* node = nodeIt.second.get(); - nodes.push_back(node); - } - - add(&dirEdges, &nodes); // might throw a TopologyException * -} - -/*public*/ -void -PolygonBuilder::add(const std::vector* dirEdges, - const std::vector* nodes) -//throw(TopologyException *) -{ - PlanarGraph::linkResultDirectedEdges(nodes->begin(), nodes->end()); - - std::vector maxEdgeRings; - buildMaximalEdgeRings(dirEdges, maxEdgeRings); - - std::vector freeHoleList; - std::vector edgeRings; - buildMinimalEdgeRings(maxEdgeRings, shellList, freeHoleList, edgeRings); - - sortShellsAndHoles(edgeRings, shellList, freeHoleList); - - std::vector indexedshellist; - for(auto const& shell : shellList) { - FastPIPRing pipRing { shell, new geos::algorithm::locate::IndexedPointInAreaLocator(*shell->getLinearRing()) }; - indexedshellist.push_back(pipRing); - } - placeFreeHoles(indexedshellist, freeHoleList); - //Assert: every hole on freeHoleList has a shell assigned to it - - for(auto const& shell : indexedshellist) { - delete shell.pipLocator; - } -} - -/*public*/ -std::vector> -PolygonBuilder::getPolygons() -{ - std::vector> resultPolyList = computePolygons(shellList); - return resultPolyList; -} - - -/*private*/ -void -PolygonBuilder::buildMaximalEdgeRings(const std::vector* dirEdges, - std::vector& maxEdgeRings) -// throw(const TopologyException &) -{ -#if GEOS_DEBUG - std::cerr << "PolygonBuilder::buildMaximalEdgeRings got " << dirEdges->size() << " dirEdges" << std::endl; -#endif - - std::vector::size_type oldSize = maxEdgeRings.size(); - - for(std::size_t i = 0, n = dirEdges->size(); i < n; i++) { - DirectedEdge* de = (*dirEdges)[i]; -#if GEOS_DEBUG - std::cerr << " dirEdge " << i << std::endl - << de->printEdge() << std::endl - << " inResult:" << de->isInResult() << std::endl - << " isArea:" << de->getLabel().isArea() << std::endl; -#endif - if(de->isInResult() && de->getLabel().isArea()) { - // if this edge has not yet been processed - if(de->getEdgeRing() == nullptr) { - MaximalEdgeRing* er; - try { - // MaximalEdgeRing constructor may throw - er = new MaximalEdgeRing(de, geometryFactory); - } - catch(util::GEOSException&) { - // cleanup if that happens (see stmlf-cases-20061020.xml) - for(std::size_t p_i = oldSize, p_n = maxEdgeRings.size(); p_i < p_n; p_i++) { - delete maxEdgeRings[p_i]; - } - //cerr << "Exception! " << e.what() << std::endl; - throw; - } - maxEdgeRings.push_back(er); - er->setInResult(); - //System.out.println("max node degree=" + er.getMaxDegree()); - } - } - } -#if GEOS_DEBUG - std::cerr << " pushed " << maxEdgeRings.size() - oldSize << " maxEdgeRings" << std::endl; -#endif -} - -/*private*/ -void -PolygonBuilder::buildMinimalEdgeRings( - std::vector& maxEdgeRings, - std::vector& newShellList, std::vector& freeHoleList, - std::vector& edgeRings) -{ - for(std::size_t i = 0, n = maxEdgeRings.size(); i < n; ++i) { - MaximalEdgeRing* er = maxEdgeRings[i]; -#if GEOS_DEBUG - std::cerr << "buildMinimalEdgeRings: maxEdgeRing " << i << " has " << er->getMaxNodeDegree() << " maxNodeDegree" << std::endl; -#endif - if(er->getMaxNodeDegree() > 2) { - er->linkDirectedEdgesForMinimalEdgeRings(); - std::vector minEdgeRings; - er->buildMinimalRings(minEdgeRings); - // at this point we can go ahead and attempt to place - // holes, if this EdgeRing is a polygon - EdgeRing* shell = findShell(&minEdgeRings); - if(shell != nullptr) { - placePolygonHoles(shell, &minEdgeRings); - newShellList.push_back(shell); - } - else { - freeHoleList.insert(freeHoleList.end(), - minEdgeRings.begin(), - minEdgeRings.end()); - } - delete er; - } - else { - edgeRings.push_back(er); - } - } -} - -/*private*/ -EdgeRing* -PolygonBuilder::findShell(std::vector* minEdgeRings) -{ - int shellCount = 0; - EdgeRing* shell = nullptr; - -#if GEOS_DEBUG - std::cerr << "PolygonBuilder::findShell got " << minEdgeRings->size() << " minEdgeRings" << std::endl; -#endif - - for(std::size_t i = 0, n = minEdgeRings->size(); i < n; ++i) { - EdgeRing* er = (*minEdgeRings)[i]; - if(! er->isHole()) { - shell = er; - ++shellCount; - } - } - - if(shellCount > 1) { - throw util::TopologyException("found two shells in MinimalEdgeRing list"); - } - - return shell; -} - -/*private*/ -void -PolygonBuilder::placePolygonHoles(EdgeRing* shell, - std::vector* minEdgeRings) -{ - for(std::size_t i = 0, n = minEdgeRings->size(); i < n; ++i) { - MinimalEdgeRing* er = (*minEdgeRings)[i]; - if(er->isHole()) { - er->setShell(shell); - } - } -} - -/*private*/ -void -PolygonBuilder::sortShellsAndHoles(std::vector& edgeRings, - std::vector& newShellList, std::vector& freeHoleList) -{ - for(std::size_t i = 0, n = edgeRings.size(); i < n; i++) { - EdgeRing* er = edgeRings[i]; - //er->setInResult(); - if(er->isHole()) { - freeHoleList.push_back(er); - } - else { - newShellList.push_back(er); - } - } -} - -/*private*/ -void -PolygonBuilder::placeFreeHoles(std::vector& newShellList, - std::vector& freeHoleList) -{ - for(std::vector::iterator - it = freeHoleList.begin(), itEnd = freeHoleList.end(); - it != itEnd; - ++it) { - EdgeRing* hole = *it; - // only place this hole if it doesn't yet have a shell - if(hole->getShell() == nullptr) { - EdgeRing* shell = findEdgeRingContaining(hole, newShellList); - if(shell == nullptr) { -#if GEOS_DEBUG - std::cerr << "CREATE TABLE shells (g geometry);" << std::endl; - std::cerr << "CREATE TABLE hole (g geometry);" << std::endl; - for(std::vector::iterator rIt = newShellList.begin(), - rEnd = newShellList.end(); rIt != rEnd; rIt++) { - std::unique_ptr geom = (*rIt).edgeRing->toPolygon(geometryFactory); - std::cerr << "INSERT INTO shells VALUES ('" - << *geom - << "');" << std::endl; - } - std::unique_ptr geom = hole->toPolygon(geometryFactory); - std::cerr << "INSERT INTO hole VALUES ('" - << *geom - << "');" << std::endl; -#endif - //assert(shell!=NULL); // unable to assign hole to a shell - throw util::TopologyException("unable to assign hole to a shell"); - } - - hole->setShell(shell); - } - } -} - -/*private*/ -EdgeRing* -PolygonBuilder::findEdgeRingContaining(EdgeRing* testEr, - std::vector& newShellList) -{ - LinearRing* testRing = testEr->getLinearRing(); - const Envelope* testEnv = testRing->getEnvelopeInternal(); - EdgeRing* minShell = nullptr; - const Envelope* minShellEnv = nullptr; - - for(auto const& tryShell : newShellList) { - LinearRing* tryShellRing = tryShell.edgeRing->getLinearRing(); - const Envelope* tryShellEnv = tryShellRing->getEnvelopeInternal(); - // the hole envelope cannot equal the shell envelope - // (also guards against testing rings against themselves) - if(tryShellEnv->equals(testEnv)) { - continue; - } - // hole must be contained in shell - if(!tryShellEnv->contains(testEnv)) { - continue; - } - - const CoordinateSequence* tsrcs = tryShellRing->getCoordinatesRO(); - const Coordinate& testPt = operation::polygonize::EdgeRing::ptNotInList(testRing->getCoordinatesRO(), tsrcs); - - bool isContained = false; - if(tryShell.pipLocator->locate(&testPt) != Location::EXTERIOR) { - isContained = true; - } - - // check if this new containing ring is smaller than - // the current minimum ring - if(isContained) { - if(minShell == nullptr - || minShellEnv->contains(tryShellEnv)) { - minShell = tryShell.edgeRing; - minShellEnv = minShell->getLinearRing()->getEnvelopeInternal(); - } - } - } - return minShell; -} - -/*private*/ -std::vector> -PolygonBuilder::computePolygons(std::vector& newShellList) -{ -#if GEOS_DEBUG - std::cerr << "PolygonBuilder::computePolygons: got " << newShellList.size() << " shells" << std::endl; -#endif - std::vector> resultPolyList; - - // add Polygons for all shells - for(std::size_t i = 0, n = newShellList.size(); i < n; i++) { - EdgeRing* er = newShellList[i]; - auto poly = er->toPolygon(geometryFactory); - resultPolyList.push_back(std::move(poly)); - } - return resultPolyList; -} - - -} // namespace geos.operation.overlay -} // namespace geos.operation -} // namespace geos -