DYT/Tool/OpenSceneGraph-3.6.5/include/geos/operation/polygonize/Polygonizer.h

261 lines
8.0 KiB
C
Raw Permalink Normal View History

2024-12-24 23:49:36 +00:00
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2010 Sandro Santilli <strk@kbt.io>
* 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 <geos/export.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/GeometryComponentFilter.h> // for LineStringAdder inheritance
#include <geos/operation/polygonize/PolygonizeGraph.h>
#include <memory>
#include <vector>
#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:
*
* - <b>Dangles</b> - edges which have one or both ends which are
* not incident on another edge endpoint
* - <b>Cut Edges</b> - edges which are connected at both ends but
* which do not form part of a polygon
* - <b>Invalid Ring Lines</b> - 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<EdgeRing*>& edgeRingList,
std::vector<EdgeRing*>& validEdgeRingList,
std::vector<EdgeRing*>& invalidRingList);
/**
* Extracts unique lines for invalid rings,
* discarding rings which correspond to outer rings and hence contain
* duplicate linework.
*/
std::vector<std::unique_ptr<geom::LineString>> extractInvalidLines(
std::vector<EdgeRing*>& 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<EdgeRing*>& edgeRingList);
void findDisjointShells();
static void findOuterShells(std::vector<EdgeRing*>& shellList);
static std::vector<std::unique_ptr<geom::Polygon>> extractPolygons(std::vector<EdgeRing*> & shellList, bool includeAll);
bool extractOnlyPolygonal;
bool computed;
protected:
std::unique_ptr<PolygonizeGraph> graph;
// initialize with empty collections, in case nothing is computed
std::vector<const geom::LineString*> dangles;
std::vector<const geom::LineString*> cutEdges;
std::vector<std::unique_ptr<geom::LineString>> invalidRingLines;
std::vector<EdgeRing*> holeList;
std::vector<EdgeRing*> shellList;
std::vector<std::unique_ptr<geom::Polygon>> 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<geom::Geometry*>* 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<const geom::Geometry*>* 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(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<std::unique_ptr<geom::Polygon>> 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<const geom::LineString*>& 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<const geom::LineString*>& 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<std::unique_ptr<geom::LineString>>& 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