GEOS  3.11.0rc0
NodedSegmentString.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2020 Paul Ramsey <pramsey@cleverelephant.ca>
7  * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
8  * Copyright (C) 2006 Refractions Research Inc.
9  * Copyright (C) 2001-2002 Vivid Solutions Inc.
10  *
11  * This is free software; you can redistribute and/or modify it under
12  * the terms of the GNU Lesser General Public Licence as published
13  * by the Free Software Foundation.
14  * See the COPYING file for more information.
15  *
16  *
17  **********************************************************************
18  *
19  * Last port: noding/NodedSegmentString.java r320 (JTS-1.12)
20  *
21  **********************************************************************/
22 
23 #pragma once
24 
25 #include <geos/export.h>
26 #include <geos/algorithm/LineIntersector.h>
27 #include <geos/geom/Coordinate.h>
28 #include <geos/geom/CoordinateSequence.h> // for inlines
29 #include <geos/noding/NodedSegmentString.h>
30 #include <geos/noding/NodableSegmentString.h> // for inheritance
31 #include <geos/noding/Octant.h>
32 #include <geos/noding/SegmentNode.h>
33 #include <geos/noding/SegmentNodeList.h>
34 #include <geos/noding/SegmentString.h>
35 #include <geos/util/IllegalArgumentException.h>
36 
37 #include <cstddef>
38 
39 #ifdef _MSC_VER
40 #pragma warning(push)
41 #pragma warning(disable: 4251 4355) // warning C4355: 'this' : used in base member initializer list
42 #endif
43 
44 namespace geos {
45 namespace noding { // geos::noding
46 
59 class GEOS_DLL NodedSegmentString : public NodableSegmentString {
60 public:
61 
62  // TODO: provide a templated method using an output iterator
63  template <class II>
64  static void
65  getNodedSubstrings(II from, II too_far,
66  SegmentString::NonConstVect* resultEdgelist)
67  {
68  for(II i = from; i != too_far; ++i) {
69  NodedSegmentString* nss = dynamic_cast<NodedSegmentString*>(*i);
70  assert(nss);
71  nss->getNodeList().addSplitEdges(resultEdgelist);
72  }
73  }
74 
75  template <class C>
76  static void
77  getNodedSubstrings(C* segStrings,
78  SegmentString::NonConstVect* resultEdgelist)
79  {
80  getNodedSubstrings(segStrings->begin(), segStrings->end(), resultEdgelist);
81  }
82 
83  static void getNodedSubstrings(const SegmentString::NonConstVect& segStrings,
84  SegmentString::NonConstVect* resultEdgeList);
85 
87  static SegmentString::NonConstVect* getNodedSubstrings(
88  const SegmentString::NonConstVect& segStrings);
89 
90  std::vector<geom::Coordinate> getNodedCoordinates();
91 
92 
102  NodedSegmentString(geom::CoordinateSequence* newPts, const void* newContext)
103  : NodableSegmentString(newContext)
104  , nodeList(this)
105  , pts(newPts)
106  {}
107 
109  : NodableSegmentString(ss->getData())
110  , nodeList(this)
111  , pts(ss->getCoordinates()->clone())
112  {}
113 
114  ~NodedSegmentString() override = default;
115 
116  SegmentNodeList& getNodeList();
117 
118  const SegmentNodeList& getNodeList() const;
119 
120  size_t
121  size() const override
122  {
123  return pts->size();
124  }
125 
126  const geom::Coordinate& getCoordinate(std::size_t i) const override;
127 
129  geom::CoordinateSequence* releaseCoordinates();
130 
131  bool isClosed() const override;
132 
133  std::ostream& print(std::ostream& os) const override;
134 
135 
143  int getSegmentOctant(std::size_t index) const
144  {
145  if (index >= size() - 1) {
146  return -1;
147  }
148  return safeOctant(getCoordinate(index), getCoordinate(index + 1));
149  //return Octant::octant(getCoordinate(index), getCoordinate(index+1));
150  };
151 
158  std::size_t segmentIndex, std::size_t geomIndex)
159  {
160  for (std::size_t i = 0, n = li->getIntersectionNum(); i < n; ++i) {
161  addIntersection(li, segmentIndex, geomIndex, i);
162  }
163  };
164 
173  std::size_t segmentIndex,
174  std::size_t geomIndex, std::size_t intIndex)
175  {
176  ::geos::ignore_unused_variable_warning(geomIndex);
177 
178  const geom::Coordinate& intPt = li->getIntersection(intIndex);
179  addIntersection(intPt, segmentIndex);
180  };
181 
190  std::size_t segmentIndex)
191  {
192  std::size_t normalizedSegmentIndex = segmentIndex;
193 
194  if (segmentIndex > size() - 2) {
195  throw util::IllegalArgumentException("SegmentString::addIntersection: SegmentIndex out of range");
196  }
197 
198  // normalize the intersection point location
199  auto nextSegIndex = normalizedSegmentIndex + 1;
200  if (nextSegIndex < size()) {
201  const geom::Coordinate& nextPt = pts->getAt(nextSegIndex);
202 
203  // Normalize segment index if intPt falls on vertex
204  // The check for point equality is 2D only -
205  // Z values are ignored
206  if(intPt.equals2D(nextPt)) {
207  normalizedSegmentIndex = nextSegIndex;
208  }
209  }
210 
211  /*
212  * Add the intersection point to edge intersection list
213  * (unless the node is already known)
214  */
215  nodeList.add(intPt, normalizedSegmentIndex);
216  };
217 
218 private:
219 
220  SegmentNodeList nodeList;
221 
222  std::unique_ptr<geom::CoordinateSequence> pts;
223 
224  static int safeOctant(const geom::Coordinate& p0, const geom::Coordinate& p1)
225  {
226  if(p0.equals2D(p1)) {
227  return 0;
228  }
229  return Octant::octant(p0, p1);
230  };
231 
232 };
233 
234 } // namespace geos::noding
235 } // namespace geos
236 
237 #ifdef _MSC_VER
238 #pragma warning(pop)
239 #endif
240 
241 
242 
243 
244 
245 
246 
247 
248 
249 
250 
A LineIntersector is an algorithm that can both test whether two line segments intersect and compute ...
Definition: LineIntersector.h:50
const geom::Coordinate & getIntersection(std::size_t intIndex) const
Definition: LineIntersector.h:211
size_t getIntersectionNum() const
Definition: LineIntersector.h:198
The internal representation of a list of coordinates inside a Geometry.
Definition: CoordinateSequence.h:44
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:58
An interface for classes which support adding nodes to a segment string.
Definition: NodableSegmentString.h:36
Represents a list of contiguous line segments, and supports noding the segments.
Definition: NodedSegmentString.h:59
void addIntersection(algorithm::LineIntersector *li, std::size_t segmentIndex, std::size_t geomIndex, std::size_t intIndex)
Add an SegmentNode for intersection intIndex.
Definition: NodedSegmentString.h:172
static SegmentString::NonConstVect * getNodedSubstrings(const SegmentString::NonConstVect &segStrings)
Returns allocated object.
NodedSegmentString(geom::CoordinateSequence *newPts, const void *newContext)
Creates a new segment string from a list of vertices.
Definition: NodedSegmentString.h:102
void addIntersections(algorithm::LineIntersector *li, std::size_t segmentIndex, std::size_t geomIndex)
Add SegmentNodes for one or both intersections found for a segment of an edge to the edge intersectio...
Definition: NodedSegmentString.h:157
void addIntersection(const geom::Coordinate &intPt, std::size_t segmentIndex)
Add an SegmentNode for intersection intIndex.
Definition: NodedSegmentString.h:189
geom::CoordinateSequence * getCoordinates() const override
Return a pointer to the CoordinateSequence associated with this SegmentString.
int getSegmentOctant(std::size_t index) const
Gets the octant of the segment starting at vertex index.
Definition: NodedSegmentString.h:143
static int octant(double dx, double dy)
A list of the SegmentNode present along a NodedSegmentString.
Definition: SegmentNodeList.h:54
void addSplitEdges(std::vector< SegmentString * > &edgeList)
An interface for classes which represent a sequence of contiguous line segments.
Definition: SegmentString.h:45
Indicates one or more illegal arguments.
Definition: IllegalArgumentException.h:33
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25