diff options
31 files changed, 724 insertions, 254 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a61cb319c1..88df040b1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,6 +174,7 @@ add_library( ${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/rotation.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/source.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/tileset.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/url_or_tileset.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/transition_options.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion_impl.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/assertion.hpp @@ -234,6 +235,23 @@ add_library( ${PROJECT_SOURCE_DIR}/include/mbgl/style/source.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/source_data.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/source_parameters.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/source_manager.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/annotation_source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/custom_geometry_source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/geojson_source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/image_source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/raster_dem_source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/raster_source_factory.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/sourcemanager/vector_source_factory.hpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/source_manager.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/annotation_source_factory.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/custom_geometry_source_factory.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/geojson_source_factory.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/image_source_factory.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/raster_dem_source_factory.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/raster_source_factory.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/sourcemanager/vector_source_factory.cpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/sources/custom_geometry_source.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/sources/geojson_source.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/style/sources/image_source.hpp @@ -571,6 +589,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/source.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/stringify.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/tileset.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/url_or_tileset.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/transition_options.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/custom_tile_loader.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/style/custom_tile_loader.hpp diff --git a/include/mbgl/sourcemanager/annotation_source_factory.hpp b/include/mbgl/sourcemanager/annotation_source_factory.hpp new file mode 100644 index 0000000000..0ea98bab99 --- /dev/null +++ b/include/mbgl/sourcemanager/annotation_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class AnnotationSourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/custom_geometry_source_factory.hpp b/include/mbgl/sourcemanager/custom_geometry_source_factory.hpp new file mode 100644 index 0000000000..12d8234182 --- /dev/null +++ b/include/mbgl/sourcemanager/custom_geometry_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class CustomGeometrySourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/geojson_source_factory.hpp b/include/mbgl/sourcemanager/geojson_source_factory.hpp new file mode 100644 index 0000000000..be6e64a6bc --- /dev/null +++ b/include/mbgl/sourcemanager/geojson_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class GeoJSONSourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/image_source_factory.hpp b/include/mbgl/sourcemanager/image_source_factory.hpp new file mode 100644 index 0000000000..c560cb112d --- /dev/null +++ b/include/mbgl/sourcemanager/image_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class ImageSourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/raster_dem_source_factory.hpp b/include/mbgl/sourcemanager/raster_dem_source_factory.hpp new file mode 100644 index 0000000000..a01b26eb0d --- /dev/null +++ b/include/mbgl/sourcemanager/raster_dem_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class RasterDEMSourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/raster_source_factory.hpp b/include/mbgl/sourcemanager/raster_source_factory.hpp new file mode 100644 index 0000000000..d5f88e65d9 --- /dev/null +++ b/include/mbgl/sourcemanager/raster_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class RasterSourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/source_factory.hpp b/include/mbgl/sourcemanager/source_factory.hpp new file mode 100644 index 0000000000..31d392163b --- /dev/null +++ b/include/mbgl/sourcemanager/source_factory.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <mbgl/style/source.hpp> + +namespace mbgl { +namespace style { +namespace conversion { +class Convertible; +struct Error; +} // namespace conversion +} // namespace style + +class RenderSource; + +/** + * @brief The SourceFactory abstract class + * + * This class is responsible for creation of the source objects that belong to a concrete source type. + */ +class SourceFactory { +public: + virtual ~SourceFactory() = default; + + /// Returns the source type data. + virtual const style::SourceTypeInfo* getTypeInfo() const noexcept = 0; + + /// Returns a new Source instance on success call; returns `nullptr` otherwise with Error updated + /// accordingly. + virtual std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept = 0; + + /// Returns a new RenderSource instance. + virtual std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept = 0; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/source_manager.hpp b/include/mbgl/sourcemanager/source_manager.hpp new file mode 100644 index 0000000000..4e4dea06ff --- /dev/null +++ b/include/mbgl/sourcemanager/source_manager.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include <mbgl/style/source.hpp> + +namespace mbgl { +namespace style { +namespace conversion { +class Convertible; +struct Error; +} // namespace conversion +} // namespace style + +class SourceFactory; +class RenderSource; + +/** + * @brief A singleton class responsible for creating source instances. + * + * The SourceManager has implementation per platform. The SourceManager implementation + * defines what source types are available. + * + * Linker excludes the unreachable code for the disabled sources from the binaries, + * significantly reducing their size. + */ +class SourceManager { +public: + /** + * @brief A singleton getter. + * + * @return SourceManager* + */ + static SourceManager* get() noexcept; + + /// Returns a new Source instance on success call; returns `nullptr` otherwise. + std::unique_ptr<style::Source> createSource(const std::string& type, + const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error& error) noexcept; + + /// Returns a new RenderSource instance on success call; returns `nullptr` otherwise. + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept; + +protected: + virtual ~SourceManager() = default; + virtual SourceFactory* getFactory(const std::string& type) noexcept = 0; + virtual SourceFactory* getFactory(const style::SourceTypeInfo*) noexcept = 0; +}; + +} // namespace mbgl diff --git a/include/mbgl/sourcemanager/vector_source_factory.hpp b/include/mbgl/sourcemanager/vector_source_factory.hpp new file mode 100644 index 0000000000..05cae49af9 --- /dev/null +++ b/include/mbgl/sourcemanager/vector_source_factory.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <mbgl/sourcemanager/source_factory.hpp> + +namespace mbgl { + +class VectorSourceFactory : public SourceFactory { +protected: + const style::SourceTypeInfo* getTypeInfo() const noexcept final; + std::unique_ptr<style::Source> createSource(const std::string& id, + const style::conversion::Convertible& value, + style::conversion::Error&) noexcept final; + std::unique_ptr<RenderSource> createRenderSource(Immutable<style::Source::Impl>) noexcept final; +}; + +} // namespace mbgl diff --git a/include/mbgl/style/conversion/url_or_tileset.hpp b/include/mbgl/style/conversion/url_or_tileset.hpp new file mode 100644 index 0000000000..a6550bf4d3 --- /dev/null +++ b/include/mbgl/style/conversion/url_or_tileset.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include <mbgl/style/conversion.hpp> +#include <mbgl/util/optional.hpp> +#include <mbgl/util/tileset.hpp> +#include <mbgl/util/variant.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +template <> +struct Converter<variant<std::string, Tileset>> { +public: + optional<variant<std::string, Tileset>> operator()(const Convertible& value, Error& error) const; +}; + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/platform/android/android.cmake b/platform/android/android.cmake index b4dd48e7db..2d1997595a 100644 --- a/platform/android/android.cmake +++ b/platform/android/android.cmake @@ -70,6 +70,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/util/thread_local.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/util/utf.cpp $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/layermanager/layer_manager.cpp> + $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/sourcemanager/source_manager.cpp> ${PROJECT_SOURCE_DIR}/platform/linux/src/headless_backend_egl.cpp ) diff --git a/platform/default/src/mbgl/sourcemanager/source_manager.cpp b/platform/default/src/mbgl/sourcemanager/source_manager.cpp new file mode 100644 index 0000000000..9af26fe4ef --- /dev/null +++ b/platform/default/src/mbgl/sourcemanager/source_manager.cpp @@ -0,0 +1,87 @@ +#include <map> +#include <mbgl/layermanager/layer_manager.hpp> +#include <mbgl/sourcemanager/annotation_source_factory.hpp> +#include <mbgl/sourcemanager/custom_geometry_source_factory.hpp> +#include <mbgl/sourcemanager/geojson_source_factory.hpp> +#include <mbgl/sourcemanager/image_source_factory.hpp> +#include <mbgl/sourcemanager/raster_dem_source_factory.hpp> +#include <mbgl/sourcemanager/raster_source_factory.hpp> +#include <mbgl/sourcemanager/source_manager.hpp> +#include <mbgl/sourcemanager/vector_source_factory.hpp> +#include <mbgl/util/logging.hpp> +#include <memory> +#include <vector> + +namespace mbgl { + +class SourceManagerDefault final : public SourceManager { +public: + SourceManagerDefault(); + +private: + void addSourceType(std::unique_ptr<SourceFactory>); + // SourceManager overrides. + SourceFactory* getFactory(const std::string& type) noexcept final; + SourceFactory* getFactory(const style::SourceTypeInfo*) noexcept final; + + std::vector<std::unique_ptr<SourceFactory>> factories; + std::map<std::string, SourceFactory*> typeToFactory; +}; + +SourceManagerDefault::SourceManagerDefault() { + if (LayerManager::annotationsEnabled) { + addSourceType(std::make_unique<AnnotationSourceFactory>()); + } +#if !defined(MBGL_SOURCE_CUSTOM_GEOMETRY_DISABLE_ALL) + addSourceType(std::make_unique<CustomGeometrySourceFactory>()); +#endif +#if !defined(MBGL_SOURCE_GEOJSON_DISABLE_ALL) + addSourceType(std::make_unique<GeoJSONSourceFactory>()); +#endif +#if !defined(MBGL_SOURCE_IMAGE_DISABLE_ALL) + addSourceType(std::make_unique<ImageSourceFactory>()); +#endif +#if !defined(MBGL_SOURCE_RASTER_DEM_DISABLE_ALL) + addSourceType(std::make_unique<RasterDEMSourceFactory>()); +#endif +#if !defined(MBGL_SOURCE_RASTER_DISABLE_ALL) + addSourceType(std::make_unique<RasterSourceFactory>()); +#endif +#if !defined(MBGL_SOURCE_VECTOR_DISABLE_ALL) + addSourceType(std::make_unique<VectorSourceFactory>()); +#endif +} + +void SourceManagerDefault::addSourceType(std::unique_ptr<SourceFactory> factory) { + std::string type{factory->getTypeInfo()->type}; + if (!type.empty()) { + typeToFactory.emplace(std::make_pair(std::move(type), factory.get())); + } else { + Log::Warning(Event::Setup, "Failure adding source factory. getTypeInfo() returned an empty type string."); + } + factories.emplace_back(std::move(factory)); +} + +SourceFactory* SourceManagerDefault::getFactory(const mbgl::style::SourceTypeInfo* typeInfo) noexcept { + assert(typeInfo); + for (const auto& factory : factories) { + if (factory->getTypeInfo() == typeInfo) { + return factory.get(); + } + } + assert(false); + return nullptr; +} + +SourceFactory* SourceManagerDefault::getFactory(const std::string& type) noexcept { + auto search = typeToFactory.find(type); + return (search != typeToFactory.end()) ? search->second : nullptr; +} + +// static +SourceManager* SourceManager::get() noexcept { + static SourceManagerDefault instance; + return &instance; +} + +} // namespace mbgl diff --git a/platform/ios/ios.cmake b/platform/ios/ios.cmake index cc231c0123..d6ff1fea0d 100644 --- a/platform/ios/ios.cmake +++ b/platform/ios/ios.cmake @@ -48,6 +48,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/gfx/headless_backend.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/gfx/headless_frontend.cpp $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/layermanager/layer_manager.cpp> + $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/sourcemanager/source_manager.cpp> ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/map/map_snapshotter.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/platform/time.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/storage/asset_file_source.cpp diff --git a/platform/linux/linux.cmake b/platform/linux/linux.cmake index d8d11e1d4a..b0db7e3928 100644 --- a/platform/linux/linux.cmake +++ b/platform/linux/linux.cmake @@ -18,6 +18,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/i18n/collator.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/i18n/number_format.cpp $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/layermanager/layer_manager.cpp> + $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/sourcemanager/source_manager.cpp> ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/platform/time.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/storage/asset_file_source.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/storage/database_file_source.cpp diff --git a/platform/macos/macos.cmake b/platform/macos/macos.cmake index 4d2091de65..d09fc74de0 100644 --- a/platform/macos/macos.cmake +++ b/platform/macos/macos.cmake @@ -39,6 +39,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/gfx/headless_backend.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/gfx/headless_frontend.cpp $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/layermanager/layer_manager.cpp> + $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/sourcemanager/source_manager.cpp> ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/map/map_snapshotter.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/platform/time.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/storage/asset_file_source.cpp diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index 50db75c695..0705c0dc05 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -31,6 +31,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/gl/headless_backend.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/i18n/collator.cpp $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/layermanager/layer_manager.cpp> + $<$<BOOL:${MBGL_PUBLIC_BUILD}>:${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/sourcemanager/source_manager.cpp> ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/platform/time.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/storage/asset_file_source.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/storage/database_file_source.cpp 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 diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index db9d90c5f2..bc19b9e9d1 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -4,6 +4,8 @@ #include <mbgl/test/stub_style_observer.hpp> #include <mbgl/test/util.hpp> +#include <mbgl/sourcemanager/source_manager.hpp> + #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/circle_layer_impl.hpp> #include <mbgl/style/layers/hillshade_layer.hpp> @@ -171,7 +173,7 @@ TEST(Source, RasterTileEmpty) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -206,7 +208,7 @@ TEST(Source, RasterDEMTileEmpty) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -243,7 +245,7 @@ TEST(Source, VectorTileEmpty) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -279,7 +281,7 @@ TEST(Source, RasterTileFail) { test.end(); }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -315,7 +317,7 @@ TEST(Source, RasterDEMTileFail) { test.end(); }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -353,7 +355,7 @@ TEST(Source, VectorTileFail) { test.end(); }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -388,7 +390,7 @@ TEST(Source, RasterTileCorrupt) { test.end(); }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -423,7 +425,7 @@ TEST(Source, RasterDEMTileCorrupt) { test.end(); }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -459,7 +461,7 @@ TEST(Source, VectorTileCorrupt) { test.end(); }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -492,7 +494,7 @@ TEST(Source, RasterTileCancel) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -525,7 +527,7 @@ TEST(Source, RasterDEMTileCancel) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -560,7 +562,7 @@ TEST(Source, VectorTileCancel) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -602,7 +604,7 @@ TEST(Source, RasterTileAttribution) { source.setObserver(&test.styleObserver); source.loadDescription(*test.fileSource); - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); test.run(); @@ -641,7 +643,7 @@ TEST(Source, RasterDEMTileAttribution) { source.setObserver(&test.styleObserver); source.loadDescription(*test.fileSource); - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); test.run(); @@ -732,7 +734,7 @@ TEST(Source, CustomGeometrySourceSetTileData) { FAIL() << "Should never be called"; }; - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); @@ -967,7 +969,7 @@ TEST(Source, SetMaxParentOverscaleFactor) { ASSERT_EQ(3, *source.getMaxOverscaleFactorForParentTiles()); source.loadDescription(*test.fileSource); - auto renderSource = RenderSource::create(source.baseImpl); + auto renderSource = SourceManager::get()->createRenderSource(source.baseImpl); renderSource->setObserver(&test.renderSourceObserver); renderSource->update(source.baseImpl, layers, true, true, test.tileParameters()); |