DYT/Tool/OpenSceneGraph-3.6.5/include/geos/simplify/PolygonHullSimplifier.h

233 lines
7.4 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) 2021 Paul Ramsey <pramsey@cleverelephant.ca>
*
* 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.
*
**********************************************************************/
#pragma once
#include <geos/geom/Geometry.h>
#include <geos/util/IllegalArgumentException.h>
#include <geos/simplify/RingHull.h>
namespace geos {
namespace geom {
class GeometryFactory;
class LinearRing;
class MultiPolygon;
class Polygon;
}
namespace algorithm {
namespace hull {
class RingHullIndex;
}
}
}
using geos::geom::Envelope;
using geos::geom::Geometry;
using geos::geom::GeometryFactory;
using geos::geom::LinearRing;
using geos::geom::MultiPolygon;
using geos::geom::Polygon;
namespace geos {
namespace simplify { // geos::simplify
/**
* Computes topology-preserving simplified hulls of polygonal geometry.
* Both outer and inner hulls can be computed.
* Outer hulls contain the input geometry and are larger in area.
* Inner hulls are contained by the input geometry and are smaller in area.
* In both the hull vertices are a subset of the input vertices.
* The hull construction attempts to minimize the area difference
* with the input geometry.
* Hulls are generally concave if the input is.
* Computed hulls are topology-preserving:
* they do not contain any self-intersections or overlaps,
* so the result polygonal geometry is valid.
*
* Polygons with holes and MultiPolygons are supported.
* The result has the same geometric type and structure as the input.
*
* The number of vertices in the computed hull is determined by a target parameter.
* Two parameters are supported:
*
* * Vertex Number fraction: the fraction of the input vertices retained in the result.
* Value 1 produces the original geometry.
* Smaller values produce less concave results.
* For outer hulls, value 0 produces the convex hull (with triangles for any holes).
* For inner hulls, value 0 produces a triangle (if no holes are present).
*
* * Area Delta ratio: the ratio of the change in area to the input area.
* Value 0 produces the original geometry.
* Larger values produce less concave results.
*
* The algorithm ensures that the result does not cause the target parameter
* to be exceeded. This allows computing outer or inner hulls
* with a small area delta ratio as an effective way of removing
* narrow gores and spikes.
*
* @author Martin Davis
*
*/
class GEOS_DLL PolygonHullSimplifier
{
public:
/**
* Creates a new instance
* to compute a simplified hull of a polygonal geometry.
* An outer or inner hull is computed
* depending on the value of "isOuter".
*
* @param geom the polygonal geometry to process
* @param bOuter indicates whether to compute an outer or inner hull
*/
PolygonHullSimplifier(const Geometry* geom, bool bOuter)
: inputGeom(geom)
, geomFactory(geom->getFactory())
, isOuter(bOuter)
, vertexNumFraction(-1.0)
, areaDeltaRatio(-1.0)
{
if (!geom->isPolygonal()) {
throw util::IllegalArgumentException("Input geometry must be polygonal");
}
};
/**
* Computes a topology-preserving simplified hull of a polygonal geometry,
* with hull shape determined by a target parameter
* specifying the fraction of the input vertices retained in the result.
* Larger values compute less concave results.
* A value of 1 produces the convex hull; a value of 0 produces the original geometry.
* Either outer or inner hulls can be computed.
*
* @param geom the polygonal geometry to process
* @param isOuter indicates whether to compute an outer or inner hull
* @param vertexNumFraction the target fraction of number of input vertices in result
* @return the hull geometry
*/
static std::unique_ptr<Geometry> hull(
const Geometry* geom,
bool isOuter,
double vertexNumFraction);
/**
* Computes a topology-preserving simplified hull of a polygonal geometry,
* with hull shape determined by a target parameter
* specifying the ratio of maximum difference in area to original area.
* Larger values compute less concave results.
* A value of 0 produces the original geometry.
* Either outer or inner hulls can be computed..
*
* @param geom the polygonal geometry to process
* @param isOuter indicates whether to compute an outer or inner hull
* @param areaDeltaRatio the target ratio of area difference to original area
* @return the hull geometry
*/
static std::unique_ptr<Geometry> hullByAreaDelta(
const Geometry* geom,
bool isOuter,
double areaDeltaRatio);
/**
* Sets the target fraction of input vertices
* which are retained in the result.
* The value should be in the range [0,1].
*
* @param p_vertexNumFraction a fraction of the number of input vertices
*/
void setVertexNumFraction(double p_vertexNumFraction);
/**
* Sets the target maximum ratio of the change in area of the result to the input area.
* The value must be 0 or greater.
*
* @param p_areaDeltaRatio a ratio of the change in area of the result
*/
void setAreaDeltaRatio(double p_areaDeltaRatio);
/**
* Gets the result polygonal hull geometry.
*
* @return the polygonal geometry for the hull
*/
std::unique_ptr<Geometry> getResult();
private:
// Members
const Geometry* inputGeom;
const GeometryFactory* geomFactory;
bool isOuter;
double vertexNumFraction;
double areaDeltaRatio;
// Allocate the RingHull* in here so they are cleaned
// up with PolygonHullSimplifier
std::vector<std::unique_ptr<RingHull>> ringStore;
/**
* Computes hulls for MultiPolygon elements for
* the cases where hulls might overlap.
*
* @param multiPoly the MultiPolygon to process
* @return the hull geometry
*/
std::unique_ptr<Geometry> computeMultiPolygonAll(const MultiPolygon* multiPoly);
std::unique_ptr<Geometry> computeMultiPolygonEach(const MultiPolygon* multiPoly);
std::unique_ptr<Polygon> computePolygon(const Polygon* poly);
/**
* Create all ring hulls for the rings of a polygon,
* so that all are in the hull index if required.
*
* @param poly the polygon being processed
* @param hullIndex the hull index if present, or null
* @return the list of ring hulls
*/
std::vector<RingHull*> initPolygon(const Polygon* poly,
RingHullIndex& hullIndex);
double ringArea(const Polygon* poly) const;
RingHull* createRingHull(
const LinearRing* ring,
bool isOuter,
double areaTotal,
RingHullIndex& hullIndex);
std::unique_ptr<Polygon> polygonHull(
const Polygon* poly,
std::vector<RingHull*>& ringHulls,
RingHullIndex& hullIndex) const;
/**
* Disable copy construction and assignment. Needed to make this
* class compile under MSVC. (See https://stackoverflow.com/q/29565299)
*/
PolygonHullSimplifier(const PolygonHullSimplifier&) = delete;
PolygonHullSimplifier& operator=(const PolygonHullSimplifier&) = delete;
}; // PolygonHullSimplifier
} // geos::simplify
} // geos