summaryrefslogtreecommitdiff
path: root/src/mbgl/map/tile_id.cpp
blob: ad7ec2e0f6623f5c2dfd5c2a5c0c026434cf9a2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <mbgl/map/tile_id.hpp>
#include <mbgl/util/string.hpp>

#include <cassert>

namespace mbgl {

TileID TileID::parent(int8_t parent_z, int8_t sourceMaxZoom) const {
    assert(parent_z < z);
    auto newX = x;
    auto newY = y;
    for (auto newZ = z; newZ > parent_z; newZ--) {
        if (newZ > sourceMaxZoom) {
            // the id represents an overscaled tile, return the same coordinates with a lower z
            // do nothing
        } else {
            newX = newX / 2;
            newY = newY / 2;
        }
    }

    return TileID{parent_z, newX, newY, parent_z > sourceMaxZoom ? sourceMaxZoom : parent_z};
}

std::forward_list<TileID> TileID::children(int8_t sourceMaxZoom) const {
    auto childZ = z + 1;

    std::forward_list<TileID> child_ids;
    if (z >= sourceMaxZoom) {
        // return a single tile id representing a an overscaled tile
        child_ids.emplace_front(childZ, x, y, sourceMaxZoom);

    } else {
        auto childX = x * 2;
        auto childY = y * 2;
        child_ids.emplace_front(childZ, childX, childY, childZ);
        child_ids.emplace_front(childZ, childX + 1, childY, childZ);
        child_ids.emplace_front(childZ, childX, childY + 1, childZ);
        child_ids.emplace_front(childZ, childX + 1, childY + 1, childZ);
    }

    return child_ids;
}

TileID TileID::normalized() const {
    int32_t dim = std::pow(2, sourceZ);
    int32_t nx = x, ny = y;
    while (nx < 0) nx += dim;
    while (nx >= dim) nx -= dim;
    return TileID { z, nx, ny, sourceZ};
}

bool TileID::isChildOf(const TileID &parent_id) const {
    if (parent_id.z >= z || parent_id.w != w) {
        return false;
    }
    int32_t scale = std::pow(2, z - parent_id.z);
    return parent_id.x == ((x < 0 ? x - scale + 1 : x) / scale) &&
           parent_id.y == y / scale;
}

TileID::operator std::string() const {
    return util::toString(z) + "/" + util::toString(x) + "/" + util::toString(y);
}

}