diff --git a/include/llmr/map/coverage.hpp b/include/llmr/map/coverage.hpp index 0d50cd9f7..c889ce701 100644 --- a/include/llmr/map/coverage.hpp +++ b/include/llmr/map/coverage.hpp @@ -2,11 +2,12 @@ #define LLMR_MAP_COVERAGE #include +#include #include namespace llmr { -std::forward_list> covering_tiles(int32_t zoom, const box& points); +std::forward_list covering_tiles(int32_t zoom, const box& points); } diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp index 922940d74..2ae1a64fe 100644 --- a/include/llmr/map/tile.hpp +++ b/include/llmr/map/tile.hpp @@ -14,16 +14,32 @@ class TileData; class Tile : private util::noncopyable { public: - typedef vec3 ID; + struct ID { + int8_t z = 0; + int32_t x = 0, y = 0; + + inline ID(uint8_t z, uint32_t x, uint32_t y) + : z(z), x(x), y(y) { + } + + inline operator uint64_t() const { + uint32_t dim = 1 << z; + return ((dim * y + x) * 32) + z; + } + + inline bool operator==(const ID& rhs) const { + return z == rhs.z && x == rhs.x && y == rhs.y; + } + + ID parent(int32_t z) const; + void normalize(); + ID normalized() const; + std::forward_list children(int32_t z) const; + }; public: Tile(const ID& id); - static ID parent(const ID& id, int32_t z); - static ID normalize(const ID& id); - static std::forward_list children(const ID& id, int32_t z); - - public: const Tile::ID id; uint8_t clip_id; diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index 4a07c98f9..a6dde2b4f 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -34,7 +35,7 @@ public: void setLonLatZoom(double lon, double lat, double zoom, double duration = 0); // Getters - void matrixFor(mat4& matrix, const vec3& id) const; + void matrixFor(mat4& matrix, const Tile::ID& id) const; float getZoom() const; int32_t getIntegerZoom() const; double getScale() const; diff --git a/src/map/coverage.cpp b/src/map/coverage.cpp index d1ead268e..c040811b5 100644 --- a/src/map/coverage.cpp +++ b/src/map/coverage.cpp @@ -64,15 +64,15 @@ void _scanTriangle(const llmr::vec2 a, const llmr::vec2 b, const if (bc.dy) _scanSpans(ca, bc, ymin, ymax, scanLine); } -std::forward_list> llmr::covering_tiles(int32_t zoom, const box& points) { +std::forward_list llmr::covering_tiles(int32_t zoom, const box& points) { int32_t dim = pow(2, zoom); - std::forward_list> tiles; + std::forward_list tiles; auto scanLine = [&tiles, zoom](int32_t x0, int32_t x1, int32_t y, int32_t ymax) { int32_t x; if (y >= 0 && y <= ymax) { for (x = x0; x < x1; x++) { - tiles.emplace_front(x, y, zoom); + tiles.emplace_front(zoom, x, y); } } }; @@ -85,7 +85,7 @@ std::forward_list> llmr::covering_tiles(int32_t zoom, const _scanTriangle(points.br, points.bl, points.tl, 0, dim, scanLine); const vec2& center = points.center; - tiles.sort([¢er](const vec3& a, const vec3& b) { + tiles.sort([¢er](const Tile::ID& a, const Tile::ID& b) { // Sorts by distance from the box center return fabs(a.x - center.x) + fabs(a.y - center.y) < fabs(b.x - center.x) + fabs(b.y - center.y); diff --git a/src/map/map.cpp b/src/map/map.cpp index 5e13727f2..06aea39a3 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -260,7 +260,7 @@ TileData::State Map::addTile(const Tile::ID& id) { // We couldn't find the tile in the list. Create a new one. // Try to find the associated TileData object. - const Tile::ID normalized_id = Tile::normalize(id); + const Tile::ID normalized_id = id.normalized(); auto it = std::find_if(tile_data.begin(), tile_data.end(), [&normalized_id](const std::weak_ptr& tile_data) { return !tile_data.expired() && tile_data.lock()->id == normalized_id; @@ -299,7 +299,8 @@ bool Map::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::f bool complete = true; int32_t z = id.z; - auto ids = Tile::children(id, z + 1); + + auto ids = id.children(z + 1); for (const Tile::ID& child_id : ids) { const TileData::State state = hasTile(child_id); if (state == TileData::State::parsed) { @@ -326,7 +327,7 @@ bool Map::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::f */ bool Map::findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list& retain) { for (int32_t z = id.z - 1; z >= minCoveringZoom; --z) { - const Tile::ID parent_id = Tile::parent(id, z); + const Tile::ID parent_id = id.parent(z); const TileData::State state = hasTile(parent_id); if (state == TileData::State::parsed) { retain.emplace_front(parent_id); diff --git a/src/map/tile.cpp b/src/map/tile.cpp index e7ee1a393..163aa60af 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -8,10 +8,10 @@ Tile::Tile(const ID& id) : id(id) { } -Tile::ID Tile::parent(const ID& id, int32_t z) { - assert(z < id.z); - ID pos(id); - while (pos.z > z) { +Tile::ID Tile::ID::parent(int32_t parent_z) const { + assert(parent_z < z); + ID pos(z, x, y); + while (pos.z > parent_z) { --pos.z; pos.x = floor(pos.x / 2); pos.y = floor(pos.y / 2); @@ -19,25 +19,27 @@ Tile::ID Tile::parent(const ID& id, int32_t z) { return pos; } - -std::forward_list Tile::children(const ID& id, int32_t z) { - assert(z > id.z); - int32_t factor = pow(2, z - id.z); +std::forward_list Tile::ID::children(int32_t child_z) const { + assert(child_z > z); + int32_t factor = pow(2, child_z - z); std::forward_list children; - for (int32_t y = id.y * factor, y_max = (id.y + 1) * factor; y < y_max; ++y) { - for (int32_t x = id.x * factor, x_max = (id.x + 1) * factor; x < x_max; ++x) { - children.emplace_front(x, y, z); + for (int32_t ty = y * factor, y_max = (y + 1) * factor; ty < y_max; ++ty) { + for (int32_t tx = x * factor, x_max = (x + 1) * factor; tx < x_max; ++tx) { + children.emplace_front(child_z, tx, ty); } } return children; } +void Tile::ID::normalize() { + int32_t dim = pow(2, z); + while (x < 0) x += dim; + while (x >= dim) x -= dim; +} -Tile::ID Tile::normalize(const ID& id) { - ID pos(id); - int32_t dim = pow(2, id.z); - while (pos.x < 0) pos.x += dim; - while (pos.x >= dim) pos.x -= dim; +Tile::ID Tile::ID::normalized() const { + ID pos(z, x, y); + pos.normalize(); return pos; } diff --git a/src/map/transform.cpp b/src/map/transform.cpp index 01f175729..8cb580ea4 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -235,7 +235,7 @@ double Transform::pixel_y() const { return center + y; } -void Transform::matrixFor(mat4& matrix, const vec3& id) const { +void Transform::matrixFor(mat4& matrix, const Tile::ID& id) const { const double tile_scale = pow(2, id.z); const double tile_size = scale * util::tileSize / tile_scale;