summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-06-23 12:00:25 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-06-24 09:39:51 -0700
commit021d4199cb9ee754e9f0f5bc42f7f75285afd405 (patch)
tree9396f291348c0ab5f3a75e1a217a78fc4dbff4b2 /src
parent16c435b1517b15a5ea8654987979ef58800b838b (diff)
downloadqtlocation-mapboxgl-021d4199cb9ee754e9f0f5bc42f7f75285afd405.tar.gz
[core, node] Implement bindings for addSource
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/style/parser.cpp66
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp13
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.cpp73
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.hpp18
-rw-r--r--src/mbgl/style/sources/raster_source_impl.cpp21
-rw-r--r--src/mbgl/style/sources/raster_source_impl.hpp2
-rw-r--r--src/mbgl/style/sources/vector_source_impl.cpp8
-rw-r--r--src/mbgl/style/sources/vector_source_impl.hpp2
-rw-r--r--src/mbgl/style/tile_source_impl.cpp94
-rw-r--r--src/mbgl/style/tile_source_impl.hpp3
-rw-r--r--src/mbgl/util/geojson.cpp11
11 files changed, 78 insertions, 233 deletions
diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp
index ac263dbc57..41b23c1bae 100644
--- a/src/mbgl/style/parser.cpp
+++ b/src/mbgl/style/parser.cpp
@@ -1,23 +1,13 @@
#include <mbgl/style/parser.hpp>
-#include <mbgl/style/sources/raster_source_impl.hpp>
-#include <mbgl/style/sources/vector_source_impl.hpp>
-#include <mbgl/style/sources/geojson_source_impl.hpp>
#include <mbgl/style/layer_impl.hpp>
-#include <mbgl/style/layers/fill_layer.hpp>
-#include <mbgl/style/layers/line_layer.hpp>
-#include <mbgl/style/layers/circle_layer.hpp>
-#include <mbgl/style/layers/symbol_layer.hpp>
-#include <mbgl/style/layers/raster_layer.hpp>
-#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/rapidjson_conversion.hpp>
#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/source.hpp>
#include <mbgl/style/conversion/layer.hpp>
#include <mbgl/platform/log.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/util/enum.hpp>
-#include <mbgl/util/tileset.hpp>
+#include <mapbox/geojsonvt.hpp>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
@@ -75,54 +65,18 @@ void Parser::parseSources(const JSValue& value) {
return;
}
- JSValue::ConstMemberIterator itr = value.MemberBegin();
- for (; itr != value.MemberEnd(); ++itr) {
- const JSValue& nameVal = itr->name;
- const JSValue& sourceVal = itr->value;
+ for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) {
+ std::string id = *conversion::toString(it->name);
- if (!sourceVal.HasMember("type")) {
- Log::Warning(Event::ParseStyle, "source must have a type");
+ conversion::Result<std::unique_ptr<Source>> source
+ = conversion::convert<std::unique_ptr<Source>>(it->value, id);
+ if (!source) {
+ Log::Warning(Event::ParseStyle, source.error().message);
continue;
}
- const JSValue& typeVal = sourceVal["type"];
- if (!typeVal.IsString()) {
- Log::Warning(Event::ParseStyle, "source type must be a string");
- continue;
- }
-
- const auto type = Enum<SourceType>::toEnum({ typeVal.GetString(), typeVal.GetStringLength() });
- if (!type) {
- Log::Warning(Event::ParseStyle, "source type must have one of the enum values");
- continue;
- }
-
- const std::string id { nameVal.GetString(), nameVal.GetStringLength() };
- std::unique_ptr<Source> source;
-
- switch (*type) {
- case SourceType::Raster: {
- source = RasterSource::Impl::parse(id, sourceVal);
- break;
- }
-
- case SourceType::Vector:
- source = VectorSource::Impl::parse(id, sourceVal);
- break;
-
- case SourceType::GeoJSON:
- source = GeoJSONSource::Impl::parse(id, sourceVal);
- break;
-
- default:
- Log::Error(Event::ParseStyle, "source type '%s' is not supported", typeVal.GetString());
- continue;
- }
-
- if (source) {
- sourcesMap.emplace(id, source.get());
- sources.emplace_back(std::move(source));
- }
+ sourcesMap.emplace(id, (*source).get());
+ sources.emplace_back(std::move(*source));
}
}
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index b5932581dd..a3eec4f4ef 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -4,5 +4,18 @@
namespace mbgl {
namespace style {
+GeoJSONSource::GeoJSONSource(const std::string& id)
+ : Source(SourceType::GeoJSON, std::make_unique<GeoJSONSource::Impl>(std::move(id), *this))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+void GeoJSONSource::setURL(const std::string& url) {
+ impl->setURL(url);
+}
+
+void GeoJSONSource::setGeoJSON(GeoJSON&& geoJSON) {
+ impl->setGeoJSON(std::move(geoJSON));
+}
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp
index f58e0fc62b..b9744d193a 100644
--- a/src/mbgl/style/sources/geojson_source_impl.cpp
+++ b/src/mbgl/style/sources/geojson_source_impl.cpp
@@ -1,9 +1,10 @@
#include <mbgl/style/sources/geojson_source_impl.hpp>
#include <mbgl/style/source_observer.hpp>
-#include <mbgl/style/parser.hpp>
+#include <mbgl/style/conversion/geojson.hpp>
#include <mbgl/tile/geojson_tile.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/platform/log.hpp>
+#include <mbgl/util/rapidjson.hpp>
#include <mapbox/geojsonvt.hpp>
#include <mapbox/geojsonvt/convert.hpp>
@@ -12,56 +13,38 @@
#include <sstream>
+using namespace mapbox::geojsonvt;
+
namespace mbgl {
namespace style {
-
-std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> GeoJSONSource::Impl::parseGeoJSON(const JSValue& value) {
- using namespace mapbox::geojsonvt;
-
+namespace conversion {
+template <>
+Result<GeoJSON> convertGeoJSON(const JSValue& value) {
Options options;
options.buffer = util::EXTENT / util::tileSize * 128;
options.extent = util::EXTENT;
try {
- return std::make_unique<GeoJSONVT>(Convert::convert(value, 0), options);
+ return GeoJSON { std::make_unique<GeoJSONVT>(Convert::convert(value, 0), options) };
} catch (const std::exception& ex) {
- Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what());
- // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
- // tiles to load.
- return std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>{}, options);
+ return Error { ex.what() };
}
}
+} // namespace conversion
-std::unique_ptr<GeoJSONSource> GeoJSONSource::Impl::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.
- if (!value.HasMember("data")) {
- Log::Error(Event::ParseStyle, "GeoJSON source must have a data value");
- return nullptr;
- }
-
- const JSValue& dataVal = value["data"];
- if (dataVal.IsString()) {
- return std::make_unique<GeoJSONSource>([&] (Source& base) {
- return std::make_unique<Impl>(id, base, std::string(dataVal.GetString(), dataVal.GetStringLength()));
- });
- } else if (dataVal.IsObject()) {
- return std::make_unique<GeoJSONSource>([&] (Source& base) {
- return std::make_unique<Impl>(id, base, parseGeoJSON(dataVal));
- });
- } else {
- Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object");
- return nullptr;
- }
+GeoJSONSource::Impl::Impl(std::string id_, Source& base_)
+ : Source::Impl(SourceType::GeoJSON, std::move(id_), base_) {
}
-GeoJSONSource::Impl::Impl(std::string id_, Source& base_, variant<std::string, GeoJSON> urlOrGeoJSON_)
- : Source::Impl(SourceType::GeoJSON, std::move(id_), base_),
- urlOrGeoJSON(std::move(urlOrGeoJSON_)) {
+GeoJSONSource::Impl::~Impl() = default;
+
+void GeoJSONSource::Impl::setURL(std::string url) {
+ urlOrGeoJSON = std::move(url);
}
-GeoJSONSource::Impl::~Impl() = default;
+void GeoJSONSource::Impl::setGeoJSON(GeoJSON&& geoJSON) {
+ urlOrGeoJSON = std::move(geoJSON);
+}
void GeoJSONSource::Impl::load(FileSource& fileSource) {
if (urlOrGeoJSON.is<GeoJSON>()) {
@@ -94,9 +77,17 @@ void GeoJSONSource::Impl::load(FileSource& fileSource) {
invalidateTiles();
- urlOrGeoJSON = parseGeoJSON(d);
- loaded = true;
+ conversion::Result<GeoJSON> geoJSON = conversion::convertGeoJSON<JSValue>(d);
+ if (!geoJSON) {
+ Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", geoJSON.error().message);
+ // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
+ // tiles to load.
+ urlOrGeoJSON = GeoJSON { std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>()) };
+ } else {
+ urlOrGeoJSON = std::move(*geoJSON);
+ }
+ loaded = true;
observer->onSourceLoaded(base);
}
});
@@ -104,13 +95,13 @@ void GeoJSONSource::Impl::load(FileSource& fileSource) {
Range<uint8_t> GeoJSONSource::Impl::getZoomRange() {
assert(loaded);
- return { 0, urlOrGeoJSON.get<GeoJSON>()->options.maxZoom };
+ return { 0, urlOrGeoJSON.get<GeoJSON>().impl->options.maxZoom };
}
std::unique_ptr<Tile> GeoJSONSource::Impl::createTile(const OverscaledTileID& tileID,
- const UpdateParameters& parameters) {
+ const UpdateParameters& parameters) {
assert(loaded);
- return std::make_unique<GeoJSONTile>(tileID, base.getID(), parameters, *urlOrGeoJSON.get<GeoJSON>());
+ return std::make_unique<GeoJSONTile>(tileID, base.getID(), parameters, *urlOrGeoJSON.get<GeoJSON>().impl);
}
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp
index 350045b27c..e6e01c06e9 100644
--- a/src/mbgl/style/sources/geojson_source_impl.hpp
+++ b/src/mbgl/style/sources/geojson_source_impl.hpp
@@ -2,15 +2,8 @@
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/source_impl.hpp>
-#include <mbgl/util/rapidjson.hpp>
#include <mbgl/util/variant.hpp>
-namespace mapbox {
-namespace geojsonvt {
-class GeoJSONVT;
-} // namespace geojsonvt
-} // namespace mapbox
-
namespace mbgl {
class AsyncRequest;
@@ -19,15 +12,12 @@ namespace style {
class GeoJSONSource::Impl : public Source::Impl {
public:
- using GeoJSON = std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>;
-
- static std::unique_ptr<GeoJSONSource> parse(const std::string& id, const JSValue&);
- static GeoJSON parseGeoJSON(const JSValue&);
-
- Impl(std::string id, Source&,
- variant<std::string, GeoJSON> urlOrGeoJSON);
+ Impl(std::string id, Source&);
~Impl() final;
+ void setURL(std::string);
+ void setGeoJSON(GeoJSON&&);
+
void load(FileSource&) final;
uint16_t getTileSize() const final {
diff --git a/src/mbgl/style/sources/raster_source_impl.cpp b/src/mbgl/style/sources/raster_source_impl.cpp
index a6e19b4757..b727651260 100644
--- a/src/mbgl/style/sources/raster_source_impl.cpp
+++ b/src/mbgl/style/sources/raster_source_impl.cpp
@@ -1,30 +1,9 @@
#include <mbgl/style/sources/raster_source_impl.hpp>
#include <mbgl/tile/raster_tile.hpp>
-#include <mbgl/platform/log.hpp>
namespace mbgl {
namespace style {
-std::unique_ptr<RasterSource> RasterSource::Impl::parse(std::string id, const JSValue& value) {
- optional<variant<std::string, Tileset>> urlOrTileset = TileSourceImpl::parseURLOrTileset(value);
- if (!urlOrTileset) {
- return nullptr;
- }
-
- uint16_t tileSize = util::tileSize;
- if (value.HasMember("tileSize")) {
- const JSValue& tileSizeVal = value["tileSize"];
- if (tileSizeVal.IsNumber() && tileSizeVal.GetUint64() <= std::numeric_limits<uint16_t>::max()) {
- tileSize = tileSizeVal.GetUint64();
- } else {
- Log::Error(Event::ParseStyle, "invalid tileSize");
- return nullptr;
- }
- }
-
- return std::make_unique<RasterSource>(std::move(id), std::move(*urlOrTileset), tileSize);
-}
-
RasterSource::Impl::Impl(std::string id_, Source& base_,
variant<std::string, Tileset> urlOrTileset_,
uint16_t tileSize_)
diff --git a/src/mbgl/style/sources/raster_source_impl.hpp b/src/mbgl/style/sources/raster_source_impl.hpp
index 2222b13082..6f34a050bb 100644
--- a/src/mbgl/style/sources/raster_source_impl.hpp
+++ b/src/mbgl/style/sources/raster_source_impl.hpp
@@ -8,8 +8,6 @@ namespace style {
class RasterSource::Impl : public TileSourceImpl {
public:
- static std::unique_ptr<RasterSource> parse(std::string id, const JSValue&);
-
Impl(std::string id, Source&, variant<std::string, Tileset>, uint16_t tileSize);
private:
diff --git a/src/mbgl/style/sources/vector_source_impl.cpp b/src/mbgl/style/sources/vector_source_impl.cpp
index 28e14f3e16..efe8afbbea 100644
--- a/src/mbgl/style/sources/vector_source_impl.cpp
+++ b/src/mbgl/style/sources/vector_source_impl.cpp
@@ -4,14 +4,6 @@
namespace mbgl {
namespace style {
-std::unique_ptr<VectorSource> VectorSource::Impl::parse(std::string id, const JSValue& value) {
- optional<variant<std::string, Tileset>> urlOrTileset = TileSourceImpl::parseURLOrTileset(value);
- if (!urlOrTileset) {
- return nullptr;
- }
- return std::make_unique<VectorSource>(std::move(id), std::move(*urlOrTileset));
-}
-
VectorSource::Impl::Impl(std::string id_, Source& base_, variant<std::string, Tileset> urlOrTileset_)
: TileSourceImpl(SourceType::Vector, std::move(id_), base_, std::move(urlOrTileset_), util::tileSize) {
}
diff --git a/src/mbgl/style/sources/vector_source_impl.hpp b/src/mbgl/style/sources/vector_source_impl.hpp
index 4a6703e5c0..6726fa6955 100644
--- a/src/mbgl/style/sources/vector_source_impl.hpp
+++ b/src/mbgl/style/sources/vector_source_impl.hpp
@@ -8,8 +8,6 @@ namespace style {
class VectorSource::Impl : public TileSourceImpl {
public:
- static std::unique_ptr<VectorSource> parse(std::string id, const JSValue&);
-
Impl(std::string id, Source&, variant<std::string, Tileset>);
private:
diff --git a/src/mbgl/style/tile_source_impl.cpp b/src/mbgl/style/tile_source_impl.cpp
index 634ef39808..3999a88a07 100644
--- a/src/mbgl/style/tile_source_impl.cpp
+++ b/src/mbgl/style/tile_source_impl.cpp
@@ -1,10 +1,10 @@
#include <mbgl/style/tile_source_impl.hpp>
#include <mbgl/style/source_observer.hpp>
-#include <mbgl/style/parser.hpp>
+#include <mbgl/style/rapidjson_conversion.hpp>
+#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/util/tileset.hpp>
#include <mbgl/util/mapbox.hpp>
#include <mbgl/storage/file_source.hpp>
-#include <mbgl/platform/log.hpp>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
@@ -14,73 +14,6 @@
namespace mbgl {
namespace style {
-namespace {
-
-void parseTileJSONMember(const JSValue& value, std::vector<std::string>& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsArray()) {
- return;
- }
-
- for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
- if (!property[i].IsString()) {
- return;
- }
- }
-
- for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
- target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength()));
- }
-}
-
-void parseTileJSONMember(const JSValue& value, std::string& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsString()) {
- return;
- }
-
- target = { property.GetString(), property.GetStringLength() };
-}
-
-void parseTileJSONMember(const JSValue& value, uint8_t& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsUint()) {
- return;
- }
-
- unsigned int uint = property.GetUint();
- if (uint > std::numeric_limits<uint8_t>::max()) {
- return;
- }
-
- target = uint;
-}
-
-Tileset parseTileJSON(const JSValue& value) {
- Tileset result;
-
- parseTileJSONMember(value, result.tiles, "tiles");
- parseTileJSONMember(value, result.zoomRange.min, "minzoom");
- parseTileJSONMember(value, result.zoomRange.max, "maxzoom");
- parseTileJSONMember(value, result.attribution, "attribution");
-
- return result;
-}
-
-} // end namespace
-
Tileset TileSourceImpl::parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType type, uint16_t tileSize) {
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> document;
document.Parse<0>(json.c_str());
@@ -91,30 +24,19 @@ Tileset TileSourceImpl::parseTileJSON(const std::string& json, const std::string
throw std::runtime_error(message.str());
}
- Tileset result = mbgl::style::parseTileJSON(document);
+ conversion::Result<Tileset> result = conversion::convert<Tileset>(document);
+ if (!result) {
+ throw std::runtime_error(result.error().message);
+ }
// TODO: Remove this hack by delivering proper URLs in the TileJSON to begin with.
if (util::mapbox::isMapboxURL(sourceURL)) {
- for (auto& url : result.tiles) {
+ for (auto& url : (*result).tiles) {
url = util::mapbox::canonicalizeTileURL(url, type, tileSize);
}
}
- return result;
-}
-
-optional<variant<std::string, Tileset>> TileSourceImpl::parseURLOrTileset(const JSValue& value) {
- if (!value.HasMember("url")) {
- return { mbgl::style::parseTileJSON(value) };
- }
-
- const JSValue& urlVal = value["url"];
- if (!urlVal.IsString()) {
- Log::Error(Event::ParseStyle, "source url must be a string");
- return {};
- }
-
- return { std::string(urlVal.GetString(), urlVal.GetStringLength()) };
+ return *result;
}
TileSourceImpl::TileSourceImpl(SourceType type_, std::string id_, Source& base_,
diff --git a/src/mbgl/style/tile_source_impl.hpp b/src/mbgl/style/tile_source_impl.hpp
index 1ceb1188db..8f420a15d5 100644
--- a/src/mbgl/style/tile_source_impl.hpp
+++ b/src/mbgl/style/tile_source_impl.hpp
@@ -4,7 +4,6 @@
#include <mbgl/util/tileset.hpp>
#include <mbgl/util/variant.hpp>
#include <mbgl/util/optional.hpp>
-#include <mbgl/util/rapidjson.hpp>
namespace mbgl {
@@ -18,8 +17,6 @@ namespace style {
*/
class TileSourceImpl : public Source::Impl {
public:
- // A tile source can either specify a URL to TileJSON, or inline TileJSON.
- static optional<variant<std::string, Tileset>> parseURLOrTileset(const JSValue&);
static Tileset parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType, uint16_t tileSize);
TileSourceImpl(SourceType, std::string id, Source&,
diff --git a/src/mbgl/util/geojson.cpp b/src/mbgl/util/geojson.cpp
new file mode 100644
index 0000000000..a17d01f933
--- /dev/null
+++ b/src/mbgl/util/geojson.cpp
@@ -0,0 +1,11 @@
+#include <mbgl/util/geojson.hpp>
+
+#include <mapbox/geojsonvt.hpp>
+
+namespace mbgl {
+
+GeoJSON::GeoJSON(std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> impl_) : impl(std::move(impl_)) {}
+GeoJSON::GeoJSON(GeoJSON&&) = default;
+GeoJSON::~GeoJSON() = default;
+
+} // namespace mbgl