summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2020-04-29 12:28:50 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2020-05-26 20:35:03 +0300
commit57972231e864cf4af18f12664dbb4a838e9e99db (patch)
tree7d39fcbfe12ad7c6b3355acd444d1413960d3a70
parent1d892b1feef4a4d15711d4596f36e6f558afae26 (diff)
downloadqtlocation-mapboxgl-57972231e864cf4af18f12664dbb4a838e9e99db.tar.gz
source manager and factories
-rw-r--r--CMakeLists.txt19
-rw-r--r--include/mbgl/sourcemanager/annotation_source_factory.hpp16
-rw-r--r--include/mbgl/sourcemanager/custom_geometry_source_factory.hpp16
-rw-r--r--include/mbgl/sourcemanager/geojson_source_factory.hpp16
-rw-r--r--include/mbgl/sourcemanager/image_source_factory.hpp16
-rw-r--r--include/mbgl/sourcemanager/raster_dem_source_factory.hpp16
-rw-r--r--include/mbgl/sourcemanager/raster_source_factory.hpp16
-rw-r--r--include/mbgl/sourcemanager/source_factory.hpp37
-rw-r--r--include/mbgl/sourcemanager/source_manager.hpp49
-rw-r--r--include/mbgl/sourcemanager/vector_source_factory.hpp16
-rw-r--r--include/mbgl/style/conversion/url_or_tileset.hpp20
-rw-r--r--platform/android/android.cmake1
-rw-r--r--platform/default/src/mbgl/sourcemanager/source_manager.cpp87
-rw-r--r--platform/ios/ios.cmake1
-rw-r--r--platform/linux/linux.cmake1
-rw-r--r--platform/macos/macos.cmake1
-rw-r--r--platform/qt/qt.cmake1
-rw-r--r--src/mbgl/renderer/render_orchestrator.cpp29
-rw-r--r--src/mbgl/renderer/render_source.cpp39
-rw-r--r--src/mbgl/renderer/render_source.hpp1
-rw-r--r--src/mbgl/sourcemanager/annotation_source_factory.cpp23
-rw-r--r--src/mbgl/sourcemanager/custom_geometry_source_factory.cpp24
-rw-r--r--src/mbgl/sourcemanager/geojson_source_factory.cpp52
-rw-r--r--src/mbgl/sourcemanager/image_source_factory.cpp59
-rw-r--r--src/mbgl/sourcemanager/raster_dem_source_factory.cpp42
-rw-r--r--src/mbgl/sourcemanager/raster_source_factory.cpp43
-rw-r--r--src/mbgl/sourcemanager/source_manager.cpp30
-rw-r--r--src/mbgl/sourcemanager/vector_source_factory.cpp49
-rw-r--r--src/mbgl/style/conversion/source.cpp193
-rw-r--r--src/mbgl/style/conversion/url_or_tileset.cpp31
-rw-r--r--test/style/source.test.cpp34
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());