Skip to content

Commit ab77656

Browse files
committed
New quadkey_t class to capture the quad key concept
Use it in expire code.
1 parent 2ef3f38 commit ab77656

4 files changed

Lines changed: 72 additions & 28 deletions

File tree

src/expire-tiles.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ int expire_tiles::from_result(pg_result_t const &result, osmid_t osm_id)
249249
return num_tuples;
250250
}
251251

252-
std::vector<uint64_t> expire_tiles::get_tiles()
252+
quadkey_list_t expire_tiles::get_tiles()
253253
{
254-
std::vector<uint64_t> tiles;
254+
quadkey_list_t tiles;
255255
tiles.reserve(m_dirty_tiles.size());
256256
tiles.assign(m_dirty_tiles.begin(), m_dirty_tiles.end());
257257
std::sort(tiles.begin(), tiles.end());
@@ -276,7 +276,7 @@ void expire_tiles::merge_and_destroy(expire_tiles *other)
276276
}
277277
}
278278

279-
std::size_t output_tiles_to_file(std::vector<uint64_t> const &tiles_maxzoom,
279+
std::size_t output_tiles_to_file(quadkey_list_t const &tiles_maxzoom,
280280
char const *filename, uint32_t minzoom,
281281
uint32_t maxzoom)
282282
{

src/expire-tiles.hpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class expire_tiles
5252
* Get tiles as a vector of quadkeys and remove them from the expire_tiles
5353
* object.
5454
*/
55-
std::vector<uint64_t> get_tiles();
55+
quadkey_list_t get_tiles();
5656

5757
/**
5858
* Merge the list of expired tiles in the other object into this
@@ -80,7 +80,7 @@ class expire_tiles
8080
void from_point_list(geom::point_list_t const &list);
8181

8282
/// This is where we collect all the expired tiles.
83-
std::unordered_set<uint64_t> m_dirty_tiles;
83+
std::unordered_set<quadkey_t> m_dirty_tiles;
8484

8585
/// The tile which has been added last to the unordered set.
8686
tile_t m_prev_tile;
@@ -104,7 +104,7 @@ class expire_tiles
104104
* \param output Output function
105105
*/
106106
template <class OUTPUT>
107-
std::size_t for_each_tile(std::vector<uint64_t> const &tiles, uint32_t minzoom,
107+
std::size_t for_each_tile(quadkey_list_t const &tiles, uint32_t minzoom,
108108
uint32_t maxzoom, OUTPUT &&output)
109109
{
110110
assert(minzoom <= maxzoom);
@@ -119,30 +119,24 @@ std::size_t for_each_tile(std::vector<uint64_t> const &tiles, uint32_t minzoom,
119119

120120
/**
121121
* Loop over all requested zoom levels (from maximum down to the minimum
122-
* zoom level). Tile IDs of the tiles enclosing this tile at lower zoom
123-
* levels are calculated using bit shifts.
124-
*
125-
* last_quadkey is initialized with a value which is not expected to exist
126-
* (larger than largest possible quadkey).
122+
* zoom level).
127123
*/
128-
uint64_t last_quadkey = 1ULL << (2 * maxzoom);
124+
quadkey_t last_quadkey{};
129125
std::size_t count = 0;
130126
for (auto const quadkey : tiles) {
131127
for (uint32_t dz = 0; dz <= maxzoom - minzoom; ++dz) {
132-
// scale down to the current zoom level
133-
uint64_t const qt_current = quadkey >> (dz * 2);
128+
auto const qt_current = quadkey.down(dz);
134129
/**
135130
* If dz > 0, there are probably multiple elements whose quadkey
136131
* is equal because they are all sub-tiles of the same tile at the
137132
* current zoom level. We skip all of them after we have written
138133
* the first sibling.
139134
*/
140-
if (qt_current == last_quadkey >> (dz * 2)) {
141-
continue;
135+
if (qt_current != last_quadkey.down(dz)) {
136+
std::forward<OUTPUT>(output)(
137+
tile_t::from_quadkey(qt_current, maxzoom - dz));
138+
++count;
142139
}
143-
auto const tile = tile_t::from_quadkey(qt_current, maxzoom - dz);
144-
std::forward<OUTPUT>(output)(tile);
145-
++count;
146140
}
147141
last_quadkey = quadkey;
148142
}
@@ -157,7 +151,7 @@ std::size_t for_each_tile(std::vector<uint64_t> const &tiles, uint32_t minzoom,
157151
* \param minzoom Minimum zoom level
158152
* \param maxzoom Maximum zoom level
159153
*/
160-
std::size_t output_tiles_to_file(std::vector<uint64_t> const &tiles,
154+
std::size_t output_tiles_to_file(quadkey_list_t const &tiles,
161155
char const *filename, uint32_t minzoom,
162156
uint32_t maxzoom);
163157

src/tile.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ static uint32_t deinterleave_lowuint32(uint64_t word) noexcept
5353
return static_cast<uint32_t>(word);
5454
}
5555

56-
uint64_t tile_t::quadkey() const noexcept
56+
quadkey_t tile_t::quadkey() const noexcept
5757
{
58-
return interleave_uint32_with_zeros(m_x) |
59-
(interleave_uint32_with_zeros(m_y) << 1U);
58+
return {interleave_uint32_with_zeros(m_x) |
59+
(interleave_uint32_with_zeros(m_y) << 1U)};
6060
}
6161

62-
tile_t tile_t::from_quadkey(uint64_t quadkey, uint32_t zoom) noexcept
62+
tile_t tile_t::from_quadkey(quadkey_t quadkey, uint32_t zoom) noexcept
6363
{
64-
return {zoom, deinterleave_lowuint32(quadkey),
65-
deinterleave_lowuint32(quadkey >> 1U)};
64+
return {zoom, deinterleave_lowuint32(quadkey.value()),
65+
deinterleave_lowuint32(quadkey.value() >> 1U)};
6666
}

src/tile.hpp

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,56 @@
1515
#include <cstdint>
1616
#include <limits>
1717

18+
class quadkey_t
19+
{
20+
public:
21+
quadkey_t() noexcept = default;
22+
23+
quadkey_t(uint64_t value) noexcept : m_value(value) {}
24+
25+
uint64_t value() const noexcept { return m_value; }
26+
27+
/**
28+
* Calculate quad key with the given number of zoom levels down from the
29+
* zoom level of this quad key.
30+
*/
31+
quadkey_t down(uint32_t levels) const noexcept
32+
{
33+
quadkey_t qk;
34+
qk.m_value = m_value >> (levels * 2);
35+
return qk;
36+
}
37+
38+
friend bool operator==(quadkey_t a, quadkey_t b) noexcept
39+
{
40+
return a.m_value == b.m_value;
41+
}
42+
43+
friend bool operator!=(quadkey_t a, quadkey_t b) noexcept
44+
{
45+
return !(a == b);
46+
}
47+
48+
friend bool operator<(quadkey_t a, quadkey_t b) noexcept
49+
{
50+
return a.value() < b.value();
51+
}
52+
53+
private:
54+
uint64_t m_value = std::numeric_limits<uint64_t>::max();
55+
}; // class quadkey_t
56+
57+
template <>
58+
struct std::hash<quadkey_t>
59+
{
60+
std::size_t operator()(quadkey_t quadkey) const noexcept
61+
{
62+
return quadkey.value();
63+
}
64+
};
65+
66+
using quadkey_list_t = std::vector<quadkey_t>;
67+
1868
/**
1969
* A tile in the usual web tile format.
2070
*/
@@ -148,12 +198,12 @@ class tile_t
148198
* bits from the x and y values, similar to what's used for Bing maps:
149199
* https://docs.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system
150200
*/
151-
uint64_t quadkey() const noexcept;
201+
quadkey_t quadkey() const noexcept;
152202

153203
/**
154204
* Construct tile from quadkey.
155205
*/
156-
static tile_t from_quadkey(uint64_t quadkey, uint32_t zoom) noexcept;
206+
static tile_t from_quadkey(quadkey_t quadkey, uint32_t zoom) noexcept;
157207

158208
private:
159209
static constexpr uint32_t const invalid_zoom =

0 commit comments

Comments
 (0)