GEOS  3.14.0dev
OrdinateSet.h
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 
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  explicit OrdinateSet(Ordinates o) : m_value(o), m_changesAllowed(true) {}
46 
47  Ordinates m_value;
48  bool m_changesAllowed;
49 
50 public:
51 
52  static OrdinateSet createXY() {
53  return OrdinateSet(Ordinates::XY);
54  }
55 
56  static OrdinateSet createXYZ() {
57  return OrdinateSet(Ordinates::XYZ);
58  }
59 
60  static OrdinateSet createXYM() {
61  return OrdinateSet(Ordinates::XYM);
62  }
63 
64  static OrdinateSet createXYZM() {
65  return OrdinateSet(Ordinates::XYZM);
66  }
67 
68  void setZ(bool value) {
69  if (hasZ() != value) {
70  if (m_changesAllowed) {
71  m_value = static_cast<Ordinates>(static_cast<unsigned char>(m_value) ^ Ordinate::Z);
72  } else {
73  throw util::GEOSException("Cannot add additional ordinates.");
74  }
75  }
76  }
77 
78  void setM(bool value) {
79  if (hasM() != value) {
80  if (m_changesAllowed){
81  m_value = static_cast<Ordinates>(static_cast<unsigned char>(m_value) ^ Ordinate::M);
82  } else {
83  throw util::GEOSException("Cannot add additional ordinates.");
84  }
85  }
86  }
87 
88  bool hasZ() const {
89  return static_cast<unsigned char>(m_value) & static_cast<unsigned char>(Ordinate::Z);
90  }
91 
92  bool hasM() const {
93  return static_cast<unsigned char>(m_value) & static_cast<unsigned char>(Ordinate::M);
94  }
95 
96  int size() const {
97  return 2 + hasZ() + hasM();
98  }
99 
100  bool changesAllowed() const {
101  return m_changesAllowed;
102  }
103 
104  void setChangesAllowed(bool allowed) {
105  m_changesAllowed = allowed;
106  }
107 
108  bool operator==(const OrdinateSet& other) const {
109  return this->m_value == other.m_value;
110  }
111 
112  bool operator!=(const OrdinateSet& other) const {
113  return !(*this == other);
114  }
115 
116 };
117 
118 }
119 }
Utility class to manipulate a set of flags indicating whether X, Y, Z, or M dimensions are present....
Definition: OrdinateSet.h:29
Base class for all GEOS exceptions.
Definition: GEOSException.h:37
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25