diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2018-10-28 22:33:06 +0200 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2018-10-31 18:05:01 +0200 |
commit | cfcb53128b41941a9cdacfec18d618b0866a96bc (patch) | |
tree | 27ee48ad45fca144d21f71673137c470bbb19459 /src/mbgl | |
parent | 278aa3370374154ad6fac7790d2da1546e8493f3 (diff) | |
download | qtlocation-mapboxgl-cfcb53128b41941a9cdacfec18d618b0866a96bc.tar.gz |
Introduce the style::Layer factory classes
This patch introduces the initial implementation of
- A `LayerFactory` abstract class that creates `style::Layer` instances of
a certain layer type (line, hillshade, round, ..)
- A singleton `LayerManager` class, which is responsible for initializing
the `LayerFactory` instances and forwarding the `create()` calls to the
corresponding factory.
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/style/conversion/layer.cpp | 114 | ||||
-rw-r--r-- | src/mbgl/style/layer.cpp | 96 | ||||
-rw-r--r-- | src/mbgl/style/layers/background_layer.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/style/layers/circle_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/layers/fill_extrusion_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/layers/fill_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/layers/heatmap_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/layers/hillshade_layer.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/style/layers/layer.cpp.ejs | 26 | ||||
-rw-r--r-- | src/mbgl/style/layers/line_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/layers/raster_layer.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer.cpp | 19 |
12 files changed, 281 insertions, 112 deletions
diff --git a/src/mbgl/style/conversion/layer.cpp b/src/mbgl/style/conversion/layer.cpp index 085d7ae4c6..b551f1bfb2 100644 --- a/src/mbgl/style/conversion/layer.cpp +++ b/src/mbgl/style/conversion/layer.cpp @@ -2,15 +2,6 @@ #include <mbgl/style/conversion/constant.hpp> #include <mbgl/style/conversion/filter.hpp> #include <mbgl/style/conversion_impl.hpp> -#include <mbgl/style/layers/background_layer.hpp> -#include <mbgl/style/layers/circle_layer.hpp> -#include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/style/layers/fill_extrusion_layer.hpp> -#include <mbgl/style/layers/heatmap_layer.hpp> -#include <mbgl/style/layers/hillshade_layer.hpp> -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/layers/raster_layer.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> namespace mbgl { namespace style { @@ -29,81 +20,6 @@ optional<Error> setPaintProperties(Layer& layer, const Convertible& value) { }); } -template <class LayerType> -optional<std::unique_ptr<Layer>> convertVectorLayer(const std::string& id, const Convertible& value, Error& error) { - auto sourceValue = objectMember(value, "source"); - if (!sourceValue) { - error.message = "layer must have a source"; - return nullopt; - } - - optional<std::string> source = toString(*sourceValue); - if (!source) { - error.message = "layer source must be a string"; - return nullopt; - } - - std::unique_ptr<LayerType> layer = std::make_unique<LayerType>(id, *source); - - auto sourceLayerValue = objectMember(value, "source-layer"); - if (sourceLayerValue) { - optional<std::string> sourceLayer = toString(*sourceLayerValue); - if (!sourceLayer) { - error.message = "layer source-layer must be a string"; - return nullopt; - } - layer->setSourceLayer(*sourceLayer); - } - - auto filterValue = objectMember(value, "filter"); - if (filterValue) { - optional<Filter> filter = convert<Filter>(*filterValue, error); - if (!filter) { - return nullopt; - } - layer->setFilter(*filter); - } - - return { std::move(layer) }; -} - -static optional<std::unique_ptr<Layer>> convertRasterLayer(const std::string& id, const Convertible& value, Error& error) { - auto sourceValue = objectMember(value, "source"); - if (!sourceValue) { - error.message = "layer must have a source"; - return nullopt; - } - - optional<std::string> source = toString(*sourceValue); - if (!source) { - error.message = "layer source must be a string"; - return nullopt; - } - - return { std::make_unique<RasterLayer>(id, *source) }; -} - -static optional<std::unique_ptr<Layer>> convertHillshadeLayer(const std::string& id, const Convertible& value, Error& error) { - auto sourceValue = objectMember(value, "source"); - if (!sourceValue) { - error.message = "layer must have a source"; - return nullopt; - } - - optional<std::string> source = toString(*sourceValue); - if (!source) { - error.message = "layer source must be a string"; - return nullopt; - } - - return { std::make_unique<HillshadeLayer>(id, *source) }; -} - - -static optional<std::unique_ptr<Layer>> convertBackgroundLayer(const std::string& id, const Convertible&, Error&) { - return { std::make_unique<BackgroundLayer>(id) }; -} - optional<std::unique_ptr<Layer>> Converter<std::unique_ptr<Layer>>::operator()(const Convertible& value, Error& error) const { if (!isObject(value)) { error.message = "layer must be an object"; @@ -134,37 +50,11 @@ optional<std::unique_ptr<Layer>> Converter<std::unique_ptr<Layer>>::operator()(c return nullopt; } - optional<std::unique_ptr<Layer>> converted; - - if (*type == "fill") { - converted = convertVectorLayer<FillLayer>(*id, value, error); - } else if (*type == "fill-extrusion") { - converted = convertVectorLayer<FillExtrusionLayer>(*id, value, error); - } else if (*type == "line") { - converted = convertVectorLayer<LineLayer>(*id, value, error); - } else if (*type == "circle") { - converted = convertVectorLayer<CircleLayer>(*id, value, error); - } else if (*type == "symbol") { - converted = convertVectorLayer<SymbolLayer>(*id, value, error); - } else if (*type == "raster") { - converted = convertRasterLayer(*id, value, error); - } else if (*type == "heatmap") { - converted = convertVectorLayer<HeatmapLayer>(*id, value, error); - } else if (*type == "hillshade") { - converted = convertHillshadeLayer(*id, value, error); - } else if (*type == "background") { - converted = convertBackgroundLayer(*id, value, error); - } else { - error.message = "invalid layer type"; + std::unique_ptr<Layer> layer = LayerManager::get()->createLayer(*type, *id, value, error); + if (!layer) { return nullopt; } - if (!converted) { - return converted; - } - - std::unique_ptr<Layer> layer = std::move(*converted); - auto minzoomValue = objectMember(value, "minzoom"); if (minzoomValue) { optional<float> minzoom = toNumber(*minzoomValue); diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp index 58c38403bc..573e6125b4 100644 --- a/src/mbgl/style/layer.cpp +++ b/src/mbgl/style/layer.cpp @@ -2,8 +2,20 @@ #include <mbgl/style/layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> #include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/filter.hpp> #include <mbgl/style/conversion_impl.hpp> +#include <mbgl/style/layers/symbol_layer.hpp> +#include <mbgl/style/layers/background_layer.hpp> +#include <mbgl/style/layers/circle_layer.hpp> +#include <mbgl/style/layers/fill_extrusion_layer.hpp> +#include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/layers/heatmap_layer.hpp> +#include <mbgl/style/layers/hillshade_layer.hpp> +#include <mbgl/style/layers/line_layer.hpp> +#include <mbgl/style/layers/raster_layer.hpp> +#include <mbgl/style/layers/symbol_layer.hpp> + namespace mbgl { namespace style { @@ -106,5 +118,89 @@ optional<conversion::Error> Layer::setVisibility(const conversion::Convertible& return nullopt; } +optional<std::string> LayerFactory::getSource(const conversion::Convertible& value) const { + auto sourceValue = objectMember(value, "source"); + if (!sourceValue) { + return nullopt; + } + + optional<std::string> source = toString(*sourceValue); + if (!source) { + return nullopt; + } + + return source; +} + +bool LayerFactory::initSourceLayerAndFilter(Layer* layer, const conversion::Convertible& value) const { + auto sourceLayerValue = objectMember(value, "source-layer"); + if (sourceLayerValue) { + optional<std::string> sourceLayer = toString(*sourceLayerValue); + if (!sourceLayer) { + return false; + } + layer->setSourceLayer(*sourceLayer); + } + + auto filterValue = objectMember(value, "filter"); + if (filterValue) { + conversion::Error error; + optional<Filter> filter = conversion::convert<Filter>(*filterValue, error); + if (!filter) { + return false; + } + layer->setFilter(*filter); + } + + return true; +} + +// TODO: Move the LayerManager implementation to the dedicated .cpp file per platform. +class LayerManagerImpl : public LayerManager { +public: + void addLayerFactory(LayerFactory* factory) { + factories.emplace(std::make_pair(factory->type(), std::unique_ptr<LayerFactory>(factory))); + } +private: + // LayerManager overrides. + std::unique_ptr<Layer> createLayer(const std::string& type, const std::string& id, const conversion::Convertible& value, conversion::Error& error) final; + + std::unordered_map<std::string, std::unique_ptr<LayerFactory>> factories; +}; + +std::unique_ptr<Layer> LayerManagerImpl::createLayer(const std::string& type, const std::string& id, const conversion::Convertible& value, conversion::Error& error) { + auto search = factories.find(type); + if (search != factories.end()) { + if (auto layer = search->second->createLayer(id, value)) { + return layer; + } + error.message = "Error parsing a layer of type: " + type; + } else { + error.message = "Unsupported layer type: " + type; + } + return nullptr; +} + +// static +LayerManager* LayerManager::get() { + static LayerManager* instance = nullptr; + if (instance == nullptr) { + static LayerManagerImpl impl; + impl.addLayerFactory(new FillLayerFactory); + impl.addLayerFactory(new LineLayerFactory); + impl.addLayerFactory(new CircleLayerFactory); + impl.addLayerFactory(new SymbolLayerFactory); + impl.addLayerFactory(new RasterLayerFactory); + impl.addLayerFactory(new BackgroundLayerFactory); + impl.addLayerFactory(new HillshadeLayerFactory); + impl.addLayerFactory(new FillExtrusionLayerFactory); + impl.addLayerFactory(new HeatmapLayerFactory); + + instance = &impl; + } + return instance; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index 417d288107..b2db8332bc 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -270,5 +270,16 @@ Mutable<Layer::Impl> BackgroundLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +BackgroundLayerFactory::~BackgroundLayerFactory() = default; + +const char* BackgroundLayerFactory::type() const { + return "background"; +} + +std::unique_ptr<style::Layer> BackgroundLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + (void)value; + return std::unique_ptr<style::Layer>(new BackgroundLayer(id)); +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index 34ea80c54c..eda4a9644e 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -687,5 +687,24 @@ Mutable<Layer::Impl> CircleLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +CircleLayerFactory::~CircleLayerFactory() = default; + +const char* CircleLayerFactory::type() const { + return "circle"; +} + +std::unique_ptr<style::Layer> CircleLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new CircleLayer(id, *source)); + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index 3a06cb78c4..f72414557e 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -489,5 +489,24 @@ Mutable<Layer::Impl> FillExtrusionLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +FillExtrusionLayerFactory::~FillExtrusionLayerFactory() = default; + +const char* FillExtrusionLayerFactory::type() const { + return "fill-extrusion"; +} + +std::unique_ptr<style::Layer> FillExtrusionLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new FillExtrusionLayer(id, *source)); + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index b244df6eea..9314d5026a 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -489,5 +489,24 @@ Mutable<Layer::Impl> FillLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +FillLayerFactory::~FillLayerFactory() = default; + +const char* FillLayerFactory::type() const { + return "fill"; +} + +std::unique_ptr<style::Layer> FillLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new FillLayer(id, *source)); + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp index b85cbf5f40..2201a39c8b 100644 --- a/src/mbgl/style/layers/heatmap_layer.cpp +++ b/src/mbgl/style/layers/heatmap_layer.cpp @@ -374,5 +374,24 @@ Mutable<Layer::Impl> HeatmapLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +HeatmapLayerFactory::~HeatmapLayerFactory() = default; + +const char* HeatmapLayerFactory::type() const { + return "heatmap"; +} + +std::unique_ptr<style::Layer> HeatmapLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new HeatmapLayer(id, *source)); + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/hillshade_layer.cpp b/src/mbgl/style/layers/hillshade_layer.cpp index badc9ef30f..b0cb812971 100644 --- a/src/mbgl/style/layers/hillshade_layer.cpp +++ b/src/mbgl/style/layers/hillshade_layer.cpp @@ -421,5 +421,21 @@ Mutable<Layer::Impl> HillshadeLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +HillshadeLayerFactory::~HillshadeLayerFactory() = default; + +const char* HillshadeLayerFactory::type() const { + return "hillshade"; +} + +std::unique_ptr<style::Layer> HillshadeLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new HillshadeLayer(id, *source)); + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index d4404ed949..6d08370342 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -260,5 +260,31 @@ Mutable<Layer::Impl> <%- camelize(type) %>Layer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +<%- camelize(type) %>LayerFactory::~<%- camelize(type) %>LayerFactory() = default; + +const char* <%- camelize(type) %>LayerFactory::type() const { + return "<%- type %>"; +} + +std::unique_ptr<style::Layer> <%- camelize(type) %>LayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { +<% if (type === 'background') { -%> + (void)value; + return std::unique_ptr<style::Layer>(new <%- camelize(type) %>Layer(id)); +<% } else { -%> + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new <%- camelize(type) %>Layer(id, *source)); +<% if (type !== 'raster' && type !== 'hillshade') { -%> + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } +<% } -%> + return layer; +<% } -%> +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index f9fc058ed7..f80cba85f1 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -828,5 +828,24 @@ Mutable<Layer::Impl> LineLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +LineLayerFactory::~LineLayerFactory() = default; + +const char* LineLayerFactory::type() const { + return "line"; +} + +std::unique_ptr<style::Layer> LineLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new LineLayer(id, *source)); + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index 76e433aa73..4cadd26cd3 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -510,5 +510,21 @@ Mutable<Layer::Impl> RasterLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +RasterLayerFactory::~RasterLayerFactory() = default; + +const char* RasterLayerFactory::type() const { + return "raster"; +} + +std::unique_ptr<style::Layer> RasterLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new RasterLayer(id, *source)); + return layer; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index d7d024d0e0..d453ddb58d 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -1978,5 +1978,24 @@ Mutable<Layer::Impl> SymbolLayer::mutableBaseImpl() const { return staticMutableCast<Layer::Impl>(mutableImpl()); } +SymbolLayerFactory::~SymbolLayerFactory() = default; + +const char* SymbolLayerFactory::type() const { + return "symbol"; +} + +std::unique_ptr<style::Layer> SymbolLayerFactory::createLayer(const std::string& id, const conversion::Convertible& value) { + optional<std::string> source = getSource(value); + if (!source) { + return nullptr; + } + + std::unique_ptr<style::Layer> layer = std::unique_ptr<style::Layer>(new SymbolLayer(id, *source)); + if (!initSourceLayerAndFilter(layer.get(), value)) { + return nullptr; + } + return layer; +} + } // namespace style } // namespace mbgl |