diff options
-rw-r--r-- | src/mbgl/map/source.cpp | 39 | ||||
-rw-r--r-- | test/fixtures/stale/stale_style_and_tilejson/expected.png | bin | 0 -> 13447 bytes | |||
-rw-r--r-- | test/fixtures/stale/style_and_tilejson.json | 25 | ||||
-rw-r--r-- | test/storage/cache_stale.cpp | 23 |
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 Binary files differnew file mode 100644 index 0000000000..d3c6ef3cd5 --- /dev/null +++ b/test/fixtures/stale/stale_style_and_tilejson/expected.png 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); +} |