NebulaGraph CPP Client  release-3.4
Geography.h
1 /* Copyright (c) 2020 vesoft inc. All rights reserved.
2  *
3  * This source code is licensed under Apache 2.0 License.
4  */
5 
6 #pragma once
7 
8 #include <string>
9 #include <variant>
10 #include <vector>
11 
12 #include "common/datatypes/Value.h"
13 
14 // Do not include <s2/s2polygon.h> here, it will indirectly includes a header file which defines a
15 // enum `BEGIN`(not enum class). While Geography.h is indirectly included by parser.yy, which has a
16 // macro named `BEGIN`. So they will be conflicted.
17 
18 class S2Polygon;
19 
20 namespace nebula {
21 
22 enum class GeoShape : uint32_t {
23  UNKNOWN = 0, // illegal
24  POINT = 1,
25  LINESTRING = 2,
26  POLYGON = 3,
27 };
28 
29 std::ostream& operator<<(std::ostream& os, const GeoShape& shape);
30 
31 // clang-format off
32 /*
33 static const std::unordered_map<GeoShape, S2Region> kShapeTypeToS2Region = {
34  // S2PointRegion is a wrapper of S2Point, and it inherits from the S2Region class while S2Point doesn't.
35  {GeoShape::POINT, S2PointRegion},
36  {GeoShape::LINESTRING, S2Polyline},
37  {GeoShape::POLYGON, S2Polygon},
38 };
39 */
40 // clang-format on
41 
42 struct Coordinate {
43  double x, y;
44 
45  Coordinate() = default;
46  Coordinate(double lng, double lat) : x(lng), y(lat) {}
47 
48  void clear() {
49  x = 0.0;
50  y = 0.0;
51  }
52  void __clear() {
53  clear();
54  }
55 
56  bool operator==(const Coordinate& rhs) const {
57  return std::abs(x - rhs.x) < kEpsilon && std::abs(y - rhs.y) < kEpsilon;
58  }
59  bool operator!=(const Coordinate& rhs) const {
60  return !(*this == rhs);
61  }
62  bool operator<(const Coordinate& rhs) const {
63  if (x != rhs.x) {
64  return x < rhs.x;
65  }
66  if (y != rhs.y) {
67  return y < rhs.y;
68  }
69  return false;
70  }
71 };
72 
73 struct Point {
74  Coordinate coord;
75 
76  Point() = default;
77  explicit Point(const Coordinate& v) : coord(v) {}
78  explicit Point(Coordinate&& v) : coord(std::move(v)) {}
79 
80  void clear() {
81  coord.clear();
82  }
83  void __clear() {
84  clear();
85  }
86 
87  bool operator==(const Point& rhs) const {
88  return coord == rhs.coord;
89  }
90  bool operator<(const Point& rhs) const {
91  return coord < rhs.coord;
92  }
93 };
94 
95 struct LineString {
96  std::vector<Coordinate> coordList;
97 
98  LineString() = default;
99  explicit LineString(const std::vector<Coordinate>& v) : coordList(v) {}
100  explicit LineString(std::vector<Coordinate>&& v) : coordList(std::move(v)) {}
101 
102  uint32_t numCoord() const {
103  return coordList.size();
104  }
105 
106  void clear() {
107  coordList.clear();
108  }
109  void __clear() {
110  clear();
111  }
112 
113  bool operator==(const LineString& rhs) const {
114  return coordList == rhs.coordList;
115  }
116  bool operator<(const LineString& rhs) const {
117  return coordList < rhs.coordList;
118  }
119 };
120 
121 struct Polygon {
122  std::vector<std::vector<Coordinate>> coordListList;
123 
124  Polygon() = default;
125  explicit Polygon(const std::vector<std::vector<Coordinate>>& v) : coordListList(v) {}
126  explicit Polygon(std::vector<std::vector<Coordinate>>&& v) : coordListList(std::move(v)) {}
127 
128  uint32_t numCoordList() const {
129  return coordListList.size();
130  }
131 
132  void clear() {
133  coordListList.clear();
134  }
135  void __clear() {
136  clear();
137  }
138 
139  bool operator==(const Polygon& rhs) const {
140  return coordListList == rhs.coordListList;
141  }
142  bool operator<(const Polygon& rhs) const {
143  return coordListList < rhs.coordListList;
144  }
145 };
146 
147 struct Geography {
148  std::variant<Point, LineString, Polygon> geo_;
149 
150  Geography() {}
151  Geography(const Point& v) : geo_(v) {} // NOLINT
152  Geography(Point&& v) : geo_(std::move(v)) {} // NOLINT
153  Geography(const LineString& v) : geo_(v) {} // NOLINT
154  Geography(LineString&& v) : geo_(std::move(v)) {} // NOLINT
155  Geography(const Polygon& v) : geo_(v) {} // NOLINT
156  Geography(Polygon&& v) : geo_(std::move(v)) {} // NOLINT
157 
158  GeoShape shape() const;
159 
160  const Point& point() const;
161  const LineString& lineString() const;
162  const Polygon& polygon() const;
163 
164  Point& mutablePoint();
165  LineString& mutableLineString();
166  Polygon& mutablePolygon();
167 
168  std::string asWKT() const;
169 
170  std::string asWKB() const;
171 
172  std::string toString() const {
173  return asWKT();
174  }
175 
176  void clear() {
177  geo_.~variant();
178  }
179 
180  void __clear() {
181  clear();
182  }
183 
184  bool operator==(const Geography& rhs) const;
185  bool operator<(const Geography& rhs) const;
186 };
187 
188 inline std::ostream& operator<<(std::ostream& os, const Geography& g) {
189  return os << g.toString();
190 }
191 
192 } // namespace nebula
193 
194 namespace std {
195 
196 // Inject a customized hash function
197 template <>
198 struct hash<nebula::Geography> {
199  std::size_t operator()(const nebula::Geography& h) const noexcept;
200 };
201 
202 } // namespace std