GEOS 3.15.0dev
RelateGeometry.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (c) 2024 Martin Davis
7 * Copyright (C) 2024 Paul Ramsey <pramsey@cleverelephant.ca>
8 *
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
13 *
14 **********************************************************************/
15
16#pragma once
17
18#include <geos/algorithm/BoundaryNodeRule.h>
19#include <geos/geom/Coordinate.h>
20#include <geos/geom/Dimension.h>
21#include <geos/geom/Location.h>
22#include <geos/operation/relateng/RelatePointLocator.h>
23#include <geos/operation/relateng/RelateSegmentString.h>
24#include <geos/export.h>
25
26#include <string>
27#include <sstream>
28
29
30// Forward declarations
31namespace geos {
32namespace geom {
33 class CoordinateSequence;
34 class Envelope;
35 class Geometry;
36 class LinearRing;
37 class LineString;
38 class MultiPolygon;
39 class Point;
40}
41namespace noding {
42 class SegmentString;
43}
44}
45
46
47namespace geos { // geos.
48namespace operation { // geos.operation
49namespace relateng { // geos.operation.relateng
50
51class GEOS_DLL RelateGeometry {
52 using Coordinate = geos::geom::Coordinate;
53 using CoordinateSequence = geos::geom::CoordinateSequence;
54 using Dimension = geos::geom::Dimension;
55 using Envelope = geos::geom::Envelope;
56 using Geometry = geos::geom::Geometry;
58 using CoordinateXY = geos::geom::CoordinateXY;
59 using LinearRing = geos::geom::LinearRing;
60 using LineString = geos::geom::LineString;
61 using MultiPolygon = geos::geom::MultiPolygon;
62 using Point = geos::geom::Point;
63 using BoundaryNodeRule = geos::algorithm::BoundaryNodeRule;
64 using SegmentString = geos::noding::SegmentString;
65
66private:
67
68 // Members
69
70 const Geometry* geom;
71 bool m_isPrepared = false;
72 const Envelope* geomEnv;
73 const BoundaryNodeRule& boundaryNodeRule;
74 int geomDim = Dimension::False;
75 bool isLineZeroLen = false;
76 bool isGeomEmpty = false;
77
78 Coordinate::ConstXYSet uniquePoints;
79 std::unique_ptr<RelatePointLocator> locator;
80 int elementId = 0;
81 bool hasPoints = false;
82 bool hasLines = false;
83 bool hasAreas = false;
84
85 /*
86 * Memory contexts for lower level allocations
87 */
88 std::vector<std::unique_ptr<const RelateSegmentString>> segStringTempStore;
89 std::vector<std::unique_ptr<const RelateSegmentString>> segStringPermStore;
90
91
92 // Methods
93
94 void analyzeDimensions();
95
103 static bool isZeroLength(const Geometry* geom);
104
105 static bool isZeroLength(const LineString* line);
106
107 bool isZeroLengthLine(const Geometry* g) const {
108 // avoid expensive zero-length calculation if not linear
109 if (getDimension() != Dimension::L)
110 return false;
111 return isZeroLength(g);
112 };
113
114 RelatePointLocator* getLocator();
115
116 Coordinate::ConstXYSet createUniquePoints();
117
118 void extractSegmentStringsFromAtomic(bool isA,
119 const Geometry* geom, const MultiPolygon* parentPolygonal,
120 const Envelope* env,
121 std::vector<const SegmentString*>& segStrings,
122 std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
123
124 void extractRingToSegmentString(bool isA,
125 const LinearRing* ring, int ringId, const Envelope* env,
126 const Geometry* parentPoly,
127 std::vector<const SegmentString*>& segStrings,
128 std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
129
130 void extractSegmentStrings(bool isA,
131 const Envelope* env, const Geometry* geom,
132 std::vector<const SegmentString*>& segStrings,
133 std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
134
135 static std::shared_ptr<const CoordinateSequence> orientAndRemoveRepeated(
136 const std::shared_ptr<const CoordinateSequence>& cs, bool orientCW);
137
138 static std::shared_ptr<const CoordinateSequence> removeRepeated(
139 const std::shared_ptr<const CoordinateSequence>& cs);
140
141public:
142
143 static constexpr bool GEOM_A = true;
144 static constexpr bool GEOM_B = false;
145
146 RelateGeometry(const Geometry* input)
147 : RelateGeometry(input, false, BoundaryNodeRule::getBoundaryRuleMod2())
148 {};
149
150 RelateGeometry(const Geometry* input, const BoundaryNodeRule& bnRule)
151 : RelateGeometry(input, false, bnRule)
152 {};
153
154 RelateGeometry(const Geometry* input, bool p_isPrepared, const BoundaryNodeRule& bnRule);
155
156 static std::string name(bool isA);
157
158 const Geometry* getGeometry() const {
159 return geom;
160 }
161
162 bool isPrepared() const {
163 return m_isPrepared;
164 }
165
166 const Envelope* getEnvelope() const {
167 return geomEnv;
168 }
169
170 inline int getDimension() const {
171 return geomDim;
172 }
173
174 bool hasDimension(int dim) const {
175 switch (dim) {
176 case Dimension::P: return hasPoints;
177 case Dimension::L: return hasLines;
178 case Dimension::A: return hasAreas;
179 }
180 return false;
181 }
182
183 bool hasAreaAndLine() const {
184 return hasAreas && hasLines;
185 }
186
193 int getDimensionReal() const;
194
195 bool hasEdges() const;
196
197 bool isNodeInArea(const CoordinateXY* nodePt, const Geometry* parentPolygonal);
198
199 int locateLineEndWithDim(const CoordinateXY* p);
200
211 Location locateAreaVertex(const CoordinateXY* pt);
212
213 Location locateNode(const CoordinateXY* pt, const Geometry* parentPolygonal);
214
215 int locateWithDim(const CoordinateXY* pt);
216
233 bool isSelfNodingRequired() const;
234
245 bool isPolygonal() const;
246
247 bool isEmpty() const;
248
249 bool hasBoundary();
250
251 Coordinate::ConstXYSet& getUniquePoints();
252
253 std::vector<const Point*> getEffectivePoints();
254
264 std::vector<const SegmentString*> extractSegmentStrings(bool isA, const Envelope* env);
265
266 std::string toString() const;
267
268 friend std::ostream& operator<<(std::ostream& os, const RelateGeometry& rg);
269
275 RelateGeometry(const RelateGeometry&) = delete;
276 RelateGeometry& operator=(const RelateGeometry&) = delete;
277
278};
279
280} // namespace geos.operation.relateng
281} // namespace geos.operation
282} // namespace geos
283
An interface for rules which determine whether node points which are in boundaries of lineal geometry...
Definition BoundaryNodeRule.h:52
The internal representation of a list of coordinates inside a Geometry.
Definition CoordinateSequence.h:56
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:217
Definition Dimension.h:27
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition Envelope.h:59
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition Geometry.h:196
Definition LineString.h:66
Models an OGC SFS LinearRing. A LinearRing is a LineString which is both closed and simple.
Definition LinearRing.h:54
Definition MultiPolygon.h:58
Definition Point.h:61
An interface for classes which represent a sequence of contiguous line segments.
Definition SegmentString.h:47
Location
Constants representing the location of a point relative to a geometry.
Definition Location.h:32
Basic namespace for all GEOS functionalities.
Definition geos.h:38