1 //
2 // Ported from JTS junit/algorithm/RobustLineIntersectorTest.java rev. 1.1
3
4 #include <tut/tut.hpp>
5 // geos
6 #include <geos/io/WKBReader.h>
7 #include <geos/io/WKTReader.h>
8 #include <geos/algorithm/LineIntersector.h>
9 #include <geos/algorithm/PointLocation.h>
10 #include <geos/algorithm/Orientation.h>
11 #include <geos/geom/PrecisionModel.h>
12 #include <geos/geom/GeometryFactory.h>
13 #include <geos/geom/Geometry.h> // required for use in unique_ptr
14 #include <geos/geom/LineString.h>
15 #include <geos/geom/Coordinate.h>
16 #include <geos/geom/Point.h>
17 #include <geos/geom/CoordinateSequence.h>
18 #include <geos/geom/CoordinateArraySequence.h>
19 // std
20 #include <sstream>
21 #include <string>
22 #include <memory>
23
24
25 using namespace geos::geom; //
26 using geos::algorithm::LineIntersector;
27 using geos::algorithm::PointLocation;
28 using geos::algorithm::Orientation;
29
30
31 namespace tut {
32 //
33 // Test Group
34 //
35
36 struct test_robustlineintersector_data {
37
38 typedef std::unique_ptr<Geometry> GeomPtr;
39
40 LineIntersector i;
41
42 };
43
44 typedef test_group<test_robustlineintersector_data> group;
45 typedef group::object object;
46
47 group test_robustlineintersector_group(
48 "geos::algorithm::RobustLineIntersector");
49
50
51
52
53 //
54 // Test Cases
55 //
56
57 // 1 - test2Lines
58 template<>
59 template<>
test()60 void object::test<1>
61 ()
62 {
63 Coordinate p1(10, 10);
64 Coordinate p2(20, 20);
65 Coordinate q1(20, 10);
66 Coordinate q2(10, 20);
67 Coordinate x(15, 15);
68 i.computeIntersection(p1, p2, q1, q2);
69
70 ensure_equals(i.getIntersectionNum(), (unsigned int)LineIntersector::POINT_INTERSECTION);
71 ensure_equals(i.getIntersectionNum(), 1UL);
72 ensure_equals(i.getIntersection(0), x);
73 ensure("isProper", i.isProper());
74 ensure("hasIntersection", i.hasIntersection());
75 }
76
77 // 2 - testCollinear1
78 template<>
79 template<>
test()80 void object::test<2>
81 ()
82 {
83 Coordinate p1(10, 10);
84 Coordinate p2(20, 10);
85 Coordinate q1(22, 10);
86 Coordinate q2(30, 10);
87 i.computeIntersection(p1, p2, q1, q2);
88
89 ensure_equals(i.getIntersectionNum(), LineIntersector::NO_INTERSECTION);
90 ensure_equals(i.getIntersectionNum(), 0UL);
91 ensure("!isProper", !i.isProper());
92 ensure("!hasIntersection", !i.hasIntersection());
93 }
94
95 // 3 - testCollinear2
96 template<>
97 template<>
test()98 void object::test<3>
99 ()
100 {
101 Coordinate p1(10, 10);
102 Coordinate p2(20, 10);
103 Coordinate q1(20, 10);
104 Coordinate q2(30, 10);
105 i.computeIntersection(p1, p2, q1, q2);
106
107 ensure_equals(i.getIntersectionNum(), LineIntersector::POINT_INTERSECTION);
108 ensure_equals(i.getIntersectionNum(), 1UL);
109 ensure("!isProper", !i.isProper());
110 ensure("hasIntersection", i.hasIntersection());
111 }
112
113 // 4 - testCollinear3
114 template<>
115 template<>
test()116 void object::test<4>
117 ()
118 {
119 Coordinate p1(10, 10);
120 Coordinate p2(20, 10);
121 Coordinate q1(15, 10);
122 Coordinate q2(30, 10);
123 i.computeIntersection(p1, p2, q1, q2);
124
125 ensure_equals(i.getIntersectionNum(), LineIntersector::COLLINEAR_INTERSECTION);
126 ensure_equals(i.getIntersectionNum(), 2UL);
127 ensure("!isProper", !i.isProper());
128 ensure("hasIntersection", i.hasIntersection());
129 }
130
131 // 5 - testCollinear4
132 template<>
133 template<>
test()134 void object::test<5>
135 ()
136 {
137 Coordinate p1(10, 10);
138 Coordinate p2(20, 10);
139 Coordinate q1(10, 10);
140 Coordinate q2(30, 10);
141 i.computeIntersection(p1, p2, q1, q2);
142
143 ensure_equals(i.getIntersectionNum(), LineIntersector::COLLINEAR_INTERSECTION);
144 ensure_equals(i.getIntersectionNum(), 2UL);
145 ensure("!isProper", !i.isProper());
146 ensure("hasIntersection", i.hasIntersection());
147 }
148
149 // 6 - testEndpointIntersection
150 template<>
151 template<>
test()152 void object::test<6>
153 ()
154 {
155 i.computeIntersection(Coordinate(100, 100), Coordinate(10, 100),
156 Coordinate(100, 10), Coordinate(100, 100));
157 ensure("hasIntersection", i.hasIntersection());
158 ensure_equals(i.getIntersectionNum(), 1UL);
159 }
160
161 // 7 - testEndpointIntersection2
162 template<>
163 template<>
test()164 void object::test<7>
165 ()
166 {
167 i.computeIntersection(Coordinate(190, 50), Coordinate(120, 100),
168 Coordinate(120, 100), Coordinate(50, 150));
169 ensure("hasIntersection", i.hasIntersection());
170 ensure_equals(i.getIntersectionNum(), 1UL);
171 ensure_equals(i.getIntersection(1), Coordinate(120, 100));
172 }
173
174 // 8 - testOverlap
175 template<>
176 template<>
test()177 void object::test<8>
178 ()
179 {
180 i.computeIntersection(Coordinate(180, 200), Coordinate(160, 180),
181 Coordinate(220, 240), Coordinate(140, 160));
182 ensure("hasIntersection", i.hasIntersection());
183 ensure_equals(i.getIntersectionNum(), 2UL);
184 }
185
186 // 9 - testIsProper1
187 template<>
188 template<>
test()189 void object::test<9>
190 ()
191 {
192 i.computeIntersection(Coordinate(30, 10), Coordinate(30, 30),
193 Coordinate(10, 10), Coordinate(90, 11));
194 ensure("hasIntersection", i.hasIntersection());
195 ensure_equals(i.getIntersectionNum(), 1UL);
196 ensure("isProper", i.isProper());
197 }
198
199 // 10 - testIsProper2
200 template<>
201 template<>
test()202 void object::test<10>
203 ()
204 {
205 i.computeIntersection(Coordinate(10, 30), Coordinate(10, 0),
206 Coordinate(11, 90), Coordinate(10, 10));
207 ensure("hasIntersection", i.hasIntersection());
208 ensure_equals(i.getIntersectionNum(), 1UL);
209 ensure("!isProper", !i.isProper());
210 }
211
212 // 11 - testIsCCW
213 template<>
214 template<>
test()215 void object::test<11>
216 ()
217 {
218 ensure_equals(Orientation::index(
219 Coordinate(-123456789, -40),
220 Coordinate(0, 0),
221 Coordinate(381039468754763.0, 123456789)), 1);
222 }
223
224 // 12 - testIsCCW2
225 template<>
226 template<>
test()227 void object::test<12>
228 ()
229 {
230 ensure_equals(Orientation::index(
231 Coordinate(10, 10),
232 Coordinate(20, 20),
233 Coordinate(0, 0)), 0);
234 }
235
236 // 13 - testA
237 template<>
238 template<>
test()239 void object::test<13>
240 ()
241 {
242 Coordinate p1(-123456789, -40);
243 Coordinate p2(381039468754763.0, 123456789);
244 Coordinate q(0, 0);
245
246 using geos::geom::CoordinateSequence;
247 using geos::geom::GeometryFactory;
248 using geos::geom::LineString;
249
250 GeometryFactory::Ptr factory = GeometryFactory::create();
251 CoordinateArraySequence* cs = new CoordinateArraySequence();
252 cs->add(p1);
253 cs->add(p2);
254
255 GeomPtr l(factory->createLineString(cs));
256 GeomPtr p(factory->createPoint(q));
257 ensure(!l->intersects(p.get()));
258
259 ensure(!PointLocation::isOnLine(q, cs));
260 ensure_equals(Orientation::index(p1, p2, q), -1);
261
262 }
263
264 // Test intersects: point on segment with FLOAT PM
265 // X coordinate of 3rd and 4th vertises of the line are not
266 // float-point exact with X coordinate of the point.
267 // The X values differ after 14th decimal place:
268 // POINT (-23.1094689600055080 50.5195368635957180)
269 // --------------------^^^^^^^------------^^^^^^^^
270 // LINESTRING 3rd and 4th points
271 // -23.1094689600055150 50.5223376452201340,
272 // -23.1094689600055010 50.5169177629559480,
273 // --------------------^^^^^^^------------^^^^^^^^
274 // So, in float-point precision model, the point does DOES NOT intersect the segment.
275 template<>
276 template<>
test()277 void object::test<14>
278 ()
279 {
280 geos::io::WKBReader reader;
281
282 // POINT located between 3rd and 4th vertex of LINESTRING
283 // POINT(-23.1094689600055080 50.5195368635957180)
284 std::string point("01010000009a266328061c37c0e21a172f80424940");
285 // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055150 50.5223376452201340,-23.1094689600055010 50.5169177629559480,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409)
286 std::string
287 line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940");
288 std::stringstream sPoint(point);
289 GeomPtr gPoint(reader.readHEX(sPoint));
290 std::stringstream sLine(line);
291 GeomPtr gLine(reader.readHEX(sLine));
292 int ret = gLine->intersects(gPoint.get());
293 ensure_equals(ret, 0);
294 }
295
296 // Test intersects: point on segment with FIXED PM
297 // X coordinate of 3rd and 4th vertises of the line are not
298 // float-point exact with X coordinate of the point.
299 // The X values differ after 14th decimal place:
300 // POINT (-23.1094689600055080 50.5195368635957180)
301 // --------------------^^^^^^^------------^^^^^^^^
302 // LINESTRING 3rd and 4th points
303 // -23.1094689600055150 50.5223376452201340,
304 // -23.1094689600055010 50.5169177629559480,
305 // --------------------^^^^^^^------------^^^^^^^^
306 // So, if float-point values are trimmed up to 14 decimal digits, the point DOES intersect the segment.
307
308 template<>
309 template<>
test()310 void object::test<15>
311 ()
312 {
313 using geos::geom::GeometryFactory;
314 geos::geom::PrecisionModel pm(1e+13);
315 GeometryFactory::Ptr factory = GeometryFactory::create(&pm);
316 geos::io::WKBReader reader(*factory);
317
318 // POINT located between 3rd and 4th vertex of LINESTRING
319 // POINT(-23.1094689600055080 50.5195368635957180)
320 std::string point("01010000009a266328061c37c0e21a172f80424940");
321 // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055150 50.5223376452201340,-23.1094689600055010 50.5169177629559480,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409)
322 std::string
323 line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940");
324 std::stringstream sPoint(point);
325 GeomPtr gPoint(reader.readHEX(sPoint));
326 std::stringstream sLine(line);
327 GeomPtr gLine(reader.readHEX(sLine));
328 int ret = gLine->intersects(gPoint.get());
329 ensure_equals(ret, 1);
330 }
331
332 } // namespace tut
333
334