Libosmium  2.7.1
Fast and flexible C++ library for working with OpenStreetMap data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
location.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_OSM_LOCATION_HPP
2 #define OSMIUM_OSM_LOCATION_HPP
3 
4 /*
5 
6 This file is part of Osmium (http://osmcode.org/libosmium).
7 
8 Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
9 
10 Boost Software License - Version 1.0 - August 17th, 2003
11 
12 Permission is hereby granted, free of charge, to any person or organization
13 obtaining a copy of the software and accompanying documentation covered by
14 this license (the "Software") to use, reproduce, display, distribute,
15 execute, and transmit the Software, and to prepare derivative works of the
16 Software, and to permit third-parties to whom the Software is furnished to
17 do so, all subject to the following:
18 
19 The copyright notices in the Software and this entire statement, including
20 the above license grant, this restriction and the following disclaimer,
21 must be included in all copies of the Software, in whole or in part, and
22 all derivative works of the Software, unless such copies or derivative
23 works are solely in the form of machine-executable object code generated by
24 a source language processor.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 DEALINGS IN THE SOFTWARE.
33 
34 */
35 
36 #include <cmath>
37 #include <cstdint>
38 #include <functional>
39 #include <iosfwd>
40 #include <stdexcept>
41 #include <string>
42 
43 #include <iostream>
44 
46 #include <osmium/util/double.hpp>
47 
48 namespace osmium {
49 
54  struct invalid_location : public std::range_error {
55 
56  explicit invalid_location(const std::string& what) :
57  std::range_error(what) {
58  }
59 
60  explicit invalid_location(const char* what) :
61  std::range_error(what) {
62  }
63 
64  }; // struct invalid_location
65 
80  class Location {
81 
82  int32_t m_x;
83  int32_t m_y;
84 
85  public:
86 
87  // this value is used for a coordinate to mark it as undefined
88  // MSVC doesn't declare std::numeric_limits<int32_t>::max() as
89  // constexpr, so we hard code this for the time being.
90  // static constexpr int32_t undefined_coordinate = std::numeric_limits<int32_t>::max();
91  static constexpr int32_t undefined_coordinate = 2147483647;
92 
93  static constexpr int coordinate_precision = 10000000;
94 
95  static int32_t double_to_fix(const double c) noexcept {
96  return static_cast<int32_t>(std::round(c * coordinate_precision));
97  }
98 
99  static constexpr double fix_to_double(const int32_t c) noexcept {
100  return static_cast<double>(c) / coordinate_precision;
101  }
102 
106  explicit constexpr Location() noexcept :
107  m_x(undefined_coordinate),
108  m_y(undefined_coordinate) {
109  }
110 
116  constexpr Location(const int32_t x, const int32_t y) noexcept :
117  m_x(x),
118  m_y(y) {
119  }
120 
126  constexpr Location(const int64_t x, const int64_t y) noexcept :
127  m_x(static_cast<int32_t>(x)),
128  m_y(static_cast<int32_t>(y)) {
129  }
130 
134  Location(const double lon, const double lat) :
135  m_x(double_to_fix(lon)),
136  m_y(double_to_fix(lat)) {
137  }
138 
139  Location(const Location&) = default;
140  Location(Location&&) = default;
141  Location& operator=(const Location&) = default;
142  Location& operator=(Location&&) = default;
143  ~Location() = default;
144 
149  explicit constexpr operator bool() const noexcept {
150  return m_x != undefined_coordinate && m_y != undefined_coordinate;
151  }
152 
157  constexpr bool valid() const noexcept {
158  return m_x >= -180 * coordinate_precision
159  && m_x <= 180 * coordinate_precision
160  && m_y >= -90 * coordinate_precision
161  && m_y <= 90 * coordinate_precision;
162  }
163 
164  constexpr int32_t x() const noexcept {
165  return m_x;
166  }
167 
168  constexpr int32_t y() const noexcept {
169  return m_y;
170  }
171 
172  Location& set_x(const int32_t x) noexcept {
173  m_x = x;
174  return *this;
175  }
176 
177  Location& set_y(const int32_t y) noexcept {
178  m_y = y;
179  return *this;
180  }
181 
187  double lon() const {
188  if (!valid()) {
189  throw osmium::invalid_location("invalid location");
190  }
191  return fix_to_double(m_x);
192  }
193 
197  double lon_without_check() const {
198  return fix_to_double(m_x);
199  }
200 
206  double lat() const {
207  if (!valid()) {
208  throw osmium::invalid_location("invalid location");
209  }
210  return fix_to_double(m_y);
211  }
212 
216  double lat_without_check() const {
217  return fix_to_double(m_y);
218  }
219 
220  Location& set_lon(double lon) noexcept {
221  m_x = double_to_fix(lon);
222  return *this;
223  }
224 
225  Location& set_lat(double lat) noexcept {
226  m_y = double_to_fix(lat);
227  return *this;
228  }
229 
230  template <typename T>
231  T as_string(T iterator, const char separator) const {
232  iterator = osmium::util::double2string(iterator, lon(), 7);
233  *iterator++ = separator;
234  return osmium::util::double2string(iterator, lat(), 7);
235  }
236 
237  }; // class Location
238 
242  inline constexpr bool operator==(const Location& lhs, const Location& rhs) noexcept {
243  return lhs.x() == rhs.x() && lhs.y() == rhs.y();
244  }
245 
246  inline constexpr bool operator!=(const Location& lhs, const Location& rhs) noexcept {
247  return ! (lhs == rhs);
248  }
249 
255  inline constexpr bool operator<(const Location& lhs, const Location& rhs) noexcept {
256  return (lhs.x() == rhs.x() && lhs.y() < rhs.y()) || lhs.x() < rhs.x();
257  }
258 
259  inline constexpr bool operator>(const Location& lhs, const Location& rhs) noexcept {
260  return rhs < lhs;
261  }
262 
263  inline constexpr bool operator<=(const Location& lhs, const Location& rhs) noexcept {
264  return ! (rhs < lhs);
265  }
266 
267  inline constexpr bool operator>=(const Location& lhs, const Location& rhs) noexcept {
268  return ! (lhs < rhs);
269  }
270 
274  template <typename TChar, typename TTraits>
275  inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const osmium::Location& location) {
276  if (location) {
277  out << '(';
278  location.as_string(std::ostream_iterator<char>(out), ',');
279  out << ')';
280  } else {
281  out << "(undefined,undefined)";
282  }
283  return out;
284  }
285 
286  namespace detail {
287 
288  template <int N>
289  inline size_t hash(const osmium::Location& location) noexcept {
290  return location.x() ^ location.y();
291  }
292 
293  template <>
294  inline size_t hash<8>(const osmium::Location& location) noexcept {
295  size_t h = location.x();
296  h <<= 32;
297  return h ^ location.y();
298  }
299 
300  } // namespace detail
301 
302 } // namespace osmium
303 
304 namespace std {
305 
306 // This pragma is a workaround for a bug in an old libc implementation
307 #ifdef __clang__
308 #pragma clang diagnostic push
309 #pragma clang diagnostic ignored "-Wmismatched-tags"
310 #endif
311  template <>
312  struct hash<osmium::Location> {
314  using result_type = size_t;
315  size_t operator()(const osmium::Location& location) const noexcept {
316  return osmium::detail::hash<sizeof(size_t)>(location);
317  }
318  };
319 #ifdef __clang__
320 #pragma clang diagnostic pop
321 #endif
322 
323 } // namespace std
324 
325 #endif // OSMIUM_OSM_LOCATION_HPP
double lat_without_check() const
Definition: location.hpp:216
static int32_t double_to_fix(const double c) noexcept
Definition: location.hpp:95
Location & operator=(const Location &)=default
bool operator<=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:446
~Location()=default
constexpr bool operator==(const Box &lhs, const Box &rhs) noexcept
Definition: box.hpp:222
Location & set_lon(double lon) noexcept
Definition: location.hpp:220
Definition: reader_iterator.hpp:39
constexpr Location(const int64_t x, const int64_t y) noexcept
Definition: location.hpp:126
constexpr Location(const int32_t x, const int32_t y) noexcept
Definition: location.hpp:116
T double2string(T iterator, double value, int precision)
Definition: double.hpp:59
constexpr bool valid() const noexcept
Definition: location.hpp:157
double lat() const
Definition: location.hpp:206
size_t operator()(const osmium::Location &location) const noexcept
Definition: location.hpp:315
static constexpr int coordinate_precision
Definition: location.hpp:93
bool operator<(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:438
double lon_without_check() const
Definition: location.hpp:197
Namespace for everything in the Osmium library.
Definition: assembler.hpp:66
Definition: attr.hpp:298
Definition: location.hpp:54
int32_t m_y
Definition: location.hpp:83
constexpr int32_t y() const noexcept
Definition: location.hpp:168
invalid_location(const std::string &what)
Definition: location.hpp:56
T as_string(T iterator, const char separator) const
Definition: location.hpp:231
Location & set_lat(double lat) noexcept
Definition: location.hpp:225
Location & set_y(const int32_t y) noexcept
Definition: location.hpp:177
Definition: location.hpp:80
int32_t m_x
Definition: location.hpp:82
Location & set_x(const int32_t x) noexcept
Definition: location.hpp:172
bool operator>=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:450
double lon() const
Definition: location.hpp:187
bool operator>(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:442
invalid_location(const char *what)
Definition: location.hpp:60
static constexpr int32_t undefined_coordinate
Definition: location.hpp:91
constexpr int32_t x() const noexcept
Definition: location.hpp:164
static constexpr double fix_to_double(const int32_t c) noexcept
Definition: location.hpp:99
Location(const double lon, const double lat)
Definition: location.hpp:134
bool operator!=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:431
size_t result_type
Definition: location.hpp:314
constexpr Location() noexcept
Definition: location.hpp:106