/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2010 Sandro Santilli * Copyright (C) 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/polygonize/Polygonizer.java 0b3c7e3eb0d3e * **********************************************************************/ #pragma once #include #include #include // for LineStringAdder inheritance #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 LineString; class Polygon; } namespace operation { namespace polygonize { class EdgeRing; } } } namespace geos { namespace operation { // geos::operation namespace polygonize { // geos::operation::polygonize /** \brief * Polygonizes a set of Geometrys which contain linework that * represents the edges of a planar graph. * * All types of Geometry are accepted as input; the constituent linework is extracted * as the edges to be polygonized. * The edges must be correctly noded; that is, they must only meet * at their endpoints. Polygonization will accept incorrectly noded input but will * not form polygons from non-noded edges, and reports them as errors. * * The Polygonizer reports the follow kinds of errors: * * - Dangles - edges which have one or both ends which are * not incident on another edge endpoint * - Cut Edges - edges which are connected at both ends but * which do not form part of a polygon * - Invalid Ring Lines - edges which form rings which are invalid * (e.g. the component lines contain a self-intersection) * * The Polygonizer constructor allows extracting only polygons which form a * valid polygonal result. * The set of extracted polygons is guaranteed to be edge-disjoint. * This is useful when it is known that the input lines form a valid * polygonal geometry (which may include holes or nested polygons). * */ class GEOS_DLL Polygonizer { private: /** * Add every linear element in a geometry into the polygonizer graph. */ class GEOS_DLL LineStringAdder: public geom::GeometryComponentFilter { public: Polygonizer* pol; explicit LineStringAdder(Polygonizer* p); //void filter_rw(geom::Geometry *g); void filter_ro(const geom::Geometry* g) override; }; // default factory LineStringAdder lineStringAdder; /** * Add a linestring to the graph of polygon edges. * * @param line the {@link LineString} to add */ void add(const geom::LineString* line); /** * Perform the polygonization, if it has not already been carried out. */ void polygonize(); static void findValidRings(const std::vector& edgeRingList, std::vector& validEdgeRingList, std::vector& invalidRingList); /** * Extracts unique lines for invalid rings, * discarding rings which correspond to outer rings and hence contain * duplicate linework. */ std::vector> extractInvalidLines( std::vector& invalidRings); /** * Tests if a invalid ring should be included in * the list of reported invalid rings. * * Rings are included only if they contain * linework which is not already in a valid ring, * or in an already-included ring. * * Because the invalid rings list is sorted by extent area, * this results in outer rings being discarded, * since all their linework is reported in the rings they contain. * * @param invalidRing the ring to test * @return true if the ring should be included */ bool isIncludedInvalid(EdgeRing* invalidRing); void findShellsAndHoles(const std::vector& edgeRingList); void findDisjointShells(); static void findOuterShells(std::vector& shellList); static std::vector> extractPolygons(std::vector & shellList, bool includeAll); bool extractOnlyPolygonal; bool computed; protected: std::unique_ptr graph; // initialize with empty collections, in case nothing is computed std::vector dangles; std::vector cutEdges; std::vector> invalidRingLines; std::vector holeList; std::vector shellList; std::vector> polyList; public: /** \brief * Create a Polygonizer with the same GeometryFactory * as the input Geometrys. * * @param onlyPolygonal true if only polygons which form a valid polygonal geometry should be extracted */ explicit Polygonizer(bool onlyPolygonal = false); ~Polygonizer() = default; /** \brief * Add a collection of geometries to be polygonized. * May be called multiple times. * Any dimension of Geometry may be added; * the constituent linework will be extracted and used * * @param geomList a list of Geometry with linework to be polygonized */ void add(std::vector* geomList); /** \brief * Add a collection of geometries to be polygonized. * May be called multiple times. * Any dimension of Geometry may be added; * the constituent linework will be extracted and used * * @param geomList a list of Geometry with linework to be polygonized */ void add(std::vector* geomList); /** * Add a geometry to the linework to be polygonized. * May be called multiple times. * Any dimension of Geometry may be added; * the constituent linework will be extracted and used * * @param g a Geometry with linework to be polygonized */ void add(geom::Geometry* g); /** * Add a geometry to the linework to be polygonized. * May be called multiple times. * Any dimension of Geometry may be added; * the constituent linework will be extracted and used * * @param g a Geometry with linework to be polygonized */ void add(const geom::Geometry* g); /** \brief * Gets the list of polygons formed by the polygonization. * * Ownership of vector is transferred to caller, subsequent * calls will return NULL. * @return a collection of Polygons */ std::vector> getPolygons(); /** \brief * Get the list of dangling lines found during polygonization. * * @return a (possibly empty) collection of pointers to * the input LineStrings which are dangles. * */ const std::vector& getDangles(); bool hasDangles(); /** \brief * Get the list of cut edges found during polygonization. * * @return a (possibly empty) collection of pointers to * the input LineStrings which are cut edges. * */ const std::vector& getCutEdges(); bool hasCutEdges(); /** \brief * Get the list of lines forming invalid rings found during * polygonization. * * @return a (possibly empty) collection of pointers to * the input LineStrings which form invalid rings * */ const std::vector>& getInvalidRingLines(); bool hasInvalidRingLines(); bool allInputsFormPolygons(); // This seems to be needed by GCC 2.95.4 friend class Polygonizer::LineStringAdder; }; } // namespace geos::operation::polygonize } // namespace geos::operation } // namespace geos #ifdef _MSC_VER #pragma warning(pop) #endif