10#include "kosm_export.h"
13#include "stringpool.h"
40 explicit constexpr Coordinate(
double lat,
double lon)
41 : latitude((lat + 90.0) * 10'000'000)
42 , longitude((lon + 180.0) * 10'000'000)
44 explicit constexpr Coordinate(uint32_t lat, uint32_t lon)
54 for (
int i = 0; i < 32; ++i) {
55 latitude += (
z & (1ull << (i * 2))) >> i;
56 longitude += (
z & (1ull << (1 + i * 2))) >> (i + 1);
60 [[nodiscard]]
constexpr inline bool isValid()
const
62 return latitude != std::numeric_limits<uint32_t>::max() && longitude != std::numeric_limits<uint32_t>::max();
64 [[nodiscard]]
constexpr inline bool operator==(
Coordinate other)
const
70 [[nodiscard]]
constexpr inline uint64_t
z()
const
73 for (
int i = 0; i < 32; ++i) {
74 z += ((uint64_t)latitude & (1 << i)) << i;
75 z += ((uint64_t)longitude & (1 << i)) << (i + 1);
80 [[nodiscard]]
constexpr inline double latF()
const
82 return (latitude / 10'000'000.0) - 90.0;
84 [[nodiscard]]
constexpr inline double lonF()
const
86 return (longitude / 10'000'000.0) - 180.0;
89 uint32_t latitude = std::numeric_limits<uint32_t>::max();
90 uint32_t longitude = std::numeric_limits<uint32_t>::max();
102 [[nodiscard]]
constexpr inline bool isValid()
const
104 return min.isValid() && max.isValid();
106 [[nodiscard]]
constexpr inline bool operator==(
BoundingBox other)
const
108 return min == other.min && max == other.max;
111 [[nodiscard]]
constexpr inline uint32_t width()
const
113 return max.longitude - min.longitude;
115 [[nodiscard]]
constexpr inline uint32_t height()
const
117 return max.latitude - min.latitude;
120 [[nodiscard]]
constexpr inline double widthF()
const
122 return width() / 10'000'000.0;
124 [[nodiscard]]
constexpr inline double heightF()
const
126 return height() / 10'000'000.0;
129 [[nodiscard]]
constexpr inline Coordinate center()
const
131 return Coordinate(min.latitude + height() / 2, min.longitude + width() / 2);
140 if (!bbox1.isValid()) {
143 if (!bbox2.isValid()) {
147 ret.min.latitude = std::min(bbox1.min.latitude, bbox2.min.latitude);
148 ret.min.longitude = std::min(bbox1.min.longitude, bbox2.min.longitude);
149 ret.max.latitude = std::max(bbox1.max.latitude, bbox2.max.latitude);
150 ret.max.longitude = std::max(bbox1.max.longitude, bbox2.max.longitude);
154[[nodiscard]]
constexpr inline bool intersects(BoundingBox bbox1, BoundingBox bbox2)
156 return !(bbox2.min.latitude > bbox1.max.latitude || bbox2.max.latitude < bbox1.min.latitude
157 || bbox2.min.longitude > bbox1.max.longitude || bbox2.max.longitude < bbox1.min.longitude);
160[[nodiscard]]
constexpr inline bool contains(BoundingBox bbox,
Coordinate coord)
162 return bbox.min.latitude <= coord.
latitude && bbox.max.latitude >= coord.
latitude
166[[nodiscard]]
constexpr inline uint32_t latitudeDistance(BoundingBox bbox1, BoundingBox bbox2)
168 return bbox1.max.latitude < bbox2.min.latitude ? bbox2.min.latitude - bbox1.max.latitude : bbox1.min.latitude - bbox2.max.latitude;
171[[nodiscard]]
constexpr inline uint32_t longitudeDifference(BoundingBox bbox1, BoundingBox bbox2)
173 return bbox1.max.longitude < bbox2.min.longitude ? bbox2.min.longitude - bbox1.max.longitude : bbox1.min.longitude - bbox2.max.longitude;
187 , value(std::move(_value))
189 Tag(
const Tag&) =
default;
191 Tag& operator=(
const Tag &other) =
default;
192 Tag& operator=(
Tag &&other)
noexcept =
default;
194 [[nodiscard]]
inline constexpr bool operator<(
const Tag &other)
const {
return key < other.key; }
200[[nodiscard]]
inline constexpr bool operator<(
const Tag &lhs,
TagKey rhs) {
return lhs.key < rhs; }
201[[nodiscard]]
inline constexpr bool operator<(TagKey lhs,
const Tag &rhs) {
return lhs < rhs.key; }
206 explicit Node() =
default;
210 *
this = std::move(other);
212 Node& operator=(
const Node &other) =
default;
213 Node& operator=(
Node &&other)
noexcept
216 coordinate = other.coordinate;
217 std::swap(tags, other.tags);
221 [[nodiscard]]
constexpr inline bool operator<(
const Node &other)
const {
return id < other.id; }
223 [[nodiscard]]
QString url()
const;
227 std::vector<Tag> tags;
233 explicit Way() =
default;
234 Way(
const Way&) =
default;
237 *
this = std::move(other);
239 Way& operator=(
const Way &other) =
default;
240 Way& operator=(
Way &&other)
noexcept
244 std::swap(nodes, other.nodes);
245 std::swap(tags, other.tags);
249 constexpr inline bool operator<(
const Way &other)
const {
return id < other.id; }
251 bool isClosed()
const;
257 std::vector<Id> nodes;
258 std::vector<Tag> tags;
270[[nodiscard]] KOSM_EXPORT
const char*
typeName(Type type);
278 constexpr inline Role() =
default;
281 explicit constexpr inline Role(
const char *keyData) :
StringKey(keyData) {}
287 [[nodiscard]]
inline bool operator==(
const Member &other)
const {
return id == other.id && m_roleAndType == other.m_roleAndType; }
291 [[nodiscard]]
constexpr inline Role role()
const
293 return Role(m_roleAndType.get());
295 constexpr inline void setRole(
Role role)
297 m_roleAndType.set(role.name());
300 [[nodiscard]]
constexpr inline Type type()
const
302 return static_cast<Type>(m_roleAndType.tag());
304 constexpr inline void setType(
Type type)
306 m_roleAndType.setTag(
static_cast<uint8_t
>(type));
320 *
this = std::move(other);
327 std::swap(members, other.members);
328 std::swap(tags, other.tags);
332 [[nodiscard]]
constexpr inline bool operator<(
const Relation &other)
const {
return id < other.id; }
334 [[nodiscard]]
QString url()
const;
338 std::vector<Member> members;
339 std::vector<Tag> tags;
356 [[nodiscard]]
const Node* node(
Id id)
const;
361 [[nodiscard]]
const Way* way(
Id id)
const;
362 [[nodiscard]]
Way* way(
Id id);
367 [[nodiscard]]
const Relation* relation(
Id id)
const;
369 void addNode(
Node &&node);
370 void addWay(
Way &&way);
377 [[nodiscard]]
TagKey tagKey(
const char *keyName)
const;
385 [[nodiscard]]
TagKey makeTagKey(
const char *keyName, StringMemory keyMemOpt = StringMemory::Transient);
390 [[nodiscard]]
Role role(
const char *roleName)
const;
394 [[nodiscard]]
Role makeRole(
const char *roleName, StringMemory memOpt = StringMemory::Transient);
397 [[nodiscard]]
Id nextInternalId()
const;
399 std::vector<Node> nodes;
400 std::vector<Way> ways;
401 std::vector<Relation> relations;
405 const std::vector<Node> *transientNodes =
nullptr;
408 template <
typename T> T stringKey(
const char *name,
const std::vector<T> ®istry)
const;
409 template <
typename T> T makeStringKey(
const char *name, StringMemory memOpt, std::vector<T> ®istry);
416template <
typename Elem>
419 const auto it = std::lower_bound(elem.tags.begin(), elem.tags.end(), key);
420 if (it != elem.tags.end() && (*it).key == key) {
430template <
typename Elem>
433 const auto it = std::find_if(elem.tags.begin(), elem.tags.end(), [keyName](
const auto &tag) { return std::strcmp(tag.key.name(), keyName) == 0; });
434 if (it != elem.tags.end()) {
443template <
typename Elem>
446 const auto keyLen = std::strlen(keyName);
447 for (
const auto &lang : languages.languages) {
448 for (
const auto &tag : elem.tags) {
449 if (std::strlen(tag.key.name()) != keyLen + lang.size() + 1) {
452 if (std::strncmp(tag.key.name(), keyName, keyLen) == 0 && tag.key.name()[keyLen] ==
':'
453 && std::strncmp(tag.key.name() + keyLen + 1, lang.c_str(), lang.size()) == 0) {
460 const auto v =
tagValue(elem, keyName);
466 const auto it = std::find_if(elem.tags.begin(), elem.tags.end(), [keyName, keyLen](
const auto &tag) {
467 return std::strlen(tag.key.name()) == keyLen + 3
468 && std::strncmp(tag.key.name(), keyName, keyLen) == 0
469 && tag.key.name()[keyLen] ==
':';
471 if (it != elem.tags.end()) {
478template <
typename Elem>
481 const auto it = std::lower_bound(elem.tags.begin(), elem.tags.end(), tag);
482 if (it == elem.tags.end() || (*it).key != tag.key) {
483 elem.tags.insert(it, std::move(tag));
485 (*it) = std::move(tag);
490template <
typename Elem>
493 setTag(elem,
Tag(key, std::move(value)));
497template <
typename Elem>
500 const auto it = std::lower_bound(elem.tags.begin(), elem.tags.end(), key);
501 if (it != elem.tags.end() && (*it).key == key) {
506template <
typename Elem>
507[[nodiscard]]
inline bool operator<(
const Elem &elem,
Id id)
Coordinate, stored as 1e7 * degree to avoid floating point precision issues, and offset to unsigned v...
constexpr uint64_t z() const
Z-order curve value for this coordinate.
constexpr Coordinate(uint64_t z)
Create a coordinate from a z-order curve index.
A set of nodes, ways and relations.
Pointer with the lower bits used for compact flag storage.
Languages in preference order to consider when looking up translated tag values.
A relation role name key.
Registry of unique string keys.
Base class for unique string keys.
KTEXTEDITOR_EXPORT QDebug operator<<(QDebug s, const MovingCursor &cursor)
Low-level types and functions to work with raw OSM data as efficiently as possible.
void setTagValue(Elem &elem, TagKey key, QByteArray &&value)
Inserts a new tag, or updates an existing one.
void setTag(Elem &elem, Tag &&tag)
Inserts a new tag, or replaces an existing one with the same key.
int64_t Id
OSM element identifier.
QByteArray tagValue(const Elem &elem, TagKey key)
Returns the tag value for key of elem.
KOSM_EXPORT const char * typeName(Type type)
Element type name.
void removeTag(Elem &elem, TagKey key)
Removes a tag from the given element.