1#ifndef OSMIUM_OSM_LOCATION_HPP
2#define OSMIUM_OSM_LOCATION_HPP
56 std::range_error(what) {
60 std::range_error(what) {
68 coordinate_precision = 10000000
73 inline int32_t string_to_location_coordinate(
const char** data) {
74 const char* str = *data;
75 const char* full = str;
94 if (*str >=
'0' && *str <=
'9') {
98 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
102 while (*str >=
'0' && *str <= '9' && max_digits > 0) {
103 result = result * 10 + (*str -
'0');
108 if (max_digits == 0) {
109 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
114 if (*(str + 1) <
'0' || *(str + 1) >
'9') {
115 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
124 for (; scale > 0 && *str >=
'0' && *str <=
'9'; --scale, ++str) {
125 result = result * 10 + (*str -
'0');
130 while (*str >=
'0' && *str <= '9' && max_digits > 0) {
135 if (max_digits == 0) {
136 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
141 if (*str ==
'e' || *str ==
'E') {
154 if (*str >=
'0' && *str <=
'9') {
155 eresult = *str -
'0';
158 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
163 while (*str >=
'0' && *str <= '9' && max_digits > 0) {
164 eresult = eresult * 10 + (*str -
'0');
169 if (max_digits == 0) {
170 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
173 scale += eresult * esign;
177 for (; scale < 0 && result > 0; ++scale) {
181 for (; scale > 0; --scale) {
186 result = (result + 5) / 10 * sign;
188 if (result > std::numeric_limits<int32_t>::max() ||
189 result < std::numeric_limits<int32_t>::min()) {
190 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
194 return static_cast<int32_t
>(result);
198 template <
typename T>
199 inline T append_location_coordinate_to_string(T iterator, int32_t value) {
201 if (value == std::numeric_limits<int32_t>::min()) {
202 static const char minresult[] =
"-214.7483648";
203 return std::copy_n(minresult,
sizeof(minresult) - 1, iterator);
217 *t++ =
static_cast<char>(v % 10) +
'0';
221 while (t - temp < 7) {
226 if (value >= coordinate_precision) {
227 if (value >= 10 * coordinate_precision) {
228 if (value >= 100 * coordinate_precision) {
239 const char* tn = temp;
240 while (tn < t && *tn ==
'0') {
277 return static_cast<double>(detail::coordinate_precision);
291 return static_cast<int32_t
>(std::round(c *
precision()));
295 return static_cast<double>(c) /
precision();
311 constexpr Location(
const int32_t
x,
const int32_t
y) noexcept :
321 constexpr Location(
const int64_t
x,
const int64_t
y) noexcept :
322 m_x(
static_cast<int32_t
>(
x)),
323 m_y(
static_cast<int32_t
>(
y)) {
342 explicit constexpr operator bool() const noexcept {
352 constexpr bool valid() const noexcept {
377 constexpr int32_t
x() const noexcept {
381 constexpr int32_t
y() const noexcept {
444 const char** data = &str;
445 const auto value = detail::string_to_location_coordinate(data);
446 if (**data !=
'\0') {
447 throw invalid_location{std::string{
"characters after coordinate: '"} + *data +
"'"};
454 const char** data = &str;
455 const auto value = detail::string_to_location_coordinate(data);
456 if (**data !=
'\0') {
457 throw invalid_location{std::string{
"characters after coordinate: '"} + *data +
"'"};
464 m_x = detail::string_to_location_coordinate(str);
469 m_y = detail::string_to_location_coordinate(str);
473 template <
typename T>
475 iterator = detail::append_location_coordinate_to_string(iterator,
x());
476 *iterator++ = separator;
477 return detail::append_location_coordinate_to_string(iterator,
y());
480 template <
typename T>
481 T
as_string(T iterator,
const char separator =
',')
const {
494 return lhs.x() == rhs.x() && lhs.y() == rhs.y();
498 return !(lhs == rhs);
507 return (lhs.x() == rhs.x() && lhs.y() < rhs.y()) || lhs.x() < rhs.x();
525 template <
typename TChar,
typename TTraits>
526 inline std::basic_ostream<TChar, TTraits>&
operator<<(std::basic_ostream<TChar, TTraits>& out,
const osmium::Location& location) {
529 location.
as_string(std::ostream_iterator<char>(out),
',');
532 out <<
"(undefined,undefined)";
541 return static_cast<uint32_t
>(location.
x()) ^
static_cast<uint32_t
>(location.
y());
546 uint64_t h = location.
x();
548 return static_cast<size_t>(h ^
static_cast<uint64_t
>(location.
y()));
559#pragma clang diagnostic push
560#pragma clang diagnostic ignored "-Wmismatched-tags"
567 return osmium::detail::hash<sizeof(size_t)>(location);
571#pragma clang diagnostic pop
Definition: location.hpp:271
double lon_without_check() const noexcept
Definition: location.hpp:410
int32_t m_x
Definition: location.hpp:273
constexpr Location(const int32_t x, const int32_t y) noexcept
Definition: location.hpp:311
constexpr bool is_defined() const noexcept
Definition: location.hpp:364
double lon() const
Definition: location.hpp:400
static constexpr double fix_to_double(const int32_t c) noexcept
Definition: location.hpp:294
int32_t m_y
Definition: location.hpp:274
Location & set_lat(const char *str)
Definition: location.hpp:453
Location(const double lon, const double lat)
Definition: location.hpp:330
Location & set_y(const int32_t y) noexcept
Definition: location.hpp:390
T as_string_without_check(T iterator, const char separator=',') const
Definition: location.hpp:474
constexpr bool is_undefined() const noexcept
Definition: location.hpp:373
static int32_t double_to_fix(const double c) noexcept
Definition: location.hpp:290
Location & set_x(const int32_t x) noexcept
Definition: location.hpp:385
Location & set_lon(double lon) noexcept
Definition: location.hpp:433
constexpr int32_t x() const noexcept
Definition: location.hpp:377
constexpr bool valid() const noexcept
Definition: location.hpp:352
constexpr Location() noexcept
Definition: location.hpp:301
@ undefined_coordinate
Definition: location.hpp:287
Location & set_lat_partial(const char **str)
Definition: location.hpp:468
T as_string(T iterator, const char separator=',') const
Definition: location.hpp:481
Location & set_lon(const char *str)
Definition: location.hpp:443
constexpr Location(const int64_t x, const int64_t y) noexcept
Definition: location.hpp:321
static constexpr double precision() noexcept
Definition: location.hpp:276
double lat_without_check() const noexcept
Definition: location.hpp:429
double lat() const
Definition: location.hpp:419
Location & set_lat(double lat) noexcept
Definition: location.hpp:438
constexpr int32_t y() const noexcept
Definition: location.hpp:381
Location & set_lon_partial(const char **str)
Definition: location.hpp:463
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
bool operator==(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:440
bool operator<=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:459
bool operator>(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:455
bool operator>=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:463
bool operator!=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:444
std::basic_ostream< TChar, TTraits > & operator<<(std::basic_ostream< TChar, TTraits > &out, const item_type item_type)
Definition: item_type.hpp:187
bool operator<(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:451
Definition: location.hpp:555
Definition: location.hpp:53
invalid_location(const char *what)
Definition: location.hpp:59
invalid_location(const std::string &what)
Definition: location.hpp:55
size_t result_type
Definition: location.hpp:565
size_t operator()(const osmium::Location &location) const noexcept
Definition: location.hpp:566