#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { Source::Source(SourceInfo& info_) : info(info_) { } // Note: This is a separate function that must be called exactly once after creation // The reason this isn't part of the constructor is that calling shared_from_this() in // the constructor fails. void Source::load(Map &map, Environment &env) { if (info.url.empty()) { loaded = true; return; } util::ptr source = shared_from_this(); const std::string url = util::mapbox::normalizeSourceURL(info.url, map.getAccessToken()); env.request({ Resource::Kind::JSON, url }, [source, &map](const Response &res) { if (res.status != Response::Successful) { Log::Warning(Event::General, "Failed to load source TileJSON: %s", res.message.c_str()); return; } rapidjson::Document d; d.Parse<0>(res.data.c_str()); if (d.HasParseError()) { Log::Warning(Event::General, "Invalid source TileJSON; Parse Error at %d: %s", d.GetErrorOffset(), d.GetParseError()); return; } source->info.parseTileJSONProperties(d); source->loaded = true; map.triggerUpdate(); }); } void Source::updateClipIDs(const std::map &mapping) { std::for_each(tiles.begin(), tiles.end(), [&mapping](std::pair> &pair) { Tile &tile = *pair.second; auto it = mapping.find(tile.id); if (it != mapping.end()) { tile.clip = it->second; } else { tile.clip = ClipID {}; } }); } void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) { for (std::pair> &pair : tiles) { Tile &tile = *pair.second; transform.matrixFor(tile.matrix, tile.id); matrix::multiply(tile.matrix, projMatrix, tile.matrix); } } size_t Source::getTileCount() const { return tiles.size(); } void Source::drawClippingMasks(Painter &painter) { for (std::pair> &pair : tiles) { Tile &tile = *pair.second; gl::group group(std::string { "mask: " } + std::string(tile.id)); painter.drawClippingMask(tile.matrix, tile.clip); } } void Source::render(Painter &painter, const StyleLayer &layer_desc) { gl::group group(std::string { "layer: " } + layer_desc.id); for (const std::pair> &pair : tiles) { Tile &tile = *pair.second; if (tile.data && tile.data->state == TileData::State::parsed) { painter.renderTileLayer(tile, layer_desc, tile.matrix); } } } void Source::render(Painter &painter, const StyleLayer &layer_desc, const Tile::ID &id, const mat4 &matrix) { auto it = tiles.find(id); if (it != tiles.end() && it->second->data && it->second->data->state == TileData::State::parsed) { painter.renderTileLayer(*it->second, layer_desc, matrix); } } void Source::finishRender(Painter &painter) { for (std::pair> &pair : tiles) { Tile &tile = *pair.second; painter.renderTileDebug(tile); } } std::forward_list Source::getIDs() const { std::forward_list ptrs; std::transform(tiles.begin(), tiles.end(), std::front_inserter(ptrs), [](const std::pair> &pair) { Tile &tile = *pair.second; return tile.id; }); return ptrs; } std::forward_list Source::getLoadedTiles() const { std::forward_list ptrs; auto it = ptrs.before_begin(); for (const auto &pair : tiles) { if (pair.second->data->ready()) { it = ptrs.insert_after(it, pair.second.get()); } } return ptrs; } TileData::State Source::hasTile(const Tile::ID& id) { auto it = tiles.find(id); if (it != tiles.end()) { Tile &tile = *it->second; if (tile.id == id && tile.data) { return tile.data->state; } } return TileData::State::invalid; } TileData::State Source::addTile(Map &map, Environment &env, uv::worker &worker, util::ptr