1#pragma once
2
3#include <mbgl/util/constants.hpp>
4
5#include <cstdint>
6#include <array>
7#include <tuple>
8#include <forward_list>
9#include <algorithm>
10#include <iosfwd>
11#include <cassert>
12
13namespace mbgl {
14
15class OverscaledTileID;
16class CanonicalTileID;
17class UnwrappedTileID;
18
19// Has integer z/x/y coordinates
20// All tiles must be derived from 0/0/0 (=no tiles outside of the main tile pyramid)
21// Used for requesting data; represents data tiles that exist out there.
22// z is never larger than the source's maxzoom
23class CanonicalTileID {
24public:
25 CanonicalTileID(uint8_t z, uint32_t x, uint32_t y);
26 bool operator==(const CanonicalTileID&) const;
27 bool operator!=(const CanonicalTileID&) const;
28 bool operator<(const CanonicalTileID&) const;
29 bool isChildOf(const CanonicalTileID&) const;
30 CanonicalTileID scaledTo(uint8_t z) const;
31 std::array<CanonicalTileID, 4> children() const;
32
33 uint8_t z;
34 uint32_t x;
35 uint32_t y;
36};
37
38::std::ostream& operator<<(::std::ostream& os, const CanonicalTileID& rhs);
39namespace util {
40std::string toString(const CanonicalTileID&);
41} // namespace util
42
43// Has integer z/x/y coordinates
44// overscaledZ describes the zoom level this tile is intented to represent, e.g. when parsing data
45// z is never larger than the source's maxzoom
46// z/x/y describe the
47class OverscaledTileID {
48public:
49 OverscaledTileID(uint8_t overscaledZ, int16_t wrap, CanonicalTileID);
50 OverscaledTileID(uint8_t overscaledZ, int16_t wrap, uint8_t z, uint32_t x, uint32_t y);
51 OverscaledTileID(uint8_t z, uint32_t x, uint32_t y);
52 explicit OverscaledTileID(const CanonicalTileID&);
53 explicit OverscaledTileID(CanonicalTileID&&);
54 bool operator==(const OverscaledTileID&) const;
55 bool operator!=(const OverscaledTileID&) const;
56 bool operator<(const OverscaledTileID&) const;
57 bool isChildOf(const OverscaledTileID&) const;
58 uint32_t overscaleFactor() const;
59 OverscaledTileID scaledTo(uint8_t z) const;
60 UnwrappedTileID toUnwrapped() const;
61 OverscaledTileID unwrapTo(int16_t wrap);
62
63 uint8_t overscaledZ;
64 int16_t wrap;
65 CanonicalTileID canonical;
66};
67
68::std::ostream& operator<<(::std::ostream& os, const OverscaledTileID& rhs);
69namespace util {
70std::string toString(const OverscaledTileID&);
71} // namespace util
72
73// Has integer z/x/y coordinates
74// wrap describes tiles that are left/right of the main tile pyramid, e.g. when wrapping the world
75// Used for describing what position tiles are getting rendered at (= calc the matrix)
76// z is never larger than the source's maxzoom
77class UnwrappedTileID {
78public:
79 UnwrappedTileID(uint8_t z, int64_t x, int64_t y);
80 UnwrappedTileID(int16_t wrap, CanonicalTileID);
81 bool operator==(const UnwrappedTileID&) const;
82 bool operator!=(const UnwrappedTileID&) const;
83 bool operator<(const UnwrappedTileID&) const;
84 bool isChildOf(const UnwrappedTileID&) const;
85 std::array<UnwrappedTileID, 4> children() const;
86 OverscaledTileID overscaleTo(uint8_t z) const;
87 float pixelsToTileUnits(float pixelValue, float zoom) const;
88 UnwrappedTileID unwrapTo(int16_t wrap);
89
90 int16_t wrap;
91 CanonicalTileID canonical;
92};
93
94::std::ostream& operator<<(::std::ostream& os, const UnwrappedTileID& rhs);
95namespace util {
96std::string toString(const UnwrappedTileID&);
97} // namespace util
98
99inline CanonicalTileID::CanonicalTileID(uint8_t z_, uint32_t x_, uint32_t y_) : z(z_), x(x_), y(y_) {
100 assert(z <= 32);
101 assert(x < (1ull << z));
102 assert(y < (1ull << z));
103}
104
105inline bool CanonicalTileID::operator==(const CanonicalTileID& rhs) const {
106 return z == rhs.z && x == rhs.x && y == rhs.y;
107}
108
109inline bool CanonicalTileID::operator!=(const CanonicalTileID& rhs) const {
110 return z != rhs.z || x != rhs.x || y != rhs.y;
111}
112
113inline bool CanonicalTileID::operator<(const CanonicalTileID& rhs) const {
114 return std::tie(args: z, args: x, args: y) < std::tie(args: rhs.z, args: rhs.x, args: rhs.y);
115}
116
117inline bool CanonicalTileID::isChildOf(const CanonicalTileID& parent) const {
118 // We're first testing for z == 0, to avoid a 32 bit shift, which is undefined.
119 return parent.z == 0 ||
120 (parent.z < z && parent.x == (x >> (z - parent.z)) && parent.y == (y >> (z - parent.z)));
121}
122
123inline CanonicalTileID CanonicalTileID::scaledTo(uint8_t targetZ) const {
124 if (targetZ <= z) {
125 return { targetZ, x >> (z - targetZ), y >> (z - targetZ) }; // parent or same
126 } else {
127 return { targetZ, x << (targetZ - z), y << (targetZ - z) }; // child
128 }
129}
130
131inline std::array<CanonicalTileID, 4> CanonicalTileID::children() const {
132 const uint8_t childZ = z + 1;
133 const uint32_t childX = x * 2;
134 const uint32_t childY = y * 2;
135 return { ._M_elems: {
136 { childZ, childX, childY },
137 { childZ, childX, childY + 1 },
138 { childZ, childX + 1, childY },
139 { childZ, childX + 1, childY + 1 },
140 } };
141}
142
143inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, int16_t wrap_, CanonicalTileID canonical_)
144 : overscaledZ(overscaledZ_), wrap(wrap_), canonical(std::move(canonical_)) {
145 assert(overscaledZ >= canonical.z);
146}
147
148inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, int16_t wrap_, uint8_t z, uint32_t x, uint32_t y)
149 : overscaledZ(overscaledZ_), wrap(wrap_), canonical(z, x, y) {
150 assert(overscaledZ >= canonical.z);
151}
152
153inline OverscaledTileID::OverscaledTileID(uint8_t z, uint32_t x, uint32_t y)
154 : overscaledZ(z), wrap(0), canonical(z, x, y) {
155}
156
157inline OverscaledTileID::OverscaledTileID(const CanonicalTileID& canonical_)
158 : overscaledZ(canonical_.z), wrap(0), canonical(canonical_) {
159 assert(overscaledZ >= canonical.z);
160}
161
162inline OverscaledTileID::OverscaledTileID(CanonicalTileID&& canonical_)
163 : overscaledZ(canonical_.z), wrap(0), canonical(std::forward<CanonicalTileID>(t&: canonical_)) {
164 assert(overscaledZ >= canonical.z);
165}
166
167inline bool OverscaledTileID::operator==(const OverscaledTileID& rhs) const {
168 return overscaledZ == rhs.overscaledZ && wrap == rhs.wrap &&canonical == rhs.canonical;
169}
170
171inline bool OverscaledTileID::operator!=(const OverscaledTileID& rhs) const {
172 return overscaledZ != rhs.overscaledZ || wrap != rhs.wrap || canonical != rhs.canonical;
173}
174
175inline bool OverscaledTileID::operator<(const OverscaledTileID& rhs) const {
176 return std::tie(args: overscaledZ, args: wrap, args: canonical) < std::tie(args: rhs.overscaledZ, args: rhs.wrap, args: rhs.canonical);
177}
178
179inline uint32_t OverscaledTileID::overscaleFactor() const {
180 return 1u << (overscaledZ - canonical.z);
181}
182
183inline bool OverscaledTileID::isChildOf(const OverscaledTileID& rhs) const {
184 return overscaledZ > rhs.overscaledZ &&
185 (canonical == rhs.canonical || canonical.isChildOf(parent: rhs.canonical));
186}
187
188inline OverscaledTileID OverscaledTileID::scaledTo(uint8_t z) const {
189 return { z, wrap, z >= canonical.z ? canonical : canonical.scaledTo(targetZ: z) };
190}
191
192inline UnwrappedTileID OverscaledTileID::toUnwrapped() const {
193 return { wrap, canonical };
194}
195
196inline OverscaledTileID OverscaledTileID::unwrapTo(int16_t newWrap) {
197 return { overscaledZ, newWrap, canonical };
198}
199
200inline UnwrappedTileID::UnwrappedTileID(uint8_t z_, int64_t x_, int64_t y_)
201 : wrap((x_ < 0 ? x_ - (1ll << z_) + 1 : x_) / (1ll << z_)),
202 canonical(
203 z_,
204 static_cast<uint32_t>(x_ - wrap * (1ll << z_)),
205 y_ < 0 ? 0 : std::min(a: static_cast<uint32_t>(y_), b: static_cast<uint32_t>(1ull << z_) - 1)) {
206}
207
208inline UnwrappedTileID::UnwrappedTileID(int16_t wrap_, CanonicalTileID canonical_)
209 : wrap(wrap_), canonical(std::move(canonical_)) {
210}
211
212inline bool UnwrappedTileID::operator==(const UnwrappedTileID& rhs) const {
213 return wrap == rhs.wrap && canonical == rhs.canonical;
214}
215
216inline bool UnwrappedTileID::operator!=(const UnwrappedTileID& rhs) const {
217 return wrap != rhs.wrap || canonical != rhs.canonical;
218}
219
220inline bool UnwrappedTileID::operator<(const UnwrappedTileID& rhs) const {
221 return std::tie(args: wrap, args: canonical) < std::tie(args: rhs.wrap, args: rhs.canonical);
222}
223
224inline UnwrappedTileID UnwrappedTileID::unwrapTo(int16_t newWrap) {
225 return { newWrap, canonical };
226}
227
228inline bool UnwrappedTileID::isChildOf(const UnwrappedTileID& parent) const {
229 return wrap == parent.wrap && canonical.isChildOf(parent: parent.canonical);
230}
231
232inline std::array<UnwrappedTileID, 4> UnwrappedTileID::children() const {
233 const uint8_t childZ = canonical.z + 1;
234 const uint32_t childX = canonical.x * 2;
235 const uint32_t childY = canonical.y * 2;
236 return { ._M_elems: {
237 { wrap, { childZ, childX, childY } },
238 { wrap, { childZ, childX, childY + 1 } },
239 { wrap, { childZ, childX + 1, childY } },
240 { wrap, { childZ, childX + 1, childY + 1 } },
241 } };
242}
243
244inline OverscaledTileID UnwrappedTileID::overscaleTo(const uint8_t overscaledZ) const {
245 assert(overscaledZ >= canonical.z);
246 return { overscaledZ, wrap, canonical };
247}
248
249inline float UnwrappedTileID::pixelsToTileUnits(const float pixelValue, const float zoom) const {
250 return pixelValue * (util::EXTENT / (util::tileSize * std::pow(x: 2, y: zoom - canonical.z)));
251}
252
253} // namespace mbgl
254
255namespace std {
256
257template <>
258struct hash<mbgl::CanonicalTileID> {
259 size_t operator()(const mbgl::CanonicalTileID& id) const;
260};
261
262template <>
263struct hash<mbgl::UnwrappedTileID> {
264 size_t operator()(const mbgl::UnwrappedTileID& id) const;
265};
266
267template <>
268struct hash<mbgl::OverscaledTileID> {
269 size_t operator()(const mbgl::OverscaledTileID& id) const;
270};
271
272} // namespace std
273
274

source code of qtlocation/src/3rdparty/mapbox-gl-native/include/mbgl/tile/tile_id.hpp