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