diff options
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/renderer/render_orchestrator.cpp | 29 | ||||
-rw-r--r-- | src/mbgl/renderer/render_source.cpp | 39 | ||||
-rw-r--r-- | src/mbgl/renderer/render_source.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/annotation_source_factory.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/custom_geometry_source_factory.cpp | 24 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/geojson_source_factory.cpp | 52 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/image_source_factory.cpp | 59 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/raster_dem_source_factory.cpp | 42 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/raster_source_factory.cpp | 43 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/source_manager.cpp | 30 | ||||
-rw-r--r-- | src/mbgl/sourcemanager/vector_source_factory.cpp | 49 | ||||
-rw-r--r-- | src/mbgl/style/conversion/source.cpp | 193 | ||||
-rw-r--r-- | src/mbgl/style/conversion/url_or_tileset.cpp | 31 |
13 files changed, 377 insertions, 238 deletions
diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index d7f13695de..76b2044a17 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -1,31 +1,32 @@ #include <mbgl/renderer/render_orchestrator.hpp> #include <mbgl/annotation/annotation_manager.hpp> +#include <mbgl/geometry/line_atlas.hpp> #include <mbgl/layermanager/layer_manager.hpp> -#include <mbgl/renderer/renderer_observer.hpp> -#include <mbgl/renderer/render_source.hpp> +#include <mbgl/renderer/image_manager.hpp> +#include <mbgl/renderer/paint_parameters.hpp> +#include <mbgl/renderer/pattern_atlas.hpp> +#include <mbgl/renderer/property_evaluation_parameters.hpp> +#include <mbgl/renderer/query.hpp> #include <mbgl/renderer/render_layer.hpp> +#include <mbgl/renderer/render_source.hpp> #include <mbgl/renderer/render_static_data.hpp> +#include <mbgl/renderer/render_tile.hpp> #include <mbgl/renderer/render_tree.hpp> +#include <mbgl/renderer/renderer_observer.hpp> +#include <mbgl/renderer/style_diff.hpp> +#include <mbgl/renderer/tile_parameters.hpp> +#include <mbgl/renderer/transition_parameters.hpp> #include <mbgl/renderer/update_parameters.hpp> #include <mbgl/renderer/upload_parameters.hpp> -#include <mbgl/renderer/pattern_atlas.hpp> -#include <mbgl/renderer/paint_parameters.hpp> -#include <mbgl/renderer/transition_parameters.hpp> -#include <mbgl/renderer/property_evaluation_parameters.hpp> -#include <mbgl/renderer/tile_parameters.hpp> -#include <mbgl/renderer/render_tile.hpp> -#include <mbgl/renderer/style_diff.hpp> -#include <mbgl/renderer/query.hpp> -#include <mbgl/renderer/image_manager.hpp> -#include <mbgl/geometry/line_atlas.hpp> +#include <mbgl/sourcemanager/source_manager.hpp> #include <mbgl/style/source_impl.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/text/glyph_manager.hpp> #include <mbgl/tile/tile.hpp> +#include <mbgl/util/logging.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/string.hpp> -#include <mbgl/util/logging.hpp> namespace mbgl { @@ -276,7 +277,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree( // Create render sources for newly added sources. for (const auto& entry : sourceDiff.added) { - std::unique_ptr<RenderSource> renderSource = RenderSource::create(entry.second); + std::unique_ptr<RenderSource> renderSource = SourceManager::get()->createRenderSource(entry.second); renderSource->setObserver(this); renderSources.emplace(entry.first, std::move(renderSource)); } diff --git a/src/mbgl/renderer/render_source.cpp b/src/mbgl/renderer/render_source.cpp index dd1959e2c7..7ac8fca3aa 100644 --- a/src/mbgl/renderer/render_source.cpp +++ b/src/mbgl/renderer/render_source.cpp @@ -1,52 +1,13 @@ -#include <mbgl/annotation/render_annotation_source.hpp> -#include <mbgl/layermanager/layer_manager.hpp> #include <mbgl/renderer/render_source.hpp> #include <mbgl/renderer/render_source_observer.hpp> -#include <mbgl/renderer/sources/render_custom_geometry_source.hpp> -#include <mbgl/renderer/sources/render_geojson_source.hpp> -#include <mbgl/renderer/sources/render_image_source.hpp> -#include <mbgl/renderer/sources/render_raster_dem_source.hpp> -#include <mbgl/renderer/sources/render_raster_source.hpp> -#include <mbgl/renderer/sources/render_vector_source.hpp> #include <mbgl/renderer/tile_parameters.hpp> #include <mbgl/tile/tile.hpp> #include <mbgl/util/constants.hpp> -#include <utility> namespace mbgl { using namespace style; -std::unique_ptr<RenderSource> RenderSource::create(const Immutable<Source::Impl>& impl) { - std::string sourceType{impl->getTypeInfo()->type}; - if (sourceType == VectorSource::Impl::staticTypeInfo()->type) { - return std::make_unique<RenderVectorSource>(staticImmutableCast<VectorSource::Impl>(impl)); - } else if (sourceType == RasterSource::Impl::staticTypeInfo()->type) { - return std::make_unique<RenderRasterSource>(staticImmutableCast<RasterSource::Impl>(impl)); - } else if (sourceType == RasterDEMSource::Impl::staticTypeInfo()->type) { - return std::make_unique<RenderRasterDEMSource>(staticImmutableCast<RasterDEMSource::Impl>(impl)); - } else if (sourceType == GeoJSONSource::Impl::staticTypeInfo()->type) { - return std::make_unique<RenderGeoJSONSource>(staticImmutableCast<GeoJSONSource::Impl>(impl)); - } else if (sourceType == "video") { - assert(false); - return nullptr; - } else if (sourceType == AnnotationSource::Impl::staticTypeInfo()->type) { - if (LayerManager::annotationsEnabled) { - return std::make_unique<RenderAnnotationSource>(staticImmutableCast<AnnotationSource::Impl>(impl)); - } else { - assert(false); - return nullptr; - } - } else if (sourceType == ImageSource::Impl::staticTypeInfo()->type) { - return std::make_unique<RenderImageSource>(staticImmutableCast<ImageSource::Impl>(impl)); - } else if (sourceType == CustomGeometrySource::Impl::staticTypeInfo()->type) { - return std::make_unique<RenderCustomGeometrySource>(staticImmutableCast<CustomGeometrySource::Impl>(impl)); - } - - assert(false); - return nullptr; -} - static RenderSourceObserver nullObserver; RenderSource::RenderSource(Immutable<style::Source::Impl> impl) : baseImpl(std::move(impl)), observer(&nullObserver) {} diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index 8e09b46931..fa0b73af7f 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -47,7 +47,6 @@ using RenderTiles = std::shared_ptr<const std::vector<std::reference_wrapper<con class RenderSource : protected TileObserver { public: - static std::unique_ptr<RenderSource> create(const Immutable<style::Source::Impl>&); ~RenderSource() override; bool isEnabled() const; diff --git a/src/mbgl/sourcemanager/annotation_source_factory.cpp b/src/mbgl/sourcemanager/annotation_source_factory.cpp new file mode 100644 index 0000000000..a5d1986efd --- /dev/null +++ b/src/mbgl/sourcemanager/annotation_source_factory.cpp @@ -0,0 +1,23 @@ +#include <mbgl/annotation/annotation_source.hpp> +#include <mbgl/annotation/render_annotation_source.hpp> +#include <mbgl/sourcemanager/annotation_source_factory.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* AnnotationSourceFactory::getTypeInfo() const noexcept { + return AnnotationSource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> AnnotationSourceFactory::createSource(const std::string&, + const style::conversion::Convertible&, + style::conversion::Error&) noexcept { + return std::unique_ptr<style::Source>(new AnnotationSource()); +} + +std::unique_ptr<RenderSource> AnnotationSourceFactory::createRenderSource( + Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderAnnotationSource>(staticImmutableCast<AnnotationSource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/custom_geometry_source_factory.cpp b/src/mbgl/sourcemanager/custom_geometry_source_factory.cpp new file mode 100644 index 0000000000..054aa15bd5 --- /dev/null +++ b/src/mbgl/sourcemanager/custom_geometry_source_factory.cpp @@ -0,0 +1,24 @@ +#include <mbgl/renderer/sources/render_custom_geometry_source.hpp> +#include <mbgl/sourcemanager/custom_geometry_source_factory.hpp> +#include <mbgl/style/sources/custom_geometry_source.hpp> +#include <mbgl/style/sources/custom_geometry_source_impl.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* CustomGeometrySourceFactory::getTypeInfo() const noexcept { + return style::CustomGeometrySource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> CustomGeometrySourceFactory::createSource(const std::string& id, + const style::conversion::Convertible&, + style::conversion::Error&) noexcept { + return std::unique_ptr<style::Source>(new style::CustomGeometrySource(id, style::CustomGeometrySource::Options{})); +} + +std::unique_ptr<RenderSource> CustomGeometrySourceFactory::createRenderSource( + Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderCustomGeometrySource>(staticImmutableCast<style::CustomGeometrySource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/geojson_source_factory.cpp b/src/mbgl/sourcemanager/geojson_source_factory.cpp new file mode 100644 index 0000000000..3152fe04ae --- /dev/null +++ b/src/mbgl/sourcemanager/geojson_source_factory.cpp @@ -0,0 +1,52 @@ +#include <mbgl/renderer/sources/render_geojson_source.hpp> +#include <mbgl/sourcemanager/geojson_source_factory.hpp> +#include <mbgl/style/conversion/geojson.hpp> +#include <mbgl/style/conversion/geojson_options.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/sources/geojson_source.hpp> +#include <mbgl/style/sources/geojson_source_impl.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* GeoJSONSourceFactory::getTypeInfo() const noexcept { + return style::GeoJSONSource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> GeoJSONSourceFactory::createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept { + auto dataValue = objectMember(value, "data"); + if (!dataValue) { + error.message = "GeoJSON source must have a data value"; + return nullptr; + } + + Immutable<style::GeoJSONOptions> options = style::GeoJSONOptions::defaultOptions(); + if (optional<style::GeoJSONOptions> converted = style::conversion::convert<style::GeoJSONOptions>(value, error)) { + options = makeMutable<style::GeoJSONOptions>(std::move(*converted)); + } + + auto result = std::make_unique<style::GeoJSONSource>(id, std::move(options)); + + if (isObject(*dataValue)) { + optional<GeoJSON> geoJSON = style::conversion::convert<GeoJSON>(*dataValue, error); + if (!geoJSON) { + return nullptr; + } + result->setGeoJSON(*geoJSON); + } else if (toString(*dataValue)) { + result->setURL(*toString(*dataValue)); + } else { + error.message = "GeoJSON data must be a URL or an object"; + return nullptr; + } + + return {std::move(result)}; +} + +std::unique_ptr<RenderSource> GeoJSONSourceFactory::createRenderSource(Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderGeoJSONSource>(staticImmutableCast<style::GeoJSONSource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/image_source_factory.cpp b/src/mbgl/sourcemanager/image_source_factory.cpp new file mode 100644 index 0000000000..3cd3c41914 --- /dev/null +++ b/src/mbgl/sourcemanager/image_source_factory.cpp @@ -0,0 +1,59 @@ +#include <mbgl/renderer/sources/render_image_source.hpp> +#include <mbgl/sourcemanager/image_source_factory.hpp> +#include <mbgl/style/conversion/coordinate.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/sources/image_source.hpp> +#include <mbgl/style/sources/image_source_impl.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* ImageSourceFactory::getTypeInfo() const noexcept { + return style::ImageSource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> ImageSourceFactory::createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept { + auto urlValue = objectMember(value, "url"); + if (!urlValue) { + error.message = "Image source must have a url value"; + return nullptr; + } + + auto urlString = toString(*urlValue); + if (!urlString) { + error.message = "Image url must be a URL string"; + return nullptr; + } + + auto coordinatesValue = objectMember(value, "coordinates"); + if (!coordinatesValue) { + error.message = "Image source must have a coordinates values"; + return nullptr; + } + + if (!isArray(*coordinatesValue) || arrayLength(*coordinatesValue) != 4) { + error.message = "Image coordinates must be an array of four longitude latitude pairs"; + return nullptr; + } + + std::array<LatLng, 4> coordinates; + for (std::size_t i = 0; i < 4; i++) { + auto latLng = style::conversion::convert<LatLng>(arrayMember(*coordinatesValue, i), error); + if (!latLng) { + return nullptr; + } + coordinates[i] = *latLng; + } + auto result = std::make_unique<style::ImageSource>(id, coordinates); + result->setURL(*urlString); + + return {std::move(result)}; +} + +std::unique_ptr<RenderSource> ImageSourceFactory::createRenderSource(Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderImageSource>(staticImmutableCast<style::ImageSource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/raster_dem_source_factory.cpp b/src/mbgl/sourcemanager/raster_dem_source_factory.cpp new file mode 100644 index 0000000000..119a7eae27 --- /dev/null +++ b/src/mbgl/sourcemanager/raster_dem_source_factory.cpp @@ -0,0 +1,42 @@ +#include <mbgl/renderer/sources/render_raster_dem_source.hpp> +#include <mbgl/sourcemanager/raster_dem_source_factory.hpp> +#include <mbgl/style/conversion/url_or_tileset.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/sources/raster_dem_source.hpp> +#include <mbgl/style/sources/raster_dem_source_impl.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* RasterDEMSourceFactory::getTypeInfo() const noexcept { + return style::RasterDEMSource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> RasterDEMSourceFactory::createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept { + optional<variant<std::string, Tileset>> urlOrTileset = + style::conversion::convert<variant<std::string, Tileset>>(value, error); + if (!urlOrTileset) { + return nullptr; + } + + uint16_t tileSize = util::tileSize; + auto tileSizeValue = objectMember(value, "tileSize"); + if (tileSizeValue) { + optional<float> size = toNumber(*tileSizeValue); + if (!size || *size < 0 || *size > std::numeric_limits<uint16_t>::max()) { + error.message = "invalid tileSize"; + return nullptr; + } + tileSize = *size; + } + + return {std::make_unique<style::RasterDEMSource>(id, std::move(*urlOrTileset), tileSize)}; +} + +std::unique_ptr<RenderSource> RasterDEMSourceFactory::createRenderSource(Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderRasterDEMSource>(staticImmutableCast<style::RasterDEMSource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/raster_source_factory.cpp b/src/mbgl/sourcemanager/raster_source_factory.cpp new file mode 100644 index 0000000000..a06595059d --- /dev/null +++ b/src/mbgl/sourcemanager/raster_source_factory.cpp @@ -0,0 +1,43 @@ +#include <mbgl/renderer/sources/render_raster_source.hpp> +#include <mbgl/sourcemanager/raster_source_factory.hpp> +#include <mbgl/style/conversion/url_or_tileset.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/sources/raster_source.hpp> +#include <mbgl/style/sources/raster_source_impl.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* RasterSourceFactory::getTypeInfo() const noexcept { + return style::RasterSource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> RasterSourceFactory::createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept { + optional<variant<std::string, Tileset>> urlOrTileset = + style::conversion::convert<variant<std::string, Tileset>>(value, error); + + if (!urlOrTileset) { + return nullptr; + } + + uint16_t tileSize = util::tileSize; + auto tileSizeValue = objectMember(value, "tileSize"); + if (tileSizeValue) { + optional<float> size = toNumber(*tileSizeValue); + if (!size || *size < 0 || *size > std::numeric_limits<uint16_t>::max()) { + error.message = "invalid tileSize"; + return nullptr; + } + tileSize = *size; + } + + return {std::make_unique<style::RasterSource>(id, std::move(*urlOrTileset), tileSize)}; +} + +std::unique_ptr<RenderSource> RasterSourceFactory::createRenderSource(Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderRasterSource>(staticImmutableCast<style::RasterSource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/source_manager.cpp b/src/mbgl/sourcemanager/source_manager.cpp new file mode 100644 index 0000000000..742cedef2d --- /dev/null +++ b/src/mbgl/sourcemanager/source_manager.cpp @@ -0,0 +1,30 @@ +#include <mbgl/renderer/render_source.hpp> +#include <mbgl/sourcemanager/source_factory.hpp> +#include <mbgl/sourcemanager/source_manager.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/source.hpp> +#include <mbgl/style/source_impl.hpp> + +namespace mbgl { + +std::unique_ptr<style::Source> SourceManager::createSource(const std::string& type, + const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept { + SourceFactory* factory = getFactory(type); + if (factory) { + return factory->createSource(id, value, error); + } else { + error.message = "Null factory for type: " + type; + } + error.message = "Unsupported source type! " + error.message; + return nullptr; +} + +std::unique_ptr<RenderSource> SourceManager::createRenderSource(Immutable<style::Source::Impl> impl) noexcept { + SourceFactory* factory = getFactory(impl->getTypeInfo()); + assert(factory); + return factory->createRenderSource(std::move(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/sourcemanager/vector_source_factory.cpp b/src/mbgl/sourcemanager/vector_source_factory.cpp new file mode 100644 index 0000000000..efc6f3144f --- /dev/null +++ b/src/mbgl/sourcemanager/vector_source_factory.cpp @@ -0,0 +1,49 @@ +#include <mbgl/renderer/sources/render_vector_source.hpp> +#include <mbgl/sourcemanager/vector_source_factory.hpp> +#include <mbgl/style/conversion/url_or_tileset.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/sources/vector_source.hpp> +#include <mbgl/style/sources/vector_source_impl.hpp> + +namespace mbgl { + +const style::SourceTypeInfo* VectorSourceFactory::getTypeInfo() const noexcept { + return style::VectorSource::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Source> VectorSourceFactory::createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept { + optional<variant<std::string, Tileset>> urlOrTileset = + style::conversion::convert<variant<std::string, Tileset>>(value, error); + if (!urlOrTileset) { + return nullptr; + } + auto maxzoomValue = objectMember(value, "maxzoom"); + optional<float> maxzoom; + if (maxzoomValue) { + maxzoom = toNumber(*maxzoomValue); + if (!maxzoom || *maxzoom < 0 || *maxzoom > std::numeric_limits<uint8_t>::max()) { + error.message = "invalid maxzoom"; + return nullptr; + } + } + auto minzoomValue = objectMember(value, "minzoom"); + optional<float> minzoom; + if (minzoomValue) { + minzoom = toNumber(*minzoomValue); + if (!minzoom || *minzoom < 0 || *minzoom > std::numeric_limits<uint8_t>::max()) { + error.message = "invalid minzoom"; + return nullptr; + } + } + return { + std::make_unique<style::VectorSource>(id, std::move(*urlOrTileset), std::move(maxzoom), std::move(minzoom))}; +} + +std::unique_ptr<RenderSource> VectorSourceFactory::createRenderSource(Immutable<style::Source::Impl> impl) noexcept { + assert(impl->getTypeInfo() == getTypeInfo()); + return std::make_unique<RenderVectorSource>(staticImmutableCast<style::VectorSource::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/style/conversion/source.cpp b/src/mbgl/style/conversion/source.cpp index cf42b40489..5c5da63171 100644 --- a/src/mbgl/style/conversion/source.cpp +++ b/src/mbgl/style/conversion/source.cpp @@ -1,185 +1,17 @@ -#include <mbgl/style/conversion/source.hpp> +#include <mbgl/sourcemanager/source_manager.hpp> #include <mbgl/style/conversion/coordinate.hpp> -#include <mbgl/style/conversion/geojson.hpp> -#include <mbgl/style/conversion/geojson_options.hpp> +#include <mbgl/style/conversion/source.hpp> #include <mbgl/style/conversion/tileset.hpp> #include <mbgl/style/conversion_impl.hpp> -#include <mbgl/style/sources/geojson_source.hpp> -#include <mbgl/style/sources/raster_source.hpp> -#include <mbgl/style/sources/raster_dem_source.hpp> -#include <mbgl/style/sources/vector_source.hpp> -#include <mbgl/style/sources/image_source.hpp> #include <mbgl/util/geo.hpp> namespace mbgl { namespace style { namespace conversion { -// A tile source can either specify a URL to TileJSON, or inline TileJSON. -static optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertible& value, Error& error) { - auto urlVal = objectMember(value, "url"); - if (!urlVal) { - optional<Tileset> tileset = convert<Tileset>(value, error); - if (!tileset) { - return nullopt; - } - return { *tileset }; - } - - optional<std::string> url = toString(*urlVal); - if (!url) { - error.message = "source url must be a string"; - return nullopt; - } - - return { *url }; -} - -static optional<std::unique_ptr<Source>> convertRasterSource(const std::string& id, - const Convertible& value, - Error& error) { - optional<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value, error); - if (!urlOrTileset) { - return nullopt; - } - - uint16_t tileSize = util::tileSize; - auto tileSizeValue = objectMember(value, "tileSize"); - if (tileSizeValue) { - optional<float> size = toNumber(*tileSizeValue); - if (!size || *size < 0 || *size > std::numeric_limits<uint16_t>::max()) { - error.message = "invalid tileSize"; - return nullopt; - } - tileSize = *size; - } - - return { std::make_unique<RasterSource>(id, std::move(*urlOrTileset), tileSize) }; -} - -static optional<std::unique_ptr<Source>> convertRasterDEMSource(const std::string& id, - const Convertible& value, - Error& error) { - optional<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value, error); - if (!urlOrTileset) { - return nullopt; - } - - uint16_t tileSize = util::tileSize; - auto tileSizeValue = objectMember(value, "tileSize"); - if (tileSizeValue) { - optional<float> size = toNumber(*tileSizeValue); - if (!size || *size < 0 || *size > std::numeric_limits<uint16_t>::max()) { - error.message = "invalid tileSize"; - return nullopt; - } - tileSize = *size; - } - - return { std::make_unique<RasterDEMSource>(id, std::move(*urlOrTileset), tileSize) }; -} - -static optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id, - const Convertible& value, - Error& error) { - optional<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value, error); - if (!urlOrTileset) { - return nullopt; - } - auto maxzoomValue = objectMember(value, "maxzoom"); - optional<float> maxzoom; - if (maxzoomValue) { - maxzoom = toNumber(*maxzoomValue); - if (!maxzoom || *maxzoom < 0 || *maxzoom > std::numeric_limits<uint8_t>::max()) { - error.message = "invalid maxzoom"; - return nullopt; - } - } - auto minzoomValue = objectMember(value, "minzoom"); - optional<float> minzoom; - if (minzoomValue) { - minzoom = toNumber(*minzoomValue); - if (!minzoom || *minzoom < 0 || *minzoom > std::numeric_limits<uint8_t>::max()) { - error.message = "invalid minzoom"; - return nullopt; - } - } - return {std::make_unique<VectorSource>(id, std::move(*urlOrTileset), std::move(maxzoom), std::move(minzoom))}; -} - -static optional<std::unique_ptr<Source>> convertGeoJSONSource(const std::string& id, - const Convertible& value, - Error& error) { - auto dataValue = objectMember(value, "data"); - if (!dataValue) { - error.message = "GeoJSON source must have a data value"; - return nullopt; - } - - Immutable<GeoJSONOptions> options = GeoJSONOptions::defaultOptions(); - if (optional<GeoJSONOptions> converted = convert<GeoJSONOptions>(value, error)) { - options = makeMutable<GeoJSONOptions>(std::move(*converted)); - } - - auto result = std::make_unique<GeoJSONSource>(id, std::move(options)); - - if (isObject(*dataValue)) { - optional<GeoJSON> geoJSON = convert<GeoJSON>(*dataValue, error); - if (!geoJSON) { - return nullopt; - } - result->setGeoJSON(*geoJSON); - } else if (toString(*dataValue)) { - result->setURL(*toString(*dataValue)); - } else { - error.message = "GeoJSON data must be a URL or an object"; - return nullopt; - } - - return { std::move(result) }; -} - -static optional<std::unique_ptr<Source>> convertImageSource(const std::string& id, - const Convertible& value, - Error& error) { - auto urlValue = objectMember(value, "url"); - if (!urlValue) { - error.message = "Image source must have a url value"; - return nullopt; - } - - auto urlString = toString(*urlValue); - if (!urlString) { - error.message = "Image url must be a URL string"; - return nullopt; - } - - auto coordinatesValue = objectMember(value, "coordinates"); - if (!coordinatesValue) { - error.message = "Image source must have a coordinates values"; - return nullopt; - } - - if (!isArray(*coordinatesValue) || arrayLength(*coordinatesValue) != 4) { - error.message = "Image coordinates must be an array of four longitude latitude pairs"; - return nullopt; - } - - std::array<LatLng, 4> coordinates; - for (std::size_t i=0; i < 4; i++) { - auto latLng = conversion::convert<LatLng>(arrayMember(*coordinatesValue,i), error); - if (!latLng) { - return nullopt; - } - coordinates[i] = *latLng; - } - auto result = std::make_unique<ImageSource>(id, coordinates); - result->setURL(*urlString); - - return { std::move(result) }; -} - -optional<std::unique_ptr<Source>> Converter<std::unique_ptr<Source>>::operator()(const Convertible& value, Error& error, const std::string& id) const { +optional<std::unique_ptr<Source>> Converter<std::unique_ptr<Source>>::operator()(const Convertible& value, + Error& error, + const std::string& id) const { if (!isObject(value)) { error.message = "source must be an object"; return nullopt; @@ -197,18 +29,11 @@ optional<std::unique_ptr<Source>> Converter<std::unique_ptr<Source>>::operator() return nullopt; } const std::string& tname = type.value(); - if (tname == "raster") { - return convertRasterSource(id, value, error); - } else if (tname == "raster-dem") { - return convertRasterDEMSource(id, value, error); - } else if (tname == "vector") { - return convertVectorSource(id, value, error); - } else if (tname == "geojson") { - return convertGeoJSONSource(id, value, error); - } else if (tname == "image") { - return convertImageSource(id, value, error); + + auto source = SourceManager::get()->createSource(tname, id, value, error); + if (source) { + return source; } else { - error.message = "invalid source type"; return nullopt; } } diff --git a/src/mbgl/style/conversion/url_or_tileset.cpp b/src/mbgl/style/conversion/url_or_tileset.cpp new file mode 100644 index 0000000000..c7a8fc63e4 --- /dev/null +++ b/src/mbgl/style/conversion/url_or_tileset.cpp @@ -0,0 +1,31 @@ +#include <mbgl/style/conversion/tileset.hpp> +#include <mbgl/style/conversion/url_or_tileset.hpp> +#include <mbgl/style/conversion_impl.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +optional<variant<std::string, Tileset>> Converter<variant<std::string, Tileset>>::operator()(const Convertible& value, + Error& error) const { + auto urlVal = objectMember(value, "url"); + if (!urlVal) { + optional<Tileset> tileset = convert<Tileset>(value, error); + if (!tileset) { + return nullopt; + } + return {*tileset}; + } + + optional<std::string> url = toString(*urlVal); + if (!url) { + error.message = "source url must be a string"; + return nullopt; + } + + return {*url}; +} + +} // namespace conversion +} // namespace style +} // namespace mbgl |