summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-06-13 13:35:24 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-06-14 11:25:45 -0700
commit2a991c6846bc6742abd618ec750bd2f01a13b75e (patch)
tree0592f4b3ebc63aeed0aeefe5c576ae9a67bfccdc
parente6ba10ceed93c3b565a80591d8def5f0e7d72aac (diff)
downloadqtlocation-mapboxgl-2a991c6846bc6742abd618ec750bd2f01a13b75e.tar.gz
[core] Virtualize Source::load
-rw-r--r--src/mbgl/annotation/annotation_source.cpp4
-rw-r--r--src/mbgl/annotation/annotation_source.hpp2
-rw-r--r--src/mbgl/style/source.cpp98
-rw-r--r--src/mbgl/style/source.hpp11
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp50
-rw-r--r--src/mbgl/style/sources/geojson_source.hpp2
-rw-r--r--src/mbgl/style/tile_source.cpp62
-rw-r--r--src/mbgl/style/tile_source.hpp2
8 files changed, 132 insertions, 99 deletions
diff --git a/src/mbgl/annotation/annotation_source.cpp b/src/mbgl/annotation/annotation_source.cpp
index 50fa7a2c09..aa52e2e434 100644
--- a/src/mbgl/annotation/annotation_source.cpp
+++ b/src/mbgl/annotation/annotation_source.cpp
@@ -8,6 +8,10 @@ AnnotationSource::AnnotationSource()
: Source(SourceType::Annotations, AnnotationManager::SourceID, "", util::tileSize, std::make_unique<Tileset>()) {
}
+void AnnotationSource::load(FileSource&) {
+ loaded = true;
+}
+
std::unique_ptr<Tile> AnnotationSource::createTile(const OverscaledTileID& tileID,
const style::UpdateParameters& parameters) {
return std::make_unique<AnnotationTile>(tileID, id, parameters);
diff --git a/src/mbgl/annotation/annotation_source.hpp b/src/mbgl/annotation/annotation_source.hpp
index 033580b645..565b9273d6 100644
--- a/src/mbgl/annotation/annotation_source.hpp
+++ b/src/mbgl/annotation/annotation_source.hpp
@@ -8,6 +8,8 @@ class AnnotationSource : public style::Source {
public:
AnnotationSource();
+ void load(FileSource&) final;
+
private:
std::unique_ptr<Tile> createTile(const OverscaledTileID&, const style::UpdateParameters&) final;
};
diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp
index 35acf3dd51..41c1d0d22b 100644
--- a/src/mbgl/style/source.cpp
+++ b/src/mbgl/style/source.cpp
@@ -7,7 +7,6 @@
#include <mbgl/util/constants.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/storage/file_source.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/style/update_parameters.hpp>
#include <mbgl/style/query_parameters.hpp>
@@ -20,7 +19,6 @@
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/enum.hpp>
-#include <mbgl/style/parser.hpp>
#include <mbgl/gl/debugging.hpp>
#include <mbgl/algorithm/update_renderables.hpp>
@@ -29,10 +27,7 @@
#include <mapbox/geojsonvt/convert.hpp>
#include <mapbox/geometry/envelope.hpp>
-#include <rapidjson/error/en.h>
-
#include <algorithm>
-#include <sstream>
namespace mbgl {
namespace style {
@@ -70,95 +65,10 @@ bool Source::isLoading() const {
return !loaded && req.operator bool();
}
-void Source::load(FileSource& fileSource) {
- if (url.empty()) {
- // In case there is no URL set, we assume that we already have all of the data because the
- // TileJSON was specified inline in the stylesheet.
- loaded = true;
- return;
- }
-
- if (req) {
- // We don't have a Tileset object yet, but there's already a request underway to load
- // the data.
- return;
- }
-
- // URL may either be a TileJSON file, or a GeoJSON file.
- req = fileSource.request(Resource::source(url), [this](Response res) {
- if (res.error) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
- return;
- } else if (res.noContent) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty source")));
- } else {
- bool reloadTiles = false;
-
- if (type == SourceType::Vector || type == SourceType::Raster) {
- std::unique_ptr<Tileset> newTileset;
-
- // Create a new copy of the Tileset object that holds the base values we've parsed
- // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
- // via the URL.
- try {
- newTileset = style::parseTileJSON(*res.data, url, type, tileSize);
- } catch (...) {
- observer->onSourceError(*this, std::current_exception());
- return;
- }
-
- // Check whether previous information specifies different tile
- if (tileset && tileset->tiles != newTileset->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
- }
-
- tileset = std::move(newTileset);
- } else if (type == SourceType::GeoJSON) {
- std::unique_ptr<Tileset> newTileset = std::make_unique<Tileset>();
-
- rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> d;
- d.Parse<0>(res.data->c_str());
-
- if (d.HasParseError()) {
- std::stringstream message;
- message << d.GetErrorOffset() << " - " << rapidjson::GetParseError_En(d.GetParseError());
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(message.str())));
- return;
- }
-
- geojsonvt = style::parseGeoJSON(d);
- reloadTiles = true;
-
- newTileset->maxZoom = geojsonvt->options.maxZoom;
- tileset = std::move(newTileset);
- }
-
- if (reloadTiles) {
- // Tile information changed because we got new GeoJSON data, or a new tile URL.
- tiles.clear();
- renderTiles.clear();
- cache.clear();
- }
-
- loaded = true;
- observer->onSourceLoaded(*this);
- }
- });
+void Source::invalidateTiles() {
+ tiles.clear();
+ renderTiles.clear();
+ cache.clear();
}
void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) {
diff --git a/src/mbgl/style/source.hpp b/src/mbgl/style/source.hpp
index 51a9ba5c71..92ca808afb 100644
--- a/src/mbgl/style/source.hpp
+++ b/src/mbgl/style/source.hpp
@@ -48,7 +48,7 @@ public:
~Source() override;
bool loaded = false;
- void load(FileSource&);
+ virtual void load(FileSource&) = 0;
bool isLoading() const;
bool isLoaded() const;
@@ -96,8 +96,13 @@ private:
virtual std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) = 0;
protected:
+ void invalidateTiles();
+
std::unique_ptr<const Tileset> tileset;
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
+ std::unique_ptr<AsyncRequest> req;
+
+ SourceObserver* observer = nullptr;
private:
// Stores the time when this source was most recently updated.
@@ -106,10 +111,6 @@ private:
std::map<OverscaledTileID, std::unique_ptr<Tile>> tiles;
std::map<UnwrappedTileID, RenderTile> renderTiles;
TileCache cache;
-
- std::unique_ptr<AsyncRequest> req;
-
- SourceObserver* observer = nullptr;
};
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index caedcffcd5..6ece894e2e 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -1,8 +1,15 @@
#include <mbgl/style/sources/geojson_source.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/parser.hpp>
#include <mbgl/tile/geojson_tile.hpp>
+#include <mbgl/storage/file_source.hpp>
#include <mapbox/geojsonvt.hpp>
+#include <rapidjson/error/en.h>
+
+#include <sstream>
+
namespace mbgl {
namespace style {
@@ -15,6 +22,49 @@ GeoJSONSource::GeoJSONSource(std::string id_,
geojsonvt = std::move(geojsonvt_);
}
+void GeoJSONSource::load(FileSource& fileSource) {
+ if (url.empty()) {
+ // If the URL is empty, the GeoJSON was specified inline in the stylesheet.
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ req = fileSource.request(Resource::source(url), [this](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
+ } else {
+ std::unique_ptr<Tileset> newTileset = std::make_unique<Tileset>();
+
+ rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> d;
+ d.Parse<0>(res.data->c_str());
+
+ if (d.HasParseError()) {
+ std::stringstream message;
+ message << d.GetErrorOffset() << " - " << rapidjson::GetParseError_En(d.GetParseError());
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(message.str())));
+ return;
+ }
+
+ geojsonvt = style::parseGeoJSON(d);
+ newTileset->maxZoom = geojsonvt->options.maxZoom;
+
+ invalidateTiles();
+
+ tileset = std::move(newTileset);
+ loaded = true;
+ observer->onSourceLoaded(*this);
+ }
+ });
+}
+
std::unique_ptr<Tile> GeoJSONSource::createTile(const OverscaledTileID& tileID,
const UpdateParameters& parameters) {
return std::make_unique<GeoJSONTile>(tileID, id, parameters, geojsonvt.get());
diff --git a/src/mbgl/style/sources/geojson_source.hpp b/src/mbgl/style/sources/geojson_source.hpp
index c9262f22b7..47984ff9da 100644
--- a/src/mbgl/style/sources/geojson_source.hpp
+++ b/src/mbgl/style/sources/geojson_source.hpp
@@ -13,6 +13,8 @@ public:
std::unique_ptr<Tileset>&&,
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>&&);
+ void load(FileSource&) final;
+
private:
std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) final;
};
diff --git a/src/mbgl/style/tile_source.cpp b/src/mbgl/style/tile_source.cpp
index 22739035a9..90f4b54d96 100644
--- a/src/mbgl/style/tile_source.cpp
+++ b/src/mbgl/style/tile_source.cpp
@@ -1,4 +1,7 @@
#include <mbgl/style/tile_source.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/parser.hpp>
+#include <mbgl/storage/file_source.hpp>
namespace mbgl {
namespace style {
@@ -11,5 +14,64 @@ TileSource::TileSource(SourceType type_,
: Source(type_, std::move(id_), std::move(url_), tileSize_, std::move(tileset_)) {
}
+void TileSource::load(FileSource& fileSource) {
+ if (url.empty()) {
+ // If the URL is empty, the TileJSON was specified inline in the stylesheet.
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ // URL may either be a TileJSON file, or a GeoJSON file.
+ req = fileSource.request(Resource::source(url), [this](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
+ } else {
+ std::unique_ptr<Tileset> newTileset;
+
+ // Create a new copy of the Tileset object that holds the base values we've parsed
+ // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
+ // via the URL.
+ try {
+ newTileset = style::parseTileJSON(*res.data, url, type, tileSize);
+ } catch (...) {
+ observer->onSourceError(*this, std::current_exception());
+ return;
+ }
+
+ // Check whether previous information specifies different tile
+ if (tileset && tileset->tiles != newTileset->tiles) {
+ // Tile URLs changed: force tiles to be reloaded.
+ invalidateTiles();
+
+ // 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
+ }
+
+ tileset = std::move(newTileset);
+ loaded = true;
+ observer->onSourceLoaded(*this);
+ }
+ });
+}
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/tile_source.hpp b/src/mbgl/style/tile_source.hpp
index 8c69ad451f..dc48080ea0 100644
--- a/src/mbgl/style/tile_source.hpp
+++ b/src/mbgl/style/tile_source.hpp
@@ -16,6 +16,8 @@ public:
std::string url,
uint16_t tileSize,
std::unique_ptr<Tileset>&&);
+
+ void load(FileSource&) final;
};
} // namespace style