Shapes
GIS made easy, a lightweight header-only planar geometry library for Modern C++
geometry.hpp
1 #pragma once
2 
3 #include <ciso646>
4 #include <simo/geom/detail/geometry.hpp>
5 #include <simo/geom/point.hpp>
6 #include <simo/geom/multipoint.hpp>
7 #include <simo/geom/linestring.hpp>
8 #include <simo/geom/multilinestring.hpp>
9 #include <simo/geom/polygon.hpp>
10 #include <simo/geom/multipolygon.hpp>
11 
12 namespace simo
13 {
14 namespace shapes
15 {
16 
17 template <typename T>
18 class geometry_t : public basic_geometry<geometry_t<T>>
19 {
20  public:
21  // default constructor
22  geometry_t()
23  {
24  std::cout << "DEFAULT CONSTRUCTOR" << std::endl;
25  }
26 
27  // copy constructor:
28  geometry_t(const geometry_t& other)
29  {
30  std::cout << "COPY CONSTRUCTOR" << std::endl;
31  m_geom_type = other.point()->geom_type();
32  switch (other.geom_type())
33  {
34  // point
35 
36  case geometry_type::POINT:
37  {
38  m_value = geom_value(*other.get_point());
39  break;
40  }
41  case geometry_type::POINTZ:
42  {
43  m_value = geom_value(*other.get_point_z());
44  break;
45  }
46  case geometry_type::POINTM:
47  {
48  m_value = geom_value(*other.get_point_m());
49  break;
50  }
51  case geometry_type::POINTZM:
52  {
53  m_value = geom_value(*other.get_point_zm());
54  break;
55  }
56 
57  // multipoint
58 
59  case geometry_type::MULTIPOINT:
60  {
61  m_value = geom_value(*other.get_multipoint());
62  break;
63  }
64  case geometry_type::MULTIPOINTZ:
65  {
66  m_value = geom_value(*other.get_multipoint_z());
67  break;
68  }
69  case geometry_type::MULTIPOINTM:
70  {
71  m_value = geom_value(*other.get_multipoint_m());
72  break;
73  }
74  case geometry_type::MULTIPOINTZM:
75  {
76  m_value = geom_value(*other.get_multipoint_zm());
77  break;
78  }
79 
80  // linestring
81 
82  case geometry_type::LINESTRING:
83  {
84  m_value = geom_value(*other.get_linestring());
85  break;
86  }
87  case geometry_type::LINESTRINGZ:
88  {
89  m_value = geom_value(*other.get_linestring_z());
90  break;
91  }
92  case geometry_type::LINESTRINGM:
93  {
94  m_value = geom_value(*other.get_linestring_m());
95  break;
96  }
97  case geometry_type::LINESTRINGZM:
98  {
99  m_value = geom_value(*other.get_linestring_zm());
100  break;
101  }
102 
103  // multilinestring
104 
105  case geometry_type::MULTILINESTRING:
106  {
107  m_value = geom_value(*other.get_multilinestring());
108  break;
109  }
110  case geometry_type::MULTILINESTRINGZ:
111  {
112  m_value = geom_value(*other.get_multilinestring_z());
113  break;
114  }
115  case geometry_type::MULTILINESTRINGM:
116  {
117  m_value = geom_value(*other.get_multilinestring_m());
118  break;
119  }
120  case geometry_type::MULTILINESTRINGZM:
121  {
122  m_value = geom_value(*other.get_multilinestring_zm());
123  break;
124  }
125 
126  // polygon
127 
128  case geometry_type::POLYGON:
129  {
130  m_value = geom_value(*other.get_polygon());
131  break;
132  }
133  case geometry_type::POLYGONZ:
134  {
135  m_value = geom_value(*other.get_polygon_z());
136  break;
137  }
138  case geometry_type::POLYGONM:
139  {
140  m_value = geom_value(*other.get_polygon_m());
141  break;
142  }
143  case geometry_type::POLYGONZM:
144  {
145  m_value = geom_value(*other.get_polygon_zm());
146  break;
147  }
148 
149  // multipolygon
150 
151  case geometry_type::MULTIPOLYGON:
152  {
153  m_value = geom_value(*other.get_multipolygon());
154  break;
155  }
156  case geometry_type::MULTIPOLYGONZ:
157  {
158  m_value = geom_value(*other.get_multipolygon_z());
159  break;
160  }
161  case geometry_type::MULTIPOLYGONM:
162  {
163  m_value = geom_value(*other.get_multipolygon_m());
164  break;
165  }
166  case geometry_type::MULTIPOLYGONZM:
167  {
168  m_value = geom_value(*other.get_multipolygon_zm());
169  break;
170  }
171  }
172  }
173  // copy assignment
174  geometry_t& operator=(const geometry_t& other)
175  {
176  std::cout << "COPY ASSIGNMENT" << std::endl;
177  geometry_t temp(other);
178  swap(*this, temp);
179  return *this;
180  }
181 
182  // move constructor
183  geometry_t(geometry_t&& other) noexcept
184  : geometry_t()
185  {
186  std::cout << "MOVE CONSTRUCTOR" << std::endl;
187  swap(*this, other);
188  }
189 
190  friend void swap(geometry_t& lhs, geometry_t& rhs) // nothrow
191  {
192  using std::swap;
193  swap(lhs.m_value, rhs.m_value);
194  swap(lhs.m_geom_type, rhs.m_geom_type);
195  }
196 
197  // point
198 
199  explicit geometry_t(const point_t<T>& p)
200  : m_value(p), m_geom_type(geometry_type::POINT)
201  {
202  }
203 
204  explicit geometry_t(const point_z_t<T>& p)
205  : m_value(p), m_geom_type(geometry_type::POINTZ)
206  {
207  }
208 
209  explicit geometry_t(const point_m_t<T>& value)
210  : m_value(value), m_geom_type(geometry_type::POINTM)
211  {
212  }
213 
214  explicit geometry_t(const point_zm_t<T>& value)
215  : m_value(value), m_geom_type(geometry_type::POINTZM)
216  {
217  }
218 
219  // multipoint
220 
221  explicit geometry_t(const multipoint_t<T>& value)
222  : m_value(value), m_geom_type(geometry_type::MULTIPOINT)
223  {
224  }
225 
226  explicit geometry_t(const multipoint_z_t<T>& value)
227  : m_value(value), m_geom_type(geometry_type::MULTIPOINTZ)
228  {
229  }
230 
231  explicit geometry_t(const multipoint_m_t<T>& value)
232  : m_value(value), m_geom_type(geometry_type::MULTIPOINTM)
233  {
234  }
235 
236  explicit geometry_t(const multipoint_zm_t<T>& value)
237  : m_value(value), m_geom_type(geometry_type::MULTIPOINTZM)
238  {
239  }
240 
241  // linestring
242 
243  explicit geometry_t(const linestring_t<T>& value)
244  : m_value(value), m_geom_type(geometry_type::LINESTRING)
245  {
246  }
247 
248  explicit geometry_t(const linestring_z_t<T>& value)
249  : m_value(value), m_geom_type(geometry_type::LINESTRINGZ)
250  {
251  }
252 
253  explicit geometry_t(const linestring_m_t<T>& value)
254  : m_value(value), m_geom_type(geometry_type::LINESTRINGM)
255  {
256  }
257 
258  explicit geometry_t(const linestring_zm_t<T>& value)
259  : m_value(value), m_geom_type(geometry_type::LINESTRINGZM)
260  {
261  }
262 
263  // multilinestring
264 
265  explicit geometry_t(const multilinestring_t<T>& value)
266  : m_value(value), m_geom_type(geometry_type::MULTILINESTRING)
267  {
268  }
269 
270  explicit geometry_t(const multilinestring_z_t<T>& value)
271  : m_value(value), m_geom_type(geometry_type::MULTILINESTRINGZ)
272  {
273  }
274 
275  explicit geometry_t(const multilinestring_m_t<T>& value)
276  : m_value(value), m_geom_type(geometry_type::MULTILINESTRINGM)
277  {
278  }
279 
280  explicit geometry_t(const multilinestring_zm_t<T>& value)
281  : m_value(value), m_geom_type(geometry_type::MULTILINESTRINGZM)
282  {
283  }
284 
285  // polygon
286 
287  explicit geometry_t(const polygon_t<T>& value)
288  : m_value(value), m_geom_type(geometry_type::POLYGON)
289  {
290  }
291 
292  explicit geometry_t(const polygon_z_t<T>& value)
293  : m_value(value), m_geom_type(geometry_type::POLYGONZ)
294  {
295  }
296 
297  explicit geometry_t(const polygon_m_t<T>& value)
298  : m_value(value), m_geom_type(geometry_type::POLYGONM)
299  {
300  }
301 
302  explicit geometry_t(const polygon_zm_t<T>& value)
303  : m_value(value), m_geom_type(geometry_type::POLYGONZM)
304  {
305  }
306 
307  // multipolygon
308 
309  explicit geometry_t(const multipolygon_t<T>& value)
310  : m_value(value), m_geom_type(geometry_type::MULTIPOLYGON)
311  {
312  }
313 
314  explicit geometry_t(const multipolygon_z_t<T>& value)
315  : m_value(value), m_geom_type(geometry_type::MULTIPOLYGONZ)
316  {
317  }
318 
319  explicit geometry_t(const multipolygon_m_t<T>& value)
320  : m_value(value), m_geom_type(geometry_type::MULTIPOLYGONM)
321  {
322  }
323 
324  explicit geometry_t(const multipolygon_zm_t<T>& value)
325  : m_value(value), m_geom_type(geometry_type::MULTIPOLYGONZM)
326  {
327  }
328 
329  ~geometry_t()
330  {
331  switch (m_geom_type)
332  {
333  // point
334 
335  case geometry_type::POINT:
336  {
337  delete m_value.m_point;
338  m_value.m_point = nullptr;
339  std::cout << "DELETE POINT" << std::endl;
340  break;
341  }
342  case geometry_type::POINTZ:
343  {
344  delete m_value.m_point_z;
345  m_value.m_point_z = nullptr;
346  std::cout << "DELETE POINT Z" << std::endl;
347  break;
348  }
349  case geometry_type::POINTM:
350  {
351  delete m_value.m_point_m;
352  m_value.m_point_m = nullptr;
353  std::cout << "DELETE POINT M" << std::endl;
354  break;
355  }
356  case geometry_type::POINTZM:
357  {
358  delete m_value.m_point_zm;
359  m_value.m_point_zm = nullptr;
360  std::cout << "DELETE POINT ZM" << std::endl;
361  break;
362  }
363 
364  // multipoint
365 
366  case geometry_type::MULTIPOINT:
367  {
368  delete m_value.m_multipoint;
369  m_value.m_multipoint = nullptr;
370  std::cout << "DELETE MULTIPOINT" << std::endl;
371  break;
372  }
373  case geometry_type::MULTIPOINTZ:
374  {
375  delete m_value.m_multipoint_z;
376  m_value.m_multipoint_z = nullptr;
377  std::cout << "DELETE MULTIPOINT Z" << std::endl;
378  break;
379  }
380  case geometry_type::MULTIPOINTM:
381  {
382  delete m_value.m_multipoint_m;
383  m_value.m_multipoint_m = nullptr;
384  std::cout << "DELETE MULTIPOINT M" << std::endl;
385  break;
386  }
387  case geometry_type::MULTIPOINTZM:
388  {
389  delete m_value.m_multipoint_zm;
390  m_value.m_multipoint_zm = nullptr;
391  std::cout << "DELETE MULTIPOINT ZM" << std::endl;
392  break;
393  }
394 
395  // linestring
396 
397  case geometry_type::LINESTRING:
398  {
399  delete m_value.m_linestring;
400  m_value.m_linestring = nullptr;
401  std::cout << "DELETE LINESTRING" << std::endl;
402  break;
403  }
404  case geometry_type::LINESTRINGZ:
405  {
406  delete m_value.m_linestring_z;
407  m_value.m_linestring_z = nullptr;
408  std::cout << "DELETE LINESTRING Z" << std::endl;
409  break;
410  }
411  case geometry_type::LINESTRINGM:
412  {
413  delete m_value.m_linestring_m;
414  m_value.m_linestring_m = nullptr;
415  std::cout << "DELETE LINESTRING M" << std::endl;
416  break;
417  }
418  case geometry_type::LINESTRINGZM:
419  {
420  delete m_value.m_linestring_zm;
421  m_value.m_linestring_zm = nullptr;
422  std::cout << "DELETE LINESTRING ZM" << std::endl;
423  break;
424  }
425 
426  // multilinestring
427 
428  case geometry_type::MULTILINESTRING:
429  {
430  delete m_value.m_multilinestring;
431  m_value.m_multilinestring = nullptr;
432  std::cout << "DELETE MULTILINESTRING" << std::endl;
433  break;
434  }
435  case geometry_type::MULTILINESTRINGZ:
436  {
437  delete m_value.m_multilinestring_z;
438  m_value.m_multilinestring_z = nullptr;
439  std::cout << "DELETE MULTILINESTRING Z" << std::endl;
440  break;
441  }
442  case geometry_type::MULTILINESTRINGM:
443  {
444  delete m_value.m_multilinestring_m;
445  m_value.m_multilinestring_m = nullptr;
446  std::cout << "DELETE MULTILINESTRING M" << std::endl;
447  break;
448  }
449  case geometry_type::MULTILINESTRINGZM:
450  {
451  delete m_value.m_multilinestring_zm;
452  m_value.m_multilinestring_zm = nullptr;
453  std::cout << "DELETE MULTILINESTRING ZM" << std::endl;
454  break;
455  }
456 
457  // polygon
458 
459  case geometry_type::POLYGON:
460  {
461  delete m_value.m_polygon;
462  m_value.m_polygon = nullptr;
463  std::cout << "DELETE POLYGON" << std::endl;
464  break;
465  }
466  case geometry_type::POLYGONZ:
467  {
468  delete m_value.m_polygon_z;
469  m_value.m_polygon_z = nullptr;
470  std::cout << "DELETE POLYGON Z" << std::endl;
471  break;
472  }
473  case geometry_type::POLYGONM:
474  {
475  delete m_value.m_polygon_m;
476  m_value.m_polygon_m = nullptr;
477  std::cout << "DELETE POLYGON M" << std::endl;
478  break;
479  }
480  case geometry_type::POLYGONZM:
481  {
482  delete m_value.m_polygon_zm;
483  m_value.m_polygon_zm = nullptr;
484  std::cout << "DELETE POLYGON ZM" << std::endl;
485  break;
486  }
487 
488  // multipolygon
489 
490  case geometry_type::MULTIPOLYGON:
491  {
492  delete m_value.m_multipolygon;
493  m_value.m_multipolygon = nullptr;
494  std::cout << "DELETE MULTIPOLYGON" << std::endl;
495  break;
496  }
497  case geometry_type::MULTIPOLYGONZ:
498  {
499  delete m_value.m_multipolygon_z;
500  m_value.m_multipolygon_z = nullptr;
501  std::cout << "DELETE MULTIPOLYGON Z" << std::endl;
502  break;
503  }
504  case geometry_type::MULTIPOLYGONM:
505  {
506  delete m_value.m_multipolygon_m;
507  m_value.m_multipolygon_m = nullptr;
508  std::cout << "DELETE MULTIPOLYGON M" << std::endl;
509  break;
510  }
511  case geometry_type::MULTIPOLYGONZM:
512  {
513  delete m_value.m_multipolygon_zm;
514  m_value.m_multipolygon_zm = nullptr;
515  std::cout << "DELETE MULTIPOLYGON ZM" << std::endl;
516  break;
517  }
518  default:
519  {
520  break;
521  }
522  }
523  }
524 
525  // getters
526 
527  template <typename ReturnType>
528  ReturnType* get()
529  {
530  // point
531 
533  {
534  return reinterpret_cast<ReturnType*>(get_point());
535  }
537  {
538  return reinterpret_cast<ReturnType*>(get_point_z());
539  }
541  {
542  return reinterpret_cast<ReturnType*>(get_point_m());
543  }
545  {
546  return reinterpret_cast<ReturnType*>(get_point_zm());
547  }
548 
549  // multipoint
550 
552  {
553  return reinterpret_cast<ReturnType*>(get_multipoint());
554  }
556  {
557  return reinterpret_cast<ReturnType*>(get_multipoint_z());
558  }
560  {
561  return reinterpret_cast<ReturnType*>(get_multipoint_m());
562  }
564  {
565  return reinterpret_cast<ReturnType*>(get_multipoint_zm());
566  }
567 
568  // linestring
569 
571  {
572  return reinterpret_cast<ReturnType*>(get_linestring());
573  }
575  {
576  return reinterpret_cast<ReturnType*>(get_linestring_z());
577  }
579  {
580  return reinterpret_cast<ReturnType*>(get_linestring_m());
581  }
583  {
584  return reinterpret_cast<ReturnType*>(get_linestring_zm());
585  }
586 
587  // multilinestring
588 
590  {
591  return reinterpret_cast<ReturnType*>(get_multilinestring());
592  }
594  {
595  return reinterpret_cast<ReturnType*>(get_multilinestring_z());
596  }
598  {
599  return reinterpret_cast<ReturnType*>(get_multilinestring_m());
600  }
602  {
603  return reinterpret_cast<ReturnType*>(get_multilinestring_zm());
604  }
605 
606  // polygon
607 
609  {
610  return reinterpret_cast<ReturnType*>(get_polygon());
611  }
613  {
614  return reinterpret_cast<ReturnType*>(get_polygon_z());
615  }
617  {
618  return reinterpret_cast<ReturnType*>(get_polygon_m());
619  }
621  {
622  return reinterpret_cast<ReturnType*>(get_polygon_zm());
623  }
624 
625  // multipolygon
626 
628  {
629  return reinterpret_cast<ReturnType*>(get_multipolygon());
630  }
632  {
633  return reinterpret_cast<ReturnType*>(get_multipolygon_z());
634  }
636  {
637  return reinterpret_cast<ReturnType*>(get_multipolygon_m());
638  }
640  {
641  return reinterpret_cast<ReturnType*>(get_multipolygon_zm());
642  }
643 
644  return nullptr;
645  }
646 
647  // point
648 
649  inline bool is_point()
650  {
651  return m_geom_type == geometry_type::POINT;
652  }
653 
654  inline bool is_point_z()
655  {
656  return m_geom_type == geometry_type::POINTZ;
657  }
658 
659  inline bool is_point_m()
660  {
661  return m_geom_type == geometry_type::POINTM;
662  }
663 
664  inline bool is_point_zm()
665  {
666  return m_geom_type == geometry_type::POINTZM;
667  }
668 
669  // multipoint
670 
671  inline bool is_multipoint()
672  {
673  return m_geom_type == geometry_type::MULTIPOINT;
674  }
675 
676  inline bool is_multipoint_z()
677  {
678  return m_geom_type == geometry_type::MULTIPOINTZ;
679  }
680 
681  inline bool is_multipoint_m()
682  {
683  return m_geom_type == geometry_type::MULTIPOINTM;
684  }
685 
686  inline bool is_multipoint_zm()
687  {
688  return m_geom_type == geometry_type::MULTIPOINTZM;
689  }
690 
691  // linestring
692 
693  inline bool is_linestring()
694  {
695  return m_geom_type == geometry_type::LINESTRING;
696  }
697 
698  inline bool is_linestring_z()
699  {
700  return m_geom_type == geometry_type::LINESTRINGZ;
701  }
702 
703  inline bool is_linestring_m()
704  {
705  return m_geom_type == geometry_type::LINESTRINGM;
706  }
707 
708  inline bool is_linestring_zm()
709  {
710  return m_geom_type == geometry_type::LINESTRINGZM;
711  }
712 
713  // multilinestring
714 
715  inline bool is_multilinestring()
716  {
717  return m_geom_type == geometry_type::MULTILINESTRING;
718  }
719 
720  inline bool is_multilinestring_z()
721  {
722  return m_geom_type == geometry_type::MULTILINESTRINGZ;
723  }
724 
725  inline bool is_multilinestring_m()
726  {
727  return m_geom_type == geometry_type::MULTILINESTRINGM;
728  }
729 
730  inline bool is_multilinestring_zm()
731  {
732  return m_geom_type == geometry_type::MULTILINESTRINGZM;
733  }
734 
735  // polygon
736 
737  inline bool is_polygon()
738  {
739  return m_geom_type == geometry_type::POLYGON;
740  }
741 
742  inline bool is_polygon_z()
743  {
744  return m_geom_type == geometry_type::POLYGONZ;
745  }
746 
747  inline bool is_polygon_m()
748  {
749  return m_geom_type == geometry_type::POLYGONM;
750  }
751 
752  inline bool is_polygon_zm()
753  {
754  return m_geom_type == geometry_type::POLYGONZM;
755  }
756 
757  // multipolygon
758 
759  inline bool is_multipolygon()
760  {
761  return m_geom_type == geometry_type::MULTIPOLYGON;
762  }
763 
764  inline bool is_multipolygon_z()
765  {
766  return m_geom_type == geometry_type::MULTIPOLYGONZ;
767  }
768 
769  inline bool is_multipolygon_m()
770  {
771  return m_geom_type == geometry_type::MULTIPOLYGONM;
772  }
773 
774  inline bool is_multipolygon_zm()
775  {
776  return m_geom_type == geometry_type::MULTIPOLYGONZM;
777  }
778 
779  // point
780 
781  point_t<T>* get_point()
782  {
783  assert(is_point());
784  return m_value.m_point;
785  }
786 
787  point_z_t<T>* get_point_z()
788  {
789  assert(is_point_z());
790  return m_value.m_point_z;
791  }
792 
793  point_m_t<T>* get_point_m()
794  {
795  assert(is_point_m());
796  return m_value.m_point_m;
797  }
798 
799  point_zm_t<T>* get_point_zm()
800  {
801  assert(is_point_zm());
802  return m_value.m_point_zm;
803  }
804 
805  // multipoint
806 
807  multipoint_t<T>* get_multipoint()
808  {
809  assert(is_multipoint());
810  return m_value.m_multipoint;
811  }
812 
813  multipoint_z_t<T>* get_multipoint_z()
814  {
815  assert(is_multipoint_z());
816  return m_value.m_multipoint_z;
817  }
818 
819  multipoint_m_t<T>* get_multipoint_m()
820  {
821  assert(is_multipoint_m());
822  return m_value.m_multipoint_m;
823  }
824 
825  multipoint_zm_t<T>* get_multipoint_zm()
826  {
827  assert(is_multipoint_zm());
828  return m_value.m_multipoint_zm;
829  }
830 
831  // linestring
832 
833  linestring_t<T>* get_linestring()
834  {
835  assert(is_linestring());
836  return m_value.m_linestring;
837  }
838 
839  linestring_z_t<T>* get_linestring_z()
840  {
841  assert(is_linestring_z());
842  return m_value.m_linestring_z;
843  }
844 
845  linestring_m_t<T>* get_linestring_m()
846  {
847  assert(is_linestring_m());
848  return m_value.m_linestring_m;
849  }
850 
851  linestring_zm_t<T>* get_linestring_zm()
852  {
853  assert(is_linestring_zm());
854  return m_value.m_linestring_zm;
855  }
856 
857  // multilinestring
858 
859  multilinestring_t<T>* get_multilinestring()
860  {
861  assert(is_multilinestring());
862  return m_value.m_multilinestring;
863  }
864 
865  multilinestring_z_t<T>* get_multilinestring_z()
866  {
867  assert(is_multilinestring_z());
868  return m_value.m_multilinestring_z;
869  }
870 
871  multilinestring_m_t<T>* get_multilinestring_m()
872  {
873  assert(is_multilinestring_m());
874  return m_value.m_multilinestring_m;
875  }
876 
877  multilinestring_zm_t<T>* get_multilinestring_zm()
878  {
879  assert(is_multilinestring_zm());
880  return m_value.m_multilinestring_zm;
881  }
882 
883  // polygon
884 
885  polygon_t<T>* get_polygon()
886  {
887  assert(is_polygon());
888  return m_value.m_polygon;
889  }
890 
891  polygon_z_t<T>* get_polygon_z()
892  {
893  assert(is_polygon_z());
894  return m_value.m_polygon_z;
895  }
896 
897  polygon_m_t<T>* get_polygon_m()
898  {
899  assert(is_polygon_m());
900  return m_value.m_polygon_m;
901  }
902 
903  polygon_zm_t<T>* get_polygon_zm()
904  {
905  assert(is_polygon_zm());
906  return m_value.m_polygon_zm;
907  }
908 
909  // multipolygon
910 
911  multipolygon_t<T>* get_multipolygon()
912  {
913  assert(is_multipolygon());
914  return m_value.m_multipolygon;
915  }
916 
917  multipolygon_z_t<T>* get_multipolygon_z()
918  {
919  assert(is_multipolygon_z());
920  return m_value.m_multipolygon_z;
921  }
922 
923  multipolygon_m_t<T>* get_multipolygon_m()
924  {
925  assert(is_multipolygon_m());
926  return m_value.m_multipolygon_m;
927  }
928 
929  multipolygon_zm_t<T>* get_multipolygon_zm()
930  {
931  assert(is_multipolygon_zm());
932  return m_value.m_multipolygon_zm;
933  }
934 
935  private:
937  friend class basic_geometry<geometry_t<T>>;
938 
939  union geom_value
940  {
941  point_t<T>* m_point;
942  point_z_t<T>* m_point_z;
943  point_m_t<T>* m_point_m;
944  point_zm_t<T>* m_point_zm;
945  multipoint_t<T>* m_multipoint;
946  multipoint_z_t<T>* m_multipoint_z;
947  multipoint_m_t<T>* m_multipoint_m;
948  multipoint_zm_t<T>* m_multipoint_zm;
949  linestring_t<T>* m_linestring;
950  linestring_z_t<T>* m_linestring_z;
951  linestring_m_t<T>* m_linestring_m;
952  linestring_zm_t<T>* m_linestring_zm;
953  multilinestring_t<T>* m_multilinestring;
954  multilinestring_z_t<T>* m_multilinestring_z;
955  multilinestring_m_t<T>* m_multilinestring_m;
956  multilinestring_zm_t<T>* m_multilinestring_zm;
957  polygon_t<T>* m_polygon;
958  polygon_z_t<T>* m_polygon_z;
959  polygon_m_t<T>* m_polygon_m;
960  polygon_zm_t<T>* m_polygon_zm;
961  multipolygon_t<T>* m_multipolygon;
962  multipolygon_z_t<T>* m_multipolygon_z;
963  multipolygon_m_t<T>* m_multipolygon_m;
964  multipolygon_zm_t<T>* m_multipolygon_zm;
965 
966  // default constructor
967  geom_value() = default;
968 
969  // point
970 
971  explicit geom_value(const point_t<T>& p)
972  : m_point(new point_t<T>(p))
973  {
974  }
975 
976  explicit geom_value(const point_z_t<T>& p)
977  : m_point_z(new point_z_t<T>(p))
978  {
979  }
980 
981  explicit geom_value(const point_m_t<T>& p)
982  : m_point_m(new point_m_t<T>(p))
983  {
984  }
985 
986  explicit geom_value(const point_zm_t<T>& p)
987  : m_point_zm(new point_zm_t<T>(p))
988  {
989  }
990 
991  // multipoint
992 
993  explicit geom_value(const multipoint_t<T>& p)
994  : m_multipoint(new multipoint_t<T>(p))
995  {
996  }
997 
998  explicit geom_value(const multipoint_z_t<T>& p)
999  : m_multipoint_z(new multipoint_z_t<T>(p))
1000  {
1001  }
1002 
1003  explicit geom_value(const multipoint_m_t<T>& p)
1004  : m_multipoint_m(new multipoint_m_t<T>(p))
1005  {
1006  }
1007 
1008  explicit geom_value(const multipoint_zm_t<T>& p)
1009  : m_multipoint_zm(new multipoint_zm_t<T>(p))
1010  {
1011  }
1012 
1013  // linestring
1014 
1015  explicit geom_value(const linestring_t<T>& p)
1016  : m_linestring(new linestring_t<T>(p))
1017  {
1018  }
1019 
1020  explicit geom_value(const linestring_z_t<T>& p)
1021  : m_linestring_z(new linestring_z_t<T>(p))
1022  {
1023  }
1024 
1025  explicit geom_value(const linestring_m_t<T>& p)
1026  : m_linestring_m(new linestring_m_t<T>(p))
1027  {
1028  }
1029 
1030  explicit geom_value(const linestring_zm_t<T>& p)
1031  : m_linestring_zm(new linestring_zm_t<T>(p))
1032  {
1033  }
1034 
1035  // multilinestring
1036 
1037  explicit geom_value(const multilinestring_t<T>& p)
1038  : m_multilinestring(new multilinestring_t<T>(p))
1039  {
1040  }
1041 
1042  explicit geom_value(const multilinestring_z_t<T>& p)
1043  : m_multilinestring_z(new multilinestring_z_t<T>(p))
1044  {
1045  }
1046 
1047  explicit geom_value(const multilinestring_m_t<T>& p)
1048  : m_multilinestring_m(new multilinestring_m_t<T>(p))
1049  {
1050  }
1051 
1052  explicit geom_value(const multilinestring_zm_t<T>& p)
1053  : m_multilinestring_zm(new multilinestring_zm_t<T>(p))
1054  {
1055  }
1056 
1057  // polygon
1058 
1059  explicit geom_value(const polygon_t<T>& p)
1060  : m_polygon(new polygon_t<T>(p))
1061  {
1062  }
1063 
1064  explicit geom_value(const polygon_z_t<T>& p)
1065  : m_polygon_z(new polygon_z_t<T>(p))
1066  {
1067  }
1068 
1069  explicit geom_value(const polygon_m_t<T>& p)
1070  : m_polygon_m(new polygon_m_t<T>(p))
1071  {
1072  }
1073 
1074  explicit geom_value(const polygon_zm_t<T>& p)
1075  : m_polygon_zm(new polygon_zm_t<T>(p))
1076  {
1077  }
1078 
1079  // multipolygon
1080 
1081  explicit geom_value(const multipolygon_t<T>& p)
1082  : m_multipolygon(new multipolygon_t<T>(p))
1083  {
1084  }
1085 
1086  explicit geom_value(const multipolygon_z_t<T>& p)
1087  : m_multipolygon_z(new multipolygon_z_t<T>(p))
1088  {
1089  }
1090 
1091  explicit geom_value(const multipolygon_m_t<T>& p)
1092  : m_multipolygon_m(new multipolygon_m_t<T>(p))
1093  {
1094  }
1095 
1096  explicit geom_value(const multipolygon_zm_t<T>& p)
1097  : m_multipolygon_zm(new multipolygon_zm_t<T>(p))
1098  {
1099  }
1100  };
1101 
1102  geom_value m_value = {};
1103  geometry_type m_geom_type = geometry_type::GEOMETRY;
1104 
1106  geometry_type geom_type_() const noexcept
1107  {
1108  return m_geom_type;
1109  }
1110 
1112  std::string tagged_text_() const noexcept
1113  {
1114  return "Geometry";
1115  }
1116 
1118  dimension_type dim_() const noexcept
1119  {
1120  return dimension_type::XY;
1121  }
1122 
1124  int32_t ndim_() const noexcept
1125  {
1126  return 2;
1127  }
1128 
1130  bool is_closed_() const noexcept
1131  {
1132  return true;
1133  }
1134 
1136  void throw_for_invalid_() const
1137  {
1138  // do nothing
1139  }
1140 
1142  bounds_t bounds_() const
1143  {
1144  return {};
1145  }
1146 
1148  bool has_z_() const noexcept
1149  {
1150  return true;
1151  }
1152 
1154  bool has_m_() const noexcept
1155  {
1156  return true;
1157  }
1158 
1159  // json
1160 
1162  static geometry_t<T> from_json_(const std::string& /*json*/)
1163  {
1164  geometry_t<T> res;
1165  return res;
1166  }
1167 
1169  std::string json_(std::int32_t precision = -1) const
1170  {
1171  switch (m_geom_type)
1172  {
1173  // point
1174  case geometry_type::POINT:
1175  {
1176  return m_value.m_point->json(precision);
1177  }
1178  case geometry_type::POINTZ:
1179  {
1180  return m_value.m_point_z->json(precision);
1181  }
1182  case geometry_type::POINTM:
1183  {
1184  return m_value.m_point_m->json(precision);
1185  }
1186  case geometry_type::POINTZM:
1187  {
1188  return m_value.m_point_zm->json(precision);
1189  }
1190 
1191  // multipoint
1192  case geometry_type::MULTIPOINT:
1193  {
1194  return m_value.m_multipoint->json(precision);
1195  }
1196  case geometry_type::MULTIPOINTZ:
1197  {
1198  return m_value.m_multipoint_z->json(precision);
1199  }
1200  case geometry_type::MULTIPOINTM:
1201  {
1202  return m_value.m_multipoint_m->json(precision);
1203  }
1204  case geometry_type::MULTIPOINTZM:
1205  {
1206  return m_value.m_multipoint_zm->json(precision);
1207  }
1208 
1209  // linestring
1210  case geometry_type::LINESTRING:
1211  {
1212  return m_value.m_linestring->json(precision);
1213  }
1214  case geometry_type::LINESTRINGZ:
1215  {
1216  return m_value.m_linestring_z->json(precision);
1217  }
1218  case geometry_type::LINESTRINGM:
1219  {
1220  return m_value.m_linestring_m->json(precision);
1221  }
1222  case geometry_type::LINESTRINGZM:
1223  {
1224  return m_value.m_linestring_zm->json(precision);
1225  }
1226 
1227  // multilinestring
1228  case geometry_type::MULTILINESTRING:
1229  {
1230  return m_value.m_multilinestring->json(precision);
1231  }
1232  case geometry_type::MULTILINESTRINGZ:
1233  {
1234  return m_value.m_multilinestring_z->json(precision);
1235  }
1236  case geometry_type::MULTILINESTRINGM:
1237  {
1238  return m_value.m_multilinestring_m->json(precision);
1239  }
1240  case geometry_type::MULTILINESTRINGZM:
1241  {
1242  return m_value.m_multilinestring_zm->json(precision);
1243  }
1244 
1245  // polygon
1246  case geometry_type::POLYGON:
1247  {
1248  return m_value.m_polygon->json(precision);
1249  }
1250  case geometry_type::POLYGONZ:
1251  {
1252  return m_value.m_polygon_z->json(precision);
1253  }
1254  case geometry_type::POLYGONM:
1255  {
1256  return m_value.m_polygon_m->json(precision);
1257  }
1258  case geometry_type::POLYGONZM:
1259  {
1260  return m_value.m_polygon_zm->json(precision);
1261  }
1262 
1263  // multipolygon
1264  case geometry_type::MULTIPOLYGON:
1265  {
1266  return m_value.m_multipolygon->json(precision);
1267  }
1268  case geometry_type::MULTIPOLYGONZ:
1269  {
1270  return m_value.m_multipolygon_z->json(precision);
1271  }
1272  case geometry_type::MULTIPOLYGONM:
1273  {
1274  return m_value.m_multipolygon_m->json(precision);
1275  }
1276  case geometry_type::MULTIPOLYGONZM:
1277  {
1278  return m_value.m_multipolygon_zm->json(precision);
1279  }
1280  default:
1281  {
1282  return "";
1283  }
1284  }
1285  }
1286 
1287  // wkt
1288 
1290  static geometry_t<T> from_wkt_(const std::string& wkt)
1291  {
1292  wkt_reader reader{};
1293  auto result = reader.read(wkt);
1294  auto data = result.data;
1295  switch (data.geom_type)
1296  {
1297  case geometry_type::POINT:
1298  return geometry_t<T>(point_t<T>(data.coords[0], data.coords[1]));
1299  case geometry_type::POINTZ:
1300  return geometry_t<T>(point_z_t<T>(data.coords[0], data.coords[1], data.coords[2]));
1301  case geometry_type::POINTM:
1302  return geometry_t<T>(point_m_t<T>(data.coords[0], data.coords[1], data.coords[2]));
1303  case geometry_type::POINTZM:
1304  return geometry_t<T>(point_zm_t<T>(data.coords[0], data.coords[1], data.coords[2], data.coords[3]));
1310  default:
1311  {
1312  throw exceptions::parse_error("invalid wkt string");
1313  }
1314  }
1315  return {};
1316  }
1317 
1319  std::string wkt_(std::int32_t precision = -1) const
1320  {
1321  switch (m_geom_type)
1322  {
1323  // point
1324  case geometry_type::POINT:
1325  {
1326  return m_value.m_point->wkt(precision);
1327  }
1328  case geometry_type::POINTZ:
1329  {
1330  return m_value.m_point_z->wkt(precision);
1331  }
1332  case geometry_type::POINTM:
1333  {
1334  return m_value.m_point_m->wkt(precision);
1335  }
1336  case geometry_type::POINTZM:
1337  {
1338  return m_value.m_point_zm->wkt(precision);
1339  }
1340 
1341  // multipoint
1342  case geometry_type::MULTIPOINT:
1343  {
1344  return m_value.m_multipoint->wkt(precision);
1345  }
1346  case geometry_type::MULTIPOINTZ:
1347  {
1348  return m_value.m_multipoint_z->wkt(precision);
1349  }
1350  case geometry_type::MULTIPOINTM:
1351  {
1352  return m_value.m_multipoint_m->wkt(precision);
1353  }
1354  case geometry_type::MULTIPOINTZM:
1355  {
1356  return m_value.m_multipoint_zm->wkt(precision);
1357  }
1358 
1359  // linestring
1360  case geometry_type::LINESTRING:
1361  {
1362  return m_value.m_linestring->wkt(precision);
1363  }
1364  case geometry_type::LINESTRINGZ:
1365  {
1366  return m_value.m_linestring_z->wkt(precision);
1367  }
1368  case geometry_type::LINESTRINGM:
1369  {
1370  return m_value.m_linestring_m->wkt(precision);
1371  }
1372  case geometry_type::LINESTRINGZM:
1373  {
1374  return m_value.m_linestring_zm->wkt(precision);
1375  }
1376 
1377  // multilinestring
1378  case geometry_type::MULTILINESTRING:
1379  {
1380  return m_value.m_multilinestring->wkt(precision);
1381  }
1382  case geometry_type::MULTILINESTRINGZ:
1383  {
1384  return m_value.m_multilinestring_z->wkt(precision);
1385  }
1386  case geometry_type::MULTILINESTRINGM:
1387  {
1388  return m_value.m_multilinestring_m->wkt(precision);
1389  }
1390  case geometry_type::MULTILINESTRINGZM:
1391  {
1392  return m_value.m_multilinestring_zm->wkt(precision);
1393  }
1394 
1395  // polygon
1396  case geometry_type::POLYGON:
1397  {
1398  return m_value.m_polygon->wkt(precision);
1399  }
1400  case geometry_type::POLYGONZ:
1401  {
1402  return m_value.m_polygon_z->wkt(precision);
1403  }
1404  case geometry_type::POLYGONM:
1405  {
1406  return m_value.m_polygon_m->wkt(precision);
1407  }
1408  case geometry_type::POLYGONZM:
1409  {
1410  return m_value.m_polygon_zm->wkt(precision);
1411  }
1412 
1413  // multipolygon
1414  case geometry_type::MULTIPOLYGON:
1415  {
1416  return m_value.m_multipolygon->wkt(precision);
1417  }
1418  case geometry_type::MULTIPOLYGONZ:
1419  {
1420  return m_value.m_multipolygon_z->wkt(precision);
1421  }
1422  case geometry_type::MULTIPOLYGONM:
1423  {
1424  return m_value.m_multipolygon_m->wkt(precision);
1425  }
1426  case geometry_type::MULTIPOLYGONZM:
1427  {
1428  return m_value.m_multipolygon_zm->wkt(precision);
1429  }
1430  default:
1431  {
1432  return "";
1433  }
1434  }
1435  }
1436 };
1437 
1440 
1441 } // namespace shapes
1442 } // namespace simo
geometry_type geom_type() const noexcept
Returns the geometry type.
Definition: geometry.hpp:35
Base class for all geometries.
Definition: geometry.hpp:26
wkt_data data
the parser result data
Definition: wkt_parser.hpp:44
wkt_result read(const std::string &wkt)
parse the given wkt string
Definition: wkt_reader.hpp:47
Represents an axis-aligned bounding box.
Definition: bounds.hpp:18
Exception thrown when an error has been found while parsing.
Definition: exceptions.hpp:67
std::string wkt(std::int32_t precision=-1) const
Dumps the wkt representation of the geometry.
Definition: geometry.hpp:283