/src/geos/include/geos/algorithm/LineIntersector.h
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2005-2006 Refractions Research Inc. |
7 | | * Copyright (C) 2001-2002 Vivid Solutions Inc. |
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 | | * Last port: algorithm/RobustLineIntersector.java r785 (JTS-1.13+) |
17 | | * |
18 | | **********************************************************************/ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <geos/export.h> |
23 | | #include <geos/algorithm/Intersection.h> |
24 | | #include <geos/algorithm/Interpolate.h> |
25 | | #include <geos/algorithm/Orientation.h> |
26 | | #include <geos/geom/Coordinate.h> |
27 | | #include <geos/geom/Envelope.h> |
28 | | #include <geos/geom/PrecisionModel.h> |
29 | | |
30 | | #include <string> |
31 | | |
32 | | // Forward declarations |
33 | | namespace geos { |
34 | | namespace geom { |
35 | | class PrecisionModel; |
36 | | } |
37 | | } |
38 | | |
39 | | namespace geos { |
40 | | namespace algorithm { // geos::algorithm |
41 | | |
42 | | /** \brief |
43 | | * A LineIntersector is an algorithm that can both test whether |
44 | | * two line segments intersect and compute the intersection point |
45 | | * if they do. |
46 | | * |
47 | | * The intersection point may be computed in a precise or non-precise manner. |
48 | | * Computing it precisely involves rounding it to an integer. (This assumes |
49 | | * that the input coordinates have been made precise by scaling them to |
50 | | * an integer grid.) |
51 | | * |
52 | | */ |
53 | | class GEOS_DLL LineIntersector { |
54 | | public: |
55 | | |
56 | | /// Computes the "edge distance" of an intersection point p in an edge. |
57 | | /// |
58 | | /// The edge distance is a metric of the point along the edge. |
59 | | /// The metric used is a robust and easy to compute metric function. |
60 | | /// It is <b>not</b> equivalent to the usual Euclidean metric. |
61 | | /// It relies on the fact that either the x or the y ordinates of the |
62 | | /// points in the edge are unique, depending on whether the edge is longer in |
63 | | /// the horizontal or vertical direction. |
64 | | /// |
65 | | /// NOTE: This function may produce incorrect distances |
66 | | /// for inputs where p is not precisely on p1-p2 |
67 | | /// (E.g. p = (139,9) p1 = (139,10), p2 = (280,1) produces distanct |
68 | | /// 0.0, which is incorrect. |
69 | | /// |
70 | | /// My hypothesis is that the function is safe to use for points which are the |
71 | | /// result of <b>rounding</b> points which lie on the line, |
72 | | /// but not safe to use for <b>truncated</b> points. |
73 | | /// |
74 | | static double computeEdgeDistance(const geom::CoordinateXY& p, const geom::CoordinateXY& p0, const geom::CoordinateXY& p1); |
75 | | |
76 | | static double nonRobustComputeEdgeDistance(const geom::Coordinate& p, const geom::Coordinate& p1, |
77 | | const geom::Coordinate& p2); |
78 | | |
79 | | explicit LineIntersector(const geom::PrecisionModel* initialPrecisionModel = nullptr) |
80 | | : |
81 | 551k | precisionModel(initialPrecisionModel), |
82 | 551k | result(0), |
83 | | inputLines(), |
84 | 551k | isProperVar(false) |
85 | 551k | {} |
86 | | |
87 | | ~LineIntersector() = default; |
88 | | |
89 | | /** \brief |
90 | | * Tests whether either intersection point is an interior point of |
91 | | * one of the input segments. |
92 | | * |
93 | | * @return <code>true</code> if either intersection point is in |
94 | | * the interior of one of the input segments |
95 | | */ |
96 | | bool isInteriorIntersection() |
97 | 152M | { |
98 | 152M | if(isInteriorIntersection(0)) { |
99 | 26.0M | return true; |
100 | 26.0M | } |
101 | 126M | if(isInteriorIntersection(1)) { |
102 | 3.86M | return true; |
103 | 3.86M | } |
104 | 122M | return false; |
105 | 126M | }; |
106 | | |
107 | | /** \brief |
108 | | * Tests whether either intersection point is an interior point |
109 | | * of the specified input segment. |
110 | | * |
111 | | * @return <code>true</code> if either intersection point is in |
112 | | * the interior of the input segment |
113 | | */ |
114 | | bool isInteriorIntersection(std::size_t inputLineIndex) |
115 | 278M | { |
116 | 576M | for(std::size_t i = 0; i < result; ++i) { |
117 | 328M | if(!(intPt[i].equals2D(*inputLines[inputLineIndex][0]) |
118 | 178M | || intPt[i].equals2D(*inputLines[inputLineIndex][1]))) { |
119 | 29.8M | return true; |
120 | 29.8M | } |
121 | 328M | } |
122 | 248M | return false; |
123 | 278M | }; |
124 | | |
125 | | /// Force computed intersection to be rounded to a given precision model. |
126 | | /// |
127 | | /// No getter is provided, because the precision model is not required |
128 | | /// to be specified. |
129 | | /// @param newPM the PrecisionModel to use for rounding |
130 | | /// |
131 | | void |
132 | | setPrecisionModel(const geom::PrecisionModel* newPM) |
133 | 0 | { |
134 | 0 | precisionModel = newPM; |
135 | 0 | } |
136 | | |
137 | | enum intersection_type : uint8_t { |
138 | | /// Indicates that line segments do not intersect |
139 | | NO_INTERSECTION = 0, |
140 | | |
141 | | /// Indicates that line segments intersect in a single point |
142 | | POINT_INTERSECTION = 1, |
143 | | |
144 | | /// Indicates that line segments intersect in a line segment |
145 | | COLLINEAR_INTERSECTION = 2 |
146 | | }; |
147 | | |
148 | | /// Computes the intersection of the lines p1-p2 and p3-p4 |
149 | | template<typename C1, typename C2> |
150 | | void computeIntersection(const C1& p1, const C1& p2, |
151 | | const C2& p3, const C2& p4) |
152 | 272M | { |
153 | 272M | inputLines[0][0] = &p1; |
154 | 272M | inputLines[0][1] = &p2; |
155 | 272M | inputLines[1][0] = &p3; |
156 | 272M | inputLines[1][1] = &p4; |
157 | 272M | result = computeIntersect(p1, p2, p3, p4); |
158 | 272M | } void geos::algorithm::LineIntersector::computeIntersection<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 152 | 261M | { | 153 | 261M | inputLines[0][0] = &p1; | 154 | 261M | inputLines[0][1] = &p2; | 155 | 261M | inputLines[1][0] = &p3; | 156 | 261M | inputLines[1][1] = &p4; | 157 | 261M | result = computeIntersect(p1, p2, p3, p4); | 158 | 261M | } |
Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXY, geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXY, geos::geom::Coordinate>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXY, geos::geom::CoordinateXYM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::Coordinate, geos::geom::CoordinateXY>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::Coordinate, geos::geom::CoordinateXYM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) void geos::algorithm::LineIntersector::computeIntersection<geos::geom::Coordinate, geos::geom::CoordinateXYZM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 152 | 1.91M | { | 153 | 1.91M | inputLines[0][0] = &p1; | 154 | 1.91M | inputLines[0][1] = &p2; | 155 | 1.91M | inputLines[1][0] = &p3; | 156 | 1.91M | inputLines[1][1] = &p4; | 157 | 1.91M | result = computeIntersect(p1, p2, p3, p4); | 158 | 1.91M | } |
Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYM, geos::geom::Coordinate>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYZM, geos::geom::Coordinate>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 152 | 689k | { | 153 | 689k | inputLines[0][0] = &p1; | 154 | 689k | inputLines[0][1] = &p2; | 155 | 689k | inputLines[1][0] = &p3; | 156 | 689k | inputLines[1][1] = &p4; | 157 | 689k | result = computeIntersect(p1, p2, p3, p4); | 158 | 689k | } |
Unexecuted instantiation: void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) void geos::algorithm::LineIntersector::computeIntersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 152 | 8.04M | { | 153 | 8.04M | inputLines[0][0] = &p1; | 154 | 8.04M | inputLines[0][1] = &p2; | 155 | 8.04M | inputLines[1][0] = &p3; | 156 | 8.04M | inputLines[1][1] = &p4; | 157 | 8.04M | result = computeIntersect(p1, p2, p3, p4); | 158 | 8.04M | } |
|
159 | | |
160 | | /// Compute the intersection between two segments, given a sequence and starting index of each |
161 | | void computeIntersection(const geom::CoordinateSequence& p, std::size_t p0, |
162 | | const geom::CoordinateSequence& q, std::size_t q0); |
163 | | |
164 | | std::string toString() const; |
165 | | |
166 | | /** |
167 | | * Tests whether the input geometries intersect. |
168 | | * |
169 | | * @return true if the input geometries intersect |
170 | | */ |
171 | | bool |
172 | | hasIntersection() const |
173 | 317M | { |
174 | 317M | return result != NO_INTERSECTION; |
175 | 317M | } |
176 | | |
177 | | |
178 | | /** |
179 | | * Gets an endpoint of an input segment. |
180 | | * |
181 | | * @param segmentIndex the index of the input segment (0 or 1) |
182 | | * @param ptIndex the index of the endpoint (0 or 1) |
183 | | * @return the specified endpoint |
184 | | */ |
185 | | const geom::CoordinateXY* |
186 | | getEndpoint(std::size_t segmentIndex, std::size_t ptIndex) const |
187 | 0 | { |
188 | 0 | return inputLines[segmentIndex][ptIndex]; |
189 | 0 | } |
190 | | |
191 | | /// Returns the number of intersection points found. |
192 | | /// |
193 | | /// This will be either 0, 1 or 2. |
194 | | /// |
195 | | size_t |
196 | | getIntersectionNum() const |
197 | 157M | { |
198 | 157M | return result; |
199 | 157M | } |
200 | | |
201 | | |
202 | | /// Returns the intIndex'th intersection point |
203 | | /// |
204 | | /// @param intIndex is 0 or 1 |
205 | | /// |
206 | | /// @return the intIndex'th intersection point |
207 | | /// |
208 | | const geom::CoordinateXYZM& |
209 | | getIntersection(std::size_t intIndex) const |
210 | 152M | { |
211 | 152M | return intPt[intIndex]; |
212 | 152M | } |
213 | | |
214 | | /// Returns false if both numbers are zero. |
215 | | /// |
216 | | /// @return true if both numbers are positive or if both numbers are negative. |
217 | | /// |
218 | | static bool isSameSignAndNonZero(double a, double b); |
219 | | |
220 | | /** \brief |
221 | | * Test whether a point is a intersection point of two line segments. |
222 | | * |
223 | | * Note that if the intersection is a line segment, this method only tests for |
224 | | * equality with the endpoints of the intersection segment. |
225 | | * It does <b>not</b> return true if |
226 | | * the input point is internal to the intersection segment. |
227 | | * |
228 | | * @return true if the input point is one of the intersection points. |
229 | | */ |
230 | | bool isIntersection(const geom::Coordinate& pt) const |
231 | 0 | { |
232 | 0 | for(std::size_t i = 0; i < result; ++i) { |
233 | 0 | if(intPt[i].equals2D(pt)) { |
234 | 0 | return true; |
235 | 0 | } |
236 | 0 | } |
237 | 0 | return false; |
238 | 0 | }; |
239 | | |
240 | | /** \brief |
241 | | * Tests whether an intersection is proper. |
242 | | * |
243 | | * The intersection between two line segments is considered proper if |
244 | | * they intersect in a single point in the interior of both segments |
245 | | * (e.g. the intersection is a single point and is not equal to any of the |
246 | | * endpoints). |
247 | | * |
248 | | * The intersection between a point and a line segment is considered proper |
249 | | * if the point lies in the interior of the segment (e.g. is not equal to |
250 | | * either of the endpoints). |
251 | | * |
252 | | * @return true if the intersection is proper |
253 | | */ |
254 | | bool |
255 | | isProper() const |
256 | 44.4M | { |
257 | 44.4M | return hasIntersection() && isProperVar; |
258 | 44.4M | } |
259 | | |
260 | | /** \brief |
261 | | * Computes the intIndex'th intersection point in the direction of |
262 | | * a specified input line segment |
263 | | * |
264 | | * @param segmentIndex is 0 or 1 |
265 | | * @param intIndex is 0 or 1 |
266 | | * |
267 | | * @return the intIndex'th intersection point in the direction of the |
268 | | * specified input line segment |
269 | | */ |
270 | | const geom::Coordinate& getIntersectionAlongSegment(std::size_t segmentIndex, std::size_t intIndex); |
271 | | |
272 | | /** \brief |
273 | | * Computes the index of the intIndex'th intersection point in the direction of |
274 | | * a specified input line segment |
275 | | * |
276 | | * @param segmentIndex is 0 or 1 |
277 | | * @param intIndex is 0 or 1 |
278 | | * |
279 | | * @return the index of the intersection point along the segment (0 or 1) |
280 | | */ |
281 | | std::size_t getIndexAlongSegment(std::size_t segmentIndex, std::size_t intIndex); |
282 | | |
283 | | /** \brief |
284 | | * Computes the "edge distance" of an intersection point along the specified |
285 | | * input line segment. |
286 | | * |
287 | | * @param geomIndex is 0 or 1 |
288 | | * @param intIndex is 0 or 1 |
289 | | * |
290 | | * @return the edge distance of the intersection point |
291 | | */ |
292 | | double getEdgeDistance(std::size_t geomIndex, std::size_t intIndex) const; |
293 | | |
294 | | private: |
295 | | |
296 | | /** |
297 | | * If makePrecise is true, computed intersection coordinates |
298 | | * will be made precise using Coordinate#makePrecise |
299 | | */ |
300 | | const geom::PrecisionModel* precisionModel; |
301 | | |
302 | | std::size_t result; |
303 | | |
304 | | const geom::CoordinateXY* inputLines[2][2]; |
305 | | |
306 | | /** |
307 | | * We store real Coordinates here because |
308 | | * we must compute the Z of intersection point. |
309 | | */ |
310 | | geom::CoordinateXYZM intPt[2]; |
311 | | |
312 | | /** |
313 | | * The indexes of the endpoints of the intersection lines, in order along |
314 | | * the corresponding line |
315 | | */ |
316 | | std::size_t intLineIndex[2][2]; |
317 | | |
318 | | bool isProperVar; |
319 | | //Coordinate &pa; |
320 | | //Coordinate &pb; |
321 | | |
322 | | bool |
323 | | isCollinear() const |
324 | 0 | { |
325 | 0 | return result == COLLINEAR_INTERSECTION; |
326 | 0 | } |
327 | | |
328 | | template<typename C1, typename C2> |
329 | | uint8_t computeIntersect(const C1& p1, const C1& p2, const C2& q1, const C2& q2) |
330 | 272M | { |
331 | 272M | isProperVar = false; |
332 | | |
333 | | // first try a fast test to see if the envelopes of the lines intersect |
334 | 272M | if(!geom::Envelope::intersects(p1, p2, q1, q2)) { |
335 | 34.6M | return NO_INTERSECTION; |
336 | 34.6M | } |
337 | | |
338 | | // for each endpoint, compute which side of the other segment it lies |
339 | | // if both endpoints lie on the same side of the other segment, |
340 | | // the segments do not intersect |
341 | 237M | int Pq1 = Orientation::index(p1, p2, q1); |
342 | 237M | int Pq2 = Orientation::index(p1, p2, q2); |
343 | | |
344 | 237M | if((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { |
345 | 36.0M | return NO_INTERSECTION; |
346 | 36.0M | } |
347 | | |
348 | 201M | int Qp1 = Orientation::index(q1, q2, p1); |
349 | 201M | int Qp2 = Orientation::index(q1, q2, p2); |
350 | | |
351 | 201M | if((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { |
352 | 17.0M | return NO_INTERSECTION; |
353 | 17.0M | } |
354 | | |
355 | | /** |
356 | | * Intersection is collinear if each endpoint lies on the other line. |
357 | | */ |
358 | 184M | bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0; |
359 | 184M | if(collinear) { |
360 | 56.1M | return computeCollinearIntersection(p1, p2, q1, q2); |
361 | 56.1M | } |
362 | | |
363 | | /* |
364 | | * At this point we know that there is a single intersection point |
365 | | * (since the lines are not collinear). |
366 | | */ |
367 | | |
368 | | /* |
369 | | * Check if the intersection is an endpoint. |
370 | | * If it is, copy the endpoint as |
371 | | * the intersection point. Copying the point rather than |
372 | | * computing it ensures the point has the exact value, |
373 | | * which is important for robustness. It is sufficient to |
374 | | * simply check for an endpoint which is on the other line, |
375 | | * since at this point we know that the inputLines must |
376 | | * intersect. |
377 | | */ |
378 | 128M | geom::CoordinateXYZM p; |
379 | 128M | double z = DoubleNotANumber; |
380 | 128M | double m = DoubleNotANumber; |
381 | | |
382 | 128M | if(Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { |
383 | | |
384 | 102M | isProperVar = false; |
385 | | |
386 | | /* Check for two equal endpoints. |
387 | | * This is done explicitly rather than by the orientation tests |
388 | | * below in order to improve robustness. |
389 | | * |
390 | | * (A example where the orientation tests fail |
391 | | * to be consistent is: |
392 | | * |
393 | | * LINESTRING ( 19.850257749638203 46.29709338043669, |
394 | | * 20.31970698357233 46.76654261437082 ) |
395 | | * and |
396 | | * LINESTRING ( -48.51001596420236 -22.063180333403878, |
397 | | * 19.850257749638203 46.29709338043669 ) |
398 | | * |
399 | | * which used to produce the INCORRECT result: |
400 | | * (20.31970698357233, 46.76654261437082, NaN) |
401 | | */ |
402 | | |
403 | 102M | if (p1.equals2D(q1)) { |
404 | 16.5M | p = p1; |
405 | 16.5M | z = Interpolate::zGet(p1, q1); |
406 | 16.5M | m = Interpolate::mGet(p1, q1); |
407 | 16.5M | } |
408 | 86.0M | else if (p1.equals2D(q2)) { |
409 | 29.4M | p = p1; |
410 | 29.4M | z = Interpolate::zGet(p1, q2); |
411 | 29.4M | m = Interpolate::mGet(p1, q2); |
412 | 29.4M | } |
413 | 56.5M | else if (p2.equals2D(q1)) { |
414 | 31.1M | p = p2; |
415 | 31.1M | z = Interpolate::zGet(p2, q1); |
416 | 31.1M | m = Interpolate::mGet(p2, q1); |
417 | 31.1M | } |
418 | 25.4M | else if (p2.equals2D(q2)) { |
419 | 16.5M | p = p2; |
420 | 16.5M | z = Interpolate::zGet(p2, q2); |
421 | 16.5M | m = Interpolate::mGet(p2, q2); |
422 | 16.5M | } |
423 | | /* |
424 | | * Now check to see if any endpoint lies on the interior of the other segment. |
425 | | */ |
426 | 8.90M | else if(Pq1 == 0) { |
427 | 3.80M | p = q1; |
428 | 3.80M | z = Interpolate::zGetOrInterpolate(q1, p1, p2); |
429 | 3.80M | m = Interpolate::mGetOrInterpolate(q1, p1, p2); |
430 | 3.80M | } |
431 | 5.10M | else if(Pq2 == 0) { |
432 | 3.07M | p = q2; |
433 | 3.07M | z = Interpolate::zGetOrInterpolate(q2, p1, p2); |
434 | 3.07M | m = Interpolate::mGetOrInterpolate(q2, p1, p2); |
435 | 3.07M | } |
436 | 2.02M | else if(Qp1 == 0) { |
437 | 1.09M | p = p1; |
438 | 1.09M | z = Interpolate::zGetOrInterpolate(p1, q1, q2); |
439 | 1.09M | m = Interpolate::mGetOrInterpolate(p1, q1, q2); |
440 | 1.09M | } |
441 | 936k | else if(Qp2 == 0) { |
442 | 936k | p = p2; |
443 | 936k | z = Interpolate::zGetOrInterpolate(p2, q1, q2); |
444 | 936k | m = Interpolate::mGetOrInterpolate(p2, q1, q2); |
445 | 936k | } |
446 | 102M | } else { |
447 | 26.0M | isProperVar = true; |
448 | 26.0M | p = intersection(p1, p2, q1, q2); |
449 | 26.0M | z = Interpolate::zInterpolate(p, p1, p2, q1, q2); |
450 | 26.0M | m = Interpolate::mInterpolate(p, p1, p2, q1, q2); |
451 | 26.0M | } |
452 | 128M | intPt[0] = geom::CoordinateXYZM(p.x, p.y, z, m); |
453 | | #if GEOS_DEBUG |
454 | | std::cerr << " POINT_INTERSECTION; intPt[0]:" << intPt[0].toString() << std::endl; |
455 | | #endif // GEOS_DEBUG |
456 | 128M | return POINT_INTERSECTION; |
457 | 184M | } unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 330 | 261M | { | 331 | 261M | isProperVar = false; | 332 | | | 333 | | // first try a fast test to see if the envelopes of the lines intersect | 334 | 261M | if(!geom::Envelope::intersects(p1, p2, q1, q2)) { | 335 | 31.0M | return NO_INTERSECTION; | 336 | 31.0M | } | 337 | | | 338 | | // for each endpoint, compute which side of the other segment it lies | 339 | | // if both endpoints lie on the same side of the other segment, | 340 | | // the segments do not intersect | 341 | 230M | int Pq1 = Orientation::index(p1, p2, q1); | 342 | 230M | int Pq2 = Orientation::index(p1, p2, q2); | 343 | | | 344 | 230M | if((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { | 345 | 34.9M | return NO_INTERSECTION; | 346 | 34.9M | } | 347 | | | 348 | 195M | int Qp1 = Orientation::index(q1, q2, p1); | 349 | 195M | int Qp2 = Orientation::index(q1, q2, p2); | 350 | | | 351 | 195M | if((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { | 352 | 16.1M | return NO_INTERSECTION; | 353 | 16.1M | } | 354 | | | 355 | | /** | 356 | | * Intersection is collinear if each endpoint lies on the other line. | 357 | | */ | 358 | 179M | bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0; | 359 | 179M | if(collinear) { | 360 | 55.0M | return computeCollinearIntersection(p1, p2, q1, q2); | 361 | 55.0M | } | 362 | | | 363 | | /* | 364 | | * At this point we know that there is a single intersection point | 365 | | * (since the lines are not collinear). | 366 | | */ | 367 | | | 368 | | /* | 369 | | * Check if the intersection is an endpoint. | 370 | | * If it is, copy the endpoint as | 371 | | * the intersection point. Copying the point rather than | 372 | | * computing it ensures the point has the exact value, | 373 | | * which is important for robustness. It is sufficient to | 374 | | * simply check for an endpoint which is on the other line, | 375 | | * since at this point we know that the inputLines must | 376 | | * intersect. | 377 | | */ | 378 | 124M | geom::CoordinateXYZM p; | 379 | 124M | double z = DoubleNotANumber; | 380 | 124M | double m = DoubleNotANumber; | 381 | | | 382 | 124M | if(Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { | 383 | | | 384 | 99.7M | isProperVar = false; | 385 | | | 386 | | /* Check for two equal endpoints. | 387 | | * This is done explicitly rather than by the orientation tests | 388 | | * below in order to improve robustness. | 389 | | * | 390 | | * (A example where the orientation tests fail | 391 | | * to be consistent is: | 392 | | * | 393 | | * LINESTRING ( 19.850257749638203 46.29709338043669, | 394 | | * 20.31970698357233 46.76654261437082 ) | 395 | | * and | 396 | | * LINESTRING ( -48.51001596420236 -22.063180333403878, | 397 | | * 19.850257749638203 46.29709338043669 ) | 398 | | * | 399 | | * which used to produce the INCORRECT result: | 400 | | * (20.31970698357233, 46.76654261437082, NaN) | 401 | | */ | 402 | | | 403 | 99.7M | if (p1.equals2D(q1)) { | 404 | 16.2M | p = p1; | 405 | 16.2M | z = Interpolate::zGet(p1, q1); | 406 | 16.2M | m = Interpolate::mGet(p1, q1); | 407 | 16.2M | } | 408 | 83.5M | else if (p1.equals2D(q2)) { | 409 | 28.8M | p = p1; | 410 | 28.8M | z = Interpolate::zGet(p1, q2); | 411 | 28.8M | m = Interpolate::mGet(p1, q2); | 412 | 28.8M | } | 413 | 54.6M | else if (p2.equals2D(q1)) { | 414 | 30.4M | p = p2; | 415 | 30.4M | z = Interpolate::zGet(p2, q1); | 416 | 30.4M | m = Interpolate::mGet(p2, q1); | 417 | 30.4M | } | 418 | 24.2M | else if (p2.equals2D(q2)) { | 419 | 16.2M | p = p2; | 420 | 16.2M | z = Interpolate::zGet(p2, q2); | 421 | 16.2M | m = Interpolate::mGet(p2, q2); | 422 | 16.2M | } | 423 | | /* | 424 | | * Now check to see if any endpoint lies on the interior of the other segment. | 425 | | */ | 426 | 8.03M | else if(Pq1 == 0) { | 427 | 3.51M | p = q1; | 428 | 3.51M | z = Interpolate::zGetOrInterpolate(q1, p1, p2); | 429 | 3.51M | m = Interpolate::mGetOrInterpolate(q1, p1, p2); | 430 | 3.51M | } | 431 | 4.51M | else if(Pq2 == 0) { | 432 | 2.81M | p = q2; | 433 | 2.81M | z = Interpolate::zGetOrInterpolate(q2, p1, p2); | 434 | 2.81M | m = Interpolate::mGetOrInterpolate(q2, p1, p2); | 435 | 2.81M | } | 436 | 1.70M | else if(Qp1 == 0) { | 437 | 921k | p = p1; | 438 | 921k | z = Interpolate::zGetOrInterpolate(p1, q1, q2); | 439 | 921k | m = Interpolate::mGetOrInterpolate(p1, q1, q2); | 440 | 921k | } | 441 | 781k | else if(Qp2 == 0) { | 442 | 781k | p = p2; | 443 | 781k | z = Interpolate::zGetOrInterpolate(p2, q1, q2); | 444 | 781k | m = Interpolate::mGetOrInterpolate(p2, q1, q2); | 445 | 781k | } | 446 | 99.7M | } else { | 447 | 24.9M | isProperVar = true; | 448 | 24.9M | p = intersection(p1, p2, q1, q2); | 449 | 24.9M | z = Interpolate::zInterpolate(p, p1, p2, q1, q2); | 450 | 24.9M | m = Interpolate::mInterpolate(p, p1, p2, q1, q2); | 451 | 24.9M | } | 452 | 124M | intPt[0] = geom::CoordinateXYZM(p.x, p.y, z, m); | 453 | | #if GEOS_DEBUG | 454 | | std::cerr << " POINT_INTERSECTION; intPt[0]:" << intPt[0].toString() << std::endl; | 455 | | #endif // GEOS_DEBUG | 456 | 124M | return POINT_INTERSECTION; | 457 | 179M | } |
Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXY, geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXY, geos::geom::Coordinate>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXY, geos::geom::CoordinateXYM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::Coordinate, geos::geom::CoordinateXY>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::Coordinate, geos::geom::CoordinateXYM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::Coordinate, geos::geom::CoordinateXYZM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 330 | 1.91M | { | 331 | 1.91M | isProperVar = false; | 332 | | | 333 | | // first try a fast test to see if the envelopes of the lines intersect | 334 | 1.91M | if(!geom::Envelope::intersects(p1, p2, q1, q2)) { | 335 | 993k | return NO_INTERSECTION; | 336 | 993k | } | 337 | | | 338 | | // for each endpoint, compute which side of the other segment it lies | 339 | | // if both endpoints lie on the same side of the other segment, | 340 | | // the segments do not intersect | 341 | 924k | int Pq1 = Orientation::index(p1, p2, q1); | 342 | 924k | int Pq2 = Orientation::index(p1, p2, q2); | 343 | | | 344 | 924k | if((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { | 345 | 131k | return NO_INTERSECTION; | 346 | 131k | } | 347 | | | 348 | 793k | int Qp1 = Orientation::index(q1, q2, p1); | 349 | 793k | int Qp2 = Orientation::index(q1, q2, p2); | 350 | | | 351 | 793k | if((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { | 352 | 206k | return NO_INTERSECTION; | 353 | 206k | } | 354 | | | 355 | | /** | 356 | | * Intersection is collinear if each endpoint lies on the other line. | 357 | | */ | 358 | 586k | bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0; | 359 | 586k | if(collinear) { | 360 | 110k | return computeCollinearIntersection(p1, p2, q1, q2); | 361 | 110k | } | 362 | | | 363 | | /* | 364 | | * At this point we know that there is a single intersection point | 365 | | * (since the lines are not collinear). | 366 | | */ | 367 | | | 368 | | /* | 369 | | * Check if the intersection is an endpoint. | 370 | | * If it is, copy the endpoint as | 371 | | * the intersection point. Copying the point rather than | 372 | | * computing it ensures the point has the exact value, | 373 | | * which is important for robustness. It is sufficient to | 374 | | * simply check for an endpoint which is on the other line, | 375 | | * since at this point we know that the inputLines must | 376 | | * intersect. | 377 | | */ | 378 | 475k | geom::CoordinateXYZM p; | 379 | 475k | double z = DoubleNotANumber; | 380 | 475k | double m = DoubleNotANumber; | 381 | | | 382 | 475k | if(Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { | 383 | | | 384 | 292k | isProperVar = false; | 385 | | | 386 | | /* Check for two equal endpoints. | 387 | | * This is done explicitly rather than by the orientation tests | 388 | | * below in order to improve robustness. | 389 | | * | 390 | | * (A example where the orientation tests fail | 391 | | * to be consistent is: | 392 | | * | 393 | | * LINESTRING ( 19.850257749638203 46.29709338043669, | 394 | | * 20.31970698357233 46.76654261437082 ) | 395 | | * and | 396 | | * LINESTRING ( -48.51001596420236 -22.063180333403878, | 397 | | * 19.850257749638203 46.29709338043669 ) | 398 | | * | 399 | | * which used to produce the INCORRECT result: | 400 | | * (20.31970698357233, 46.76654261437082, NaN) | 401 | | */ | 402 | | | 403 | 292k | if (p1.equals2D(q1)) { | 404 | 57.7k | p = p1; | 405 | 57.7k | z = Interpolate::zGet(p1, q1); | 406 | 57.7k | m = Interpolate::mGet(p1, q1); | 407 | 57.7k | } | 408 | 235k | else if (p1.equals2D(q2)) { | 409 | 27.4k | p = p1; | 410 | 27.4k | z = Interpolate::zGet(p1, q2); | 411 | 27.4k | m = Interpolate::mGet(p1, q2); | 412 | 27.4k | } | 413 | 207k | else if (p2.equals2D(q1)) { | 414 | 57.3k | p = p2; | 415 | 57.3k | z = Interpolate::zGet(p2, q1); | 416 | 57.3k | m = Interpolate::mGet(p2, q1); | 417 | 57.3k | } | 418 | 150k | else if (p2.equals2D(q2)) { | 419 | 29.4k | p = p2; | 420 | 29.4k | z = Interpolate::zGet(p2, q2); | 421 | 29.4k | m = Interpolate::mGet(p2, q2); | 422 | 29.4k | } | 423 | | /* | 424 | | * Now check to see if any endpoint lies on the interior of the other segment. | 425 | | */ | 426 | 120k | else if(Pq1 == 0) { | 427 | 57.1k | p = q1; | 428 | 57.1k | z = Interpolate::zGetOrInterpolate(q1, p1, p2); | 429 | 57.1k | m = Interpolate::mGetOrInterpolate(q1, p1, p2); | 430 | 57.1k | } | 431 | 63.6k | else if(Pq2 == 0) { | 432 | 49.8k | p = q2; | 433 | 49.8k | z = Interpolate::zGetOrInterpolate(q2, p1, p2); | 434 | 49.8k | m = Interpolate::mGetOrInterpolate(q2, p1, p2); | 435 | 49.8k | } | 436 | 13.8k | else if(Qp1 == 0) { | 437 | 6.26k | p = p1; | 438 | 6.26k | z = Interpolate::zGetOrInterpolate(p1, q1, q2); | 439 | 6.26k | m = Interpolate::mGetOrInterpolate(p1, q1, q2); | 440 | 6.26k | } | 441 | 7.56k | else if(Qp2 == 0) { | 442 | 7.56k | p = p2; | 443 | 7.56k | z = Interpolate::zGetOrInterpolate(p2, q1, q2); | 444 | 7.56k | m = Interpolate::mGetOrInterpolate(p2, q1, q2); | 445 | 7.56k | } | 446 | 292k | } else { | 447 | 182k | isProperVar = true; | 448 | 182k | p = intersection(p1, p2, q1, q2); | 449 | 182k | z = Interpolate::zInterpolate(p, p1, p2, q1, q2); | 450 | 182k | m = Interpolate::mInterpolate(p, p1, p2, q1, q2); | 451 | 182k | } | 452 | 475k | intPt[0] = geom::CoordinateXYZM(p.x, p.y, z, m); | 453 | | #if GEOS_DEBUG | 454 | | std::cerr << " POINT_INTERSECTION; intPt[0]:" << intPt[0].toString() << std::endl; | 455 | | #endif // GEOS_DEBUG | 456 | 475k | return POINT_INTERSECTION; | 457 | 586k | } |
Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYM, geos::geom::Coordinate>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYZM, geos::geom::Coordinate>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 330 | 689k | { | 331 | 689k | isProperVar = false; | 332 | | | 333 | | // first try a fast test to see if the envelopes of the lines intersect | 334 | 689k | if(!geom::Envelope::intersects(p1, p2, q1, q2)) { | 335 | 182k | return NO_INTERSECTION; | 336 | 182k | } | 337 | | | 338 | | // for each endpoint, compute which side of the other segment it lies | 339 | | // if both endpoints lie on the same side of the other segment, | 340 | | // the segments do not intersect | 341 | 507k | int Pq1 = Orientation::index(p1, p2, q1); | 342 | 507k | int Pq2 = Orientation::index(p1, p2, q2); | 343 | | | 344 | 507k | if((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { | 345 | 54.6k | return NO_INTERSECTION; | 346 | 54.6k | } | 347 | | | 348 | 452k | int Qp1 = Orientation::index(q1, q2, p1); | 349 | 452k | int Qp2 = Orientation::index(q1, q2, p2); | 350 | | | 351 | 452k | if((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { | 352 | 92.6k | return NO_INTERSECTION; | 353 | 92.6k | } | 354 | | | 355 | | /** | 356 | | * Intersection is collinear if each endpoint lies on the other line. | 357 | | */ | 358 | 359k | bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0; | 359 | 359k | if(collinear) { | 360 | 64.6k | return computeCollinearIntersection(p1, p2, q1, q2); | 361 | 64.6k | } | 362 | | | 363 | | /* | 364 | | * At this point we know that there is a single intersection point | 365 | | * (since the lines are not collinear). | 366 | | */ | 367 | | | 368 | | /* | 369 | | * Check if the intersection is an endpoint. | 370 | | * If it is, copy the endpoint as | 371 | | * the intersection point. Copying the point rather than | 372 | | * computing it ensures the point has the exact value, | 373 | | * which is important for robustness. It is sufficient to | 374 | | * simply check for an endpoint which is on the other line, | 375 | | * since at this point we know that the inputLines must | 376 | | * intersect. | 377 | | */ | 378 | 295k | geom::CoordinateXYZM p; | 379 | 295k | double z = DoubleNotANumber; | 380 | 295k | double m = DoubleNotANumber; | 381 | | | 382 | 295k | if(Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { | 383 | | | 384 | 187k | isProperVar = false; | 385 | | | 386 | | /* Check for two equal endpoints. | 387 | | * This is done explicitly rather than by the orientation tests | 388 | | * below in order to improve robustness. | 389 | | * | 390 | | * (A example where the orientation tests fail | 391 | | * to be consistent is: | 392 | | * | 393 | | * LINESTRING ( 19.850257749638203 46.29709338043669, | 394 | | * 20.31970698357233 46.76654261437082 ) | 395 | | * and | 396 | | * LINESTRING ( -48.51001596420236 -22.063180333403878, | 397 | | * 19.850257749638203 46.29709338043669 ) | 398 | | * | 399 | | * which used to produce the INCORRECT result: | 400 | | * (20.31970698357233, 46.76654261437082, NaN) | 401 | | */ | 402 | | | 403 | 187k | if (p1.equals2D(q1)) { | 404 | 16.3k | p = p1; | 405 | 16.3k | z = Interpolate::zGet(p1, q1); | 406 | 16.3k | m = Interpolate::mGet(p1, q1); | 407 | 16.3k | } | 408 | 170k | else if (p1.equals2D(q2)) { | 409 | 14.0k | p = p1; | 410 | 14.0k | z = Interpolate::zGet(p1, q2); | 411 | 14.0k | m = Interpolate::mGet(p1, q2); | 412 | 14.0k | } | 413 | 156k | else if (p2.equals2D(q1)) { | 414 | 32.9k | p = p2; | 415 | 32.9k | z = Interpolate::zGet(p2, q1); | 416 | 32.9k | m = Interpolate::mGet(p2, q1); | 417 | 32.9k | } | 418 | 123k | else if (p2.equals2D(q2)) { | 419 | 32.0k | p = p2; | 420 | 32.0k | z = Interpolate::zGet(p2, q2); | 421 | 32.0k | m = Interpolate::mGet(p2, q2); | 422 | 32.0k | } | 423 | | /* | 424 | | * Now check to see if any endpoint lies on the interior of the other segment. | 425 | | */ | 426 | 91.8k | else if(Pq1 == 0) { | 427 | 39.9k | p = q1; | 428 | 39.9k | z = Interpolate::zGetOrInterpolate(q1, p1, p2); | 429 | 39.9k | m = Interpolate::mGetOrInterpolate(q1, p1, p2); | 430 | 39.9k | } | 431 | 51.9k | else if(Pq2 == 0) { | 432 | 34.7k | p = q2; | 433 | 34.7k | z = Interpolate::zGetOrInterpolate(q2, p1, p2); | 434 | 34.7k | m = Interpolate::mGetOrInterpolate(q2, p1, p2); | 435 | 34.7k | } | 436 | 17.1k | else if(Qp1 == 0) { | 437 | 9.08k | p = p1; | 438 | 9.08k | z = Interpolate::zGetOrInterpolate(p1, q1, q2); | 439 | 9.08k | m = Interpolate::mGetOrInterpolate(p1, q1, q2); | 440 | 9.08k | } | 441 | 8.04k | else if(Qp2 == 0) { | 442 | 8.04k | p = p2; | 443 | 8.04k | z = Interpolate::zGetOrInterpolate(p2, q1, q2); | 444 | 8.04k | m = Interpolate::mGetOrInterpolate(p2, q1, q2); | 445 | 8.04k | } | 446 | 187k | } else { | 447 | 107k | isProperVar = true; | 448 | 107k | p = intersection(p1, p2, q1, q2); | 449 | 107k | z = Interpolate::zInterpolate(p, p1, p2, q1, q2); | 450 | 107k | m = Interpolate::mInterpolate(p, p1, p2, q1, q2); | 451 | 107k | } | 452 | 295k | intPt[0] = geom::CoordinateXYZM(p.x, p.y, z, m); | 453 | | #if GEOS_DEBUG | 454 | | std::cerr << " POINT_INTERSECTION; intPt[0]:" << intPt[0].toString() << std::endl; | 455 | | #endif // GEOS_DEBUG | 456 | 295k | return POINT_INTERSECTION; | 457 | 359k | } |
Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 330 | 8.04M | { | 331 | 8.04M | isProperVar = false; | 332 | | | 333 | | // first try a fast test to see if the envelopes of the lines intersect | 334 | 8.04M | if(!geom::Envelope::intersects(p1, p2, q1, q2)) { | 335 | 2.49M | return NO_INTERSECTION; | 336 | 2.49M | } | 337 | | | 338 | | // for each endpoint, compute which side of the other segment it lies | 339 | | // if both endpoints lie on the same side of the other segment, | 340 | | // the segments do not intersect | 341 | 5.55M | int Pq1 = Orientation::index(p1, p2, q1); | 342 | 5.55M | int Pq2 = Orientation::index(p1, p2, q2); | 343 | | | 344 | 5.55M | if((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { | 345 | 899k | return NO_INTERSECTION; | 346 | 899k | } | 347 | | | 348 | 4.65M | int Qp1 = Orientation::index(q1, q2, p1); | 349 | 4.65M | int Qp2 = Orientation::index(q1, q2, p2); | 350 | | | 351 | 4.65M | if((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { | 352 | 582k | return NO_INTERSECTION; | 353 | 582k | } | 354 | | | 355 | | /** | 356 | | * Intersection is collinear if each endpoint lies on the other line. | 357 | | */ | 358 | 4.07M | bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0; | 359 | 4.07M | if(collinear) { | 360 | 942k | return computeCollinearIntersection(p1, p2, q1, q2); | 361 | 942k | } | 362 | | | 363 | | /* | 364 | | * At this point we know that there is a single intersection point | 365 | | * (since the lines are not collinear). | 366 | | */ | 367 | | | 368 | | /* | 369 | | * Check if the intersection is an endpoint. | 370 | | * If it is, copy the endpoint as | 371 | | * the intersection point. Copying the point rather than | 372 | | * computing it ensures the point has the exact value, | 373 | | * which is important for robustness. It is sufficient to | 374 | | * simply check for an endpoint which is on the other line, | 375 | | * since at this point we know that the inputLines must | 376 | | * intersect. | 377 | | */ | 378 | 3.13M | geom::CoordinateXYZM p; | 379 | 3.13M | double z = DoubleNotANumber; | 380 | 3.13M | double m = DoubleNotANumber; | 381 | | | 382 | 3.13M | if(Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { | 383 | | | 384 | 2.32M | isProperVar = false; | 385 | | | 386 | | /* Check for two equal endpoints. | 387 | | * This is done explicitly rather than by the orientation tests | 388 | | * below in order to improve robustness. | 389 | | * | 390 | | * (A example where the orientation tests fail | 391 | | * to be consistent is: | 392 | | * | 393 | | * LINESTRING ( 19.850257749638203 46.29709338043669, | 394 | | * 20.31970698357233 46.76654261437082 ) | 395 | | * and | 396 | | * LINESTRING ( -48.51001596420236 -22.063180333403878, | 397 | | * 19.850257749638203 46.29709338043669 ) | 398 | | * | 399 | | * which used to produce the INCORRECT result: | 400 | | * (20.31970698357233, 46.76654261437082, NaN) | 401 | | */ | 402 | | | 403 | 2.32M | if (p1.equals2D(q1)) { | 404 | 237k | p = p1; | 405 | 237k | z = Interpolate::zGet(p1, q1); | 406 | 237k | m = Interpolate::mGet(p1, q1); | 407 | 237k | } | 408 | 2.09M | else if (p1.equals2D(q2)) { | 409 | 603k | p = p1; | 410 | 603k | z = Interpolate::zGet(p1, q2); | 411 | 603k | m = Interpolate::mGet(p1, q2); | 412 | 603k | } | 413 | 1.48M | else if (p2.equals2D(q1)) { | 414 | 599k | p = p2; | 415 | 599k | z = Interpolate::zGet(p2, q1); | 416 | 599k | m = Interpolate::mGet(p2, q1); | 417 | 599k | } | 418 | 888k | else if (p2.equals2D(q2)) { | 419 | 224k | p = p2; | 420 | 224k | z = Interpolate::zGet(p2, q2); | 421 | 224k | m = Interpolate::mGet(p2, q2); | 422 | 224k | } | 423 | | /* | 424 | | * Now check to see if any endpoint lies on the interior of the other segment. | 425 | | */ | 426 | 663k | else if(Pq1 == 0) { | 427 | 191k | p = q1; | 428 | 191k | z = Interpolate::zGetOrInterpolate(q1, p1, p2); | 429 | 191k | m = Interpolate::mGetOrInterpolate(q1, p1, p2); | 430 | 191k | } | 431 | 472k | else if(Pq2 == 0) { | 432 | 178k | p = q2; | 433 | 178k | z = Interpolate::zGetOrInterpolate(q2, p1, p2); | 434 | 178k | m = Interpolate::mGetOrInterpolate(q2, p1, p2); | 435 | 178k | } | 436 | 293k | else if(Qp1 == 0) { | 437 | 154k | p = p1; | 438 | 154k | z = Interpolate::zGetOrInterpolate(p1, q1, q2); | 439 | 154k | m = Interpolate::mGetOrInterpolate(p1, q1, q2); | 440 | 154k | } | 441 | 139k | else if(Qp2 == 0) { | 442 | 139k | p = p2; | 443 | 139k | z = Interpolate::zGetOrInterpolate(p2, q1, q2); | 444 | 139k | m = Interpolate::mGetOrInterpolate(p2, q1, q2); | 445 | 139k | } | 446 | 2.32M | } else { | 447 | 805k | isProperVar = true; | 448 | 805k | p = intersection(p1, p2, q1, q2); | 449 | 805k | z = Interpolate::zInterpolate(p, p1, p2, q1, q2); | 450 | 805k | m = Interpolate::mInterpolate(p, p1, p2, q1, q2); | 451 | 805k | } | 452 | 3.13M | intPt[0] = geom::CoordinateXYZM(p.x, p.y, z, m); | 453 | | #if GEOS_DEBUG | 454 | | std::cerr << " POINT_INTERSECTION; intPt[0]:" << intPt[0].toString() << std::endl; | 455 | | #endif // GEOS_DEBUG | 456 | 3.13M | return POINT_INTERSECTION; | 457 | 4.07M | } |
|
458 | | |
459 | | bool |
460 | | isEndPoint() const |
461 | 0 | { |
462 | 0 | return hasIntersection() && !isProperVar; |
463 | 0 | } |
464 | | |
465 | | void computeIntLineIndex(); |
466 | | |
467 | | void computeIntLineIndex(std::size_t segmentIndex); |
468 | | |
469 | | template<typename C1, typename C2> |
470 | | uint8_t computeCollinearIntersection(const C1& p1, const C1& p2, const C2& q1, const C2& q2) |
471 | 56.1M | { |
472 | 56.1M | bool q1inP = geom::Envelope::intersects(p1, p2, q1); |
473 | 56.1M | bool q2inP = geom::Envelope::intersects(p1, p2, q2); |
474 | 56.1M | bool p1inQ = geom::Envelope::intersects(q1, q2, p1); |
475 | 56.1M | bool p2inQ = geom::Envelope::intersects(q1, q2, p2); |
476 | | |
477 | 56.1M | if(q1inP && q2inP) { |
478 | 29.5M | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); |
479 | 29.5M | intPt[1] = zmGetOrInterpolateCopy(q2, p1, p2); |
480 | 29.5M | return COLLINEAR_INTERSECTION; |
481 | 29.5M | } |
482 | 26.5M | if(p1inQ && p2inQ) { |
483 | 3.08M | intPt[0] = zmGetOrInterpolateCopy(p1, q1, q2); |
484 | 3.08M | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); |
485 | 3.08M | return COLLINEAR_INTERSECTION; |
486 | 3.08M | } |
487 | 23.5M | if(q1inP && p1inQ) { |
488 | | // if pts are equal Z is chosen arbitrarily |
489 | 4.26M | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); |
490 | 4.26M | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); |
491 | | |
492 | 4.26M | return (q1 == p1) && !q2inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; |
493 | 4.26M | } |
494 | 19.2M | if(q1inP && p2inQ) { |
495 | | // if pts are equal Z is chosen arbitrarily |
496 | 5.39M | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); |
497 | 5.39M | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); |
498 | | |
499 | 5.39M | return (q1 == p2) && !q2inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; |
500 | 5.39M | } |
501 | 13.8M | if(q2inP && p1inQ) { |
502 | | // if pts are equal Z is chosen arbitrarily |
503 | 6.63M | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); |
504 | 6.63M | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); |
505 | | |
506 | 6.63M | return (q2 == p1) && !q1inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; |
507 | 6.63M | } |
508 | 7.21M | if(q2inP && p2inQ) { |
509 | | // if pts are equal Z is chosen arbitrarily |
510 | 4.42M | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); |
511 | 4.42M | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); |
512 | 4.42M | return (q2 == p2) && !q1inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; |
513 | 4.42M | } |
514 | 2.79M | return NO_INTERSECTION; |
515 | 7.21M | } unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 471 | 55.0M | { | 472 | 55.0M | bool q1inP = geom::Envelope::intersects(p1, p2, q1); | 473 | 55.0M | bool q2inP = geom::Envelope::intersects(p1, p2, q2); | 474 | 55.0M | bool p1inQ = geom::Envelope::intersects(q1, q2, p1); | 475 | 55.0M | bool p2inQ = geom::Envelope::intersects(q1, q2, p2); | 476 | | | 477 | 55.0M | if(q1inP && q2inP) { | 478 | 29.1M | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 479 | 29.1M | intPt[1] = zmGetOrInterpolateCopy(q2, p1, p2); | 480 | 29.1M | return COLLINEAR_INTERSECTION; | 481 | 29.1M | } | 482 | 25.9M | if(p1inQ && p2inQ) { | 483 | 2.81M | intPt[0] = zmGetOrInterpolateCopy(p1, q1, q2); | 484 | 2.81M | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 485 | 2.81M | return COLLINEAR_INTERSECTION; | 486 | 2.81M | } | 487 | 23.1M | if(q1inP && p1inQ) { | 488 | | // if pts are equal Z is chosen arbitrarily | 489 | 4.19M | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 490 | 4.19M | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 491 | | | 492 | 4.19M | return (q1 == p1) && !q2inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 493 | 4.19M | } | 494 | 18.9M | if(q1inP && p2inQ) { | 495 | | // if pts are equal Z is chosen arbitrarily | 496 | 5.32M | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 497 | 5.32M | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 498 | | | 499 | 5.32M | return (q1 == p2) && !q2inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 500 | 5.32M | } | 501 | 13.5M | if(q2inP && p1inQ) { | 502 | | // if pts are equal Z is chosen arbitrarily | 503 | 6.56M | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 504 | 6.56M | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 505 | | | 506 | 6.56M | return (q2 == p1) && !q1inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 507 | 6.56M | } | 508 | 7.02M | if(q2inP && p2inQ) { | 509 | | // if pts are equal Z is chosen arbitrarily | 510 | 4.37M | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 511 | 4.37M | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 512 | 4.37M | return (q2 == p2) && !q1inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 513 | 4.37M | } | 514 | 2.65M | return NO_INTERSECTION; | 515 | 7.02M | } |
Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXY, geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXY, geos::geom::Coordinate>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXY, geos::geom::CoordinateXYM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::Coordinate, geos::geom::CoordinateXY>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::Coordinate, geos::geom::CoordinateXYM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::Coordinate, geos::geom::CoordinateXYZM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 471 | 110k | { | 472 | 110k | bool q1inP = geom::Envelope::intersects(p1, p2, q1); | 473 | 110k | bool q2inP = geom::Envelope::intersects(p1, p2, q2); | 474 | 110k | bool p1inQ = geom::Envelope::intersects(q1, q2, p1); | 475 | 110k | bool p2inQ = geom::Envelope::intersects(q1, q2, p2); | 476 | | | 477 | 110k | if(q1inP && q2inP) { | 478 | 10.5k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 479 | 10.5k | intPt[1] = zmGetOrInterpolateCopy(q2, p1, p2); | 480 | 10.5k | return COLLINEAR_INTERSECTION; | 481 | 10.5k | } | 482 | 100k | if(p1inQ && p2inQ) { | 483 | 64.9k | intPt[0] = zmGetOrInterpolateCopy(p1, q1, q2); | 484 | 64.9k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 485 | 64.9k | return COLLINEAR_INTERSECTION; | 486 | 64.9k | } | 487 | 35.4k | if(q1inP && p1inQ) { | 488 | | // if pts are equal Z is chosen arbitrarily | 489 | 7.82k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 490 | 7.82k | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 491 | | | 492 | 7.82k | return (q1 == p1) && !q2inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 493 | 7.82k | } | 494 | 27.5k | if(q1inP && p2inQ) { | 495 | | // if pts are equal Z is chosen arbitrarily | 496 | 6.77k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 497 | 6.77k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 498 | | | 499 | 6.77k | return (q1 == p2) && !q2inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 500 | 6.77k | } | 501 | 20.8k | if(q2inP && p1inQ) { | 502 | | // if pts are equal Z is chosen arbitrarily | 503 | 8.31k | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 504 | 8.31k | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 505 | | | 506 | 8.31k | return (q2 == p1) && !q1inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 507 | 8.31k | } | 508 | 12.4k | if(q2inP && p2inQ) { | 509 | | // if pts are equal Z is chosen arbitrarily | 510 | 7.24k | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 511 | 7.24k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 512 | 7.24k | return (q2 == p2) && !q1inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 513 | 7.24k | } | 514 | 5.24k | return NO_INTERSECTION; | 515 | 12.4k | } |
Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYM, geos::geom::Coordinate>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYZM, geos::geom::Coordinate>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 471 | 64.6k | { | 472 | 64.6k | bool q1inP = geom::Envelope::intersects(p1, p2, q1); | 473 | 64.6k | bool q2inP = geom::Envelope::intersects(p1, p2, q2); | 474 | 64.6k | bool p1inQ = geom::Envelope::intersects(q1, q2, p1); | 475 | 64.6k | bool p2inQ = geom::Envelope::intersects(q1, q2, p2); | 476 | | | 477 | 64.6k | if(q1inP && q2inP) { | 478 | 16.0k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 479 | 16.0k | intPt[1] = zmGetOrInterpolateCopy(q2, p1, p2); | 480 | 16.0k | return COLLINEAR_INTERSECTION; | 481 | 16.0k | } | 482 | 48.6k | if(p1inQ && p2inQ) { | 483 | 18.7k | intPt[0] = zmGetOrInterpolateCopy(p1, q1, q2); | 484 | 18.7k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 485 | 18.7k | return COLLINEAR_INTERSECTION; | 486 | 18.7k | } | 487 | 29.8k | if(q1inP && p1inQ) { | 488 | | // if pts are equal Z is chosen arbitrarily | 489 | 7.90k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 490 | 7.90k | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 491 | | | 492 | 7.90k | return (q1 == p1) && !q2inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 493 | 7.90k | } | 494 | 21.9k | if(q1inP && p2inQ) { | 495 | | // if pts are equal Z is chosen arbitrarily | 496 | 5.99k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 497 | 5.99k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 498 | | | 499 | 5.99k | return (q1 == p2) && !q2inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 500 | 5.99k | } | 501 | 15.9k | if(q2inP && p1inQ) { | 502 | | // if pts are equal Z is chosen arbitrarily | 503 | 5.59k | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 504 | 5.59k | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 505 | | | 506 | 5.59k | return (q2 == p1) && !q1inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 507 | 5.59k | } | 508 | 10.3k | if(q2inP && p2inQ) { | 509 | | // if pts are equal Z is chosen arbitrarily | 510 | 6.46k | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 511 | 6.46k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 512 | 6.46k | return (q2 == p2) && !q1inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 513 | 6.46k | } | 514 | 3.89k | return NO_INTERSECTION; | 515 | 10.3k | } |
Unexecuted instantiation: unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 471 | 942k | { | 472 | 942k | bool q1inP = geom::Envelope::intersects(p1, p2, q1); | 473 | 942k | bool q2inP = geom::Envelope::intersects(p1, p2, q2); | 474 | 942k | bool p1inQ = geom::Envelope::intersects(q1, q2, p1); | 475 | 942k | bool p2inQ = geom::Envelope::intersects(q1, q2, p2); | 476 | | | 477 | 942k | if(q1inP && q2inP) { | 478 | 426k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 479 | 426k | intPt[1] = zmGetOrInterpolateCopy(q2, p1, p2); | 480 | 426k | return COLLINEAR_INTERSECTION; | 481 | 426k | } | 482 | 515k | if(p1inQ && p2inQ) { | 483 | 188k | intPt[0] = zmGetOrInterpolateCopy(p1, q1, q2); | 484 | 188k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 485 | 188k | return COLLINEAR_INTERSECTION; | 486 | 188k | } | 487 | 327k | if(q1inP && p1inQ) { | 488 | | // if pts are equal Z is chosen arbitrarily | 489 | 53.8k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 490 | 53.8k | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 491 | | | 492 | 53.8k | return (q1 == p1) && !q2inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 493 | 53.8k | } | 494 | 273k | if(q1inP && p2inQ) { | 495 | | // if pts are equal Z is chosen arbitrarily | 496 | 59.9k | intPt[0] = zmGetOrInterpolateCopy(q1, p1, p2); | 497 | 59.9k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 498 | | | 499 | 59.9k | return (q1 == p2) && !q2inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 500 | 59.9k | } | 501 | 213k | if(q2inP && p1inQ) { | 502 | | // if pts are equal Z is chosen arbitrarily | 503 | 48.7k | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 504 | 48.7k | intPt[1] = zmGetOrInterpolateCopy(p1, q1, q2); | 505 | | | 506 | 48.7k | return (q2 == p1) && !q1inP && !p2inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 507 | 48.7k | } | 508 | 164k | if(q2inP && p2inQ) { | 509 | | // if pts are equal Z is chosen arbitrarily | 510 | 35.0k | intPt[0] = zmGetOrInterpolateCopy(q2, p1, p2); | 511 | 35.0k | intPt[1] = zmGetOrInterpolateCopy(p2, q1, q2); | 512 | 35.0k | return (q2 == p2) && !q1inP && !p1inQ ? POINT_INTERSECTION : COLLINEAR_INTERSECTION; | 513 | 35.0k | } | 514 | 129k | return NO_INTERSECTION; | 515 | 164k | } |
|
516 | | |
517 | | /** \brief |
518 | | * This method computes the actual value of the intersection point. |
519 | | * |
520 | | * To obtain the maximum precision from the intersection calculation, |
521 | | * the coordinates are normalized by subtracting the minimum |
522 | | * ordinate values (in absolute value). This has the effect of |
523 | | * removing common significant digits from the calculation to |
524 | | * maintain more bits of precision. |
525 | | */ |
526 | | template<typename C1, typename C2> |
527 | 26.0M | geom::CoordinateXYZM intersection (const C1& p1, const C1& p2, const C2& q1, const C2& q2) const { |
528 | 26.0M | auto intPtOut = intersectionSafe(p1, p2, q1, q2); |
529 | | |
530 | | /* |
531 | | * Due to rounding it can happen that the computed intersection is |
532 | | * outside the envelopes of the input segments. Clearly this |
533 | | * is inconsistent. |
534 | | * This code checks this condition and forces a more reasonable answer |
535 | | * |
536 | | * MD - May 4 2005 - This is still a problem. Here is a failure case: |
537 | | * |
538 | | * LINESTRING (2089426.5233462777 1180182.3877339689, |
539 | | * 2085646.6891757075 1195618.7333999649) |
540 | | * LINESTRING (1889281.8148903656 1997547.0560044837, |
541 | | * 2259977.3672235999 483675.17050843034) |
542 | | * int point = (2097408.2633752143,1144595.8008114607) |
543 | | */ |
544 | | |
545 | 26.0M | if(! isInSegmentEnvelopes(intPtOut)) { |
546 | | //intPt = CentralEndpointIntersector::getIntersection(p1, p2, q1, q2); |
547 | 830k | intPtOut = nearestEndpoint(p1, p2, q1, q2); |
548 | 830k | } |
549 | | |
550 | 26.0M | if(precisionModel != nullptr) { |
551 | 0 | precisionModel->makePrecise(intPtOut); |
552 | 0 | } |
553 | | |
554 | 26.0M | return intPtOut; |
555 | 26.0M | } geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Line | Count | Source | 527 | 24.9M | geom::CoordinateXYZM intersection (const C1& p1, const C1& p2, const C2& q1, const C2& q2) const { | 528 | 24.9M | auto intPtOut = intersectionSafe(p1, p2, q1, q2); | 529 | | | 530 | | /* | 531 | | * Due to rounding it can happen that the computed intersection is | 532 | | * outside the envelopes of the input segments. Clearly this | 533 | | * is inconsistent. | 534 | | * This code checks this condition and forces a more reasonable answer | 535 | | * | 536 | | * MD - May 4 2005 - This is still a problem. Here is a failure case: | 537 | | * | 538 | | * LINESTRING (2089426.5233462777 1180182.3877339689, | 539 | | * 2085646.6891757075 1195618.7333999649) | 540 | | * LINESTRING (1889281.8148903656 1997547.0560044837, | 541 | | * 2259977.3672235999 483675.17050843034) | 542 | | * int point = (2097408.2633752143,1144595.8008114607) | 543 | | */ | 544 | | | 545 | 24.9M | if(! isInSegmentEnvelopes(intPtOut)) { | 546 | | //intPt = CentralEndpointIntersector::getIntersection(p1, p2, q1, q2); | 547 | 660k | intPtOut = nearestEndpoint(p1, p2, q1, q2); | 548 | 660k | } | 549 | | | 550 | 24.9M | if(precisionModel != nullptr) { | 551 | 0 | precisionModel->makePrecise(intPtOut); | 552 | 0 | } | 553 | | | 554 | 24.9M | return intPtOut; | 555 | 24.9M | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXY, geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXY, geos::geom::Coordinate>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXY, geos::geom::CoordinateXYM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::Coordinate, geos::geom::CoordinateXY>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::Coordinate, geos::geom::CoordinateXYM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::Coordinate, geos::geom::CoordinateXYZM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Line | Count | Source | 527 | 182k | geom::CoordinateXYZM intersection (const C1& p1, const C1& p2, const C2& q1, const C2& q2) const { | 528 | 182k | auto intPtOut = intersectionSafe(p1, p2, q1, q2); | 529 | | | 530 | | /* | 531 | | * Due to rounding it can happen that the computed intersection is | 532 | | * outside the envelopes of the input segments. Clearly this | 533 | | * is inconsistent. | 534 | | * This code checks this condition and forces a more reasonable answer | 535 | | * | 536 | | * MD - May 4 2005 - This is still a problem. Here is a failure case: | 537 | | * | 538 | | * LINESTRING (2089426.5233462777 1180182.3877339689, | 539 | | * 2085646.6891757075 1195618.7333999649) | 540 | | * LINESTRING (1889281.8148903656 1997547.0560044837, | 541 | | * 2259977.3672235999 483675.17050843034) | 542 | | * int point = (2097408.2633752143,1144595.8008114607) | 543 | | */ | 544 | | | 545 | 182k | if(! isInSegmentEnvelopes(intPtOut)) { | 546 | | //intPt = CentralEndpointIntersector::getIntersection(p1, p2, q1, q2); | 547 | 22.9k | intPtOut = nearestEndpoint(p1, p2, q1, q2); | 548 | 22.9k | } | 549 | | | 550 | 182k | if(precisionModel != nullptr) { | 551 | 0 | precisionModel->makePrecise(intPtOut); | 552 | 0 | } | 553 | | | 554 | 182k | return intPtOut; | 555 | 182k | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYM, geos::geom::Coordinate>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYZM, geos::geom::Coordinate>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Line | Count | Source | 527 | 107k | geom::CoordinateXYZM intersection (const C1& p1, const C1& p2, const C2& q1, const C2& q2) const { | 528 | 107k | auto intPtOut = intersectionSafe(p1, p2, q1, q2); | 529 | | | 530 | | /* | 531 | | * Due to rounding it can happen that the computed intersection is | 532 | | * outside the envelopes of the input segments. Clearly this | 533 | | * is inconsistent. | 534 | | * This code checks this condition and forces a more reasonable answer | 535 | | * | 536 | | * MD - May 4 2005 - This is still a problem. Here is a failure case: | 537 | | * | 538 | | * LINESTRING (2089426.5233462777 1180182.3877339689, | 539 | | * 2085646.6891757075 1195618.7333999649) | 540 | | * LINESTRING (1889281.8148903656 1997547.0560044837, | 541 | | * 2259977.3672235999 483675.17050843034) | 542 | | * int point = (2097408.2633752143,1144595.8008114607) | 543 | | */ | 544 | | | 545 | 107k | if(! isInSegmentEnvelopes(intPtOut)) { | 546 | | //intPt = CentralEndpointIntersector::getIntersection(p1, p2, q1, q2); | 547 | 11.2k | intPtOut = nearestEndpoint(p1, p2, q1, q2); | 548 | 11.2k | } | 549 | | | 550 | 107k | if(precisionModel != nullptr) { | 551 | 0 | precisionModel->makePrecise(intPtOut); | 552 | 0 | } | 553 | | | 554 | 107k | return intPtOut; | 555 | 107k | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersection<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Line | Count | Source | 527 | 805k | geom::CoordinateXYZM intersection (const C1& p1, const C1& p2, const C2& q1, const C2& q2) const { | 528 | 805k | auto intPtOut = intersectionSafe(p1, p2, q1, q2); | 529 | | | 530 | | /* | 531 | | * Due to rounding it can happen that the computed intersection is | 532 | | * outside the envelopes of the input segments. Clearly this | 533 | | * is inconsistent. | 534 | | * This code checks this condition and forces a more reasonable answer | 535 | | * | 536 | | * MD - May 4 2005 - This is still a problem. Here is a failure case: | 537 | | * | 538 | | * LINESTRING (2089426.5233462777 1180182.3877339689, | 539 | | * 2085646.6891757075 1195618.7333999649) | 540 | | * LINESTRING (1889281.8148903656 1997547.0560044837, | 541 | | * 2259977.3672235999 483675.17050843034) | 542 | | * int point = (2097408.2633752143,1144595.8008114607) | 543 | | */ | 544 | | | 545 | 805k | if(! isInSegmentEnvelopes(intPtOut)) { | 546 | | //intPt = CentralEndpointIntersector::getIntersection(p1, p2, q1, q2); | 547 | 136k | intPtOut = nearestEndpoint(p1, p2, q1, q2); | 548 | 136k | } | 549 | | | 550 | 805k | if(precisionModel != nullptr) { | 551 | 0 | precisionModel->makePrecise(intPtOut); | 552 | 0 | } | 553 | | | 554 | 805k | return intPtOut; | 555 | 805k | } |
|
556 | | |
557 | | /** |
558 | | * Test whether a point lies in the envelopes of both input segments. |
559 | | * A correctly computed intersection point should return true |
560 | | * for this test. |
561 | | * Since this test is for debugging purposes only, no attempt is |
562 | | * made to optimize the envelope test. |
563 | | * |
564 | | * @return true if the input point lies within both |
565 | | * input segment envelopes |
566 | | */ |
567 | | bool isInSegmentEnvelopes(const geom::CoordinateXY& pt) const |
568 | 26.0M | { |
569 | 26.0M | geom::Envelope env0(*inputLines[0][0], *inputLines[0][1]); |
570 | 26.0M | geom::Envelope env1(*inputLines[1][0], *inputLines[1][1]); |
571 | 26.0M | return env0.contains(pt) && env1.contains(pt); |
572 | 26.0M | }; |
573 | | |
574 | | /** |
575 | | * Computes a segment intersection. |
576 | | * Round-off error can cause the raw computation to fail, |
577 | | * (usually due to the segments being approximately parallel). |
578 | | * If this happens, a reasonable approximation is computed instead. |
579 | | * |
580 | | * @param p1 a segment endpoint |
581 | | * @param p2 a segment endpoint |
582 | | * @param q1 a segment endpoint |
583 | | * @param q2 a segment endpoint |
584 | | * @return the computed intersection point is stored there |
585 | | */ |
586 | | template<typename C1, typename C2> |
587 | | geom::CoordinateXYZM intersectionSafe(const C1& p1, const C1& p2, |
588 | | const C2& q1, const C2& q2) const |
589 | 26.0M | { |
590 | 26.0M | geom::CoordinateXYZM ptInt(Intersection::intersection(p1, p2, q1, q2)); |
591 | 26.0M | if (ptInt.isNull()) { |
592 | 558k | const geom::CoordinateXY& nearest = nearestEndpoint(p1, p2, q1, q2); |
593 | 558k | #if __cplusplus >= 201703L |
594 | 558k | if constexpr (std::is_same<C1, C2>::value) { |
595 | | #else |
596 | | if (std::is_same<C1, C2>::value) { |
597 | | #endif |
598 | 531k | ptInt = static_cast<const C1&>(nearest); |
599 | 531k | } else { |
600 | 27.2k | if (&nearest == static_cast<const geom::CoordinateXY*>(&p1) || &nearest == static_cast<const geom::CoordinateXY*>(&p2)) { |
601 | 24.6k | ptInt = static_cast<const C1&>(nearest); |
602 | 24.6k | } else { |
603 | 2.56k | ptInt = static_cast<const C2&>(nearest); |
604 | 2.56k | } |
605 | 27.2k | } |
606 | 558k | } |
607 | 26.0M | return ptInt; |
608 | 26.0M | } geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Line | Count | Source | 589 | 24.9M | { | 590 | 24.9M | geom::CoordinateXYZM ptInt(Intersection::intersection(p1, p2, q1, q2)); | 591 | 24.9M | if (ptInt.isNull()) { | 592 | 472k | const geom::CoordinateXY& nearest = nearestEndpoint(p1, p2, q1, q2); | 593 | 472k | #if __cplusplus >= 201703L | 594 | 472k | if constexpr (std::is_same<C1, C2>::value) { | 595 | | #else | 596 | | if (std::is_same<C1, C2>::value) { | 597 | | #endif | 598 | 472k | ptInt = static_cast<const C1&>(nearest); | 599 | | } else { | 600 | | if (&nearest == static_cast<const geom::CoordinateXY*>(&p1) || &nearest == static_cast<const geom::CoordinateXY*>(&p2)) { | 601 | | ptInt = static_cast<const C1&>(nearest); | 602 | | } else { | 603 | | ptInt = static_cast<const C2&>(nearest); | 604 | | } | 605 | | } | 606 | 472k | } | 607 | 24.9M | return ptInt; | 608 | 24.9M | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXY, geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXY, geos::geom::Coordinate>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXY, geos::geom::CoordinateXYM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::Coordinate, geos::geom::CoordinateXY>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::Coordinate, geos::geom::CoordinateXYM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::Coordinate, geos::geom::CoordinateXYZM>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Line | Count | Source | 589 | 182k | { | 590 | 182k | geom::CoordinateXYZM ptInt(Intersection::intersection(p1, p2, q1, q2)); | 591 | 182k | if (ptInt.isNull()) { | 592 | 19.2k | const geom::CoordinateXY& nearest = nearestEndpoint(p1, p2, q1, q2); | 593 | 19.2k | #if __cplusplus >= 201703L | 594 | | if constexpr (std::is_same<C1, C2>::value) { | 595 | | #else | 596 | | if (std::is_same<C1, C2>::value) { | 597 | | #endif | 598 | | ptInt = static_cast<const C1&>(nearest); | 599 | 19.2k | } else { | 600 | 19.2k | if (&nearest == static_cast<const geom::CoordinateXY*>(&p1) || &nearest == static_cast<const geom::CoordinateXY*>(&p2)) { | 601 | 17.8k | ptInt = static_cast<const C1&>(nearest); | 602 | 17.8k | } else { | 603 | 1.46k | ptInt = static_cast<const C2&>(nearest); | 604 | 1.46k | } | 605 | 19.2k | } | 606 | 19.2k | } | 607 | 182k | return ptInt; | 608 | 182k | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYM, geos::geom::Coordinate>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) const geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYZM, geos::geom::Coordinate>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) const Line | Count | Source | 589 | 107k | { | 590 | 107k | geom::CoordinateXYZM ptInt(Intersection::intersection(p1, p2, q1, q2)); | 591 | 107k | if (ptInt.isNull()) { | 592 | 7.95k | const geom::CoordinateXY& nearest = nearestEndpoint(p1, p2, q1, q2); | 593 | 7.95k | #if __cplusplus >= 201703L | 594 | | if constexpr (std::is_same<C1, C2>::value) { | 595 | | #else | 596 | | if (std::is_same<C1, C2>::value) { | 597 | | #endif | 598 | | ptInt = static_cast<const C1&>(nearest); | 599 | 7.95k | } else { | 600 | 7.95k | if (&nearest == static_cast<const geom::CoordinateXY*>(&p1) || &nearest == static_cast<const geom::CoordinateXY*>(&p2)) { | 601 | 6.86k | ptInt = static_cast<const C1&>(nearest); | 602 | 6.86k | } else { | 603 | 1.09k | ptInt = static_cast<const C2&>(nearest); | 604 | 1.09k | } | 605 | 7.95k | } | 606 | 7.95k | } | 607 | 107k | return ptInt; | 608 | 107k | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) const geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::intersectionSafe<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) const Line | Count | Source | 589 | 805k | { | 590 | 805k | geom::CoordinateXYZM ptInt(Intersection::intersection(p1, p2, q1, q2)); | 591 | 805k | if (ptInt.isNull()) { | 592 | 58.5k | const geom::CoordinateXY& nearest = nearestEndpoint(p1, p2, q1, q2); | 593 | 58.5k | #if __cplusplus >= 201703L | 594 | 58.5k | if constexpr (std::is_same<C1, C2>::value) { | 595 | | #else | 596 | | if (std::is_same<C1, C2>::value) { | 597 | | #endif | 598 | 58.5k | ptInt = static_cast<const C1&>(nearest); | 599 | | } else { | 600 | | if (&nearest == static_cast<const geom::CoordinateXY*>(&p1) || &nearest == static_cast<const geom::CoordinateXY*>(&p2)) { | 601 | | ptInt = static_cast<const C1&>(nearest); | 602 | | } else { | 603 | | ptInt = static_cast<const C2&>(nearest); | 604 | | } | 605 | | } | 606 | 58.5k | } | 607 | 805k | return ptInt; | 608 | 805k | } |
|
609 | | |
610 | | /** |
611 | | * Finds the endpoint of the segments P and Q which |
612 | | * is closest to the other segment. |
613 | | * This is a reasonable surrogate for the true |
614 | | * intersection points in ill-conditioned cases |
615 | | * (e.g. where two segments are nearly coincident, |
616 | | * or where the endpoint of one segment lies almost on the other segment). |
617 | | * <p> |
618 | | * This replaces the older CentralEndpoint heuristic, |
619 | | * which chose the wrong endpoint in some cases |
620 | | * where the segments had very distinct slopes |
621 | | * and one endpoint lay almost on the other segment. |
622 | | * |
623 | | * @param p1 an endpoint of segment P |
624 | | * @param p2 an endpoint of segment P |
625 | | * @param q1 an endpoint of segment Q |
626 | | * @param q2 an endpoint of segment Q |
627 | | * @return the nearest endpoint to the other segment |
628 | | */ |
629 | | static const geom::CoordinateXY& nearestEndpoint(const geom::CoordinateXY& p1, |
630 | | const geom::CoordinateXY& p2, |
631 | | const geom::CoordinateXY& q1, |
632 | | const geom::CoordinateXY& q2); |
633 | | |
634 | | |
635 | | template<typename C1, typename C2> |
636 | | static geom::CoordinateXYZM zmGetOrInterpolateCopy( |
637 | | const C1& p, |
638 | | const C2& p1, |
639 | | const C2& p2) |
640 | 106M | { |
641 | 106M | geom::CoordinateXYZM pCopy(p); |
642 | 106M | pCopy.z = Interpolate::zGetOrInterpolate(p, p1, p2); |
643 | 106M | pCopy.m = Interpolate::mGetOrInterpolate(p, p1, p2); |
644 | 106M | return pCopy; |
645 | 106M | } geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 640 | 104M | { | 641 | 104M | geom::CoordinateXYZM pCopy(p); | 642 | 104M | pCopy.z = Interpolate::zGetOrInterpolate(p, p1, p2); | 643 | 104M | pCopy.m = Interpolate::mGetOrInterpolate(p, p1, p2); | 644 | 104M | return pCopy; | 645 | 104M | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXY, geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::Coordinate, geos::geom::CoordinateXY>(geos::geom::Coordinate const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXY, geos::geom::Coordinate>(geos::geom::CoordinateXY const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXY, geos::geom::CoordinateXYM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXY const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYM, geos::geom::Coordinate>(geos::geom::CoordinateXYM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::Coordinate, geos::geom::CoordinateXYM>(geos::geom::Coordinate const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYZM, geos::geom::Coordinate>(geos::geom::CoordinateXYZM const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) Line | Count | Source | 640 | 114k | { | 641 | 114k | geom::CoordinateXYZM pCopy(p); | 642 | 114k | pCopy.z = Interpolate::zGetOrInterpolate(p, p1, p2); | 643 | 114k | pCopy.m = Interpolate::mGetOrInterpolate(p, p1, p2); | 644 | 114k | return pCopy; | 645 | 114k | } |
geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::Coordinate, geos::geom::CoordinateXYZM>(geos::geom::Coordinate const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 640 | 217k | { | 641 | 217k | geom::CoordinateXYZM pCopy(p); | 642 | 217k | pCopy.z = Interpolate::zGetOrInterpolate(p, p1, p2); | 643 | 217k | pCopy.m = Interpolate::mGetOrInterpolate(p, p1, p2); | 644 | 217k | return pCopy; | 645 | 217k | } |
Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYM const&) Unexecuted instantiation: geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&, geos::geom::CoordinateXYZM const&) Line | Count | Source | 640 | 1.62M | { | 641 | 1.62M | geom::CoordinateXYZM pCopy(p); | 642 | 1.62M | pCopy.z = Interpolate::zGetOrInterpolate(p, p1, p2); | 643 | 1.62M | pCopy.m = Interpolate::mGetOrInterpolate(p, p1, p2); | 644 | 1.62M | return pCopy; | 645 | 1.62M | } |
|
646 | | |
647 | | }; |
648 | | |
649 | | |
650 | | } // namespace geos::algorithm |
651 | | } // namespace geos |
652 | | |
653 | | |
654 | | |
655 | | |
656 | | |
657 | | |
658 | | |
659 | | |
660 | | |
661 | | |
662 | | |
663 | | |
664 | | |
665 | | |
666 | | |
667 | | |