/src/geos/include/geos/io/OrdinateSet.h
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2022 ISciences LLC |
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/util/GEOSException.h> |
19 | | |
20 | | namespace geos { |
21 | | namespace io { |
22 | | |
23 | | /** |
24 | | * \class OrdinateSet |
25 | | * \brief Utility class to manipulate a set of flags indicating whether |
26 | | * X, Y, Z, or M dimensions are present. |
27 | | * Based on JTS EnumSet<Ordinate>. |
28 | | */ |
29 | | class GEOS_DLL OrdinateSet { |
30 | | private: |
31 | | enum Ordinate : unsigned char { |
32 | | X = 1, |
33 | | Y = 2, |
34 | | Z = 4, |
35 | | M = 8, |
36 | | }; |
37 | | |
38 | | enum Ordinates : unsigned char { |
39 | | XY = Ordinate::X | Ordinate::Y, |
40 | | XYZ = Ordinate::X | Ordinate::Y | Ordinate::Z, |
41 | | XYM = Ordinate::X | Ordinate::Y | Ordinate::M, |
42 | | XYZM = Ordinate::X | Ordinate::Y | Ordinate::Z | Ordinate::M |
43 | | }; |
44 | | |
45 | 5.69M | explicit OrdinateSet(Ordinates o) : m_value(o), m_changesAllowed(true) {} |
46 | | |
47 | | Ordinates m_value; |
48 | | bool m_changesAllowed; |
49 | | |
50 | | public: |
51 | | |
52 | 5.67M | static OrdinateSet createXY() { |
53 | 5.67M | return OrdinateSet(Ordinates::XY); |
54 | 5.67M | } |
55 | | |
56 | 0 | static OrdinateSet createXYZ() { |
57 | 0 | return OrdinateSet(Ordinates::XYZ); |
58 | 0 | } |
59 | | |
60 | 0 | static OrdinateSet createXYM() { |
61 | 0 | return OrdinateSet(Ordinates::XYM); |
62 | 0 | } |
63 | | |
64 | 15.6k | static OrdinateSet createXYZM() { |
65 | 15.6k | return OrdinateSet(Ordinates::XYZM); |
66 | 15.6k | } |
67 | | |
68 | 5.64M | void setZ(bool value) { |
69 | 5.64M | if (hasZ() != value) { |
70 | 34.6k | if (m_changesAllowed) { |
71 | 34.6k | m_value = static_cast<Ordinates>(static_cast<unsigned char>(m_value) ^ Ordinate::Z); |
72 | 34.6k | } else { |
73 | 0 | throw util::GEOSException("Cannot add additional ordinates."); |
74 | 0 | } |
75 | 34.6k | } |
76 | 5.64M | } |
77 | | |
78 | 5.66M | void setM(bool value) { |
79 | 5.66M | if (hasM() != value) { |
80 | 63.9k | if (m_changesAllowed){ |
81 | 63.9k | m_value = static_cast<Ordinates>(static_cast<unsigned char>(m_value) ^ Ordinate::M); |
82 | 63.9k | } else { |
83 | 0 | throw util::GEOSException("Cannot add additional ordinates."); |
84 | 0 | } |
85 | 63.9k | } |
86 | 5.66M | } |
87 | | |
88 | 70.8M | bool hasZ() const { |
89 | 70.8M | return static_cast<unsigned char>(m_value) & static_cast<unsigned char>(Ordinate::Z); |
90 | 70.8M | } |
91 | | |
92 | 70.9M | bool hasM() const { |
93 | 70.9M | return static_cast<unsigned char>(m_value) & static_cast<unsigned char>(Ordinate::M); |
94 | 70.9M | } |
95 | | |
96 | 5.68M | int size() const { |
97 | 5.68M | return 2 + hasZ() + hasM(); |
98 | 5.68M | } |
99 | | |
100 | 38.6M | bool changesAllowed() const { |
101 | 38.6M | return m_changesAllowed; |
102 | 38.6M | } |
103 | | |
104 | 17.3M | void setChangesAllowed(bool allowed) { |
105 | 17.3M | m_changesAllowed = allowed; |
106 | 17.3M | } |
107 | | |
108 | 1.90k | bool operator==(const OrdinateSet& other) const { |
109 | 1.90k | return this->m_value == other.m_value; |
110 | 1.90k | } |
111 | | |
112 | 1.90k | bool operator!=(const OrdinateSet& other) const { |
113 | 1.90k | return !(*this == other); |
114 | 1.90k | } |
115 | | |
116 | | }; |
117 | | |
118 | | } |
119 | | } |