GEOS 3.12.0
Coordinate.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2006 Refractions Research Inc.
7 *
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
12 *
13 **********************************************************************/
14
15#pragma once
16
17#include <geos/export.h>
18#include <geos/constants.h> // for DoubleNotANumber
19#include <set>
20#include <unordered_set>
21#include <stack>
22#include <vector> // for typedefs
23#include <string>
24#include <limits>
25
26#ifdef _MSC_VER
27#pragma warning(push)
28#pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
29#endif
30
31namespace geos {
32namespace geom { // geos.geom
33
34// Forward declarations
35struct CoordinateLessThan;
36class CoordinateXYZM;
37class CoordinateXYM;
38class Coordinate;
39
40enum class CoordinateType : std::uint8_t {
41 XY,
42 XYZ,
43 XYZM,
44 XYM,
45};
46
47enum class Ordinate : std::uint8_t {
48 X,
49 Y,
50 Z,
51 M
52};
53
54GEOS_DLL std::ostream& operator<< (std::ostream&, const CoordinateType);
55
56class GEOS_DLL CoordinateXY {
57
58 const static CoordinateXY _nullCoord;
59
60protected:
61 constexpr const static double DEFAULT_X = 0.0;
62 constexpr const static double DEFAULT_Y = 0.0;
63 constexpr const static double DEFAULT_Z = DoubleNotANumber;
64 constexpr const static double DEFAULT_M = DoubleNotANumber;
65
66public:
67 CoordinateXY()
68 : x(DEFAULT_X)
69 , y(DEFAULT_Y)
70 {}
71
72 CoordinateXY(double xNew, double yNew)
73 : x(xNew)
74 , y(yNew)
75 {}
76
77 template<Ordinate>
78 double get() const;
79
81 double x;
82
84 double y;
85
87 GEOS_DLL friend bool operator==(const CoordinateXY& a, const CoordinateXY& b)
88 {
89 return a.equals2D(b);
90 };
91
93 GEOS_DLL friend bool operator!=(const CoordinateXY& a, const CoordinateXY& b)
94 {
95 return ! a.equals2D(b);
96 };
97
98 bool isValid() const
99 {
100 return std::isfinite(x) && std::isfinite(y);
101 };
102
103 bool equals2D(const CoordinateXY& other) const
104 {
105 if(x != other.x) {
106 return false;
107 }
108 if(y != other.y) {
109 return false;
110 }
111 return true;
112 };
113
114 bool equals2D(const CoordinateXY& other, double tolerance) const
115 {
116 if (std::abs(x - other.x) > tolerance) {
117 return false;
118 }
119 if (std::abs(y - other.y) > tolerance) {
120 return false;
121 }
122 return true;
123 };
124
126 bool equals(const CoordinateXY& other) const
127 {
128 return equals2D(other);
129 };
130
132 inline int compareTo(const CoordinateXY& other) const
133 {
134 if(x < other.x) {
135 return -1;
136 }
137 if(x > other.x) {
138 return 1;
139 }
140 if(y < other.y) {
141 return -1;
142 }
143 if(y > other.y) {
144 return 1;
145 }
146 return 0;
147 };
148
149 static const CoordinateXY& getNull();
150
151 double distance(const CoordinateXY& p) const
152 {
153 double dx = x - p.x;
154 double dy = y - p.y;
155 return std::sqrt(dx * dx + dy * dy);
156 };
157
158 double distanceSquared(const CoordinateXY& p) const
159 {
160 double dx = x - p.x;
161 double dy = y - p.y;
162 return dx * dx + dy * dy;
163 };
164
165 bool isNull() const
166 {
167 return (std::isnan(x) && std::isnan(y));
168 };
169
170 void setNull()
171 {
172 x = DoubleNotANumber;
173 y = DoubleNotANumber;
174 };
175
176 struct GEOS_DLL HashCode
177 {
178 inline std::size_t operator()(const CoordinateXY& c) const
179 {
180 size_t h = std::hash<double>{}(c.x);
181 h ^= std::hash<double>{}(c.y) << 1;
182 // z ordinate ignored for consistency with operator==
183 return h;
184 };
185 };
186
187 using UnorderedSet = std::unordered_set<Coordinate, HashCode>;
188
190 std::string toString() const;
191};
192
213// Define the following to make assignments and copy constructions
214// NON-(will let profilers report usages)
215//#define PROFILE_COORDINATE_COPIES 1
216class GEOS_DLL Coordinate : public CoordinateXY {
217
218private:
219
220 static const Coordinate _nullCoord;
221
222public:
224 typedef std::set<const Coordinate*, CoordinateLessThan> ConstSet;
225
227 typedef std::vector<const Coordinate*> ConstVect;
228
230 typedef std::stack<const Coordinate*> ConstStack;
231
233 typedef std::vector<Coordinate> Vect;
234
236 double z;
237
238 Coordinate()
239 : CoordinateXY()
240 , z(DEFAULT_Z)
241 {};
242
243 Coordinate(double xNew, double yNew, double zNew = DEFAULT_Z)
244 : CoordinateXY(xNew, yNew)
245 , z(zNew)
246 {};
247
248 explicit Coordinate(const CoordinateXY& other)
249 : CoordinateXY(other)
250 , z(DEFAULT_Z)
251 {};
252
253 template<Ordinate>
254 double get() const;
255
256 void setNull()
257 {
258 CoordinateXY::setNull();
259 z = DoubleNotANumber;
260 };
261
262 static const Coordinate& getNull();
263
264 bool isNull() const
265 {
266 return CoordinateXY::isNull() && std::isnan(z);
267 };
268
270 bool equals3D(const Coordinate& other) const
271 {
272 return (x == other.x) && (y == other.y) &&
273 ((z == other.z) || (std::isnan(z) && std::isnan(other.z)));
274 };
275
277 std::string toString() const;
278
279 Coordinate& operator=(const CoordinateXY& other){
280 x = other.x;
281 y = other.y;
282 z = DEFAULT_Z;
283
284 return *this;
285 }
286};
287
288
289class GEOS_DLL CoordinateXYM : public CoordinateXY {
290private:
291 static const CoordinateXYM _nullCoord;
292
293public:
294 CoordinateXYM() : CoordinateXYM(DEFAULT_X, DEFAULT_Y, DEFAULT_M) {}
295
296 explicit CoordinateXYM(const CoordinateXY& c)
297 : CoordinateXY(c)
298 , m(DEFAULT_M) {}
299
300 CoordinateXYM(double x_, double y_, double m_)
301 : CoordinateXY(x_, y_)
302 , m(m_) {}
303
304 double m;
305
306 template<Ordinate>
307 double get() const;
308
309 static const CoordinateXYM& getNull();
310
311 void setNull()
312 {
313 CoordinateXY::setNull();
314 m = DoubleNotANumber;
315 };
316
317 bool isNull() const
318 {
319 return CoordinateXY::isNull() && std::isnan(m);
320 }
321 bool equals3D(const CoordinateXYM& other) const {
322 return x == other.x && y == other.y && (m == other.m || (std::isnan(m) && std::isnan(other.m)));
323 }
324
325 CoordinateXYM& operator=(const CoordinateXYZM& other);
326
327 CoordinateXYM& operator=(const CoordinateXY& other) {
328 x = other.x;
329 y = other.y;
330 m = DEFAULT_M;
331
332 return *this;
333 }
334
335 std::string toString() const;
336};
337
338
339class GEOS_DLL CoordinateXYZM : public Coordinate {
340private:
341 static const CoordinateXYZM _nullCoord;
342
343public:
344 CoordinateXYZM() : CoordinateXYZM(DEFAULT_X, DEFAULT_Y, DEFAULT_Z, DEFAULT_M) {}
345
346 explicit CoordinateXYZM(const CoordinateXY& c)
347 : Coordinate(c)
348 , m(DEFAULT_M) {}
349
350 explicit CoordinateXYZM(const CoordinateXYM& c)
351 : Coordinate(c)
352 , m(c.m) {}
353
354 explicit CoordinateXYZM(const Coordinate& c)
355 : Coordinate(c)
356 , m(DEFAULT_M) {}
357
358 CoordinateXYZM(double x_, double y_, double z_, double m_)
359 : Coordinate(x_, y_, z_)
360 , m(m_) {}
361
362 double m;
363
364 template<Ordinate>
365 double get() const;
366
367 static const CoordinateXYZM& getNull();
368
369 void setNull()
370 {
371 Coordinate::setNull();
372 m = DoubleNotANumber;
373 };
374
375
376 bool isNull() const
377 {
378 return Coordinate::isNull() && std::isnan(m);
379 }
380
381 bool equals4D(const CoordinateXYZM& other) const {
382 return x == other.x && y == other.y &&
383 (z == other.z || (std::isnan(z) && std::isnan(other.z))) &&
384 (m == other.m || (std::isnan(m) && std::isnan(other.m)));
385 }
386
387 CoordinateXYZM& operator=(const CoordinateXY& other) {
388 x = other.x;
389 y = other.y;
390 z = DEFAULT_Z;
391 m = DEFAULT_M;
392
393 return *this;
394 }
395
396 CoordinateXYZM& operator=(const Coordinate& other) {
397 x = other.x;
398 y = other.y;
399 z = other.z;
400 m = DEFAULT_M;
401
402 return *this;
403 }
404
405 CoordinateXYZM& operator=(const CoordinateXYM& other) {
406 x = other.x;
407 y = other.y;
408 z = DEFAULT_Z;
409 m = other.m;
410
411 return *this;
412 }
413
414 std::string toString() const;
415};
416
417inline CoordinateXYM&
418CoordinateXYM::operator=(const CoordinateXYZM& other) {
419 x = other.x;
420 y = other.y;
421 m = other.m;
422
423 return *this;
424}
425
426
428struct GEOS_DLL CoordinateLessThan {
429
430 bool operator()(const CoordinateXY* a, const CoordinateXY* b) const
431 {
432 if(a->compareTo(*b) < 0) {
433 return true;
434 }
435 else {
436 return false;
437 }
438 };
439
440 bool operator()(const CoordinateXY& a, const CoordinateXY& b) const
441 {
442 if(a.compareTo(b) < 0) {
443 return true;
444 }
445 else {
446 return false;
447 }
448 };
449
450};
451
453inline bool operator<(const CoordinateXY& a, const CoordinateXY& b)
454{
455 return CoordinateLessThan()(a, b);
456}
457
458
459// Generic accessors, XY
460
461template<>
462inline double CoordinateXY::get<Ordinate::X>() const
463{
464 return x;
465}
466
467template<>
468inline double CoordinateXY::get<Ordinate::Y>() const
469{
470 return y;
471}
472
473template<>
474inline double CoordinateXY::get<Ordinate::Z>() const
475{
476 return DEFAULT_Z;
477}
478
479template<>
480inline double CoordinateXY::get<Ordinate::M>() const
481{
482 return DEFAULT_M;
483}
484
485// Generic accessors, XYZ
486
487template<>
488inline double Coordinate::get<Ordinate::X>() const
489{
490 return x;
491}
492
493template<>
494inline double Coordinate::get<Ordinate::Y>() const
495{
496 return y;
497}
498
499template<>
500inline double Coordinate::get<Ordinate::Z>() const
501{
502 return z;
503}
504
505template<>
506inline double Coordinate::get<Ordinate::M>() const
507{
508 return DEFAULT_M;
509}
510
511// Generic accessors, XYM
512
513template<>
514inline double CoordinateXYM::get<Ordinate::X>() const
515{
516 return x;
517}
518
519template<>
520inline double CoordinateXYM::get<Ordinate::Y>() const
521{
522 return y;
523}
524
525template<>
526inline double CoordinateXYM::get<Ordinate::Z>() const
527{
528 return DEFAULT_Z;
529}
530
531template<>
532inline double CoordinateXYM::get<Ordinate::M>() const
533{
534 return m;
535}
536
537// Generic accessors, XYZM
538
539template<>
540inline double CoordinateXYZM::get<Ordinate::X>() const
541{
542 return x;
543}
544
545template<>
546inline double CoordinateXYZM::get<Ordinate::Y>() const
547{
548 return y;
549}
550
551template<>
552inline double CoordinateXYZM::get<Ordinate::Z>() const
553{
554 return z;
555}
556
557template<>
558inline double CoordinateXYZM::get<Ordinate::M>() const
559{
560 return m;
561}
562
563GEOS_DLL std::ostream& operator<< (std::ostream& os, const CoordinateXY& c);
564GEOS_DLL std::ostream& operator<< (std::ostream& os, const Coordinate& c);
565GEOS_DLL std::ostream& operator<< (std::ostream& os, const CoordinateXYM& c);
566GEOS_DLL std::ostream& operator<< (std::ostream& os, const CoordinateXYZM& c);
567
568} // namespace geos.geom
569} // namespace geos
570
571// Add specializations of std::common_type for Coordinate types
572namespace std {
573 template<> struct common_type<geos::geom::CoordinateXY, geos::geom::CoordinateXY> { using type = geos::geom::CoordinateXY; };
574 template<> struct common_type<geos::geom::CoordinateXY, geos::geom::Coordinate> { using type = geos::geom::Coordinate; };
575 template<> struct common_type<geos::geom::CoordinateXY, geos::geom::CoordinateXYM> { using type = geos::geom::CoordinateXYM; };
576 template<> struct common_type<geos::geom::CoordinateXY, geos::geom::CoordinateXYZM> { using type = geos::geom::CoordinateXYZM; };
577
578 template<> struct common_type<geos::geom::Coordinate, geos::geom::CoordinateXY> { using type = geos::geom::Coordinate; };
579 template<> struct common_type<geos::geom::Coordinate, geos::geom::Coordinate> { using type = geos::geom::Coordinate; };
580 template<> struct common_type<geos::geom::Coordinate, geos::geom::CoordinateXYM> { using type = geos::geom::CoordinateXYZM; };
581 template<> struct common_type<geos::geom::Coordinate, geos::geom::CoordinateXYZM> { using type = geos::geom::CoordinateXYZM; };
582
583 template<> struct common_type<geos::geom::CoordinateXYM, geos::geom::CoordinateXY> { using type = geos::geom::CoordinateXYM; };
584 template<> struct common_type<geos::geom::CoordinateXYM, geos::geom::Coordinate> { using type = geos::geom::CoordinateXYZM; };
585 template<> struct common_type<geos::geom::CoordinateXYM, geos::geom::CoordinateXYM> { using type = geos::geom::CoordinateXYM; };
586 template<> struct common_type<geos::geom::CoordinateXYM, geos::geom::CoordinateXYZM> { using type = geos::geom::CoordinateXYZM; };
587
588 template<> struct common_type<geos::geom::CoordinateXYZM, geos::geom::CoordinateXY> { using type = geos::geom::CoordinateXYZM; };
589 template<> struct common_type<geos::geom::CoordinateXYZM, geos::geom::Coordinate> { using type = geos::geom::CoordinateXYZM; };
590 template<> struct common_type<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYM> { using type = geos::geom::CoordinateXYZM; };
591 template<> struct common_type<geos::geom::CoordinateXYZM, geos::geom::CoordinateXYZM> { using type = geos::geom::CoordinateXYZM; };
592}
593
594#ifdef _MSC_VER
595#pragma warning(pop)
596#endif
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:216
std::string toString() const
Returns a string of the form (x,y,z) .
std::set< const Coordinate *, CoordinateLessThan > ConstSet
A set of const Coordinate pointers.
Definition Coordinate.h:224
std::vector< Coordinate > Vect
A vector of Coordinate objects (real object, not pointers)
Definition Coordinate.h:233
std::vector< const Coordinate * > ConstVect
A vector of const Coordinate pointers.
Definition Coordinate.h:227
std::stack< const Coordinate * > ConstStack
A stack of const Coordinate pointers.
Definition Coordinate.h:230
bool equals3D(const Coordinate &other) const
3D comparison
Definition Coordinate.h:270
double z
z-coordinate
Definition Coordinate.h:236
bool operator<(const CoordinateXY &a, const CoordinateXY &b)
Strict weak ordering operator for Coordinate.
Definition Coordinate.h:453
Basic namespace for all GEOS functionalities.
Definition geos.h:39
Strict weak ordering Functor for Coordinate.
Definition Coordinate.h:428