271 lines
7.7 KiB
C
271 lines
7.7 KiB
C
|
/**********************************************************************
|
||
|
*
|
||
|
* 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
|
||
|
|