[geos-commits] [SCM] GEOS branch main updated. 88a987895022ff77fedad776d7835e5743208abb
git at osgeo.org
git at osgeo.org
Tue Dec 16 06:47:06 PST 2025
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".
The branch, main has been updated
via 88a987895022ff77fedad776d7835e5743208abb (commit)
from e8c6acca2cd023ea699eaa9237695f860e2ee72a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 88a987895022ff77fedad776d7835e5743208abb
Author: Daniel Baston <dbaston at gmail.com>
Date: Tue Dec 16 09:46:35 2025 -0500
SimpleCurve / SegmentString: Store coordinates as std::shared_ptr (#1329)
diff --git a/include/geos/coverage/CoverageCleaner.h b/include/geos/coverage/CoverageCleaner.h
index 79b0ed855..233302045 100644
--- a/include/geos/coverage/CoverageCleaner.h
+++ b/include/geos/coverage/CoverageCleaner.h
@@ -323,7 +323,7 @@ public:
*/
std::vector<const Polygon*> getMergedGaps();
- std::unique_ptr<Geometry> toGeometry(
+ static std::unique_ptr<Geometry> toGeometry(
std::vector<std::unique_ptr<SegmentString>>& segStrings,
const GeometryFactory* geomFact);
diff --git a/include/geos/coverage/CoverageEdge.h b/include/geos/coverage/CoverageEdge.h
index 60afd1c7c..69d8f1fc4 100644
--- a/include/geos/coverage/CoverageEdge.h
+++ b/include/geos/coverage/CoverageEdge.h
@@ -56,7 +56,7 @@ class GEOS_DLL CoverageEdge {
private:
// Members
- std::unique_ptr<CoordinateSequence> m_pts;
+ std::shared_ptr<const CoordinateSequence> m_pts;
std::size_t m_ringCount ;
bool m_isFreeRing = true;
@@ -119,7 +119,7 @@ public:
const GeometryFactory* geomFactory);
std::unique_ptr<LineString> toLineString(
- const GeometryFactory* geomFactory);
+ const GeometryFactory* geomFactory) const;
/* public */
void incRingCount()
@@ -144,14 +144,14 @@ public:
return m_isFreeRing;
}
- void setCoordinates(const CoordinateSequence* pts)
+ void setCoordinates(const std::shared_ptr<const CoordinateSequence>& pts)
{
- m_pts = pts->clone();
+ m_pts = pts;
}
- const CoordinateSequence* getCoordinates() const
+ const std::shared_ptr<const CoordinateSequence>& getCoordinates() const
{
- return m_pts.get();
+ return m_pts;
}
const Coordinate& getEndCoordinate() const
diff --git a/include/geos/coverage/CoveragePolygonValidator.h b/include/geos/coverage/CoveragePolygonValidator.h
index 8c49bcc01..8751be7ed 100644
--- a/include/geos/coverage/CoveragePolygonValidator.h
+++ b/include/geos/coverage/CoveragePolygonValidator.h
@@ -204,7 +204,6 @@ private:
double gapWidth = 0.0;
std::vector<std::unique_ptr<CoveragePolygon>> m_adjCovPolygons;
std::deque<CoverageRing> coverageRingStore;
- std::vector<std::unique_ptr<CoordinateSequence>> localCoordinateSequences;
std::deque<CoverageRingSegment> coverageRingSegmentStore;
typedef std::unordered_map<CoverageRingSegment*, CoverageRingSegment*, CoverageRingSegment::CoverageRingSegHash, CoverageRingSegment::CoverageRingSegEq> CoverageRingSegmentMap;
diff --git a/include/geos/coverage/CoverageRing.h b/include/geos/coverage/CoverageRing.h
index f9a78f730..d74a256b6 100644
--- a/include/geos/coverage/CoverageRing.h
+++ b/include/geos/coverage/CoverageRing.h
@@ -78,7 +78,7 @@ private:
public:
- CoverageRing(CoordinateSequence* pts, bool interiorOnRight);
+ CoverageRing(const std::shared_ptr<const CoordinateSequence>& pts, bool interiorOnRight);
CoverageRing(const LinearRing* ring, bool isShell);
diff --git a/include/geos/geom/CircularString.h b/include/geos/geom/CircularString.h
index 85dc3014e..6a6d5f8c3 100644
--- a/include/geos/geom/CircularString.h
+++ b/include/geos/geom/CircularString.h
@@ -58,6 +58,9 @@ protected:
CircularString(std::unique_ptr<CoordinateSequence>&& pts,
const GeometryFactory& newFactory);
+ CircularString(const std::shared_ptr<const CoordinateSequence>& pts,
+ const GeometryFactory& newFactory);
+
CircularString* cloneImpl() const override
{
return new CircularString(*this);
diff --git a/include/geos/geom/GeometryFactory.h b/include/geos/geom/GeometryFactory.h
index 125217770..4dfe6b593 100644
--- a/include/geos/geom/GeometryFactory.h
+++ b/include/geos/geom/GeometryFactory.h
@@ -236,6 +236,9 @@ public:
std::unique_ptr<LinearRing> createLinearRing(
std::unique_ptr<CoordinateSequence> && newCoords) const;
+ std::unique_ptr<LinearRing> createLinearRing(
+ const std::shared_ptr<const CoordinateSequence>& newCoords) const;
+
/// Construct a LinearRing with a deep-copy of given arguments
std::unique_ptr<LinearRing> createLinearRing(
const CoordinateSequence& coordinates) const;
@@ -312,6 +315,10 @@ public:
std::unique_ptr<LineString> createLineString(
const CoordinateSequence& coordinates) const;
+ /// Construct a LineString with a reference to shared coordinates
+ std::unique_ptr<LineString> createLineString(
+ const std::shared_ptr<const CoordinateSequence>&) const;
+
/// Construct an EMPTY CircularString
std::unique_ptr<CircularString> createCircularString(bool hasZ, bool hasM) const;
@@ -322,6 +329,10 @@ public:
std::unique_ptr<CircularString> createCircularString(
std::unique_ptr<CoordinateSequence> && coordinates) const;
+ /// Construct a CircularStrign with a reference to shared coordinates
+ std::unique_ptr<CircularString> createCircularString(
+ const std::shared_ptr<const CoordinateSequence>& coordinates) const;
+
/// Construct a CircularString with a deep-copy of given argument
std::unique_ptr<CircularString> createCircularString(
const CoordinateSequence& coordinates) const;
diff --git a/include/geos/geom/LineString.h b/include/geos/geom/LineString.h
index 478970874..8d59cda5a 100644
--- a/include/geos/geom/LineString.h
+++ b/include/geos/geom/LineString.h
@@ -114,6 +114,9 @@ protected:
LineString(CoordinateSequence::Ptr && pts,
const GeometryFactory& newFactory);
+ LineString(const std::shared_ptr<const CoordinateSequence> & pts,
+ const GeometryFactory& newFactory);
+
LineString* cloneImpl() const override { return new LineString(*this); }
LineString* reverseImpl() const override;
diff --git a/include/geos/geom/LinearRing.h b/include/geos/geom/LinearRing.h
index b04b3bd35..545bcb655 100644
--- a/include/geos/geom/LinearRing.h
+++ b/include/geos/geom/LinearRing.h
@@ -78,6 +78,9 @@ public:
LinearRing(CoordinateSequence::Ptr && points,
const GeometryFactory& newFactory);
+ LinearRing(const std::shared_ptr<const CoordinateSequence>& points,
+ const GeometryFactory& newFactory);
+
std::unique_ptr<LinearRing> clone() const
{
return std::unique_ptr<LinearRing>(cloneImpl());
diff --git a/include/geos/geom/SimpleCurve.h b/include/geos/geom/SimpleCurve.h
index 1bf674f69..acfc8fc7e 100644
--- a/include/geos/geom/SimpleCurve.h
+++ b/include/geos/geom/SimpleCurve.h
@@ -61,6 +61,9 @@ public:
/// Returns a read-only pointer to internal CoordinateSequence
const CoordinateSequence* getCoordinatesRO() const;
+ /// Returns a read-only pointer to internal CoordinateSequence
+ const std::shared_ptr<const CoordinateSequence>& getSharedCoordinates() const;
+
const SimpleCurve* getCurveN(std::size_t) const override;
/// \brief
@@ -107,19 +110,14 @@ public:
*/
void normalize() override;
- /**
- * \brief
- * Take ownership of the CoordinateSequence managed by this geometry.
- * After releasing the coordinates, the geometry should be considered
- * in a moved-from state and should not be accessed.
- * @return this Geometry's CoordinateSequence.
- */
- std::unique_ptr<CoordinateSequence> releaseCoordinates();
-
protected:
SimpleCurve(const SimpleCurve& other);
+ SimpleCurve(const std::shared_ptr<const CoordinateSequence>& newCoords,
+ bool isLinear,
+ const GeometryFactory& factory);
+
SimpleCurve(std::unique_ptr<CoordinateSequence>&& newCoords,
bool isLinear,
const GeometryFactory& factory);
@@ -128,8 +126,7 @@ protected:
Envelope computeEnvelopeInternal(bool isLinear) const;
- // TODO: hold value or shared_ptr instead of unique_ptr?
- std::unique_ptr<CoordinateSequence> points;
+ std::shared_ptr<const CoordinateSequence> points;
mutable Envelope envelope;
diff --git a/include/geos/geomgraph/EdgeNodingValidator.h b/include/geos/geomgraph/EdgeNodingValidator.h
index 84a506b01..e80b95e9d 100644
--- a/include/geos/geomgraph/EdgeNodingValidator.h
+++ b/include/geos/geomgraph/EdgeNodingValidator.h
@@ -62,12 +62,6 @@ private:
// in turn expects this member to be initialized
std::vector<std::unique_ptr<noding::SegmentString>> segStr;
- // Make sure this member is initialized *before*
- // the NodingValidator, as initialization of
- // NodingValidator will use toSegmentString(), that
- // in turn expects this member to be initialized
- std::vector<geom::CoordinateSequence*> newCoordSeq;
-
noding::FastNodingValidator nv;
public:
@@ -91,7 +85,6 @@ public:
EdgeNodingValidator(std::vector<Edge*>& edges)
:
segStr(),
- newCoordSeq(),
nv(toSegmentStrings(edges))
{}
diff --git a/include/geos/noding/BasicSegmentString.h b/include/geos/noding/BasicSegmentString.h
index 1d253d637..079b02af2 100644
--- a/include/geos/noding/BasicSegmentString.h
+++ b/include/geos/noding/BasicSegmentString.h
@@ -50,7 +50,7 @@ public:
/// @param newPts CoordinateSequence representing the string, externally owned
/// @param newContext the context associated to this SegmentString
///
- BasicSegmentString(geom::CoordinateSequence* newPts,
+ BasicSegmentString(const std::shared_ptr<const geom::CoordinateSequence>& newPts,
const void* newContext)
:
SegmentString(newContext, newPts)
diff --git a/include/geos/noding/NodableSegmentString.h b/include/geos/noding/NodableSegmentString.h
index 8b4e0e1ff..7b3440d95 100644
--- a/include/geos/noding/NodableSegmentString.h
+++ b/include/geos/noding/NodableSegmentString.h
@@ -37,7 +37,7 @@ class GEOS_DLL NodableSegmentString : public SegmentString {
private:
protected:
public:
- NodableSegmentString(const void* newContext, geom::CoordinateSequence* newSeq)
+ NodableSegmentString(const void* newContext, std::shared_ptr<const geom::CoordinateSequence> newSeq)
:
SegmentString(newContext, newSeq)
{ }
diff --git a/include/geos/noding/NodedSegmentString.h b/include/geos/noding/NodedSegmentString.h
index 632ac9493..c63abf708 100644
--- a/include/geos/noding/NodedSegmentString.h
+++ b/include/geos/noding/NodedSegmentString.h
@@ -102,26 +102,23 @@ public:
* @param newContext the user-defined data of this segment string
* (may be null)
*/
- NodedSegmentString(geom::CoordinateSequence* newPts, bool constructZ, bool constructM, const void* newContext)
+ NodedSegmentString(const std::shared_ptr<const geom::CoordinateSequence>& newPts, bool constructZ, bool constructM, const void* newContext)
: NodableSegmentString(newContext, newPts)
, nodeList(*this, constructZ, constructM)
{}
NodedSegmentString(SegmentString* ss, bool constructZ, bool constructM)
- : NodableSegmentString(ss->getData(), ss->getCoordinates()->clone().release())
+ : NodableSegmentString(ss->getData(), ss->getCoordinates())
, nodeList(*this, constructZ, constructM)
{}
~NodedSegmentString() override {
- delete seq;
}
SegmentNodeList& getNodeList();
const SegmentNodeList& getNodeList() const;
- std::unique_ptr<geom::CoordinateSequence> releaseCoordinates();
-
std::ostream& print(std::ostream& os) const override;
/** \brief
diff --git a/include/geos/noding/SegmentNodeList.h b/include/geos/noding/SegmentNodeList.h
index 6791e9704..3abaf4a51 100644
--- a/include/geos/noding/SegmentNodeList.h
+++ b/include/geos/noding/SegmentNodeList.h
@@ -97,7 +97,7 @@ private:
* @param ei1 the end node of the split edge
* @return the points for the split edge
*/
- std::unique_ptr<geom::CoordinateSequence> createSplitEdgePts(const SegmentNode* ei0, const SegmentNode* ei1) const;
+ std::shared_ptr<geom::CoordinateSequence> createSplitEdgePts(const SegmentNode *ei0, const SegmentNode *ei1) const;
/**
* Adds nodes for any collapsed edge pairs.
diff --git a/include/geos/noding/SegmentString.h b/include/geos/noding/SegmentString.h
index 8e08b853b..5b76d8c89 100644
--- a/include/geos/noding/SegmentString.h
+++ b/include/geos/noding/SegmentString.h
@@ -57,7 +57,7 @@ public:
/// @param newContext the context associated to this SegmentString
/// @param newSeq coordinates of this SegmentString
///
- SegmentString(const void* newContext, geom::CoordinateSequence* newSeq)
+ SegmentString(const void* newContext, const std::shared_ptr<const geom::CoordinateSequence>& newSeq)
:
seq(newSeq),
context(newContext)
@@ -100,15 +100,12 @@ public:
/// \brief
/// Return a pointer to the CoordinateSequence associated
/// with this SegmentString.
- ///
- /// @note The CoordinateSequence is owned by this SegmentString!
- ///
- const geom::CoordinateSequence* getCoordinates() const {
+ const std::shared_ptr<const geom::CoordinateSequence>& getCoordinates() const {
return seq;
}
- geom::CoordinateSequence* getCoordinates() {
- return seq;
+ void setCoordinates(const std::shared_ptr<const geom::CoordinateSequence>& newSeq) {
+ seq = newSeq;
}
/** \brief
@@ -176,7 +173,7 @@ public:
virtual std::ostream& print(std::ostream& os) const;
protected:
- geom::CoordinateSequence* seq;
+ std::shared_ptr<const geom::CoordinateSequence> seq;
private:
const void* context;
diff --git a/include/geos/noding/SegmentStringUtil.h b/include/geos/noding/SegmentStringUtil.h
index b780a8f57..f489f6599 100644
--- a/include/geos/noding/SegmentStringUtil.h
+++ b/include/geos/noding/SegmentStringUtil.h
@@ -55,8 +55,8 @@ public:
geom::util::LinearComponentExtracter::getLines(*g, lines);
for(const geom::LineString* line : lines) {
- auto pts = line->getCoordinatesRO();
- segStr.push_back(new BasicSegmentString(const_cast<geom::CoordinateSequence*>(pts), g));
+ const auto& pts = line->getSharedCoordinates();
+ segStr.push_back(new BasicSegmentString(pts, g));
}
}
diff --git a/include/geos/noding/snap/SnappingNoder.h b/include/geos/noding/snap/SnappingNoder.h
index a143419c5..c872fbcc4 100644
--- a/include/geos/noding/snap/SnappingNoder.h
+++ b/include/geos/noding/snap/SnappingNoder.h
@@ -82,7 +82,7 @@ private:
std::unique_ptr<SegmentString> snapVertices(const SegmentString* ss);
- std::unique_ptr<geom::CoordinateSequence> snap(const geom::CoordinateSequence* cs);
+ std::shared_ptr<geom::CoordinateSequence> snap(const geom::CoordinateSequence *cs);
/**
* Computes all interior intersections in the collection of {@link SegmentString}s,
diff --git a/include/geos/operation/buffer/BufferCurveSetBuilder.h b/include/geos/operation/buffer/BufferCurveSetBuilder.h
index 789b8c935..20be31912 100644
--- a/include/geos/operation/buffer/BufferCurveSetBuilder.h
+++ b/include/geos/operation/buffer/BufferCurveSetBuilder.h
@@ -104,7 +104,7 @@ private:
*
* @param coord is raw offset curve, ownership transferred here
*/
- void addCurve(geom::CoordinateSequence* coord, geom::Location leftLoc,
+ void addCurve(std::unique_ptr<geom::CoordinateSequence> coord, geom::Location leftLoc,
geom::Location rightLoc);
void add(const geom::Geometry& g);
@@ -279,7 +279,7 @@ public:
/// @param leftLoc left location
/// @param rightLoc right location
///
- void addCurves(const std::vector<geom::CoordinateSequence*>& lineList,
+ void addCurves(std::vector<std::unique_ptr<geom::CoordinateSequence>>& lineList,
geom::Location leftLoc, geom::Location rightLoc);
/**
diff --git a/include/geos/operation/buffer/OffsetCurveBuilder.h b/include/geos/operation/buffer/OffsetCurveBuilder.h
index 1f6cddf74..0990305f0 100644
--- a/include/geos/operation/buffer/OffsetCurveBuilder.h
+++ b/include/geos/operation/buffer/OffsetCurveBuilder.h
@@ -117,11 +117,10 @@ public:
* @param distance offset distance
* @param lineList the std::vector to which the newly created
* CoordinateSequences will be pushed_back.
- * Caller is responsible to delete these new elements.
*/
void getLineCurve(const CoordinateSequence* inputPts,
double distance,
- std::vector<CoordinateSequence*>& lineList);
+ std::vector<std::unique_ptr<CoordinateSequence>>& lineList);
/**
* This method handles single points as well as LineStrings.
@@ -156,7 +155,7 @@ public:
* @note This is a GEOS extension.
*/
void getSingleSidedLineCurve(const CoordinateSequence* inputPts,
- double distance, std::vector<CoordinateSequence*>& lineList,
+ double distance, std::vector<std::unique_ptr<CoordinateSequence>>& lineList,
bool leftSide, bool rightSide) ;
/** \brief
@@ -171,7 +170,7 @@ public:
*/
void getRingCurve(const CoordinateSequence* inputPts, int side,
double distance,
- std::vector<CoordinateSequence*>& lineList);
+ std::vector<std::unique_ptr<CoordinateSequence>>& lineList);
/**
* This method handles the degenerate cases of single points and lines,
@@ -189,7 +188,7 @@ public:
void getOffsetCurve(const CoordinateSequence* inputPts,
double p_distance,
- std::vector<CoordinateSequence*>& lineList);
+ std::vector<std::unique_ptr<CoordinateSequence>>& lineList);
std::unique_ptr<CoordinateSequence> getOffsetCurve(
const CoordinateSequence* inputPts,
diff --git a/include/geos/operation/buffer/OffsetSegmentGenerator.h b/include/geos/operation/buffer/OffsetSegmentGenerator.h
index 2f3a369c6..5408f8787 100644
--- a/include/geos/operation/buffer/OffsetSegmentGenerator.h
+++ b/include/geos/operation/buffer/OffsetSegmentGenerator.h
@@ -101,9 +101,9 @@ public:
/// FIXME: refactor memory management of this
///
void
- getCoordinates(std::vector<geom::CoordinateSequence*>& to)
+ getCoordinates(std::vector<std::unique_ptr<geom::CoordinateSequence>>& to)
{
- to.push_back(segList.getCoordinates());
+ to.emplace_back(segList.getCoordinates());
}
std::unique_ptr<geom::CoordinateSequence>
diff --git a/include/geos/operation/overlayng/Edge.h b/include/geos/operation/overlayng/Edge.h
index b0f670b7b..4ed90968c 100644
--- a/include/geos/operation/overlayng/Edge.h
+++ b/include/geos/operation/overlayng/Edge.h
@@ -64,7 +64,7 @@ private:
int bDim = OverlayLabel::DIM_UNKNOWN;
int bDepthDelta = 0;
bool bIsHole = false;
- std::unique_ptr<geom::CoordinateSequence> pts;
+ std::shared_ptr<const geom::CoordinateSequence> pts;
// Methods
@@ -198,8 +198,7 @@ public:
static bool isCollapsed(const geom::CoordinateSequence* pts);
- // takes ownership of pts from caller
- Edge(std::unique_ptr<geom::CoordinateSequence>&& p_pts, const EdgeSourceInfo* info);
+ Edge(const std::shared_ptr<const geom::CoordinateSequence>& p_pts, const EdgeSourceInfo* info);
// return a clone of the underlying points
std::unique_ptr<geom::CoordinateSequence> getCoordinates()
@@ -214,10 +213,10 @@ public:
};
// release the underlying points to the caller
- geom::CoordinateSequence* releaseCoordinates()
+ std::shared_ptr<const geom::CoordinateSequence> releaseCoordinates()
{
- geom::CoordinateSequence* cs = pts.release();
- pts.reset(nullptr);
+ auto cs = pts;
+ pts.reset();
return cs;
};
diff --git a/include/geos/operation/overlayng/OverlayEdge.h b/include/geos/operation/overlayng/OverlayEdge.h
index 42d3632cd..031e743a2 100644
--- a/include/geos/operation/overlayng/OverlayEdge.h
+++ b/include/geos/operation/overlayng/OverlayEdge.h
@@ -53,7 +53,7 @@ class GEOS_DLL OverlayEdge : public edgegraph::HalfEdge {
private:
// Members
- const CoordinateSequence* pts;
+ std::shared_ptr<const CoordinateSequence> pts;
/**
* 'true' indicates direction is forward along segString
* 'false' is reverse direction
@@ -80,7 +80,7 @@ public:
OverlayEdge(const CoordinateXYZM& p_orig, const CoordinateXYZM& p_dirPt,
bool p_direction, OverlayLabel* p_label,
- const CoordinateSequence* p_pts)
+ const std::shared_ptr<const CoordinateSequence>& p_pts)
: HalfEdge(p_orig)
, pts(p_pts)
, direction(p_direction)
@@ -124,16 +124,10 @@ public:
const CoordinateSequence* getCoordinatesRO() const
{
- return pts;
+ return pts.get();
};
- std::unique_ptr<CoordinateSequence> getCoordinates()
- {
- // return a copy of pts
- return pts->clone();
- };
-
- std::unique_ptr<CoordinateSequence> getCoordinatesOriented();
+ std::shared_ptr<const CoordinateSequence> getCoordinatesOriented() const;
/**
* Adds the coordinates of this edge to the given list,
diff --git a/include/geos/operation/overlayng/OverlayGraph.h b/include/geos/operation/overlayng/OverlayGraph.h
index e44c46b2e..39dcbd15b 100644
--- a/include/geos/operation/overlayng/OverlayGraph.h
+++ b/include/geos/operation/overlayng/OverlayGraph.h
@@ -63,21 +63,19 @@ private:
std::deque<OverlayEdge> ovEdgeQue;
std::deque<OverlayLabel> ovLabelQue;
- std::vector<std::unique_ptr<const geom::CoordinateSequence>> csQue;
-
// Methods
/**
* Create and add HalfEdge pairs to map and vector containers,
* using local std::deque storage for objects.
*/
- OverlayEdge* createEdgePair(const CoordinateSequence* pts, OverlayLabel* lbl);
+ OverlayEdge* createEdgePair(const std::shared_ptr<const CoordinateSequence> &pts, OverlayLabel *lbl);
/**
* Create a single OverlayEdge in local std::deque storage, and return the
* pointer.
*/
- OverlayEdge* createOverlayEdge(const CoordinateSequence* pts, OverlayLabel* lbl, bool direction);
+ OverlayEdge* createOverlayEdge(const std::shared_ptr<const CoordinateSequence> &pts, OverlayLabel *lbl, bool direction);
void insert(OverlayEdge* e);
diff --git a/include/geos/operation/relateng/RelateGeometry.h b/include/geos/operation/relateng/RelateGeometry.h
index d1282d52f..89d396909 100644
--- a/include/geos/operation/relateng/RelateGeometry.h
+++ b/include/geos/operation/relateng/RelateGeometry.h
@@ -87,7 +87,6 @@ private:
*/
std::vector<std::unique_ptr<const RelateSegmentString>> segStringTempStore;
std::vector<std::unique_ptr<const RelateSegmentString>> segStringPermStore;
- std::vector<std::unique_ptr<CoordinateSequence>> csStore;
// Methods
@@ -133,11 +132,11 @@ private:
std::vector<const SegmentString*>& segStrings,
std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
- const CoordinateSequence* orientAndRemoveRepeated(
- const CoordinateSequence* cs, bool orientCW);
+ static std::shared_ptr<const CoordinateSequence> orientAndRemoveRepeated(
+ const std::shared_ptr<const CoordinateSequence>& cs, bool orientCW);
- const CoordinateSequence* removeRepeated(
- const CoordinateSequence* cs);
+ static std::shared_ptr<const CoordinateSequence> removeRepeated(
+ const std::shared_ptr<const CoordinateSequence>& cs);
public:
diff --git a/include/geos/operation/relateng/RelateSegmentString.h b/include/geos/operation/relateng/RelateSegmentString.h
index dcd486a76..c059092ec 100644
--- a/include/geos/operation/relateng/RelateSegmentString.h
+++ b/include/geos/operation/relateng/RelateSegmentString.h
@@ -62,14 +62,14 @@ private:
// Constructor
RelateSegmentString(
- const CoordinateSequence* pts,
+ std::shared_ptr<const CoordinateSequence> pts,
bool isA,
int dimension,
int id,
int ringId,
const Geometry* poly,
const RelateGeometry* inputGeom)
- : BasicSegmentString(const_cast<CoordinateSequence*>(pts), nullptr)
+ : BasicSegmentString(pts, nullptr)
, m_isA(isA)
, m_dimension(dimension)
, m_id(id)
@@ -82,7 +82,7 @@ private:
// Methods
static const RelateSegmentString* createSegmentString(
- const CoordinateSequence* pts,
+ const std::shared_ptr<const CoordinateSequence>& pts,
bool isA, int dim, int elementId, int ringId,
const Geometry* poly, const RelateGeometry* parent);
@@ -111,14 +111,14 @@ private:
public:
static const RelateSegmentString* createLine(
- const CoordinateSequence* pts,
+ const std::shared_ptr<const CoordinateSequence> &pts,
bool isA, int elementId,
- const RelateGeometry* parent);
+ const RelateGeometry *parent);
static const RelateSegmentString* createRing(
- const CoordinateSequence* pts,
+ const std::shared_ptr<const CoordinateSequence> &pts,
bool isA, int elementId, int ringId,
- const Geometry* poly, const RelateGeometry* parent);
+ const Geometry *poly, const RelateGeometry *parent);
inline bool isA() const {
return m_isA;
@@ -132,7 +132,7 @@ public:
return m_parentPolygonal;
}
- NodeSection* createNodeSection(std::size_t segIndex, const CoordinateXY intPt) const;
+ NodeSection* createNodeSection(std::size_t segIndex, const CoordinateXY &intPt) const;
/**
* Tests if a segment intersection point has that segment as its
diff --git a/include/geos/operation/valid/IsSimpleOp.h b/include/geos/operation/valid/IsSimpleOp.h
index 1f2abfa68..23a178591 100644
--- a/include/geos/operation/valid/IsSimpleOp.h
+++ b/include/geos/operation/valid/IsSimpleOp.h
@@ -129,11 +129,11 @@ private:
bool isSimpleLinearGeometry(const geom::Geometry& geom);
- static std::vector<std::unique_ptr<geos::geom::CoordinateSequence>>
+ static std::vector<std::shared_ptr<const geos::geom::CoordinateSequence>>
removeRepeatedPts(const geom::Geometry& geom);
static std::vector<std::unique_ptr<noding::SegmentString>>
- createSegmentStrings(std::vector<std::unique_ptr<geos::geom::CoordinateSequence>>& seqs);
+ createSegmentStrings(std::vector<std::shared_ptr<const geos::geom::CoordinateSequence>>& seqs);
class NonSimpleIntersectionFinder : public noding::SegmentIntersector
{
diff --git a/include/geos/operation/valid/PolygonTopologyAnalyzer.h b/include/geos/operation/valid/PolygonTopologyAnalyzer.h
index 8d7238112..91beba6bb 100644
--- a/include/geos/operation/valid/PolygonTopologyAnalyzer.h
+++ b/include/geos/operation/valid/PolygonTopologyAnalyzer.h
@@ -55,11 +55,6 @@ private:
// can pass around pointers with abandon
std::deque<PolygonRing> polyRingStore;
std::deque<noding::BasicSegmentString> segStringStore;
- // when building SegmentStrings we sometimes want
- // to use deduped CoordinateSequences so we will
- // keep the deduped ones here so they get cleaned
- // up when processing is complete
- std::vector<std::unique_ptr<CoordinateSequence>> coordSeqStore;
PolygonRing* createPolygonRing(const LinearRing* p_ring);
PolygonRing* createPolygonRing(const LinearRing* p_ring, int p_index, PolygonRing* p_shell);
diff --git a/include/geos/triangulate/polygon/PolygonHoleJoiner.h b/include/geos/triangulate/polygon/PolygonHoleJoiner.h
index 870282f7d..2ed2ec50c 100644
--- a/include/geos/triangulate/polygon/PolygonHoleJoiner.h
+++ b/include/geos/triangulate/polygon/PolygonHoleJoiner.h
@@ -74,8 +74,8 @@ private:
const Polygon* inputPolygon;
//-- normalized, sorted and noded polygon rings
- std::unique_ptr<CoordinateSequence> shellRing;
- std::vector<std::unique_ptr<CoordinateSequence>> holeRings;
+ std::shared_ptr<const CoordinateSequence> shellRing;
+ std::vector<std::shared_ptr<const CoordinateSequence>> holeRings;
//-- indicates whether a hole should be testing for touching
std::vector<bool> isHoleTouchingHint;
@@ -97,7 +97,7 @@ private:
void extractOrientedRings(const Polygon* polygon);
- static std::unique_ptr<CoordinateSequence> extractOrientedRing(const LinearRing* ring, bool isCW);
+ static std::shared_ptr<const CoordinateSequence> extractOrientedRing(const LinearRing* ring, bool isCW);
void nodeRings();
void joinHoles();
diff --git a/include/geos/triangulate/polygon/PolygonNoder.h b/include/geos/triangulate/polygon/PolygonNoder.h
index fde921356..465e63b98 100644
--- a/include/geos/triangulate/polygon/PolygonNoder.h
+++ b/include/geos/triangulate/polygon/PolygonNoder.h
@@ -66,8 +66,8 @@ class GEOS_DLL PolygonNoder {
public:
PolygonNoder(
- std::unique_ptr<CoordinateSequence>& shellRing,
- std::vector<std::unique_ptr<CoordinateSequence>>& holeRings);
+ const std::shared_ptr<const CoordinateSequence>& shellRing,
+ const std::vector<std::shared_ptr<const CoordinateSequence>>& holeRings);
void node();
bool isShellNoded();
@@ -91,11 +91,11 @@ private:
// Methods
NodedSegmentString*
- createNodedSegString(std::unique_ptr<CoordinateSequence>& ringPts, std::size_t i);
+ createNodedSegString(const std::shared_ptr<const CoordinateSequence> &ringPts, std::size_t i);
void createNodedSegmentStrings(
- std::unique_ptr<CoordinateSequence>& shellRing,
- std::vector<std::unique_ptr<CoordinateSequence>>& holeRings);
+ const std::shared_ptr<const CoordinateSequence> &shellRing,
+ const std::vector<std::shared_ptr<const CoordinateSequence>> &holeRings);
/* Turn off copy constructors for MSVC */
PolygonNoder(const PolygonNoder&) = delete;
diff --git a/src/algorithm/MinimumDiameter.cpp b/src/algorithm/MinimumDiameter.cpp
index 813b161f9..a55f78e6f 100644
--- a/src/algorithm/MinimumDiameter.cpp
+++ b/src/algorithm/MinimumDiameter.cpp
@@ -135,7 +135,7 @@ MinimumDiameter::getDiameter()
computeMinimumDiameter();
// return empty linestring if no minimum width calculated
if(minWidthPt.isNull()) {
- return std::unique_ptr<LineString>(inputGeom->getFactory()->createLineString(nullptr));
+ return std::unique_ptr<LineString>(inputGeom->getFactory()->createLineString());
}
Coordinate basePt;
diff --git a/src/coverage/CoverageCleaner.cpp b/src/coverage/CoverageCleaner.cpp
index 940dcd444..51c822e05 100644
--- a/src/coverage/CoverageCleaner.cpp
+++ b/src/coverage/CoverageCleaner.cpp
@@ -389,8 +389,8 @@ CoverageCleaner::toGeometry(
{
std::vector<std::unique_ptr<LineString>> lines;
for (auto& ss : segStrings) {
- auto cs = ss->getCoordinates()->clone();
- std::unique_ptr<LineString> line = geomFact->createLineString(std::move(cs));
+ const auto& cs = ss->getCoordinates();
+ std::unique_ptr<LineString> line = geomFact->createLineString(cs);
lines.emplace_back(line.release());
}
if (lines.size() == 1) return lines[0]->clone();
diff --git a/src/coverage/CoverageEdge.cpp b/src/coverage/CoverageEdge.cpp
index 65971fc3a..a3504a2f6 100644
--- a/src/coverage/CoverageEdge.cpp
+++ b/src/coverage/CoverageEdge.cpp
@@ -59,8 +59,8 @@ CoverageEdge::createLines(
{
std::vector<std::unique_ptr<LineString>> lines;
for (const CoverageEdge* edge : edges) {
- auto cs = edge->getCoordinates()->clone();
- auto ls = geomFactory->createLineString(std::move(cs));
+ const auto& cs = edge->getCoordinates();
+ auto ls = geomFactory->createLineString(cs);
lines.push_back(std::move(ls));
}
return geomFactory->createMultiLineString(std::move(lines));
@@ -68,10 +68,10 @@ CoverageEdge::createLines(
/* public */
std::unique_ptr<LineString>
-CoverageEdge::toLineString(const GeometryFactory* geomFactory)
+CoverageEdge::toLineString(const GeometryFactory* geomFactory) const
{
- const CoordinateSequence* cs = getCoordinates();
- return geomFactory->createLineString(cs->clone());
+ const auto& cs = getCoordinates();
+ return geomFactory->createLineString(cs);
}
/* private static */
diff --git a/src/coverage/CoveragePolygonValidator.cpp b/src/coverage/CoveragePolygonValidator.cpp
index 16b252e00..d77f95aab 100644
--- a/src/coverage/CoveragePolygonValidator.cpp
+++ b/src/coverage/CoveragePolygonValidator.cpp
@@ -386,13 +386,12 @@ CoveragePolygonValidator::addRing(
CoverageRing*
CoveragePolygonValidator::createRing(const LinearRing* ring, bool isShell)
{
- CoordinateSequence* pts = const_cast<CoordinateSequence*>(ring->getCoordinatesRO());
+ std::shared_ptr<const CoordinateSequence> pts = ring->getSharedCoordinates();
if (pts->hasRepeatedOrInvalidPoints()) {
- CoordinateSequence* cleanPts = RepeatedPointRemover::removeRepeatedAndInvalidPoints(pts).release();
- localCoordinateSequences.emplace_back(cleanPts);
- pts = cleanPts;
+ auto cleanPts = RepeatedPointRemover::removeRepeatedAndInvalidPoints(pts.get());
+ pts = std::move(cleanPts);
}
- bool isCCW = Orientation::isCCW(pts);
+ bool isCCW = Orientation::isCCW(pts.get());
bool isInteriorOnRight = isShell ? ! isCCW : isCCW;
coverageRingStore.emplace_back(pts, isInteriorOnRight);
CoverageRing& cRing = coverageRingStore.back();
diff --git a/src/coverage/CoverageRing.cpp b/src/coverage/CoverageRing.cpp
index 9a331291f..d68c46cc6 100644
--- a/src/coverage/CoverageRing.cpp
+++ b/src/coverage/CoverageRing.cpp
@@ -51,7 +51,7 @@ CoverageRing::isKnown(std::vector<CoverageRing*>& rings)
/* public */
-CoverageRing::CoverageRing(CoordinateSequence* inPts, bool interiorOnRight)
+CoverageRing::CoverageRing(const std::shared_ptr<const CoordinateSequence>& inPts, bool interiorOnRight)
: noding::BasicSegmentString(inPts, nullptr)
, m_isInteriorOnRight(interiorOnRight)
{
@@ -63,13 +63,7 @@ CoverageRing::CoverageRing(CoordinateSequence* inPts, bool interiorOnRight)
/* public */
CoverageRing::CoverageRing(const LinearRing* ring, bool isShell)
: CoverageRing(
- // This is bad. The ownership rules of SegmentStrings need
- // to be carefully considered. Most noders don't even touch
- // them so a const CoordinateSequence makes sense. Some add
- // things, like the NodedSegmentString, but do so out-of-line.
- // Some noders (just ScalingNoder?) completely transform the
- // inputs. Could maybe do bulk copying for that case?
- const_cast<CoordinateSequence*>(ring->getCoordinatesRO()),
+ ring->getSharedCoordinates(),
algorithm::Orientation::isCCW(ring->getCoordinatesRO()) != isShell)
{}
diff --git a/src/coverage/CoverageRingEdges.cpp b/src/coverage/CoverageRingEdges.cpp
index a5a697cc1..99c53b04e 100644
--- a/src/coverage/CoverageRingEdges.cpp
+++ b/src/coverage/CoverageRingEdges.cpp
@@ -374,7 +374,7 @@ CoverageRingEdges::buildRing(const LinearRing* ring) const
for (std::size_t i = 0; i < ringEdges->size(); i++) {
Coordinate& lastPt = pts->isEmpty() ? nullPt : pts->back();
bool dir = isEdgeDirForward(*ringEdges, i, lastPt);
- const CoordinateSequence* ringCs = ringEdges->at(i)->getCoordinates();
+ const auto& ringCs = ringEdges->at(i)->getCoordinates();
pts->add(*ringCs, false, dir);
}
return ring->getFactory()->createLinearRing(std::move(pts));
diff --git a/src/coverage/CoverageSimplifier.cpp b/src/coverage/CoverageSimplifier.cpp
index 98ba1ad87..0623cedce 100644
--- a/src/coverage/CoverageSimplifier.cpp
+++ b/src/coverage/CoverageSimplifier.cpp
@@ -136,7 +136,7 @@ CoverageSimplifier::setCoordinates(std::vector<CoverageEdge*>& edges, const Mult
{
for (std::size_t i = 0; i < edges.size(); i++) {
CoverageEdge* edge = edges[i];
- edge->setCoordinates(lines->getGeometryN(i)->getCoordinatesRO());
+ edge->setCoordinates(lines->getGeometryN(i)->getSharedCoordinates());
}
}
diff --git a/src/dissolve/LineDissolver.cpp b/src/dissolve/LineDissolver.cpp
index 674c132d5..3c1d808fb 100644
--- a/src/dissolve/LineDissolver.cpp
+++ b/src/dissolve/LineDissolver.cpp
@@ -88,6 +88,7 @@ void
LineDissolver::add(const LineString* lineString)
{
const CoordinateSequence* seq = lineString->getCoordinatesRO();
+
bool doneStart = false;
for (std::size_t i = 1; i < seq->size(); i++) {
CoordinateXYZM orig, dest;
diff --git a/src/geom/CircularString.cpp b/src/geom/CircularString.cpp
index b666c8eb1..26f74d96f 100644
--- a/src/geom/CircularString.cpp
+++ b/src/geom/CircularString.cpp
@@ -30,6 +30,14 @@ CircularString::CircularString(std::unique_ptr<CoordinateSequence>&& newCoords,
validateConstruction();
}
+CircularString::CircularString(const std::shared_ptr<const CoordinateSequence>& newCoords,
+ const GeometryFactory& factory)
+ :
+ SimpleCurve(newCoords, false, factory)
+{
+ validateConstruction();
+}
+
CircularString::~CircularString() = default;
std::unique_ptr<CircularString>
diff --git a/src/geom/GeometryFactory.cpp b/src/geom/GeometryFactory.cpp
index 4e97f85cd..458fbe8e1 100644
--- a/src/geom/GeometryFactory.cpp
+++ b/src/geom/GeometryFactory.cpp
@@ -458,6 +458,13 @@ GeometryFactory::createLinearRing(CoordinateSequence::Ptr && newCoords) const
return std::unique_ptr<LinearRing>(new LinearRing(std::move(newCoords), *this));
}
+std::unique_ptr<LinearRing>
+GeometryFactory::createLinearRing(const std::shared_ptr<const CoordinateSequence>& newCoords) const
+{
+ // Can't use make_unique with protected constructor
+ return std::unique_ptr<LinearRing>(new LinearRing(newCoords, *this));
+}
+
/*public*/
std::unique_ptr<LinearRing>
GeometryFactory::createLinearRing(const CoordinateSequence& fromCoords) const
@@ -641,6 +648,16 @@ GeometryFactory::createCircularString(const CircularString& ls) const
return std::unique_ptr<CircularString>(new CircularString(ls));
}
+/*public*/
+std::unique_ptr<LineString>
+GeometryFactory::createLineString(const std::shared_ptr<const CoordinateSequence>& newCoords) const
+{
+ if (!newCoords)
+ return createLineString();
+ // Can't use make_unique with protected constructor
+ return std::unique_ptr<LineString>(new LineString(newCoords, *this));
+}
+
/*public*/
std::unique_ptr<LineString>
GeometryFactory::createLineString(CoordinateSequence::Ptr && newCoords)
@@ -663,6 +680,16 @@ const
return std::unique_ptr<CircularString>(new CircularString(std::move(newCoords), *this));
}
+std::unique_ptr<CircularString>
+GeometryFactory::createCircularString(const std::shared_ptr<const CoordinateSequence>& newCoords)
+const
+{
+ if (!newCoords)
+ return createCircularString(false, false);
+ // Can't use make_unique with protected constructor
+ return std::unique_ptr<CircularString>(new CircularString(newCoords, *this));
+}
+
/*public*/
std::unique_ptr<CompoundCurve>
GeometryFactory::createCompoundCurve()
diff --git a/src/geom/LineString.cpp b/src/geom/LineString.cpp
index 90e37479f..fb52a2c5e 100644
--- a/src/geom/LineString.cpp
+++ b/src/geom/LineString.cpp
@@ -54,6 +54,15 @@ LineString::LineString(const LineString& ls)
{
}
+/*public*/
+LineString::LineString(const std::shared_ptr<const CoordinateSequence> & newCoords,
+ const GeometryFactory& factory)
+ :
+ SimpleCurve(newCoords, true, factory)
+{
+ validateConstruction();
+}
+
/*public*/
LineString::LineString(CoordinateSequence::Ptr && newCoords,
const GeometryFactory& factory)
diff --git a/src/geom/LinearRing.cpp b/src/geom/LinearRing.cpp
index 6afc506c0..da3d848a5 100644
--- a/src/geom/LinearRing.cpp
+++ b/src/geom/LinearRing.cpp
@@ -44,6 +44,13 @@ LinearRing::LinearRing(CoordinateSequence::Ptr && newCoords,
validateConstruction();
}
+LinearRing::LinearRing(const std::shared_ptr<const CoordinateSequence>& newCoords,
+ const GeometryFactory& newFactory)
+ : LineString(newCoords, newFactory)
+{
+ validateConstruction();
+}
+
void
LinearRing::validateConstruction()
{
@@ -108,7 +115,13 @@ LinearRing::orient(bool isCW)
}
if (algorithm::Orientation::isCCW(points.get()) == isCW) {
- points->reverse();
+ if (points.use_count() == 1) {
+ const_cast<CoordinateSequence*>(points.get())->reverse();
+ } else {
+ auto newPoints = points->clone();
+ newPoints->reverse();
+ points = std::move(newPoints);
+ }
}
}
diff --git a/src/geom/Polygon.cpp b/src/geom/Polygon.cpp
index 3163e8543..850331c04 100644
--- a/src/geom/Polygon.cpp
+++ b/src/geom/Polygon.cpp
@@ -147,7 +147,7 @@ Polygon::getArea() const
double area = 0.0;
area += algorithm::Area::ofRing(shell->getCoordinatesRO());
for(const auto& lr : holes) {
- const CoordinateSequence* h = lr->getCoordinatesRO();
+ const auto& h = lr->getCoordinatesRO();
area -= algorithm::Area::ofRing(h);
}
return area;
diff --git a/src/geom/SimpleCurve.cpp b/src/geom/SimpleCurve.cpp
index 952d207d0..e062c4c8b 100644
--- a/src/geom/SimpleCurve.cpp
+++ b/src/geom/SimpleCurve.cpp
@@ -38,11 +38,20 @@ SimpleCurve::SimpleCurve(const SimpleCurve& other)
{
}
+SimpleCurve::SimpleCurve(const std::shared_ptr<const CoordinateSequence>& newCoords,
+ bool isLinear,
+ const GeometryFactory& factory)
+ : Curve(factory),
+ points(newCoords),
+ envelope(computeEnvelopeInternal(isLinear))
+{
+}
+
SimpleCurve::SimpleCurve(std::unique_ptr<CoordinateSequence>&& newCoords,
bool isLinear,
const GeometryFactory& factory)
: Curve(factory),
- points(newCoords ? std::move(newCoords) : std::make_unique<CoordinateSequence>()),
+ points(newCoords ? std::move(newCoords) : std::make_shared<CoordinateSequence>()),
envelope(computeEnvelopeInternal(isLinear))
{
}
@@ -73,18 +82,24 @@ void
SimpleCurve::apply_rw(const CoordinateFilter* filter)
{
assert(points.get());
- points->apply_rw(filter);
+ if (points.use_count() > 1) {
+ points = points->clone();
+ }
+ const_cast<CoordinateSequence*>(points.get())->apply_rw(filter);
}
void
SimpleCurve::apply_rw(CoordinateSequenceFilter& filter)
{
+ if (points.use_count() > 1) {
+ points = points->clone();
+ }
std::size_t npts = points->size();
if (!npts) {
return;
}
for (std::size_t i = 0; i < npts; ++i) {
- filter.filter_rw(*points, i);
+ filter.filter_rw(const_cast<CoordinateSequence&>(*points), i);
if (filter.isDone()) {
break;
}
@@ -218,6 +233,13 @@ SimpleCurve::getCoordinatesRO() const
return points.get();
}
+const std::shared_ptr<const CoordinateSequence>&
+SimpleCurve::getSharedCoordinates() const
+{
+ assert(nullptr != points.get());
+ return points;
+}
+
const SimpleCurve*
SimpleCurve::getCurveN(std::size_t) const
{
@@ -326,7 +348,10 @@ SimpleCurve::normalize()
std::size_t j = npts - 1 - i;
if (!(points->getAt<CoordinateXY>(i) == points->getAt<CoordinateXY>(j))) {
if (points->getAt<CoordinateXY>(i).compareTo(points->getAt<CoordinateXY>(j)) > 0) {
- points->reverse();
+ if (points.use_count() > 1) {
+ points = points->clone();
+ }
+ const_cast<CoordinateSequence*>(points.get())->reverse();
}
return;
}
@@ -360,15 +385,5 @@ SimpleCurve::normalizeClosed()
points = std::move(coords);
}
-std::unique_ptr<CoordinateSequence>
-SimpleCurve::releaseCoordinates()
-{
- auto newPts = std::make_unique<CoordinateSequence>(0u, points->hasZ(), points->hasM());
- auto ret = std::move(points);
- points = std::move(newPts);
- geometryChanged();
- return ret;
-}
-
} // namespace geos::geom
} // namespace geos
diff --git a/src/geom/util/CoordinateOperation.cpp b/src/geom/util/CoordinateOperation.cpp
index 621b74142..07bc85695 100644
--- a/src/geom/util/CoordinateOperation.cpp
+++ b/src/geom/util/CoordinateOperation.cpp
@@ -35,13 +35,13 @@ CoordinateOperation::edit(const Geometry* geometry,
}
if(const LinearRing* ring = dynamic_cast<const LinearRing*>(geometry)) {
- const CoordinateSequence* coords = ring->getCoordinatesRO();
+ const auto& coords = ring->getCoordinatesRO();
auto newCoords = edit(coords, geometry);
// LinearRing instance takes over ownership of newCoords instance
return factory->createLinearRing(std::move(newCoords));
}
if(const LineString* line = dynamic_cast<const LineString*>(geometry)) {
- const CoordinateSequence* coords = line->getCoordinatesRO();
+ const auto& coords = line->getCoordinatesRO();
auto newCoords = edit(coords, geometry);
return factory->createLineString(std::move(newCoords));
}
diff --git a/src/geomgraph/EdgeNodingValidator.cpp b/src/geomgraph/EdgeNodingValidator.cpp
index eab396e81..6e30a7abd 100644
--- a/src/geomgraph/EdgeNodingValidator.cpp
+++ b/src/geomgraph/EdgeNodingValidator.cpp
@@ -37,17 +37,13 @@ EdgeNodingValidator::toSegmentStrings(std::vector<Edge*>& edges)
for(std::size_t i = 0, n = edges.size(); i < n; ++i) {
Edge* e = edges[i];
auto cs = e->getCoordinates()->clone();
- segStr.push_back(std::make_unique<BasicSegmentString>(cs.get(), e));
- newCoordSeq.push_back(cs.release());
+ segStr.push_back(std::make_unique<BasicSegmentString>(std::move(cs), e));
}
return segStr;
}
EdgeNodingValidator::~EdgeNodingValidator()
{
- for(std::size_t i = 0, n = newCoordSeq.size(); i < n; ++i) {
- delete newCoordSeq[i];
- }
}
} // namespace geos.geomgraph
diff --git a/src/noding/BoundaryChainNoder.cpp b/src/noding/BoundaryChainNoder.cpp
index 35b3a6bfe..ad9d88d38 100644
--- a/src/noding/BoundaryChainNoder.cpp
+++ b/src/noding/BoundaryChainNoder.cpp
@@ -107,13 +107,9 @@ BoundaryChainNoder::nodeChain(
std::unique_ptr<BasicSegmentString>
BoundaryChainNoder::substring(const SegmentString* segString, std::size_t start, std::size_t end)
{
- // A BasicSegmentString does not own its CoordinateSequence, so why does this not leak?
- // At least in the CoverageUnion case, we end up here from EdgeNodingBuilder::node, where the
- // created BasicSegmentStrings are (incorrectly) down-casted to NodedSegmentStrings, and
- // the coordinate ownership is transferred to an overlayng::Edge.
- auto pts = std::make_unique<CoordinateSequence>();
+ auto pts = std::make_shared<CoordinateSequence>();
pts->add(*segString->getCoordinates(), start, end);
- return std::make_unique<BasicSegmentString>(pts.release(), segString->getData());
+ return std::make_unique<BasicSegmentString>(pts, segString->getData());
}
@@ -250,11 +246,11 @@ BoundaryChainNoder::BoundaryChainMap::createChain(
bool constructM)
{
auto npts = endIndex - startIndex + 1;
- auto pts = detail::make_unique<CoordinateSequence>(0, constructZ, constructM);
+ auto pts = std::make_shared<CoordinateSequence>(0, constructZ, constructM);
pts->reserve(npts);
pts->add(*segString->getCoordinates(), startIndex, endIndex);
- return std::make_unique<NodedSegmentString>(pts.release(), constructZ, constructM, segString->getData());
+ return std::make_unique<NodedSegmentString>(pts, constructZ, constructM, segString->getData());
}
/* private */
diff --git a/src/noding/GeometryNoder.cpp b/src/noding/GeometryNoder.cpp
index 5ec79d1f7..46a5f0e04 100644
--- a/src/noding/GeometryNoder.cpp
+++ b/src/noding/GeometryNoder.cpp
@@ -61,9 +61,8 @@ public:
{
const geom::LineString* ls = dynamic_cast<const geom::LineString*>(g);
if(ls) {
- auto coord = ls->getCoordinates();
- // coord ownership transferred to SegmentString
- SegmentString* ss = new NodedSegmentString(coord.release(), _constructZ, _constructM, nullptr);
+ auto coord = ls->getSharedCoordinates();
+ SegmentString* ss = new NodedSegmentString(coord, _constructZ, _constructM, nullptr);
_to.push_back(ss);
}
}
@@ -107,12 +106,12 @@ GeometryNoder::toGeometry(std::vector<std::unique_ptr<SegmentString>>& nodedEdge
std::vector<std::unique_ptr<geom::Geometry>> lines;
lines.reserve(nodedEdges.size());
for(auto& ss : nodedEdges) {
- const geom::CoordinateSequence* coords = ss->getCoordinates();
+ const auto& coords = ss->getCoordinates();
// Check if an equivalent edge is known
OrientedCoordinateArray oca1(*coords);
if(ocas.insert(oca1).second) {
- lines.push_back(geomFact->createLineString(coords->clone()));
+ lines.push_back(geomFact->createLineString(coords));
}
}
diff --git a/src/noding/MCIndexNoder.cpp b/src/noding/MCIndexNoder.cpp
index 556738ff4..9619e9adf 100644
--- a/src/noding/MCIndexNoder.cpp
+++ b/src/noding/MCIndexNoder.cpp
@@ -83,7 +83,7 @@ MCIndexNoder::add(SegmentString* segStr)
// std::vector<std::unique_ptr<MonotoneChain>> segChains;
// segChains will contain newly allocated MonotoneChain objects
- MonotoneChainBuilder::getChains(segStr->getCoordinates(),
+ MonotoneChainBuilder::getChains(segStr->getCoordinates().get(),
segStr, monoChains);
}
diff --git a/src/noding/MCIndexSegmentSetMutualIntersector.cpp b/src/noding/MCIndexSegmentSetMutualIntersector.cpp
index b5b5e4d49..f51301acb 100644
--- a/src/noding/MCIndexSegmentSetMutualIntersector.cpp
+++ b/src/noding/MCIndexSegmentSetMutualIntersector.cpp
@@ -36,7 +36,7 @@ namespace noding { // geos::noding
void
MCIndexSegmentSetMutualIntersector::addToIndex(SegmentString* segStr)
{
- MonotoneChainBuilder::getChains(segStr->getCoordinates(),
+ MonotoneChainBuilder::getChains(segStr->getCoordinates().get(),
segStr, indexChains);
}
@@ -49,7 +49,7 @@ MCIndexSegmentSetMutualIntersector::addToMonoChains(SegmentString* segStr)
if (segStr->size() == 0)
return;
MonoChains segChains;
- MonotoneChainBuilder::getChains(segStr->getCoordinates(),
+ MonotoneChainBuilder::getChains(segStr->getCoordinates().get(),
segStr, segChains);
for (auto& mc : segChains) {
if (envelope == nullptr || envelope->intersects(mc.getEnvelope())) {
diff --git a/src/noding/NodedSegmentString.cpp b/src/noding/NodedSegmentString.cpp
index 4074d7342..7bcc5aa7d 100644
--- a/src/noding/NodedSegmentString.cpp
+++ b/src/noding/NodedSegmentString.cpp
@@ -70,14 +70,6 @@ NodedSegmentString::getNodedSubstrings(
return resultEdgelist;
}
-std::unique_ptr<geom::CoordinateSequence>
-NodedSegmentString::releaseCoordinates()
-{
- auto ret = std::unique_ptr<CoordinateSequence>(seq);
- seq = nullptr;
- return ret;
-}
-
/* public virtual */
std::ostream&
NodedSegmentString::print(std::ostream& os) const
diff --git a/src/noding/ScaledNoder.cpp b/src/noding/ScaledNoder.cpp
index 02192cac2..c6dec8502 100644
--- a/src/noding/ScaledNoder.cpp
+++ b/src/noding/ScaledNoder.cpp
@@ -139,7 +139,9 @@ ScaledNoder::rescale(std::vector<std::unique_ptr<SegmentString>>& segStrings) co
{
ReScaler rescaler(*this);
for(auto& ss : segStrings) {
- ss->getCoordinates()->apply_rw(&rescaler);
+ auto copy = ss->getCoordinates()->clone();
+ copy->apply_rw(&rescaler);
+ ss->setCoordinates(std::move(copy));
}
}
@@ -152,7 +154,7 @@ ScaledNoder::scale(const SegmentString::NonConstVect& segStrings) const
for(std::size_t i = 0; i < segStrings.size(); i++) {
SegmentString* ss = segStrings[i];
- CoordinateSequence* cs = ss->getCoordinates();
+ auto cs = ss->getCoordinates()->clone();
#ifndef NDEBUG
std::size_t npts = cs->size();
@@ -162,10 +164,12 @@ ScaledNoder::scale(const SegmentString::NonConstVect& segStrings) const
operation::valid::RepeatedPointTester rpt;
// FIXME remove hardcoded hasZ, hasM and derive from input
- if (rpt.hasRepeatedPoint(cs)) {
- auto cs2 = operation::valid::RepeatedPointRemover::removeRepeatedPoints(cs);
- const_cast<std::vector<SegmentString*>&>(segStrings)[i] = new NodedSegmentString(cs2.release(), true, false, ss->getData());
+ if (rpt.hasRepeatedPoint(cs.get())) {
+ auto cs2 = operation::valid::RepeatedPointRemover::removeRepeatedPoints(cs.get());
+ const_cast<std::vector<SegmentString*>&>(segStrings)[i] = new NodedSegmentString(std::move(cs2), true, false, ss->getData());
delete ss;
+ } else {
+ ss->setCoordinates(std::move(cs));
}
}
}
diff --git a/src/noding/SegmentExtractingNoder.cpp b/src/noding/SegmentExtractingNoder.cpp
index 0bfb095bf..67d79df50 100644
--- a/src/noding/SegmentExtractingNoder.cpp
+++ b/src/noding/SegmentExtractingNoder.cpp
@@ -54,17 +54,17 @@ SegmentExtractingNoder::extractSegments(
const SegmentString* ss,
std::vector<std::unique_ptr<SegmentString>>& outputSegs)
{
- const CoordinateSequence* ss_seq = ss->getCoordinates();
+ const auto& ss_seq = ss->getCoordinates();
const NodedSegmentString* nss = dynamic_cast<const NodedSegmentString*>(ss);
bool constructZ = nss ? nss->getNodeList().getConstructZ() : ss_seq->hasZ();
bool constructM = nss ? nss->getNodeList().getConstructM() : ss_seq->hasM();
for (std::size_t i = 0; i < ss_seq->getSize() - 1; i++) {
- auto cs = detail::make_unique<CoordinateSequence>(0, constructZ, constructM);
+ auto cs = std::make_shared<CoordinateSequence>(0, constructZ, constructM);
cs->reserve(2);
cs->add(*ss_seq, i, i + 1);
- std::unique_ptr<SegmentString> seg(new NodedSegmentString(cs.release(), constructZ, constructM, ss->getData()));
+ std::unique_ptr<SegmentString> seg(new NodedSegmentString(cs, constructZ, constructM, ss->getData()));
outputSegs.push_back(std::move(seg));
}
}
diff --git a/src/noding/SegmentNodeList.cpp b/src/noding/SegmentNodeList.cpp
index 5fa6dd7dc..4404ddfb0 100644
--- a/src/noding/SegmentNodeList.cpp
+++ b/src/noding/SegmentNodeList.cpp
@@ -67,7 +67,7 @@ SegmentNodeList::addEndpoints()
{
std::size_t maxSegIndex = edge.size() - 1;
- const auto* edgePts = edge.getCoordinates();
+ const auto& edgePts = edge.getCoordinates();
CoordinateXYZM p0, p1;
edgePts->getAt(0, p0);
@@ -212,7 +212,7 @@ SegmentNodeList::checkSplitEdgesCorrectness(const std::vector<SegmentString*>& s
if (splitEdges.empty())
return;
- const CoordinateSequence* edgePts = edge.getCoordinates();
+ const auto& edgePts = edge.getCoordinates();
assert(edgePts);
// check that first and last points of split edges
@@ -228,7 +228,7 @@ SegmentNodeList::checkSplitEdgesCorrectness(const std::vector<SegmentString*>& s
SegmentString* splitn = splitEdges[splitEdges.size() - 1];
assert(splitn);
- const CoordinateSequence* splitnPts = splitn->getCoordinates();
+ const auto& splitnPts = splitn->getCoordinates();
assert(splitnPts);
const Coordinate& ptn = splitnPts->getAt(splitnPts->getSize() - 1);
@@ -242,19 +242,19 @@ std::unique_ptr<SegmentString>
SegmentNodeList::createSplitEdge(const SegmentNode* ei0, const SegmentNode* ei1) const
{
auto pts = createSplitEdgePts(ei0, ei1);
- return detail::make_unique<NodedSegmentString>(pts.release(), constructZ, constructM, edge.getData());
+ return detail::make_unique<NodedSegmentString>(std::move(pts), constructZ, constructM, edge.getData());
}
/*private*/
-std::unique_ptr<CoordinateSequence>
-SegmentNodeList::createSplitEdgePts(const SegmentNode* ei0, const SegmentNode* ei1) const
+std::shared_ptr<CoordinateSequence>
+SegmentNodeList::createSplitEdgePts(const SegmentNode *ei0, const SegmentNode *ei1) const
{
bool twoPoints = (ei1->segmentIndex == ei0->segmentIndex);
// if only two points in split edge they must be the node points
if (twoPoints) {
- auto pts = detail::make_unique<CoordinateSequence>(2u, constructZ, constructM);
+ auto pts = std::make_shared<CoordinateSequence>(2u, constructZ, constructM);
pts->setAt(ei0->coord, 0);
pts->setAt(ei1->coord, 1);
return pts;
@@ -272,11 +272,11 @@ SegmentNodeList::createSplitEdgePts(const SegmentNode* ei0, const SegmentNode* e
std::size_t npts = 1 + (ei1->segmentIndex - ei0->segmentIndex) + useIntPt1;
- auto pts = detail::make_unique<CoordinateSequence>(0u, constructZ, constructM);
+ auto pts = std::make_shared<CoordinateSequence>(0u, constructZ, constructM);
pts->reserve(npts);
pts->add(ei0->coord);
- const CoordinateSequence* edgeCoords = edge.getCoordinates();
+ const auto& edgeCoords = edge.getCoordinates();
pts->add(*edgeCoords, ei0->segmentIndex + 1, ei1->segmentIndex);
if (useIntPt1) {
pts->add(ei1->coord);
diff --git a/src/noding/SimpleNoder.cpp b/src/noding/SimpleNoder.cpp
index 8f5ea1d9e..6719a093e 100644
--- a/src/noding/SimpleNoder.cpp
+++ b/src/noding/SimpleNoder.cpp
@@ -33,8 +33,8 @@ SimpleNoder::computeIntersects(SegmentString* e0, SegmentString* e1)
{
assert(segInt); // must provide a segment intersector!
- const CoordinateSequence* pts0 = e0->getCoordinates();
- const CoordinateSequence* pts1 = e1->getCoordinates();
+ const CoordinateSequence* pts0 = e0->getCoordinates().get();
+ const CoordinateSequence* pts1 = e1->getCoordinates().get();
for(std::size_t i0 = 0, n0 = pts0->getSize() - 1; i0 < n0; i0++) {
for(std::size_t i1 = 0, n1 = pts1->getSize() - 1; i1 < n1; i1++) {
segInt->processIntersections(e0, i0, e1, i1);
diff --git a/src/noding/snap/SnappingNoder.cpp b/src/noding/snap/SnappingNoder.cpp
index 614aeac7e..f4848d1fc 100644
--- a/src/noding/snap/SnappingNoder.cpp
+++ b/src/noding/snap/SnappingNoder.cpp
@@ -77,13 +77,13 @@ SnappingNoder::seedSnapIndex(const std::vector<SegmentString*>& segStrings)
double PHI_INV = (std::sqrt(5.0) - 1.0) / 2.0;
for (SegmentString* ss: segStrings) {
- CoordinateSequence* cs = ss->getCoordinates();
+ const auto& cs = ss->getCoordinates();
int numPts = (int) cs->size();
int numPtsToLoad = numPts / 100;
double rand = 0.0;
for (int i = 0; i < numPtsToLoad; i++) {
- // quasi-random sequennce generated by additive recurrence with irrational constant
+ // quasi-random sequence generated by additive recurrence with irrational constant
rand = rand + PHI_INV;
if (rand > 1) rand = rand - floor(rand);
@@ -97,17 +97,17 @@ SnappingNoder::seedSnapIndex(const std::vector<SegmentString*>& segStrings)
std::unique_ptr<SegmentString>
SnappingNoder::snapVertices(const SegmentString* ss)
{
- auto snapCoords = snap(ss->getCoordinates());
+ auto snapCoords = snap(ss->getCoordinates().get());
// FIXME remove hardcoded hasZ, hasM and derive from input
- return std::make_unique<NodedSegmentString>(snapCoords.release(), false, false, ss->getData());
+ return std::make_unique<NodedSegmentString>(std::move(snapCoords), false, false, ss->getData());
}
/*private*/
-std::unique_ptr<CoordinateSequence>
-SnappingNoder::snap(const CoordinateSequence* cs)
+std::shared_ptr<CoordinateSequence>
+SnappingNoder::snap(const CoordinateSequence *cs)
{
- auto snapCoords = detail::make_unique<CoordinateSequence>();
+ auto snapCoords = std::make_shared<CoordinateSequence>();
snapCoords->reserve(cs->size());
cs->forEach<Coordinate>([&snapCoords, this](const Coordinate& origPt) {
diff --git a/src/noding/snapround/MCIndexSnapRounder.cpp b/src/noding/snapround/MCIndexSnapRounder.cpp
index d76152ffb..fd65b1f63 100644
--- a/src/noding/snapround/MCIndexSnapRounder.cpp
+++ b/src/noding/snapround/MCIndexSnapRounder.cpp
@@ -60,7 +60,7 @@ MCIndexSnapRounder::computeIntersectionSnaps(std::vector<Coordinate>& snapPts)
void
MCIndexSnapRounder::computeVertexSnaps(NodedSegmentString* e)
{
- CoordinateSequence& pts0 = *(e->getCoordinates());
+ const CoordinateSequence& pts0 = *(e->getCoordinates());
for(std::size_t i = 0, n = pts0.size() - 1; i < n; ++i) {
HotPixel hotPixel(pts0.getAt(i), scaleFactor);
bool isNodeAdded = pointSnapper->snap(hotPixel, e, i);
diff --git a/src/noding/snapround/SnapRoundingNoder.cpp b/src/noding/snapround/SnapRoundingNoder.cpp
index 30d7b7be5..8eca8dd1d 100644
--- a/src/noding/snapround/SnapRoundingNoder.cpp
+++ b/src/noding/snapround/SnapRoundingNoder.cpp
@@ -89,8 +89,8 @@ void
SnapRoundingNoder::addVertexPixels(const std::vector<SegmentString*>& segStrings)
{
for (SegmentString* nss : segStrings) {
- const CoordinateSequence* pts = nss->getCoordinates();
- pixelIndex.add(pts);
+ const auto& pts = nss->getCoordinates();
+ pixelIndex.add(pts.get());
}
}
@@ -153,7 +153,7 @@ SnapRoundingNoder::computeSegmentSnaps(NodedSegmentString* ss)
return nullptr;
// Create new nodedSS to allow adding any hot pixel nodes
- NodedSegmentString* snapSS = new NodedSegmentString(ptsRound.release(), ss->getNodeList().getConstructZ(), ss->getNodeList().getConstructM(), ss->getData());
+ NodedSegmentString* snapSS = new NodedSegmentString(std::move(ptsRound), ss->getNodeList().getConstructZ(), ss->getNodeList().getConstructM(), ss->getData());
std::size_t snapSSindex = 0;
for (std::size_t i = 0, sz = pts->size()-1; i < sz; i++ ) {
@@ -240,7 +240,7 @@ SnapRoundingNoder::snapSegment(const CoordinateXY& p0, const CoordinateXY& p1, N
void
SnapRoundingNoder::addVertexNodeSnaps(NodedSegmentString* ss)
{
- const CoordinateSequence* pts = ss->getCoordinates();
+ const auto& pts = ss->getCoordinates();
std::size_t i = 0;
pts->forEach([this, ss, &i](const auto& p0) -> void {
if (i > 0 && i < ss->size() - 1) {
diff --git a/src/operation/buffer/BufferBuilder.cpp b/src/operation/buffer/BufferBuilder.cpp
index 1bdf09493..3c7c89da8 100644
--- a/src/operation/buffer/BufferBuilder.cpp
+++ b/src/operation/buffer/BufferBuilder.cpp
@@ -177,7 +177,7 @@ BufferBuilder::bufferLineSingleSided(const Geometry* g, double distance,
// Then, get the raw (i.e. unnoded) single sided offset curve.
OffsetCurveBuilder curveBuilder(precisionModel, modParams);
- std::vector< CoordinateSequence* > lineList;
+ std::vector<std::unique_ptr<CoordinateSequence>> lineList;
{
std::unique_ptr< CoordinateSequence > coords(g->getCoordinates());
@@ -188,11 +188,11 @@ BufferBuilder::bufferLineSingleSided(const Geometry* g, double distance,
// Create a SegmentString from these coordinates.
SegmentString::NonConstVect curveList;
- for(unsigned int i = 0; i < lineList.size(); ++i) {
- CoordinateSequence* seq = lineList[i];
-
+ for(auto& seq : lineList) {
+ const bool hasZ = seq->hasZ();
+ const bool hasM = seq->hasM();
// SegmentString takes ownership of CoordinateSequence
- SegmentString* ss = new NodedSegmentString(seq, seq->hasZ(), seq->hasM(), nullptr);
+ SegmentString* ss = new NodedSegmentString(std::move(seq), hasZ, hasM, nullptr);
curveList.push_back(ss);
}
lineList.clear();
@@ -666,7 +666,7 @@ BufferBuilder::computeNodedEdges(SegmentString::NonConstVect& bufferSegStrList,
for(auto& segStr : nodedSegStrings) {
const Label* oldLabel = static_cast<const Label*>(segStr->getData());
- auto cs = operation::valid::RepeatedPointRemover::removeRepeatedPoints(segStr->getCoordinates());
+ auto cs = operation::valid::RepeatedPointRemover::removeRepeatedPoints(segStr->getCoordinates().get());
segStr.reset();
if(cs->size() < 2) {
// don't insert collapsed edges
diff --git a/src/operation/buffer/BufferCurveSetBuilder.cpp b/src/operation/buffer/BufferCurveSetBuilder.cpp
index 69e5976e3..1e4b38820 100644
--- a/src/operation/buffer/BufferCurveSetBuilder.cpp
+++ b/src/operation/buffer/BufferCurveSetBuilder.cpp
@@ -85,18 +85,17 @@ BufferCurveSetBuilder::getCurves()
/*public*/
void
-BufferCurveSetBuilder::addCurves(const std::vector<CoordinateSequence*>& lineList,
+BufferCurveSetBuilder::addCurves(std::vector<std::unique_ptr<CoordinateSequence>>& lineList,
geom::Location leftLoc, geom::Location rightLoc)
{
for(std::size_t i = 0, n = lineList.size(); i < n; ++i) {
- CoordinateSequence* coords = lineList[i];
- addCurve(coords, leftLoc, rightLoc);
+ addCurve(std::move(lineList[i]), leftLoc, rightLoc);
}
}
/*private*/
void
-BufferCurveSetBuilder::addCurve(CoordinateSequence* coord,
+BufferCurveSetBuilder::addCurve(std::unique_ptr<CoordinateSequence> coord,
geom::Location leftLoc, geom::Location rightLoc)
{
#if GEOS_DEBUG
@@ -107,15 +106,16 @@ BufferCurveSetBuilder::addCurve(CoordinateSequence* coord,
#if GEOS_DEBUG
std::cerr << " skipped (size<2)" << std::endl;
#endif
- delete coord;
return;
}
// add the edge for a coordinate list which is a raw offset curve
Label* newlabel = new Label(0, Location::BOUNDARY, leftLoc, rightLoc);
+ const bool hasZ = coord->hasZ();
+ const bool hasM = coord->hasM();
// coord ownership transferred to SegmentString
- SegmentString* e = new NodedSegmentString(coord, coord->hasZ(), coord->hasM(), newlabel);
+ SegmentString* e = new NodedSegmentString(std::move(coord), hasZ, hasM, newlabel);
// SegmentString doesn't own the sequence, so we need to delete in
// the destructor
@@ -185,7 +185,7 @@ BufferCurveSetBuilder::addPoint(const Point* p)
if (coord->size() >= 1 && ! coord->getAt(0).isValid()) {
return;
}
- std::vector<CoordinateSequence*> lineList;
+ std::vector<std::unique_ptr<CoordinateSequence>> lineList;
curveBuilder.getLineCurve(coord, distance, lineList);
addCurves(lineList, Location::EXTERIOR, Location::INTERIOR);
@@ -217,7 +217,7 @@ BufferCurveSetBuilder::addLineString(const LineString* line)
addLinearRingSides(coord.get(), distance);
}
else {
- std::vector<CoordinateSequence*> lineList;
+ std::vector<std::unique_ptr<CoordinateSequence>> lineList;
curveBuilder.getLineCurve(coord.get(), distance, lineList);
addCurves(lineList, Location::EXTERIOR, Location::INTERIOR);
}
@@ -365,20 +365,20 @@ BufferCurveSetBuilder::addPolygonRingSide(const CoordinateSequence* coord,
/* private */
void
BufferCurveSetBuilder::addRingSide(const CoordinateSequence* coord,
- double offsetDistance, int side, geom::Location leftLoc, geom::Location rightLoc)
+ double offsetDistance, int side, geom::Location leftLoc, geom::Location rightLoc)
{
- std::vector<CoordinateSequence*> lineList;
+ std::vector<std::unique_ptr<CoordinateSequence>> lineList;
curveBuilder.getRingCurve(coord, side, offsetDistance, lineList);
// ASSERT: lineList contains exactly 1 curve (this is the JTS semantics)
if (lineList.size() > 0) {
- const CoordinateSequence* curve = lineList[0];
+ const CoordinateSequence* curve = lineList[0].get();
/**
* If the offset curve has inverted completely it will produce
* an unwanted artifact in the result, so skip it.
*/
if (isRingCurveInverted(coord, offsetDistance, curve)) {
- for( auto line: lineList ) {
- delete line;
+ for(auto& line: lineList ) {
+ line.reset();
}
return;
}
diff --git a/src/operation/buffer/OffsetCurveBuilder.cpp b/src/operation/buffer/OffsetCurveBuilder.cpp
index 1628ef9bb..ed2ae6c22 100644
--- a/src/operation/buffer/OffsetCurveBuilder.cpp
+++ b/src/operation/buffer/OffsetCurveBuilder.cpp
@@ -53,7 +53,7 @@ const double OffsetCurveBuilder::SIMPLIFY_FACTOR = 100.0;
/*public*/
void
OffsetCurveBuilder::getLineCurve(const CoordinateSequence* inputPts,
- double nDistance, std::vector<CoordinateSequence*>& lineList)
+ double nDistance, std::vector<std::unique_ptr<CoordinateSequence>>& lineList)
{
distance = nDistance;
@@ -112,7 +112,7 @@ void
OffsetCurveBuilder::getOffsetCurve(
const CoordinateSequence* inputPts,
double p_distance,
- std::vector<CoordinateSequence*>& lineList)
+ std::vector<std::unique_ptr<CoordinateSequence>>& lineList)
{
distance = p_distance;
@@ -133,7 +133,7 @@ OffsetCurveBuilder::getOffsetCurve(
// for right side line is traversed in reverse direction, so have to reverse generated line
if (isRightSide) {
- for (auto* cs: lineList) {
+ for (auto& cs: lineList) {
cs->reverse();
}
}
@@ -234,7 +234,7 @@ OffsetCurveBuilder::computePointCurve(const Coordinate& pt,
/*public*/
void
OffsetCurveBuilder::getSingleSidedLineCurve(const CoordinateSequence* inputPts,
- double p_distance, std::vector<CoordinateSequence*>& lineList, bool leftSide,
+ double p_distance, std::vector<std::unique_ptr<CoordinateSequence>>& lineList, bool leftSide,
bool rightSide)
{
// A zero or negative width buffer of a line/point is empty.
@@ -311,13 +311,13 @@ OffsetCurveBuilder::isLineOffsetEmpty(double p_distance)
void
OffsetCurveBuilder::getRingCurve(const CoordinateSequence* inputPts,
int side, double nDistance,
- std::vector<CoordinateSequence*>& lineList)
+ std::vector<std::unique_ptr<CoordinateSequence>>& lineList)
{
distance = nDistance;
// optimize creating ring for zero distance
if(distance == 0.0) {
- lineList.push_back(inputPts->clone().release());
+ lineList.push_back(inputPts->clone());
return;
}
diff --git a/src/operation/overlayng/Edge.cpp b/src/operation/overlayng/Edge.cpp
index fce8b1e58..7f231d722 100644
--- a/src/operation/overlayng/Edge.cpp
+++ b/src/operation/overlayng/Edge.cpp
@@ -27,14 +27,14 @@ using namespace geos::geom;
using geos::util::GEOSException;
/*public*/
-Edge::Edge(std::unique_ptr<CoordinateSequence>&& p_pts, const EdgeSourceInfo* info)
+Edge::Edge(const std::shared_ptr<const CoordinateSequence>& p_pts, const EdgeSourceInfo* info)
: aDim(OverlayLabel::DIM_UNKNOWN)
, aDepthDelta(0)
, aIsHole(false)
, bDim(OverlayLabel::DIM_UNKNOWN)
, bDepthDelta(0)
, bIsHole(false)
- , pts(std::move(p_pts))
+ , pts(p_pts)
{
copyInfo(info);
}
diff --git a/src/operation/overlayng/EdgeNodingBuilder.cpp b/src/operation/overlayng/EdgeNodingBuilder.cpp
index 0800e8fcf..d63f4acb3 100644
--- a/src/operation/overlayng/EdgeNodingBuilder.cpp
+++ b/src/operation/overlayng/EdgeNodingBuilder.cpp
@@ -140,18 +140,17 @@ EdgeNodingBuilder::createEdges(std::vector<std::unique_ptr<SegmentString>>& segS
std::vector<Edge*> createdEdges;
for (auto& ss : segStrings) {
- const CoordinateSequence* pts = ss->getCoordinates();
+ const auto& pts = ss->getCoordinates();
// don't create edges from collapsed lines
- if (Edge::isCollapsed(pts)) continue;
+ if (Edge::isCollapsed(pts.get())) continue;
// This EdgeSourceInfo is already managed locally in a std::deque
const EdgeSourceInfo* info = static_cast<const EdgeSourceInfo*>(ss->getData());
// Record that a non-collapsed edge exists for the parent geometry
hasEdges[info->getIndex()] = true;
// Allocate the new Edge locally in a std::deque
- NodedSegmentString* nss = detail::down_cast<NodedSegmentString*>(ss.get());
- edgeQue.emplace_back(nss->releaseCoordinates(), info);
+ edgeQue.emplace_back(ss->getCoordinates(), info);
Edge* newEdge = &(edgeQue.back());
createdEdges.push_back(newEdge);
}
@@ -287,7 +286,7 @@ EdgeNodingBuilder::addEdge(std::unique_ptr<CoordinateSequence>& cas, const EdgeS
// TODO: manage these internally to EdgeNodingBuilder in a std::deque,
// since they do not have a life span longer than the EdgeNodingBuilder
// in OverlayNG::buildGraph()
- NodedSegmentString* ss = new NodedSegmentString(cas.release(), inputHasZ, inputHasM, reinterpret_cast<const void*>(info));
+ NodedSegmentString* ss = new NodedSegmentString(std::move(cas), inputHasZ, inputHasM, reinterpret_cast<const void*>(info));
inputEdges->push_back(ss);
}
diff --git a/src/operation/overlayng/OverlayEdge.cpp b/src/operation/overlayng/OverlayEdge.cpp
index a7e95c10f..8716e1503 100644
--- a/src/operation/overlayng/OverlayEdge.cpp
+++ b/src/operation/overlayng/OverlayEdge.cpp
@@ -31,11 +31,11 @@ namespace operation { // geos.operation
namespace overlayng { // geos.operation.overlayng
/*public*/
-std::unique_ptr<CoordinateSequence>
-OverlayEdge::getCoordinatesOriented()
+std::shared_ptr<const CoordinateSequence>
+OverlayEdge::getCoordinatesOriented() const
{
if (direction) {
- return pts->clone();
+ return pts;
}
std::unique_ptr<CoordinateSequence> ptsCopy = pts->clone();
ptsCopy->reverse();
diff --git a/src/operation/overlayng/OverlayGraph.cpp b/src/operation/overlayng/OverlayGraph.cpp
index 01ce395b0..a58983e21 100644
--- a/src/operation/overlayng/OverlayGraph.cpp
+++ b/src/operation/overlayng/OverlayGraph.cpp
@@ -83,7 +83,7 @@ OverlayEdge*
OverlayGraph::addEdge(Edge* edge)
{
// CoordinateSequence* pts = = edge->getCoordinates().release();
- CoordinateSequence* pts = edge->releaseCoordinates();
+ std::shared_ptr<const CoordinateSequence> pts = edge->releaseCoordinates();
OverlayEdge* e = createEdgePair(pts, createOverlayLabel(edge));
#if GEOS_DEBUG
std::cerr << "added edge: " << *e << std::endl;
@@ -95,9 +95,8 @@ OverlayGraph::addEdge(Edge* edge)
/*private*/
OverlayEdge*
-OverlayGraph::createEdgePair(const CoordinateSequence *pts, OverlayLabel *lbl)
+OverlayGraph::createEdgePair(const std::shared_ptr<const CoordinateSequence>& pts, OverlayLabel *lbl)
{
- csQue.emplace_back(const_cast<CoordinateSequence *>(pts));
OverlayEdge* e0 = createOverlayEdge(pts, lbl, true);
OverlayEdge* e1 = createOverlayEdge(pts, lbl, false);
e0->link(e1);
@@ -106,7 +105,7 @@ OverlayGraph::createEdgePair(const CoordinateSequence *pts, OverlayLabel *lbl)
/*private*/
OverlayEdge*
-OverlayGraph::createOverlayEdge(const CoordinateSequence* pts, OverlayLabel* lbl, bool direction)
+OverlayGraph::createOverlayEdge(const std::shared_ptr<const CoordinateSequence>& pts, OverlayLabel* lbl, bool direction)
{
CoordinateXYZM origin;
CoordinateXYZM dirPt;
diff --git a/src/operation/overlayng/OverlayUtil.cpp b/src/operation/overlayng/OverlayUtil.cpp
index 0f77d1da8..23b07f22e 100644
--- a/src/operation/overlayng/OverlayUtil.cpp
+++ b/src/operation/overlayng/OverlayUtil.cpp
@@ -311,8 +311,8 @@ OverlayUtil::toLines(OverlayGraph* graph, bool isOutputEdges, const GeometryFact
bool includeEdge = isOutputEdges || edge->isInResultArea();
if (! includeEdge) continue;
- std::unique_ptr<CoordinateSequence> pts = edge->getCoordinatesOriented();
- std::unique_ptr<LineString> line = geomFact->createLineString(std::move(pts));
+ std::shared_ptr<const CoordinateSequence> pts = edge->getCoordinatesOriented();
+ std::unique_ptr<LineString> line = geomFact->createLineString(pts);
// line->setUserData(labelForResult(edge));
lines.push_back(std::move(line));
}
diff --git a/src/operation/relateng/EdgeSetIntersector.cpp b/src/operation/relateng/EdgeSetIntersector.cpp
index 5a33ef387..c512884c5 100644
--- a/src/operation/relateng/EdgeSetIntersector.cpp
+++ b/src/operation/relateng/EdgeSetIntersector.cpp
@@ -51,7 +51,7 @@ void
EdgeSetIntersector::addToIndex(const SegmentString* segStr)
{
std::vector<MonotoneChain> segChains;
- MonotoneChainBuilder::getChains(segStr->getCoordinates(), const_cast<SegmentString*>(segStr), segChains);
+ MonotoneChainBuilder::getChains(segStr->getCoordinates().get(), const_cast<SegmentString*>(segStr), segChains);
for (MonotoneChain& mc : segChains) {
if (envelope == nullptr || envelope->intersects(mc.getEnvelope())) {
diff --git a/src/operation/relateng/RelateGeometry.cpp b/src/operation/relateng/RelateGeometry.cpp
index df00ad594..a54271f4b 100644
--- a/src/operation/relateng/RelateGeometry.cpp
+++ b/src/operation/relateng/RelateGeometry.cpp
@@ -404,9 +404,8 @@ RelateGeometry::extractSegmentStringsFromAtomic(bool isA,
const LineString* line = static_cast<const LineString*>(p_geom);
/*
* Condition the input Coordinate sequence so that it has no repeated points.
- * This requires taking a copy which removeRepeated does behind the scenes and stores in csStore.
*/
- const CoordinateSequence* cs = removeRepeated(line->getCoordinatesRO());
+ std::shared_ptr<const CoordinateSequence> cs = removeRepeated(line->getSharedCoordinates());
auto ss = RelateSegmentString::createLine(cs, isA, elementId, this);
segStore.emplace_back(ss);
segStrings.push_back(ss);
@@ -441,11 +440,11 @@ RelateGeometry::extractRingToSegmentString(bool isA,
/*
* Condition the input Coordinate sequence so that it has no repeated points
- * and is oriented in a deterministic way. This requires taking a copy which
- * orientAndRemoveRepeated does behind the scenes and stores in csStore.
+ * and is oriented in a deterministic way. This may require taking a copy which
+ * orientAndRemoveRepeated does behind the scenes.
*/
bool requireCW = (ringId == 0);
- const CoordinateSequence* cs = orientAndRemoveRepeated(ring->getCoordinatesRO(), requireCW);
+ std::shared_ptr<const CoordinateSequence> cs = orientAndRemoveRepeated(ring->getSharedCoordinates(), requireCW);
auto ss = RelateSegmentString::createRing(cs, isA, elementId, ringId, parentPoly, this);
segStore.emplace_back(ss);
segStrings.push_back(ss);
@@ -471,10 +470,10 @@ operator<<(std::ostream& os, const RelateGeometry& rg)
/* private */
-const CoordinateSequence *
-RelateGeometry::orientAndRemoveRepeated(const CoordinateSequence *seq, bool orientCW)
+std::shared_ptr<const CoordinateSequence>
+RelateGeometry::orientAndRemoveRepeated(const std::shared_ptr<const CoordinateSequence>& seq, bool orientCW)
{
- bool isFlipped = (orientCW == Orientation::isCCW(seq));
+ bool isFlipped = (orientCW == Orientation::isCCW(seq.get()));
bool hasRepeated = seq->hasRepeatedPoints();
/* Already conditioned */
if (!isFlipped && !hasRepeated) {
@@ -482,36 +481,29 @@ RelateGeometry::orientAndRemoveRepeated(const CoordinateSequence *seq, bool orie
}
if (hasRepeated) {
- auto deduped = RepeatedPointRemover::removeRepeatedPoints(seq);
+ auto deduped = RepeatedPointRemover::removeRepeatedPoints(seq.get());
if (isFlipped)
deduped->reverse();
- CoordinateSequence* cs = deduped.release();
- csStore.emplace_back(cs);
- return cs;
+ return deduped;
}
if (isFlipped) {
auto reversed = seq->clone();
reversed->reverse();
- CoordinateSequence* cs = reversed.release();
- csStore.emplace_back(cs);
- return cs;
+ return reversed;
}
return seq;
}
/* private */
-const CoordinateSequence *
-RelateGeometry::removeRepeated(const CoordinateSequence *seq)
+std::shared_ptr<const CoordinateSequence>
+RelateGeometry::removeRepeated(const std::shared_ptr<const CoordinateSequence>& seq)
{
bool hasRepeated = seq->hasRepeatedPoints();
if (!hasRepeated)
return seq;
- auto deduped = RepeatedPointRemover::removeRepeatedPoints(seq);
- CoordinateSequence* cs = deduped.release();
- csStore.emplace_back(cs);
- return cs;
+ return RepeatedPointRemover::removeRepeatedPoints(seq.get());
}
diff --git a/src/operation/relateng/RelateSegmentString.cpp b/src/operation/relateng/RelateSegmentString.cpp
index 41c0c4bbf..5325da2ee 100644
--- a/src/operation/relateng/RelateSegmentString.cpp
+++ b/src/operation/relateng/RelateSegmentString.cpp
@@ -39,7 +39,7 @@ namespace relateng { // geos.operation.relateng
/* public static */
const RelateSegmentString*
RelateSegmentString::createLine(
- const CoordinateSequence* pts,
+ const std::shared_ptr<const CoordinateSequence>& pts,
bool isA, int elementId,
const RelateGeometry* parent)
{
@@ -50,7 +50,7 @@ RelateSegmentString::createLine(
/* public static */
const RelateSegmentString*
RelateSegmentString::createRing(
- const CoordinateSequence* pts,
+ const std::shared_ptr<const CoordinateSequence>& pts,
bool isA, int elementId, int ringId,
const Geometry* poly, const RelateGeometry* parent)
{
@@ -61,7 +61,7 @@ RelateSegmentString::createRing(
/* private static */
const RelateSegmentString*
RelateSegmentString::createSegmentString(
- const CoordinateSequence* pts,
+ const std::shared_ptr<const CoordinateSequence>& pts,
bool isA, int dim, int elementId, int ringId,
const Geometry* poly, const RelateGeometry* parent)
{
@@ -71,7 +71,7 @@ RelateSegmentString::createSegmentString(
/* public */
NodeSection*
-RelateSegmentString::createNodeSection(std::size_t segIndex, const CoordinateXY intPt) const
+RelateSegmentString::createNodeSection(std::size_t segIndex, const CoordinateXY& intPt) const
{
const CoordinateXY& c0 = getCoordinate(segIndex);
const CoordinateXY& c1 = getCoordinate(segIndex + 1);
diff --git a/src/operation/valid/IsSimpleOp.cpp b/src/operation/valid/IsSimpleOp.cpp
index 2a5d136f8..e7bea5442 100644
--- a/src/operation/valid/IsSimpleOp.cpp
+++ b/src/operation/valid/IsSimpleOp.cpp
@@ -224,15 +224,19 @@ IsSimpleOp::isSimpleLinearGeometry(const Geometry& geom)
}
/* private static */
-std::vector<std::unique_ptr<CoordinateSequence>>
+std::vector<std::shared_ptr<const CoordinateSequence>>
IsSimpleOp::removeRepeatedPts(const Geometry& geom)
{
- std::vector<std::unique_ptr<CoordinateSequence>> coordseqs;
+ std::vector<std::shared_ptr<const CoordinateSequence>> coordseqs;
for (std::size_t i = 0, sz = geom.getNumGeometries(); i < sz; i++) {
const LineString* line = dynamic_cast<const LineString*>(geom.getGeometryN(i));
if (line) {
- auto ptsNoRepeat = RepeatedPointRemover::removeRepeatedPoints(line->getCoordinatesRO());
- coordseqs.emplace_back(ptsNoRepeat.release());
+ auto pts = line->getSharedCoordinates();
+ if (pts->hasRepeatedPoints()) {
+ pts = RepeatedPointRemover::removeRepeatedPoints(line->getCoordinatesRO());
+ }
+
+ coordseqs.push_back(pts);
}
}
return coordseqs;
@@ -240,12 +244,12 @@ IsSimpleOp::removeRepeatedPts(const Geometry& geom)
/* private static */
std::vector<std::unique_ptr<SegmentString>>
-IsSimpleOp::createSegmentStrings(std::vector<std::unique_ptr<CoordinateSequence>>& seqs)
+IsSimpleOp::createSegmentStrings(std::vector<std::shared_ptr<const CoordinateSequence>>& seqs)
{
std::vector<std::unique_ptr<SegmentString>> segStrings;
for (auto& seq : seqs) {
BasicSegmentString* bss = new BasicSegmentString(
- seq.get(),
+ seq,
nullptr);
segStrings.emplace_back(static_cast<SegmentString*>(bss));
}
diff --git a/src/operation/valid/PolygonTopologyAnalyzer.cpp b/src/operation/valid/PolygonTopologyAnalyzer.cpp
index 121d4f5ce..2a65cbc16 100644
--- a/src/operation/valid/PolygonTopologyAnalyzer.cpp
+++ b/src/operation/valid/PolygonTopologyAnalyzer.cpp
@@ -320,15 +320,14 @@ PolygonTopologyAnalyzer::createSegString(const LinearRing* ring, const PolygonRi
// Let the input LinearRing retain ownership of the
// CoordinateSequence, and pass it directly into the BasicSegmentString
// constructor.
- CoordinateSequence* pts = const_cast<CoordinateSequence*>(ring->getCoordinatesRO());
+ std::shared_ptr<const CoordinateSequence> pts = ring->getSharedCoordinates();
// Repeated points must be removed for accurate intersection detection
- // So, in this case we create a de-duped copy of the CoordinateSequence
- // and manage the lifecycle locally. This we pass on to the SegmentString
+ // So, in this case we create a de-duped copy of the CoordinateSequence.
+ // This we pass on to the SegmentString.
if (pts->hasRepeatedPoints()) {
- std::unique_ptr<CoordinateSequence> newPts = RepeatedPointRemover::removeRepeatedPoints(pts);
- pts = newPts.get();
- coordSeqStore.emplace_back(newPts.release());
+ std::unique_ptr<CoordinateSequence> newPts = RepeatedPointRemover::removeRepeatedPoints(pts.get());
+ pts = std::move(newPts);
}
// Allocate the BasicSegmentString in the store and return a
diff --git a/src/triangulate/polygon/PolygonHoleJoiner.cpp b/src/triangulate/polygon/PolygonHoleJoiner.cpp
index 239491672..fc453def7 100644
--- a/src/triangulate/polygon/PolygonHoleJoiner.cpp
+++ b/src/triangulate/polygon/PolygonHoleJoiner.cpp
@@ -142,18 +142,20 @@ PolygonHoleJoiner::extractOrientedRings(const Polygon* polygon)
std::vector<const LinearRing*> holes = sortHoles(polygon);
for (const LinearRing* hole : holes) {
auto oHole = extractOrientedRing(hole, false);
- holeRings.emplace_back(oHole.release());
+ holeRings.emplace_back(oHole);
}
}
/* private static */
-std::unique_ptr<CoordinateSequence>
+std::shared_ptr<const CoordinateSequence>
PolygonHoleJoiner::extractOrientedRing(const LinearRing* ring, bool isCW)
{
- std::unique_ptr<CoordinateSequence> pts = ring->getCoordinates();
+ auto pts = ring->getSharedCoordinates();
bool isRingCW = ! Orientation::isCCW(pts.get());
if (isCW != isRingCW) {
- pts->reverse();
+ auto reversed = pts->clone();
+ reversed->reverse();
+ pts = std::move(reversed);
}
return pts;
}
@@ -408,8 +410,9 @@ PolygonHoleJoiner::findLowestLeftVertexIndex(const CoordinateSequence& holeCoord
bool
PolygonHoleJoiner::intersectsBoundary(const Coordinate& p0, const Coordinate& p1)
{
- CoordinateSequence cs { p0, p1 };
- BasicSegmentString bss(&cs, nullptr);
+ auto cs = std::make_shared<CoordinateSequence>(std::initializer_list<Coordinate>{p0, p1});
+
+ BasicSegmentString bss(cs, nullptr);
std::vector<const SegmentString*> segStrings { &bss };
InteriorIntersectionDetector segInt;
@@ -425,11 +428,11 @@ PolygonHoleJoiner::createBoundaryIntersector()
{
std::vector<const SegmentString*> polySegStrings;
polySegStringStore.clear();
- BasicSegmentString* bss = new BasicSegmentString(shellRing.get(), nullptr);
+ BasicSegmentString* bss = new BasicSegmentString(shellRing, nullptr);
polySegStringStore.emplace_back(bss);
polySegStrings.push_back(bss);
for (auto& hole : holeRings) {
- bss = new BasicSegmentString(hole.get(), nullptr);
+ bss = new BasicSegmentString(hole, nullptr);
polySegStringStore.emplace_back(bss);
polySegStrings.push_back(bss);
}
diff --git a/src/triangulate/polygon/PolygonNoder.cpp b/src/triangulate/polygon/PolygonNoder.cpp
index 08462469e..51abcd845 100644
--- a/src/triangulate/polygon/PolygonNoder.cpp
+++ b/src/triangulate/polygon/PolygonNoder.cpp
@@ -37,8 +37,8 @@ namespace polygon {
PolygonNoder::PolygonNoder(
- std::unique_ptr<CoordinateSequence>& shellRing,
- std::vector<std::unique_ptr<CoordinateSequence>>& holeRings)
+ const std::shared_ptr<const CoordinateSequence>& shellRing,
+ const std::vector<std::shared_ptr<const CoordinateSequence>>& holeRings)
{
isHoleTouching.resize(holeRings.size(), false);
createNodedSegmentStrings(shellRing, holeRings);
@@ -172,8 +172,8 @@ PolygonNoder::getHolesTouching()
/* private */
void
PolygonNoder::createNodedSegmentStrings(
- std::unique_ptr<CoordinateSequence>& shellRing,
- std::vector<std::unique_ptr<CoordinateSequence>>& holeRings)
+ const std::shared_ptr<const CoordinateSequence>& shellRing,
+ const std::vector<std::shared_ptr<const CoordinateSequence>>& holeRings)
{
nodedRings.emplace_back(createNodedSegString(shellRing, 0));
for (std::size_t i = 1; i <= holeRings.size(); i++) {
@@ -184,12 +184,12 @@ PolygonNoder::createNodedSegmentStrings(
/* private */
NodedSegmentString*
-PolygonNoder::createNodedSegString(std::unique_ptr<CoordinateSequence>& ringPts, std::size_t i)
+PolygonNoder::createNodedSegString(const std::shared_ptr<const CoordinateSequence>& ringPts, std::size_t i)
{
// note: in PolygonHoleJoiner::nodeRings we will replace the contents
// of the shellRing and holeRings with the results of the calculation
// here, so it's OK to take ownership of the points from them here
- NodedSegmentString* nss = new NodedSegmentString(ringPts.release(), false, false, nullptr);
+ NodedSegmentString* nss = new NodedSegmentString(ringPts, false, false, nullptr);
nss->setData(nss);
// need to map the identity of this nss to the index number of the
// ring it represents. use an external map to avoid abusing the void*
diff --git a/tests/unit/geom/LineStringTest.cpp b/tests/unit/geom/LineStringTest.cpp
index 930f8885a..33d74af9d 100644
--- a/tests/unit/geom/LineStringTest.cpp
+++ b/tests/unit/geom/LineStringTest.cpp
@@ -7,6 +7,7 @@
// geos
#include <geos/geom/LineString.h>
#include <geos/geom/Coordinate.h>
+#include <geos/geom/CoordinateFilter.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/Dimension.h>
#include <geos/geom/Geometry.h>
@@ -22,6 +23,8 @@
#include <cmath>
#include <cassert>
+using geos::geom::CoordinateXY;
+
namespace tut {
//
// Test Group
@@ -533,7 +536,7 @@ void object::test<29>
ensure(c != nullptr);
}
-// releaseCoordinates
+// getSharedCoordinates
template<>
template<>
void object::test<30>()
@@ -542,8 +545,21 @@ void object::test<30>()
auto env = ls->getEnvelopeInternal();
ensure_equals(*env, geos::geom::Envelope(0,10, 0, 10));
- auto cs = ls->releaseCoordinates();
+ auto cs = ls->getSharedCoordinates();
ensure_equals(cs->getSize(), 2u);
+
+ struct AddFive : public geos::geom::CoordinateFilter {
+ void filter_rw(CoordinateXY* pt) const override {
+ pt->x += 5;
+ pt->y += 5;
+ }
+ };
+
+ AddFive filter;
+ ls->apply_rw(&filter);
+
+ ensure_equals(cs->getAt<CoordinateXY>(0), CoordinateXY(0, 0));
+ ensure_equals(cs->getAt<CoordinateXY>(1), CoordinateXY(10, 10));
}
// Test of LinearRing constructor with a NaN coordinate
diff --git a/tests/unit/geom/LinearRingTest.cpp b/tests/unit/geom/LinearRingTest.cpp
index 80314767f..81f503e04 100644
--- a/tests/unit/geom/LinearRingTest.cpp
+++ b/tests/unit/geom/LinearRingTest.cpp
@@ -497,6 +497,34 @@ void object::test<35>
}
}
+template<>
+template<>
+void object::test<36>()
+{
+ set_test_name("LinearRing::orient modifies coordinates in-place if there are no external references");
+ auto lr = reader_.read<geos::geom::LinearRing>("LINEARRING(0 0, 1 0, 1 1, 0 1, 0 0)");
+ auto seq0 = lr->getCoordinatesRO();
+
+ lr->orient(false);
+ ensure_equals(lr->getCoordinatesRO(), seq0);
+ lr->orient(true);
+ ensure_equals(lr->getCoordinatesRO(), seq0);
+}
+
+template<>
+template<>
+void object::test<37>()
+{
+ set_test_name("LinearRing::orient does not modify coordinates in-place if there are external references");
+
+ auto lr = reader_.read<geos::geom::LinearRing>("LINEARRING(0 0, 1 0, 1 1, 0 1, 0 0)");
+ auto seq0 = lr->getSharedCoordinates();
+
+ lr->orient(false);
+ ensure_equals(lr->getCoordinatesRO(), seq0.get());
+ lr->orient(true);
+ ensure(lr->getCoordinatesRO() != seq0.get());
+}
} // namespace tut
diff --git a/tests/unit/noding/BasicSegmentStringTest.cpp b/tests/unit/noding/BasicSegmentStringTest.cpp
index 808383c64..4abc8f4ea 100644
--- a/tests/unit/noding/BasicSegmentStringTest.cpp
+++ b/tests/unit/noding/BasicSegmentStringTest.cpp
@@ -26,7 +26,7 @@ struct test_basicsegmentstring_data {
SegmentStringAutoPtr;
SegmentStringAutoPtr
- makeSegmentString(geos::geom::CoordinateSequence* cs, void* d = nullptr)
+ makeSegmentString(std::shared_ptr<geos::geom::CoordinateSequence> cs, void* d = nullptr)
{
return SegmentStringAutoPtr(
new geos::noding::BasicSegmentString(cs, d)
@@ -58,7 +58,7 @@ template<>
void object::test<1>
()
{
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, 2u);
+ auto cs = std::make_shared<geos::geom::CoordinateSequence>(0u, 2u);
ensure(nullptr != cs.get());
@@ -70,14 +70,14 @@ void object::test<1>
ensure_equals(cs->size(), 2u);
- SegmentStringAutoPtr ss(makeSegmentString(cs.get()));
+ SegmentStringAutoPtr ss(makeSegmentString(cs));
ensure(nullptr != ss.get());
ensure_equals(ss->size(), 2u);
ensure_equals(ss->getData(), (void*)nullptr);
- ensure_equals(ss->getCoordinates(), cs.get());
+ ensure_equals(ss->getCoordinates().get(), cs.get());
ensure_equals(ss->getCoordinate(0), c0);
@@ -103,7 +103,7 @@ template<>
void object::test<2>
()
{
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, 2u);
+ auto cs = std::make_shared<geos::geom::CoordinateSequence>(0u, 2u);
ensure(nullptr != cs.get());
@@ -115,14 +115,14 @@ void object::test<2>
ensure_equals(cs->size(), 2u);
- SegmentStringAutoPtr ss(makeSegmentString(cs.get()));
+ SegmentStringAutoPtr ss(makeSegmentString(cs));
ensure(nullptr != ss.get());
ensure_equals(ss->size(), 2u);
ensure_equals(ss->getData(), (void*)nullptr);
- ensure_equals(ss->getCoordinates(), cs.get());
+ ensure_equals(ss->getCoordinates().get(), cs.get());
ensure_equals(ss->getCoordinate(0), c0);
@@ -140,7 +140,7 @@ template<>
void object::test<3>
()
{
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, 2u);
+ auto cs = std::make_shared<geos::geom::CoordinateSequence>(0u, 2u);
ensure(nullptr != cs.get());
@@ -155,14 +155,14 @@ void object::test<3>
ensure_equals(cs->size(), 4u);
- SegmentStringAutoPtr ss(makeSegmentString(cs.get()));
+ SegmentStringAutoPtr ss(makeSegmentString(cs));
ensure(nullptr != ss.get());
ensure_equals(ss->size(), 4u);
ensure_equals(ss->getData(), (void*)nullptr);
- ensure_equals(ss->getCoordinates(), cs.get());
+ ensure_equals(ss->getCoordinates().get(), cs.get());
ensure_equals(ss->getCoordinate(0), c0);
diff --git a/tests/unit/noding/NodedSegmentStringTest.cpp b/tests/unit/noding/NodedSegmentStringTest.cpp
index 26f8cc904..f4dd858ba 100644
--- a/tests/unit/noding/NodedSegmentStringTest.cpp
+++ b/tests/unit/noding/NodedSegmentStringTest.cpp
@@ -38,10 +38,10 @@ struct test_nodedsegmentstring_data {
WKTReader r;
SegmentStringAutoPtr
- makeSegmentString(geos::geom::CoordinateSequence* cs, void* d = nullptr)
+ makeSegmentString(std::unique_ptr<geos::geom::CoordinateSequence> cs, void* d = nullptr)
{
return SegmentStringAutoPtr(
- new geos::noding::NodedSegmentString(cs, true, false, d)
+ new geos::noding::NodedSegmentString(std::move(cs), true, false, d)
);
}
@@ -65,7 +65,7 @@ struct test_nodedsegmentstring_data {
std::unique_ptr<Geometry> line = r.read(wktLine);
std::unique_ptr<Geometry> pts = r.read(wktNodes);
- NodedSegmentString nss(line->getCoordinates().release(), true, false, 0);
+ NodedSegmentString nss(line->getCoordinates(), true, false, 0);
std::unique_ptr<CoordinateSequence> node = pts->getCoordinates();
for (std::size_t i = 0, n=node->size(); i < n; ++i) {
@@ -116,7 +116,7 @@ void object::test<1>
ensure_equals(cs->size(), 2u);
- SegmentStringAutoPtr ss(makeSegmentString(cs.release()));
+ SegmentStringAutoPtr ss(makeSegmentString(std::move(cs)));
ensure(nullptr != ss.get());
ensure_equals(ss->size(), 2u);
@@ -152,7 +152,7 @@ void object::test<2>
ensure_equals(cs->size(), 2u);
- SegmentStringAutoPtr ss(makeSegmentString(cs.release()));
+ SegmentStringAutoPtr ss(makeSegmentString(std::move(cs)));
ensure(nullptr != ss.get());
ensure_equals(ss->size(), 2u);
@@ -191,7 +191,7 @@ void object::test<3>
ensure_equals(cs->size(), 4u);
- SegmentStringAutoPtr ss(makeSegmentString(cs.release()));
+ SegmentStringAutoPtr ss(makeSegmentString(std::move(cs)));
ensure(nullptr != ss.get());
ensure_equals(ss->size(), 4u);
@@ -253,7 +253,7 @@ void object::test<5>
cs->add(p0);
cs->add(p1);
- SegmentStringAutoPtr ss(makeSegmentString(cs.release()));
+ SegmentStringAutoPtr ss(makeSegmentString(std::move(cs)));
ensure_equals(ss->getNodeList().size(), 0u);
diff --git a/tests/unit/noding/SegmentNodeTest.cpp b/tests/unit/noding/SegmentNodeTest.cpp
index 8b71af518..4cb9e7098 100644
--- a/tests/unit/noding/SegmentNodeTest.cpp
+++ b/tests/unit/noding/SegmentNodeTest.cpp
@@ -50,7 +50,7 @@ void object::test<1>
// Create coordinates sequence
const std::size_t coords_size = 2;
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
+ auto cs = std::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
ensure(nullptr != cs.get());
@@ -63,7 +63,7 @@ void object::test<1>
// Create SegmentString instance
- NodedSegmentString segment(cs.release(), false, false, nullptr);
+ NodedSegmentString segment(std::move(cs), false, false, nullptr);
ensure_equals(segment.size(), coords_size);
@@ -99,7 +99,7 @@ void object::test<2>
// Create coordinates sequence
const std::size_t coords_size = 2;
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
+ auto cs = std::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
ensure(nullptr != cs.get());
@@ -112,7 +112,7 @@ void object::test<2>
// Create SegmentString instance
- NodedSegmentString segment(cs.release(), false, false, nullptr);
+ NodedSegmentString segment(std::move(cs), false, false, nullptr);
ensure_equals(segment.size(), coords_size);
@@ -142,7 +142,7 @@ void object::test<3>
// Create coordinates sequence
const std::size_t coords_size = 2;
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
+ auto cs = std::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
ensure(nullptr != cs.get());
@@ -155,7 +155,7 @@ void object::test<3>
// Create SegmentString instance
- NodedSegmentString segment(cs.release(), false, false, nullptr);
+ NodedSegmentString segment(std::move(cs), false, false, nullptr);
ensure_equals(segment.size(), coords_size);
@@ -185,7 +185,7 @@ void object::test<4>
// Create coordinates sequence
const std::size_t coords_size = 2;
- auto cs = geos::detail::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
+ auto cs = std::make_unique<geos::geom::CoordinateSequence>(0u, coords_size);
ensure(nullptr != cs.get());
@@ -198,7 +198,7 @@ void object::test<4>
// Create SegmentString instance
- NodedSegmentString segment(cs.release(), false, false, nullptr);
+ NodedSegmentString segment(std::move(cs), false, false, nullptr);
ensure_equals(segment.size(), coords_size);
diff --git a/tests/unit/noding/snapround/MCIndexSnapRounderTest.cpp b/tests/unit/noding/snapround/MCIndexSnapRounderTest.cpp
index d9d569a69..177f44e93 100644
--- a/tests/unit/noding/snapround/MCIndexSnapRounderTest.cpp
+++ b/tests/unit/noding/snapround/MCIndexSnapRounderTest.cpp
@@ -69,7 +69,7 @@ struct test_mcidxsnprndr_data {
getSegmentStrings(const Geometry& g, SegStrVct& vct)
{
CoordSeqPtr s(g.getCoordinates());
- vct.push_back(new NodedSegmentString(s.release(), g.hasZ(), g.hasM(), nullptr));
+ vct.push_back(new NodedSegmentString(std::move(s), g.hasZ(), g.hasM(), nullptr));
}
GeomPtr
diff --git a/tests/unit/util/NodingTestUtil.cpp b/tests/unit/util/NodingTestUtil.cpp
index edb0b8072..dd6819f01 100644
--- a/tests/unit/util/NodingTestUtil.cpp
+++ b/tests/unit/util/NodingTestUtil.cpp
@@ -31,11 +31,8 @@ NodingTestUtil::toLines(const std::vector<SegmentString*>& nodedList, const Geom
std::vector<std::unique_ptr<Geometry>> lines;
for (auto nss : nodedList) {
- CoordinateSequence* pts = nss->getCoordinates();
- // pts is owned by nss, so we make a copy to build the line
- // on top of. Lines are 100% self-contained and own all their parts.
- // Input nodedList can be freed.
- lines.emplace_back(geomFact->createLineString(pts->clone()));
+ const auto& pts = nss->getCoordinates();
+ lines.emplace_back(geomFact->createLineString(pts));
}
if (lines.size() == 1) return std::move(lines[0]);
@@ -62,7 +59,7 @@ NodingTestUtil::toSegmentStrings(std::vector<const LineString*>& lines)
// into a unique_ptr<> which we have to release() to the
// NodedSegmentString constructor, so
// nss now owns nss->pts
- NodedSegmentString* nss = new NodedSegmentString(line->getCoordinates().release(), constructZ, constructM, line);
+ NodedSegmentString* nss = new NodedSegmentString(line->getCoordinates(), constructZ, constructM, line);
nssList.push_back(nss);
}
return nssList;
-----------------------------------------------------------------------
Summary of changes:
include/geos/coverage/CoverageCleaner.h | 2 +-
include/geos/coverage/CoverageEdge.h | 12 +++---
include/geos/coverage/CoveragePolygonValidator.h | 1 -
include/geos/coverage/CoverageRing.h | 2 +-
include/geos/geom/CircularString.h | 3 ++
include/geos/geom/GeometryFactory.h | 11 ++++++
include/geos/geom/LineString.h | 3 ++
include/geos/geom/LinearRing.h | 3 ++
include/geos/geom/SimpleCurve.h | 19 ++++------
include/geos/geomgraph/EdgeNodingValidator.h | 7 ----
include/geos/noding/BasicSegmentString.h | 2 +-
include/geos/noding/NodableSegmentString.h | 2 +-
include/geos/noding/NodedSegmentString.h | 7 +---
include/geos/noding/SegmentNodeList.h | 2 +-
include/geos/noding/SegmentString.h | 13 +++----
include/geos/noding/SegmentStringUtil.h | 4 +-
include/geos/noding/snap/SnappingNoder.h | 2 +-
.../geos/operation/buffer/BufferCurveSetBuilder.h | 4 +-
include/geos/operation/buffer/OffsetCurveBuilder.h | 9 ++---
.../geos/operation/buffer/OffsetSegmentGenerator.h | 4 +-
include/geos/operation/overlayng/Edge.h | 11 +++---
include/geos/operation/overlayng/OverlayEdge.h | 14 ++-----
include/geos/operation/overlayng/OverlayGraph.h | 6 +--
include/geos/operation/relateng/RelateGeometry.h | 9 ++---
.../geos/operation/relateng/RelateSegmentString.h | 16 ++++----
include/geos/operation/valid/IsSimpleOp.h | 4 +-
.../geos/operation/valid/PolygonTopologyAnalyzer.h | 5 ---
.../geos/triangulate/polygon/PolygonHoleJoiner.h | 6 +--
include/geos/triangulate/polygon/PolygonNoder.h | 10 ++---
src/algorithm/MinimumDiameter.cpp | 2 +-
src/coverage/CoverageCleaner.cpp | 4 +-
src/coverage/CoverageEdge.cpp | 10 ++---
src/coverage/CoveragePolygonValidator.cpp | 9 ++---
src/coverage/CoverageRing.cpp | 10 +----
src/coverage/CoverageRingEdges.cpp | 2 +-
src/coverage/CoverageSimplifier.cpp | 2 +-
src/dissolve/LineDissolver.cpp | 1 +
src/geom/CircularString.cpp | 8 ++++
src/geom/GeometryFactory.cpp | 27 ++++++++++++++
src/geom/LineString.cpp | 9 +++++
src/geom/LinearRing.cpp | 15 +++++++-
src/geom/Polygon.cpp | 2 +-
src/geom/SimpleCurve.cpp | 43 +++++++++++++++-------
src/geom/util/CoordinateOperation.cpp | 4 +-
src/geomgraph/EdgeNodingValidator.cpp | 6 +--
src/noding/BoundaryChainNoder.cpp | 12 ++----
src/noding/GeometryNoder.cpp | 9 ++---
src/noding/MCIndexNoder.cpp | 2 +-
src/noding/MCIndexSegmentSetMutualIntersector.cpp | 4 +-
src/noding/NodedSegmentString.cpp | 8 ----
src/noding/ScaledNoder.cpp | 14 ++++---
src/noding/SegmentExtractingNoder.cpp | 6 +--
src/noding/SegmentNodeList.cpp | 18 ++++-----
src/noding/SimpleNoder.cpp | 4 +-
src/noding/snap/SnappingNoder.cpp | 14 +++----
src/noding/snapround/MCIndexSnapRounder.cpp | 2 +-
src/noding/snapround/SnapRoundingNoder.cpp | 8 ++--
src/operation/buffer/BufferBuilder.cpp | 12 +++---
src/operation/buffer/BufferCurveSetBuilder.cpp | 26 ++++++-------
src/operation/buffer/OffsetCurveBuilder.cpp | 12 +++---
src/operation/overlayng/Edge.cpp | 4 +-
src/operation/overlayng/EdgeNodingBuilder.cpp | 9 ++---
src/operation/overlayng/OverlayEdge.cpp | 6 +--
src/operation/overlayng/OverlayGraph.cpp | 7 ++--
src/operation/overlayng/OverlayUtil.cpp | 4 +-
src/operation/relateng/EdgeSetIntersector.cpp | 2 +-
src/operation/relateng/RelateGeometry.cpp | 34 +++++++----------
src/operation/relateng/RelateSegmentString.cpp | 8 ++--
src/operation/valid/IsSimpleOp.cpp | 16 +++++---
src/operation/valid/PolygonTopologyAnalyzer.cpp | 11 +++---
src/triangulate/polygon/PolygonHoleJoiner.cpp | 19 ++++++----
src/triangulate/polygon/PolygonNoder.cpp | 12 +++---
tests/unit/geom/LineStringTest.cpp | 20 +++++++++-
tests/unit/geom/LinearRingTest.cpp | 28 ++++++++++++++
tests/unit/noding/BasicSegmentStringTest.cpp | 20 +++++-----
tests/unit/noding/NodedSegmentStringTest.cpp | 14 +++----
tests/unit/noding/SegmentNodeTest.cpp | 16 ++++----
.../noding/snapround/MCIndexSnapRounderTest.cpp | 2 +-
tests/unit/util/NodingTestUtil.cpp | 9 ++---
79 files changed, 408 insertions(+), 331 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list