Beispiel #1
0
/**
 * Recursively find children of the given tile that are already loaded.
 *
 * @param id The tile ID that we should find children for.
 * @param maxCoveringZoom The maximum zoom level of children to look for.
 * @param retain An object that we add the found tiles to.
 *
 * @return boolean Whether the children found completely cover the tile.
 */
bool Source::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::forward_list<Tile::ID>& retain) {
    bool complete = true;
    int32_t z = id.z;
    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) {
            retain.emplace_front(child_id);
        } else {
            complete = false;
            if (z < maxCoveringZoom) {
                // Go further down the hierarchy to find more unloaded children.
                findLoadedChildren(child_id, maxCoveringZoom, retain);
            }
        }
    }
    return complete;
}
Beispiel #2
0
std::forward_list<mbgl::Tile::ID> Source::covering_tiles(const TransformState &state, int32_t clamped_zoom, const box& points) {
    int32_t dim = std::pow(2, clamped_zoom);
    std::forward_list<mbgl::Tile::ID> tiles;
    bool is_raster = (info.type == SourceType::Raster);
    double search_zoom = getZoom(state);

    auto scanLine = [&tiles, clamped_zoom, is_raster, search_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++) {
                if (is_raster) {
                    Tile::ID id = Tile::ID(clamped_zoom, x, y);
                    auto ids = id.children(search_zoom);
                    for (const Tile::ID& child_id : ids) {
                        tiles.emplace_front(child_id.z, child_id.x, child_id.y);
                    }
                } else {
                    tiles.emplace_front(clamped_zoom, x, y);
                }
            }
        }
    };

    // Divide the screen up in two triangles and scan each of them:
    // \---+
    // | \ |
    // +---\.
    _scanTriangle(points.tl, points.tr, points.br, 0, dim, scanLine);
    _scanTriangle(points.br, points.bl, points.tl, 0, dim, scanLine);

    const vec2<double>& center = points.center;
    tiles.sort([&center](const Tile::ID& a, const Tile::ID& b) {
        // Sorts by distance from the box center
        return std::fabs(a.x - center.x) + std::fabs(a.y - center.y) <
        std::fabs(b.x - center.x) + std::fabs(b.y - center.y);
    });

    tiles.unique();

    return tiles;
}