[core] use stale and refreshing TileJSON/GeoJSON data

We're now supporting using stale TileJSON and GeoJSON data. When we receive a new answer with an updated TileJSON file, we're replacing the Source's metadata with the new one and trigger updates to make sure we're loading the correct tiles. Similarly, GeoJSON data will be reparsed.
This commit is contained in:
Konstantin Käfer
2016-01-07 10:22:20 +01:00
parent 21e4029acf
commit 8a964fb931
4 changed files with 83 additions and 6 deletions

View File

@@ -90,17 +90,16 @@ 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.
return;
}
req = nullptr;
if (res.error) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
return;
}
if (res.notModified) {
// We got the same data back as last time. Abort early.
return;
}
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> d;
d.Parse<0>(res.data->c_str());
@@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -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"
}
}]
}

View File

@@ -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);
}