use a custom struct for Tile IDs
This commit is contained in:
@@ -2,11 +2,12 @@
|
||||
#define LLMR_MAP_COVERAGE
|
||||
|
||||
#include <llmr/util/vec.hpp>
|
||||
#include <llmr/map/tile.hpp>
|
||||
#include <forward_list>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
std::forward_list<vec3<int32_t>> covering_tiles(int32_t zoom, const box& points);
|
||||
std::forward_list<Tile::ID> covering_tiles(int32_t zoom, const box& points);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,16 +14,32 @@ class TileData;
|
||||
|
||||
class Tile : private util::noncopyable {
|
||||
public:
|
||||
typedef vec3<int32_t> 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<ID> 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<ID> children(const ID& id, int32_t z);
|
||||
|
||||
|
||||
public:
|
||||
const Tile::ID id;
|
||||
uint8_t clip_id;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <llmr/util/mat4.hpp>
|
||||
#include <llmr/util/animation.hpp>
|
||||
#include <llmr/util/noncopyable.hpp>
|
||||
#include <llmr/map/tile.hpp>
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
void setLonLatZoom(double lon, double lat, double zoom, double duration = 0);
|
||||
|
||||
// Getters
|
||||
void matrixFor(mat4& matrix, const vec3<int32_t>& id) const;
|
||||
void matrixFor(mat4& matrix, const Tile::ID& id) const;
|
||||
float getZoom() const;
|
||||
int32_t getIntegerZoom() const;
|
||||
double getScale() const;
|
||||
|
||||
@@ -64,15 +64,15 @@ void _scanTriangle(const llmr::vec2<double> a, const llmr::vec2<double> b, const
|
||||
if (bc.dy) _scanSpans(ca, bc, ymin, ymax, scanLine);
|
||||
}
|
||||
|
||||
std::forward_list<llmr::vec3<int32_t>> llmr::covering_tiles(int32_t zoom, const box& points) {
|
||||
std::forward_list<llmr::Tile::ID> llmr::covering_tiles(int32_t zoom, const box& points) {
|
||||
int32_t dim = pow(2, zoom);
|
||||
std::forward_list<vec3<int32_t>> tiles;
|
||||
std::forward_list<llmr::Tile::ID> 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::vec3<int32_t>> llmr::covering_tiles(int32_t zoom, const
|
||||
_scanTriangle(points.br, points.bl, points.tl, 0, dim, scanLine);
|
||||
|
||||
const vec2<double>& center = points.center;
|
||||
tiles.sort([¢er](const vec3<int32_t>& a, const vec3<int32_t>& 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);
|
||||
|
||||
@@ -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<TileData>& 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<Tile::ID>& 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);
|
||||
|
||||
@@ -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::ID> 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> Tile::ID::children(int32_t child_z) const {
|
||||
assert(child_z > z);
|
||||
int32_t factor = pow(2, child_z - z);
|
||||
|
||||
std::forward_list<ID> 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;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ double Transform::pixel_y() const {
|
||||
return center + y;
|
||||
}
|
||||
|
||||
void Transform::matrixFor(mat4& matrix, const vec3<int32_t>& 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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user