[core] Use variant<std::string, GeoJSON> in GeoJSON source

This commit is contained in:
John Firebaugh
2016-06-14 12:46:29 -07:00
parent 87edff4047
commit 41760b5696
5 changed files with 41 additions and 44 deletions

View File

@@ -127,7 +127,9 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
case SourceType::GeoJSON: {
style::GeoJSONSource* geojsonSource = static_cast<style::GeoJSONSource*>(source.get());
if (!geojsonSource->getURL().empty()) {
const variant<std::string, style::GeoJSONSource::GeoJSON>& urlOrGeoJSON = geojsonSource->getURLOrGeoJSON();
if (urlOrGeoJSON.is<std::string>()) {
result.requiredResourceCount += 1;
}
break;
@@ -188,8 +190,10 @@ void OfflineDownload::activateDownload() {
case SourceType::GeoJSON: {
style::GeoJSONSource* geojsonSource = static_cast<style::GeoJSONSource*>(source.get());
if (!geojsonSource->getURL().empty()) {
ensureResource(Resource::source(geojsonSource->getURL()));
const variant<std::string, style::GeoJSONSource::GeoJSON>& urlOrGeoJSON = geojsonSource->getURLOrGeoJSON();
if (urlOrGeoJSON.is<std::string>()) {
ensureResource(Resource::source(urlOrGeoJSON.get<std::string>()));
}
break;
}

View File

@@ -15,7 +15,7 @@
namespace mbgl {
namespace style {
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> parseGeoJSON(const JSValue& value) {
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> GeoJSONSource::parseGeoJSON(const JSValue& value) {
using namespace mapbox::geojsonvt;
Options options;
@@ -32,11 +32,7 @@ std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> parseGeoJSON(const JSValue& value)
}
}
std::unique_ptr<GeoJSONSource> GeoJSONSource::parse(const std::string& id,
const JSValue& value) {
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
std::string url;
std::unique_ptr<GeoJSONSource> GeoJSONSource::parse(const std::string& id, const JSValue& value) {
// We should probably split this up to have URLs in the url property, and actual data
// in the data property. Until then, we're going to detect the content based on the
// object type.
@@ -47,36 +43,24 @@ std::unique_ptr<GeoJSONSource> GeoJSONSource::parse(const std::string& id,
const JSValue& dataVal = value["data"];
if (dataVal.IsString()) {
// We need to load an external GeoJSON file
url = { dataVal.GetString(), dataVal.GetStringLength() };
return std::make_unique<GeoJSONSource>(id, std::string(dataVal.GetString(), dataVal.GetStringLength()));
} else if (dataVal.IsObject()) {
// We need to parse dataVal as a GeoJSON object
geojsonvt = parseGeoJSON(dataVal);
return std::make_unique<GeoJSONSource>(id, parseGeoJSON(dataVal));
} else {
Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object");
return nullptr;
}
return std::make_unique<GeoJSONSource>(id, url, std::move(geojsonvt));
}
GeoJSONSource::GeoJSONSource(std::string id_,
std::string url_,
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>&& geojsonvt_)
GeoJSONSource::GeoJSONSource(std::string id_, variant<std::string, GeoJSON> urlOrGeoJSON_)
: Source(SourceType::GeoJSON, std::move(id_)),
url(std::move(url_)),
geojsonvt(std::move(geojsonvt_)) {
urlOrGeoJSON(std::move(urlOrGeoJSON_)) {
}
GeoJSONSource::~GeoJSONSource() = default;
Range<uint8_t> GeoJSONSource::getZoomRange() {
return { 0, geojsonvt->options.maxZoom };
}
void GeoJSONSource::load(FileSource& fileSource) {
if (url.empty()) {
// If the URL is empty, the GeoJSON was specified inline in the stylesheet.
if (urlOrGeoJSON.is<GeoJSON>()) {
loaded = true;
return;
}
@@ -85,6 +69,7 @@ void GeoJSONSource::load(FileSource& fileSource) {
return;
}
const std::string& url = urlOrGeoJSON.get<std::string>();
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)));
@@ -103,19 +88,25 @@ void GeoJSONSource::load(FileSource& fileSource) {
return;
}
geojsonvt = style::parseGeoJSON(d);
invalidateTiles();
urlOrGeoJSON = parseGeoJSON(d);
loaded = true;
observer->onSourceLoaded(*this);
}
});
}
Range<uint8_t> GeoJSONSource::getZoomRange() {
assert(loaded);
return { 0, urlOrGeoJSON.get<GeoJSON>()->options.maxZoom };
}
std::unique_ptr<Tile> GeoJSONSource::createTile(const OverscaledTileID& tileID,
const UpdateParameters& parameters) {
return std::make_unique<GeoJSONTile>(tileID, id, parameters, geojsonvt.get());
assert(loaded);
return std::make_unique<GeoJSONTile>(tileID, id, parameters, *urlOrGeoJSON.get<GeoJSON>());
}
} // namespace style

View File

@@ -1,8 +1,8 @@
#pragma once
#include <mbgl/style/source.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <mbgl/util/variant.hpp>
namespace mapbox {
namespace geojsonvt {
@@ -18,25 +18,29 @@ namespace style {
class GeoJSONSource : public Source {
public:
static std::unique_ptr<GeoJSONSource> parse(const std::string& id,
const JSValue&);
using GeoJSON = std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>;
GeoJSONSource(std::string id,
std::string url,
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>&&);
static std::unique_ptr<GeoJSONSource> parse(const std::string& id, const JSValue&);
static GeoJSON parseGeoJSON(const JSValue&);
GeoJSONSource(std::string id, variant<std::string, GeoJSON> urlOrGeoJSON);
~GeoJSONSource() final;
void load(FileSource&) final;
const std::string& getURL() const { return url; }
uint16_t getTileSize() const final {
return util::tileSize;
}
const variant<std::string, GeoJSON>& getURLOrGeoJSON() const {
return urlOrGeoJSON;
}
private:
uint16_t getTileSize() const final { return util::tileSize; }
Range<uint8_t> getZoomRange() final;
std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) final;
const std::string url;
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
variant<std::string, GeoJSON> urlOrGeoJSON;
std::unique_ptr<AsyncRequest> req;
};

View File

@@ -109,11 +109,9 @@ std::unique_ptr<GeoJSONTileData> convertTile(const mapbox::geojsonvt::Tile& tile
GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID,
std::string sourceID,
const style::UpdateParameters& parameters,
mapbox::geojsonvt::GeoJSONVT* geojsonvt)
mapbox::geojsonvt::GeoJSONVT& geojsonvt)
: GeometryTile(overscaledTileID, sourceID, parameters.style, parameters.mode) {
if (geojsonvt) {
setData(convertTile(geojsonvt->getTile(id.canonical.z, id.canonical.x, id.canonical.y)));
}
setData(convertTile(geojsonvt.getTile(id.canonical.z, id.canonical.x, id.canonical.y)));
}
void GeoJSONTile::setNecessity(Necessity) {}

View File

@@ -19,7 +19,7 @@ public:
GeoJSONTile(const OverscaledTileID&,
std::string sourceID,
const style::UpdateParameters&,
mapbox::geojsonvt::GeoJSONVT*);
mapbox::geojsonvt::GeoJSONVT&);
void setNecessity(Necessity) final;
};