summaryrefslogtreecommitdiff
path: root/platform/default/mbgl/storage/offline_download.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default/mbgl/storage/offline_download.cpp')
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp120
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;
}