1#ifndef OSMIUM_OSM_LOCATION_HPP
2#define OSMIUM_OSM_LOCATION_HPP
57 std::range_error(what) {
61 std::range_error(what) {
69 coordinate_precision = 10000000
74 inline int32_t string_to_location_coordinate(
const char** data) {
75 const char* str = *data;
76 const char* full = str;
95 if (*str >=
'0' && *str <=
'9') {
99 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
103 while (*str >=
'0' && *str <=
'9' && max_digits > 0) {
104 result = result * 10 + (*str -
'0');
109 if (max_digits == 0) {
110 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
115 if (*(str + 1) <
'0' || *(str + 1) >
'9') {
116 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
125 for (; scale > 0 && *str >=
'0' && *str <=
'9'; --scale, ++str) {
126 result = result * 10 + (*str -
'0');
131 while (*str >=
'0' && *str <=
'9' && max_digits > 0) {
136 if (max_digits == 0) {
137 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
142 if (*str ==
'e' || *str ==
'E') {
155 if (*str >=
'0' && *str <=
'9') {
156 eresult = *str -
'0';
159 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
164 while (*str >=
'0' && *str <=
'9' && max_digits > 0) {
165 eresult = eresult * 10 + (*str -
'0');
170 if (max_digits == 0) {
171 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
174 scale += eresult * esign;
178 for (; scale < 0 && result > 0; ++scale) {
182 for (; scale > 0; --scale) {
187 result = (result + 5) / 10 * sign;
189 if (result > std::numeric_limits<int32_t>::max() ||
190 result < std::numeric_limits<int32_t>::min()) {
191 throw invalid_location{std::string{
"wrong format for coordinate: '"} + full +
"'"};
195 return static_cast<int32_t
>(result);
199 template <
typename T>
200 inline T append_location_coordinate_to_string(T iterator, int32_t value) {
202 if (value == std::numeric_limits<int32_t>::min()) {
203 static const char minresult[] =
"-214.7483648";
204 return std::copy_n(minresult,
sizeof(minresult) - 1, iterator);
218 *t++ =
static_cast<char>(v % 10) +
'0';
222 while (t - temp < 7) {
227 if (value >= coordinate_precision) {
228 if (value >= 10 * coordinate_precision) {
229 if (value >= 100 * coordinate_precision) {
240 const char* tn = temp;
241 while (tn < t && *tn ==
'0') {
285 return static_cast<double>(detail::coordinate_precision);
288#ifdef OSMIUM_LOCATION_WITH_EXTRA_BIT
295 mask_b30 = 1UL << 30UL
302 auto const value =
static_cast<uint32_t
>(v);
303 auto const n30 = value & ~mask_b30;
304 auto const b30 = (value >> 1UL) & mask_b30;
305 return static_cast<int32_t
>(n30 | b30);
324 return static_cast<int32_t
>(std::round(c *
precision()));
328 return static_cast<double>(c) /
precision();
344 constexpr Location(
const int32_t
x,
const int32_t
y) noexcept :
354 constexpr Location(
const int64_t
x,
const int64_t
y) noexcept :
355 m_x(
static_cast<int32_t
>(
x)),
375 explicit constexpr operator bool() const noexcept {
385 constexpr bool valid() const noexcept {
410 constexpr int32_t
x() const noexcept {
414 constexpr int32_t
y() const noexcept {
480 const char** data = &str;
481 const auto value = detail::string_to_location_coordinate(data);
482 if (**data !=
'\0') {
483 throw invalid_location{std::string{
"characters after coordinate: '"} + *data +
"'"};
489 const char** data = &str;
490 const auto value = detail::string_to_location_coordinate(data);
491 if (**data !=
'\0') {
492 throw invalid_location{std::string{
"characters after coordinate: '"} + *data +
"'"};
498 return set_x(detail::string_to_location_coordinate(str));
502 return set_y(detail::string_to_location_coordinate(str));
505 template <
typename T>
507 iterator = detail::append_location_coordinate_to_string(iterator,
x());
508 *iterator++ = separator;
509 return detail::append_location_coordinate_to_string(iterator,
y());
512 template <
typename T>
513 T
as_string(T iterator,
const char separator =
',')
const {
520#ifdef OSMIUM_LOCATION_WITH_EXTRA_BIT
524 constexpr bool get_extra_bit() const noexcept {
527 auto const b =
static_cast<uint32_t
>(
m_y);
528 auto const b31 = b >> 31UL;
529 auto const b30 = (b >> 30UL) & 1UL;
538 constexpr void set_extra_bit() noexcept {
541 auto const b =
static_cast<uint32_t
>(
m_y);
542 auto const n30 = b & ~mask_b30;
543 auto const b30 = (~b >> 1UL) & mask_b30;
544 m_y =
static_cast<int32_t
>(n30 | b30);
552 constexpr void set_extra_bit(
bool value)
noexcept {
555 auto const b =
static_cast<uint32_t
>(
m_y);
556 auto const n30 = b & ~mask_b30;
557 auto const b30 = ((b >> 31UL) ^ value) << 30UL;
558 m_y =
static_cast<int32_t
>(n30 | b30);
566 constexpr void clear_extra_bit() noexcept {
577 constexpr void toggle_extra_bit() noexcept {
580 auto const b =
static_cast<uint32_t
>(
m_y);
581 auto const n30 = b & ~mask_b30;
582 auto const b30 = ~b & mask_b30;
583 m_y =
static_cast<int32_t
>(n30 | b30);
593 return lhs.x() == rhs.x() && lhs.y() == rhs.y();
597 return !(lhs == rhs);
606 return (lhs.x() == rhs.x() && lhs.y() < rhs.y()) || lhs.x() < rhs.x();
624 template <
typename TChar,
typename TTraits>
625 inline std::basic_ostream<TChar, TTraits>&
operator<<(std::basic_ostream<TChar, TTraits>& out,
const osmium::Location& location) {
628 location.
as_string(std::ostream_iterator<char>(out),
',');
631 out <<
"(undefined,undefined)";
640 return static_cast<uint32_t
>(location.
x()) ^
static_cast<uint32_t
>(location.
y());
645 uint64_t h = location.
x();
647 return static_cast<size_t>(h ^
static_cast<uint64_t
>(location.
y()));
658#pragma clang diagnostic push
659#pragma clang diagnostic ignored "-Wmismatched-tags"
666 return osmium::detail::hash<sizeof(size_t)>(location);
670#pragma clang diagnostic pop
Definition location.hpp:279
double lon_without_check() const noexcept
Definition location.hpp:448
int32_t m_x
Definition location.hpp:281
constexpr Location(const int32_t x, const int32_t y) noexcept
Definition location.hpp:344
constexpr bool is_defined() const noexcept
Definition location.hpp:397
double lon() const
Definition location.hpp:438
static constexpr double fix_to_double(const int32_t c) noexcept
Definition location.hpp:327
int32_t m_y
Definition location.hpp:282
Location & set_lat(const char *str)
Definition location.hpp:488
Location(const double lon, const double lat)
Definition location.hpp:363
Location & set_y(const int32_t y) noexcept
Definition location.hpp:428
T as_string_without_check(T iterator, const char separator=',') const
Definition location.hpp:506
constexpr bool is_undefined() const noexcept
Definition location.hpp:406
static int32_t double_to_fix(const double c) noexcept
Definition location.hpp:323
Location & set_x(const int32_t x) noexcept
Definition location.hpp:418
Location & set_lon(double lon) noexcept
Definition location.hpp:471
static constexpr int32_t remove_extra_bit(int32_t v) noexcept
Definition location.hpp:308
constexpr int32_t x() const noexcept
Definition location.hpp:410
constexpr bool valid() const noexcept
Definition location.hpp:385
constexpr Location() noexcept
Definition location.hpp:334
@ undefined_coordinate
Definition location.hpp:320
Location & set_lat_partial(const char **str)
Definition location.hpp:501
T as_string(T iterator, const char separator=',') const
Definition location.hpp:513
Location & set_lon(const char *str)
Definition location.hpp:479
constexpr Location(const int64_t x, const int64_t y) noexcept
Definition location.hpp:354
static constexpr double precision() noexcept
Definition location.hpp:284
double lat_without_check() const noexcept
Definition location.hpp:467
double lat() const
Definition location.hpp:457
Location & set_lat(double lat) noexcept
Definition location.hpp:475
constexpr int32_t y() const noexcept
Definition location.hpp:414
Location & set_lon_partial(const char **str)
Definition location.hpp:497
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:654
Definition location.hpp:54
invalid_location(const char *what)
Definition location.hpp:60
invalid_location(const std::string &what)
Definition location.hpp:56
size_t result_type
Definition location.hpp:664
size_t operator()(const osmium::Location &location) const noexcept
Definition location.hpp:665