From 9c768bb2c0e031b3716218a32874d048e22a9e53 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 22 Nov 2018 18:01:40 +0200 Subject: [offline] Support style-optimized tiles for offline regions --- bin/offline.cpp | 6 +++++ include/mbgl/storage/default_file_source.hpp | 5 ++++ include/mbgl/storage/offline.hpp | 10 +++++++- platform/default/default_file_source.cpp | 10 ++++++++ platform/default/mbgl/storage/offline_download.cpp | 29 +++++++++++++++++----- platform/default/mbgl/storage/offline_download.hpp | 4 ++- 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/bin/offline.cpp b/bin/offline.cpp index 0d0fe57281..1417ff9f09 100644 --- a/bin/offline.cpp +++ b/bin/offline.cpp @@ -101,6 +101,7 @@ int main(int argc, char *argv[]) { args::ValueFlag minZoomValue(argumentParser, "number", "Min zoom level", {"minZoom"}); args::ValueFlag maxZoomValue(argumentParser, "number", "Max zoom level", {"maxZoom"}); args::ValueFlag pixelRatioValue(argumentParser, "number", "Pixel ratio", {"pixelRatio"}); + args::ValueFlag styleOptimizedTilesValue(argumentParser, "boolean", "Style optimized tiles", { "style-optimized-tiles" }); try { argumentParser.ParseCLI(argc, argv); @@ -128,6 +129,7 @@ int main(int argc, char *argv[]) { const double maxZoom = maxZoomValue ? args::get(maxZoomValue) : 15.0; const double pixelRatio = pixelRatioValue ? args::get(pixelRatioValue) : 1.0; const std::string output = outputValue ? args::get(outputValue) : "offline.db"; + const bool styleOptimizedTiles = styleOptimizedTilesValue ? args::get(styleOptimizedTilesValue) : false; using namespace mbgl; @@ -250,6 +252,9 @@ int main(int argc, char *argv[]) { std::signal(SIGINT, [] (int) { stop(); }); + const auto options = styleOptimizedTiles ? OfflineRegionDownloadOptions::StyleOptimizedTiles + : OfflineRegionDownloadOptions::DefaultOptions; + fileSource.createOfflineRegion(definition, metadata, [&] (mbgl::expected region_) { if (!region_) { std::cerr << "Error creating region: " << util::toString(region_.error()) << std::endl; @@ -259,6 +264,7 @@ int main(int argc, char *argv[]) { assert(region_); region = std::make_unique(std::move(*region_)); fileSource.setOfflineRegionObserver(*region, std::make_unique(*region, fileSource, loop, mergePath)); + fileSource.setOfflineRegionDownloadOptions(*region, options); fileSource.setOfflineRegionDownloadState(*region, OfflineRegionDownloadState::Active); } }); diff --git a/include/mbgl/storage/default_file_source.hpp b/include/mbgl/storage/default_file_source.hpp index 6ce7e8c6f9..b4c318bb1c 100644 --- a/include/mbgl/storage/default_file_source.hpp +++ b/include/mbgl/storage/default_file_source.hpp @@ -84,6 +84,11 @@ public: */ void setOfflineRegionObserver(OfflineRegion&, std::unique_ptr); + /* + * Provides additional hints when dowloading offline regions. + */ + void setOfflineRegionDownloadOptions(OfflineRegion&, OfflineRegionDownloadOptions); + /* * Pause or resume downloading of regional resources. */ diff --git a/include/mbgl/storage/offline.hpp b/include/mbgl/storage/offline.hpp index b4e40cb5f3..0e971f6d36 100644 --- a/include/mbgl/storage/offline.hpp +++ b/include/mbgl/storage/offline.hpp @@ -91,11 +91,19 @@ using OfflineRegionMetadata = std::vector; * is currently available for offline use. To check if that is the case, use * `OfflineRegionStatus::complete()`. */ -enum class OfflineRegionDownloadState { +enum class OfflineRegionDownloadState : bool { Inactive, Active }; +/* + * Provides additional hints when downloading offline regions. + */ +enum class OfflineRegionDownloadOptions : uint8_t { + DefaultOptions = 0, + StyleOptimizedTiles = 1 << 0 +}; + /* * A region's status includes its active/inactive state as well as counts * of the number of resources that have completed downloading, their total diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp index cad68e7de9..77d7b32fe1 100644 --- a/platform/default/default_file_source.cpp +++ b/platform/default/default_file_source.cpp @@ -85,6 +85,12 @@ public: } } + void setRegionDownloadOptions(int64_t regionID, OfflineRegionDownloadOptions options) { + if (auto download = getDownload(regionID)) { + download.value()->setOptions(options); + } + } + void setRegionDownloadState(int64_t regionID, OfflineRegionDownloadState state) { if (auto download = getDownload(regionID)) { download.value()->setState(state); @@ -283,6 +289,10 @@ void DefaultFileSource::setOfflineRegionObserver(OfflineRegion& region, std::uni impl->actor().invoke(&Impl::setRegionObserver, region.getID(), std::move(observer)); } +void DefaultFileSource::setOfflineRegionDownloadOptions(OfflineRegion& region, OfflineRegionDownloadOptions options) { + impl->actor().invoke(&Impl::setRegionDownloadOptions, region.getID(), options); +} + void DefaultFileSource::setOfflineRegionDownloadState(OfflineRegion& region, OfflineRegionDownloadState state) { impl->actor().invoke(&Impl::setRegionDownloadState, region.getID(), state); } diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp index c97797a5a2..7a335bb346 100644 --- a/platform/default/mbgl/storage/offline_download.cpp +++ b/platform/default/mbgl/storage/offline_download.cpp @@ -98,6 +98,10 @@ void OfflineDownload::setObserver(std::unique_ptr observe observer = observer_ ? std::move(observer_) : std::make_unique(); } +void OfflineDownload::setOptions(OfflineRegionDownloadOptions options_) { + options = options_; +} + void OfflineDownload::setState(OfflineRegionDownloadState state) { if (status.downloadState == state) { return; @@ -219,19 +223,26 @@ void OfflineDownload::activateDownload() { status = OfflineRegionStatus(); status.downloadState = OfflineRegionDownloadState::Active; status.requiredResourceCount++; - ensureResource(Resource::style(definition.match([](auto& reg){ return reg.styleURL; }), Resource::Priority::Low), - [&](Response styleResponse) { + + const std::string styleURL = definition.match([&](auto& reg){ return reg.styleURL; }); + ensureResource(Resource::style(styleURL, Resource::Priority::Low), + [&, styleURL](Response styleResponse) { status.requiredResourceCountIsPrecise = true; style::Parser parser; parser.parse(*styleResponse.data); + std::string queryExtras; + if (static_cast(options) & static_cast(OfflineRegionDownloadOptions::StyleOptimizedTiles)) { + queryExtras = "?style=" + styleURL + "@" + parser.modified; + } + for (const auto& source : parser.sources) { SourceType type = source->getType(); auto handleTiledSource = [&] (const variant& urlOrTileset, const uint16_t tileSize) { if (urlOrTileset.is()) { - queueTiles(type, tileSize, urlOrTileset.get()); + queueTiles(type, tileSize, urlOrTileset.get(), queryExtras); } else { const auto& url = urlOrTileset.get(); status.requiredResourceCountIsPrecise = false; @@ -243,7 +254,7 @@ void OfflineDownload::activateDownload() { optional tileset = style::conversion::convertJSON(*sourceResponse.data, error); if (tileset) { util::mapbox::canonicalizeTileset(*tileset, url, type, tileSize); - queueTiles(type, tileSize, *tileset); + queueTiles(type, tileSize, *tileset, queryExtras); requiredSourceURLs.erase(url); if (requiredSourceURLs.empty()) { @@ -358,11 +369,17 @@ void OfflineDownload::queueResource(Resource resource) { resourcesRemaining.push_front(std::move(resource)); } -void OfflineDownload::queueTiles(SourceType type, uint16_t tileSize, const Tileset& tileset) { +void OfflineDownload::queueTiles(SourceType type, uint16_t tileSize, const Tileset& tileset, const std::string& queryExtras) { + static size_t count = 0; + std::string tileURL = tileset.tiles[++count % tileset.tiles.size()]; + if (!queryExtras.empty()) { + tileURL.append(queryExtras); + } + tileCover(definition, type, tileSize, tileset.zoomRange, [&](const auto& tile) { status.requiredResourceCount++; resourcesRemaining.push_back(Resource::tile( - tileset.tiles[0], definition.match([](auto& def) { return def.pixelRatio; }), tile.x, + tileURL, definition.match([](auto& def) { return def.pixelRatio; }), tile.x, tile.y, tile.z, tileset.scheme, Resource::Priority::Low)); }); } diff --git a/platform/default/mbgl/storage/offline_download.hpp b/platform/default/mbgl/storage/offline_download.hpp index 1e77ff1d35..3ec911a4ab 100644 --- a/platform/default/mbgl/storage/offline_download.hpp +++ b/platform/default/mbgl/storage/offline_download.hpp @@ -32,6 +32,7 @@ public: ~OfflineDownload(); void setObserver(std::unique_ptr); + void setOptions(OfflineRegionDownloadOptions); void setState(OfflineRegionDownloadState); OfflineRegionStatus getStatus() const; @@ -55,6 +56,7 @@ private: OfflineDatabase& offlineDatabase; OnlineFileSource& onlineFileSource; OfflineRegionStatus status; + OfflineRegionDownloadOptions options = OfflineRegionDownloadOptions::DefaultOptions; std::unique_ptr observer; std::list> requests; @@ -63,7 +65,7 @@ private: std::list> buffer; void queueResource(Resource); - void queueTiles(style::SourceType, uint16_t tileSize, const Tileset&); + void queueTiles(style::SourceType, uint16_t tileSize, const Tileset&, const std::string& queryExtras); }; } // namespace mbgl -- cgit v1.2.1