diff options
Diffstat (limited to 'platform/default/mbgl/storage/offline_download.cpp')
-rw-r--r-- | platform/default/mbgl/storage/offline_download.cpp | 120 |
1 files changed, 78 insertions, 42 deletions
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp index 11ca862925..dd66abf982 100644 --- a/platform/default/mbgl/storage/offline_download.cpp +++ b/platform/default/mbgl/storage/offline_download.cpp @@ -1,13 +1,16 @@ -#include <mbgl/storage/offline_download.hpp> -#include <mbgl/storage/offline_database.hpp> #include <mbgl/storage/file_source.hpp> +#include <mbgl/storage/offline_database.hpp> +#include <mbgl/storage/offline_download.hpp> #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> #include <mbgl/style/parser.hpp> +#include <mbgl/style/sources/geojson_source_impl.hpp> +#include <mbgl/style/tile_source_impl.hpp> #include <mbgl/text/glyph.hpp> -#include <mbgl/util/tile_cover.hpp> #include <mbgl/util/mapbox.hpp> #include <mbgl/util/run_loop.hpp> +#include <mbgl/util/tile_cover.hpp> +#include <mbgl/util/tileset.hpp> #include <set> @@ -63,7 +66,8 @@ std::vector<Resource> OfflineDownload::glyphResources(const style::Parser& parse if (!parser.glyphURL.empty()) { for (const auto& fontStack : parser.fontStacks()) { for (uint32_t i = 0; i < 256; i++) { - result.push_back(Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * 256))); + result.push_back( + Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * 256))); } } } @@ -71,11 +75,13 @@ std::vector<Resource> OfflineDownload::glyphResources(const style::Parser& parse return result; } -std::vector<Resource> OfflineDownload::tileResources(SourceType type, uint16_t tileSize, const Tileset& tileset) const { +std::vector<Resource> +OfflineDownload::tileResources(SourceType type, uint16_t tileSize, const Tileset& tileset) const { std::vector<Resource> result; - for (const auto& tile : definition.tileCover(type, tileSize, tileset)) { - result.push_back(Resource::tile(tileset.tiles[0], definition.pixelRatio, tile.x, tile.y, tile.z)); + for (const auto& tile : definition.tileCover(type, tileSize, tileset.zoomRange)) { + result.push_back( + Resource::tile(tileset.tiles[0], definition.pixelRatio, tile.x, tile.y, tile.z)); } return result; @@ -100,28 +106,45 @@ OfflineRegionStatus OfflineDownload::getStatus() const { result.requiredResourceCountIsPrecise = true; for (const auto& source : parser.sources) { - switch (source->type) { + switch (source->baseImpl->type) { case SourceType::Vector: - case SourceType::Raster: - if (source->getTileset()) { - result.requiredResourceCount += tileResources(source->type, source->tileSize, *source->getTileset()).size(); + case SourceType::Raster: { + style::TileSourceImpl* tileSource = + static_cast<style::TileSourceImpl*>(source->baseImpl.get()); + const variant<std::string, Tileset>& urlOrTileset = tileSource->getURLOrTileset(); + + if (urlOrTileset.is<Tileset>()) { + result.requiredResourceCount += + tileResources(source->baseImpl->type, tileSource->getTileSize(), + urlOrTileset.get<Tileset>()) + .size(); } else { result.requiredResourceCount += 1; - optional<Response> sourceResponse = offlineDatabase.get(Resource::source(source->url)); + const std::string& url = urlOrTileset.get<std::string>(); + optional<Response> sourceResponse = offlineDatabase.get(Resource::source(url)); if (sourceResponse) { - result.requiredResourceCount += tileResources(source->type, source->tileSize, - *style::parseTileJSON(*sourceResponse->data, source->url, source->type, source->tileSize)).size(); + result.requiredResourceCount += + tileResources(source->baseImpl->type, tileSource->getTileSize(), + style::TileSourceImpl::parseTileJSON( + *sourceResponse->data, url, source->baseImpl->type, + tileSource->getTileSize())) + .size(); } else { result.requiredResourceCountIsPrecise = false; } } break; + } + + case SourceType::GeoJSON: { + style::GeoJSONSource::Impl* geojsonSource = + static_cast<style::GeoJSONSource::Impl*>(source->baseImpl.get()); - case SourceType::GeoJSON: - if (!source->url.empty()) { + if (!geojsonSource->loaded) { result.requiredResourceCount += 1; } break; + } case SourceType::Video: case SourceType::Annotations: @@ -141,28 +164,33 @@ void OfflineDownload::activateDownload() { requiredSourceURLs.clear(); - ensureResource(Resource::style(definition.styleURL), [&] (Response styleResponse) { + ensureResource(Resource::style(definition.styleURL), [&](Response styleResponse) { status.requiredResourceCountIsPrecise = true; style::Parser parser; parser.parse(*styleResponse.data); for (const auto& source : parser.sources) { - SourceType type = source->type; - uint16_t tileSize = source->tileSize; - std::string url = source->url; + SourceType type = source->baseImpl->type; switch (type) { case SourceType::Vector: - case SourceType::Raster: - if (source->getTileset()) { - ensureTiles(type, tileSize, *source->getTileset()); + case SourceType::Raster: { + const style::TileSourceImpl* tileSource = + static_cast<style::TileSourceImpl*>(source->baseImpl.get()); + const variant<std::string, Tileset>& urlOrTileset = tileSource->getURLOrTileset(); + const uint16_t tileSize = tileSource->getTileSize(); + + if (urlOrTileset.is<Tileset>()) { + ensureTiles(type, tileSize, urlOrTileset.get<Tileset>()); } else { + const std::string& url = urlOrTileset.get<std::string>(); status.requiredResourceCountIsPrecise = false; requiredSourceURLs.insert(url); - ensureResource(Resource::source(url), [=] (Response sourceResponse) { - ensureTiles(type, tileSize, *style::parseTileJSON(*sourceResponse.data, url, type, tileSize)); + ensureResource(Resource::source(url), [=](Response sourceResponse) { + ensureTiles(type, tileSize, style::TileSourceImpl::parseTileJSON( + *sourceResponse.data, url, type, tileSize)); requiredSourceURLs.erase(url); if (requiredSourceURLs.empty()) { @@ -171,19 +199,24 @@ void OfflineDownload::activateDownload() { }); } break; + } - case SourceType::GeoJSON: - if (!source->url.empty()) { - ensureResource(Resource::source(source->url)); + case SourceType::GeoJSON: { + style::GeoJSONSource::Impl* geojsonSource = + static_cast<style::GeoJSONSource::Impl*>(source->baseImpl.get()); + + if (!geojsonSource->loaded) { + ensureResource(Resource::source(geojsonSource->getURL())); } break; + } case SourceType::Video: case SourceType::Annotations: break; } } - + for (const auto& resource : spriteResources(parser)) { ensureResource(resource); } @@ -204,14 +237,16 @@ void OfflineDownload::ensureTiles(SourceType type, uint16_t tileSize, const Tile } } -void OfflineDownload::ensureResource(const Resource& resource, std::function<void (Response)> callback) { +void OfflineDownload::ensureResource(const Resource& resource, + std::function<void(Response)> callback) { status.requiredResourceCount++; auto workRequestsIt = requests.insert(requests.begin(), nullptr); - *workRequestsIt = util::RunLoop::Get()->invokeCancellable([=] () { + *workRequestsIt = util::RunLoop::Get()->invokeCancellable([=]() { requests.erase(workRequestsIt); - optional<std::pair<Response, uint64_t>> offlineResponse = offlineDatabase.getRegionResource(id, resource); + optional<std::pair<Response, uint64_t>> offlineResponse = + offlineDatabase.getRegionResource(id, resource); if (offlineResponse) { if (callback) { callback(offlineResponse->first); @@ -220,24 +255,25 @@ void OfflineDownload::ensureResource(const Resource& resource, std::function<voi status.completedResourceCount++; status.completedResourceSize += offlineResponse->second; if (resource.kind == Resource::Kind::Tile) { + status.completedTileCount += 1; status.completedTileSize += offlineResponse->second; } - + observer->statusChanged(status); - + if (status.complete()) { setState(OfflineRegionDownloadState::Inactive); } return; } - + if (checkTileCountLimit(resource)) { return; } auto fileRequestsIt = requests.insert(requests.begin(), nullptr); - *fileRequestsIt = onlineFileSource.request(resource, [=] (Response onlineResponse) { + *fileRequestsIt = onlineFileSource.request(resource, [=](Response onlineResponse) { if (onlineResponse.error) { observer->responseError(*onlineResponse.error); return; @@ -253,15 +289,16 @@ void OfflineDownload::ensureResource(const Resource& resource, std::function<voi uint64_t resourceSize = offlineDatabase.putRegionResource(id, resource, onlineResponse); status.completedResourceSize += resourceSize; if (resource.kind == Resource::Kind::Tile) { + status.completedTileCount += 1; status.completedTileSize += resourceSize; } observer->statusChanged(status); - + if (checkTileCountLimit(resource)) { return; } - + if (status.complete()) { setState(OfflineRegionDownloadState::Inactive); } @@ -270,14 +307,13 @@ void OfflineDownload::ensureResource(const Resource& resource, std::function<voi } bool OfflineDownload::checkTileCountLimit(const Resource& resource) { - if (resource.kind == Resource::Kind::Tile - && util::mapbox::isMapboxURL(resource.url) - && offlineDatabase.offlineMapboxTileCountLimitExceeded()) { + if (resource.kind == Resource::Kind::Tile && util::mapbox::isMapboxURL(resource.url) && + offlineDatabase.offlineMapboxTileCountLimitExceeded()) { observer->mapboxTileCountLimitExceeded(offlineDatabase.getOfflineMapboxTileCountLimit()); setState(OfflineRegionDownloadState::Inactive); return true; } - + return false; } |