summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mbgl/map/source.cpp39
-rw-r--r--test/fixtures/stale/stale_style_and_tilejson/expected.pngbin0 -> 13447 bytes
-rw-r--r--test/fixtures/stale/style_and_tilejson.json25
-rw-r--r--test/storage/cache_stale.cpp23
4 files changed, 82 insertions, 5 deletions
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index ed57ddce0b..4432b3a490 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -90,14 +90,13 @@ void Source::load() {
// URL may either be a TileJSON file, or a GeoJSON file.
FileSource* fs = util::ThreadContext::getFileSource();
req = fs->request({ Resource::Kind::Source, url }, [this](Response res) {
- if (res.stale) {
- // Only handle fresh responses.
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
return;
}
- req = nullptr;
- if (res.error) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ if (res.notModified) {
+ // We got the same data back as last time. Abort early.
return;
}
@@ -111,6 +110,7 @@ void Source::load() {
return;
}
+ bool reloadTiles = false;
if (type == SourceType::Vector || type == SourceType::Raster) {
// Create a new copy of the SourceInfo object that holds the base values we've parsed
// from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
@@ -124,10 +124,39 @@ void Source::load() {
std::transform(newInfo->tiles.begin(), newInfo->tiles.end(), newInfo->tiles.begin(),
util::mapbox::normalizeRasterTileURL);
}
+
+ // Check whether previous information specifies different tile
+ if (info && info->tiles != newInfo->tiles) {
+ reloadTiles = true;
+
+ // Tile size changed: We need to recalculate the tiles we need to load because we
+ // might have to load tiles for a different zoom level
+ // This is done automatically when we trigger the onSourceLoaded observer below.
+
+ // Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles
+ // loaded that are outside the new zoom range
+ // This is done automatically when we trigger the onSourceLoaded observer below.
+
+ // Attribution changed: We need to notify the embedding application that this
+ // changed. See https://github.com/mapbox/mapbox-gl-native/issues/2723
+ // This is not yet implemented.
+
+ // Center/bounds changed: We're not using these values currently
+ }
+
info = std::move(newInfo);
} else if (type == SourceType::GeoJSON) {
info = std::make_unique<SourceInfo>();
geojsonvt = StyleParser::parseGeoJSON(d);
+ reloadTiles = true;
+ }
+
+ if (reloadTiles) {
+ // Tile information changed because we got new GeoJSON data, or a new tile URL.
+ tilePtrs.clear();
+ tileDataMap.clear();
+ tiles.clear();
+ cache.clear();
}
loaded = true;
diff --git a/test/fixtures/stale/stale_style_and_tilejson/expected.png b/test/fixtures/stale/stale_style_and_tilejson/expected.png
new file mode 100644
index 0000000000..d3c6ef3cd5
--- /dev/null
+++ b/test/fixtures/stale/stale_style_and_tilejson/expected.png
Binary files differ
diff --git a/test/fixtures/stale/style_and_tilejson.json b/test/fixtures/stale/style_and_tilejson.json
new file mode 100644
index 0000000000..f2a4fddd0b
--- /dev/null
+++ b/test/fixtures/stale/style_and_tilejson.json
@@ -0,0 +1,25 @@
+{
+ "version": 8,
+ "name": "Water",
+ "sources": {
+ "mapbox": {
+ "type": "vector",
+ "url": "http://127.0.0.1:3000/stale/streets.json"
+ }
+ },
+ "layers": [{
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "red"
+ }
+ }, {
+ "id": "water",
+ "type": "fill",
+ "source": "mapbox",
+ "source-layer": "water",
+ "paint": {
+ "fill-color": "blue"
+ }
+ }]
+}
diff --git a/test/storage/cache_stale.cpp b/test/storage/cache_stale.cpp
index cc421f7c34..7f379b78a2 100644
--- a/test/storage/cache_stale.cpp
+++ b/test/storage/cache_stale.cpp
@@ -49,3 +49,26 @@ TEST_F(Storage, CacheStaleStyle) {
checkRendering(map, "stale_style", 1000ms);
}
+
+TEST_F(Storage, CacheStaleStyleAndTileJSON) {
+ HeadlessView view(display, 1);
+
+ auto cache = SQLiteCache::getShared(":memory:");
+
+ // Rig the cache with an expired stylesheet.
+ const std::string stylePath = "stale/style_and_tilejson.json";
+ const Resource styleResource{ Resource::Kind::Style, prefix + "/" + stylePath };
+ cache->put(styleResource, expiredItem(stylePath));
+
+ // Rig the cache with an expired TileJSON.
+ const std::string tilejsonPath = "stale/streets.json";
+ const Resource tilejsonResource{ Resource::Kind::Source, prefix + "/" + tilejsonPath };
+ cache->put(tilejsonResource, expiredItem(tilejsonPath));
+
+ DefaultFileSource fileSource(":memory:", ".");
+
+ Map map(view, fileSource, MapMode::Still);
+ map.setStyleURL(styleResource.url);
+
+ checkRendering(map, "stale_style_and_tilejson", 1000ms);
+}