/** * 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; }
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([¢er](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; }