DYT/Tool/OpenSceneGraph-3.6.5/include/geos/operation/buffer/BufferBuilder.h

271 lines
7.7 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) 2009-2011 Sandro Santilli <strk@kbt.io>
* Copyright (C) 2008-2010 Safe Software Inc.
* Copyright (C) 2006-2007 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/buffer/BufferBuilder.java 149b38907 (JTS-1.12)
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <vector>
#include <geos/operation/buffer/BufferOp.h> // for inlines (BufferOp enums)
#include <geos/operation/buffer/OffsetCurveBuilder.h> // for inline (OffsetCurveBuilder enums)
#include <geos/geomgraph/EdgeList.h> // for composition
#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 PrecisionModel;
class Geometry;
class GeometryFactory;
}
namespace algorithm {
class LineIntersector;
}
namespace noding {
class Noder;
class SegmentString;
class IntersectionAdder;
}
namespace geomgraph {
class Edge;
class Label;
class PlanarGraph;
}
namespace operation {
namespace buffer {
class BufferSubgraph;
}
namespace overlay {
class PolygonBuilder;
}
}
}
namespace geos {
namespace operation { // geos.operation
namespace buffer { // geos.operation.buffer
/**
*
* \brief
* Builds the buffer geometry for a given input geometry and precision model.
*
* Allows setting the level of approximation for circular arcs,
* and the precision model in which to carry out the computation.
*
* When computing buffers in floating point double-precision
* it can happen that the process of iterated noding can fail to converge
* (terminate).
*
* In this case a TopologyException will be thrown.
* Retrying the computation in a fixed precision
* can produce more robust results.
*
*/
class GEOS_DLL BufferBuilder {
public:
/**
* Creates a new BufferBuilder
*
* @param nBufParams buffer parameters, this object will
* keep a reference to the passed parameters
* so caller must make sure the object is
* kept alive for the whole lifetime of
* the buffer builder.
*/
BufferBuilder(const BufferParameters& nBufParams)
:
bufParams(nBufParams),
workingPrecisionModel(nullptr),
li(nullptr),
intersectionAdder(nullptr),
workingNoder(nullptr),
geomFact(nullptr),
edgeList(),
isInvertOrientation(false)
{}
~BufferBuilder();
/**
* Sets the precision model to use during the curve computation
* and noding,
* if it is different to the precision model of the Geometry.
* If the precision model is less than the precision of the
* Geometry precision model,
* the Geometry must have previously been rounded to that precision.
*
* @param pm the precision model to use
*/
void
setWorkingPrecisionModel(const geom::PrecisionModel* pm)
{
workingPrecisionModel = pm;
}
/**
* Sets the {@link noding::Noder} to use during noding.
* This allows choosing fast but non-robust noding, or slower
* but robust noding.
*
* @param newNoder the noder to use
*/
void
setNoder(noding::Noder* newNoder)
{
workingNoder = newNoder;
}
/**
* Sets whether the offset curve is generated
* using the inverted orientation of input rings.
* This allows generating a buffer(0) polygon from the smaller lobes
* of self-crossing rings.
*
* @param p_isInvertOrientation true if input ring orientation should be inverted
*/
void
setInvertOrientation(bool p_isInvertOrientation)
{
isInvertOrientation = p_isInvertOrientation;
}
std::unique_ptr<geom::Geometry> buffer(const geom::Geometry* g, double distance);
/**
* Generates offset curve for linear geometry.
*
* @param g non-areal geometry object
* @param distance width of offset
* @param leftSide controls on which side of the input geometry
* offset curve is generated.
*
* @note For left-side offset curve, the offset will be at the left side
* of the input line and retain the same direction.
* For right-side offset curve, it'll be at the right side
* and in the opposite direction.
*
* @note BufferParameters::setSingleSided parameter, which is specific to
* areal geometries only, is ignored by this routine.
*
* @note Not in JTS: this is a GEOS extension
*/
std::unique_ptr<geom::Geometry> bufferLineSingleSided(
const geom::Geometry* g,
double distance, bool leftSide);
private:
/**
* Compute the change in depth as an edge is crossed from R to L
*/
static int depthDelta(const geomgraph::Label& label);
const BufferParameters& bufParams;
const geom::PrecisionModel* workingPrecisionModel;
algorithm::LineIntersector* li;
noding::IntersectionAdder* intersectionAdder;
noding::Noder* workingNoder;
const geom::GeometryFactory* geomFact;
geomgraph::EdgeList edgeList;
std::vector<geomgraph::Label*> newLabels;
bool isInvertOrientation;
void computeNodedEdges(std::vector<noding::SegmentString*>& bufSegStr,
const geom::PrecisionModel* precisionModel);
// throw(GEOSException);
/**
* Inserted edges are checked to see if an identical edge already
* exists.
* If so, the edge is not inserted, but its label is merged
* with the existing edge.
*
* The function takes responsibility of releasing the Edge parameter
* memory when appropriate.
*/
void insertUniqueEdge(geomgraph::Edge* e);
void createSubgraphs(geomgraph::PlanarGraph* graph,
std::vector<BufferSubgraph*>& list);
/**
* Completes the building of the input subgraphs by
* depth-labelling them,
* and adds them to the PolygonBuilder.
* The subgraph list must be sorted in rightmost-coordinate order.
*
* @param subgraphList the subgraphs to build
* @param polyBuilder the PolygonBuilder which will build
* the final polygons
*/
void buildSubgraphs(const std::vector<BufferSubgraph*>& subgraphList,
overlay::PolygonBuilder& polyBuilder);
/// \brief
/// Return the externally-set noding::Noder OR a newly created
/// one using the given precisionModel.
///
/// NOTE: if an externally-set noding::Noder is available no
/// check is performed to ensure it will use the
/// given PrecisionModel
///
noding::Noder* getNoder(const geom::PrecisionModel* precisionModel);
/**
* Gets the standard result for an empty buffer.
* Since buffer always returns a polygonal result,
* this is chosen to be an empty polygon.
*
* @return the empty result geometry, transferring ownership to caller.
*/
std::unique_ptr<geom::Geometry> createEmptyResultGeometry() const;
// Declare type as noncopyable
BufferBuilder(const BufferBuilder& other) = delete;
BufferBuilder& operator=(const BufferBuilder& rhs) = delete;
};
} // namespace geos::operation::buffer
} // namespace geos::operation
} // namespace geos
#ifdef _MSC_VER
#pragma warning(pop)
#endif