From e6cfcba264c3893880eda1c05f2ed90576f3c6c9 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 10:19:56 +0200 Subject: [PATCH 1/8] [core] Add layer serialization method --- include/mbgl/style/filter.hpp | 2 + include/mbgl/style/layer.hpp | 2 + include/mbgl/style/layers/layer.hpp.ejs | 1 + src/mbgl/style/layer.cpp | 48 +++++++++++++++++ src/mbgl/style/layers/layer.cpp.ejs | 69 +++++++++++++++++-------- 5 files changed, 100 insertions(+), 22 deletions(-) diff --git a/include/mbgl/style/filter.hpp b/include/mbgl/style/filter.hpp index c9dc9fb1ec7..e0623a20d46 100644 --- a/include/mbgl/style/filter.hpp +++ b/include/mbgl/style/filter.hpp @@ -28,6 +28,8 @@ class Filter { bool operator()(const expression::EvaluationContext& context) const; + operator bool() const { return expression || legacyFilter; } + friend bool operator==(const Filter& lhs, const Filter& rhs) { if (!lhs.expression || !rhs.expression) { return lhs.expression == rhs.expression; diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp index c80312bc231..840ef9ce880 100644 --- a/include/mbgl/style/layer.hpp +++ b/include/mbgl/style/layer.hpp @@ -114,6 +114,7 @@ class Layer { optional setVisibility(const conversion::Convertible& value); virtual StyleProperty getProperty(const std::string&) const = 0; + virtual Value serialize() const; // Private implementation // TODO : We should not have public mutable data members. @@ -140,6 +141,7 @@ class Layer { protected: virtual Mutable mutableBaseImpl() const = 0; + void serializeProperty(Value&, const StyleProperty&, const char* propertyName, bool isPaint) const; LayerObserver* observer; mapbox::base::WeakPtrFactory weakFactory {this}; diff --git a/include/mbgl/style/layers/layer.hpp.ejs b/include/mbgl/style/layers/layer.hpp.ejs index 3709f53beef..aecbe256018 100644 --- a/include/mbgl/style/layers/layer.hpp.ejs +++ b/include/mbgl/style/layers/layer.hpp.ejs @@ -40,6 +40,7 @@ public: optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; <% if (layoutProperties.length) { -%> // Layout properties diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp index 04a897022c1..3183d84ab55 100644 --- a/src/mbgl/style/layer.cpp +++ b/src/mbgl/style/layer.cpp @@ -91,6 +91,54 @@ void Layer::setMaxZoom(float maxZoom) { observer->onLayerChanged(*this); } +Value Layer::serialize() const { + mapbox::base::ValueObject result; + result.emplace(std::make_pair("id", getID())); + result.emplace(std::make_pair("type", Layer::getTypeInfo()->type)); + + auto source = getSourceID(); + if (!source.empty()) { + result.emplace(std::make_pair("source", std::move(source))); + } + + auto sourceLayer = getSourceLayer(); + if (!sourceLayer.empty()) { + result.emplace(std::make_pair("source-layer", std::move(sourceLayer))); + } + + if (getFilter()) { + result.emplace(std::make_pair("filter", getFilter().serialize())); + } + + if (getMinZoom() != -std::numeric_limits::infinity()) { + result.emplace(std::make_pair("minzoom", getMinZoom())); + } + + if (getMaxZoom() != std::numeric_limits::infinity()) { + result.emplace(std::make_pair("maxzoom", getMaxZoom())); + } + + if (getVisibility() == VisibilityType::None) { + result["layout"] = mapbox::base::ValueObject{std::make_pair("visibility", "none")}; + } + + return result; +} + +void Layer::serializeProperty(Value& out, const StyleProperty& property, const char* propertyName, bool isPaint) const { + assert(out.getObject()); + auto& object = *(out.getObject()); + std::string propertyType = isPaint ? "paint" : "layout"; + auto it = object.find(propertyType); + auto pair = std::make_pair(std::string(propertyName), Value{property.getValue()}); + if (it != object.end()) { + assert(it->second.getObject()); + it->second.getObject()->emplace(std::move(pair)); + } else { + object[propertyType] = mapbox::base::ValueObject{{std::move(pair)}}; + } +} + void Layer::setObserver(LayerObserver* observer_) { observer = observer_ ? observer_ : &nullObserver; } diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index e74e7ab345e..a17b9e803cd 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -200,6 +200,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = <%- paintProperties.length * 2 -%>u; + enum class Property : uint8_t { <% for (const property of paintProperties) { -%> <%- camelize(property.name) %>, @@ -207,8 +209,12 @@ enum class Property : uint8_t { <% for (const property of paintProperties) { -%> <%- camelize(property.name) %>Transition, <% } -%> -<% for (const property of layoutProperties) { -%> - <%- camelize(property.name) %>, +<% for (let i = 0; i < layoutProperties.length; ++i) { -%> +<% if (i===0) { -%> + <%- camelize(layoutProperties[i].name) %> = kPaintPropertyCount, +<% } else { -%> + <%- camelize(layoutProperties[i].name) %>, +<% } -%> <% } -%> }; @@ -225,8 +231,46 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< <%- paintProperties.map(p => `{"${p.name}-transition", toUint8(Property::${camelize(p.name)}Transition)}`).join(',\n ') %>, <%- layoutProperties.map(p => `{"${p.name}", toUint8(Property::${camelize(p.name)})}`).join(',\n ') %>}); <% } -%> + +StyleProperty getLayerProperty(const <%- camelize(type) %>Layer& layer, Property property) { + switch (property) { +<% for (const property of paintProperties) { -%> + case Property::<%- camelize(property.name) %>: + return makeStyleProperty(layer.get<%- camelize(property.name) %>()); +<% } -%> +<% for (const property of paintProperties) { -%> + case Property::<%- camelize(property.name) %>Transition: + return makeStyleProperty(layer.get<%- camelize(property.name) %>Transition()); +<% } -%> +<% for (const property of layoutProperties) { -%> + case Property::<%- camelize(property.name) %>: + return makeStyleProperty(layer.get<%- camelize(property.name) %>()); +<% } -%> + } + return {}; +} + +StyleProperty getLayerProperty(const <%- camelize(type) -%>Layer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value <%- camelize(type) %>Layer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional <%- camelize(type) %>Layer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -289,26 +333,7 @@ optional <%- camelize(type) %>Layer::setProperty(const std::string& name, } StyleProperty <%- camelize(type) %>Layer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { -<% for (const property of paintProperties) { -%> - case Property::<%- camelize(property.name) %>: - return makeStyleProperty(get<%- camelize(property.name) %>()); -<% } -%> -<% for (const property of paintProperties) { -%> - case Property::<%- camelize(property.name) %>Transition: - return makeStyleProperty(get<%- camelize(property.name) %>Transition()); -<% } -%> -<% for (const property of layoutProperties) { -%> - case Property::<%- camelize(property.name) %>: - return makeStyleProperty(get<%- camelize(property.name) %>()); -<% } -%> - } - return {}; + return getLayerProperty(*this, name); } Mutable <%- camelize(type) %>Layer::mutableBaseImpl() const { From 7f93511527170c9b2ec7babd1c7ab921a9dec863 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 10:21:46 +0200 Subject: [PATCH 2/8] [core] Generate layer code --- .../mbgl/style/layers/background_layer.hpp | 1 + include/mbgl/style/layers/circle_layer.hpp | 1 + .../style/layers/fill_extrusion_layer.hpp | 1 + include/mbgl/style/layers/fill_layer.hpp | 1 + include/mbgl/style/layers/heatmap_layer.hpp | 1 + include/mbgl/style/layers/hillshade_layer.hpp | 1 + include/mbgl/style/layers/line_layer.hpp | 1 + include/mbgl/style/layers/raster_layer.hpp | 1 + include/mbgl/style/layers/symbol_layer.hpp | 1 + src/mbgl/style/layers/background_layer.cpp | 61 ++-- src/mbgl/style/layers/circle_layer.cpp | 125 ++++--- .../style/layers/fill_extrusion_layer.cpp | 101 +++--- src/mbgl/style/layers/fill_layer.cpp | 99 +++--- src/mbgl/style/layers/heatmap_layer.cpp | 77 +++-- src/mbgl/style/layers/hillshade_layer.cpp | 85 +++-- src/mbgl/style/layers/line_layer.cpp | 147 ++++---- src/mbgl/style/layers/raster_layer.cpp | 101 +++--- src/mbgl/style/layers/symbol_layer.cpp | 315 ++++++++++-------- 18 files changed, 659 insertions(+), 461 deletions(-) diff --git a/include/mbgl/style/layers/background_layer.hpp b/include/mbgl/style/layers/background_layer.hpp index 1f499884bbd..7f486183462 100644 --- a/include/mbgl/style/layers/background_layer.hpp +++ b/include/mbgl/style/layers/background_layer.hpp @@ -24,6 +24,7 @@ class BackgroundLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Paint properties diff --git a/include/mbgl/style/layers/circle_layer.hpp b/include/mbgl/style/layers/circle_layer.hpp index 6c511345f03..1ad16cd033e 100644 --- a/include/mbgl/style/layers/circle_layer.hpp +++ b/include/mbgl/style/layers/circle_layer.hpp @@ -24,6 +24,7 @@ class CircleLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Paint properties diff --git a/include/mbgl/style/layers/fill_extrusion_layer.hpp b/include/mbgl/style/layers/fill_extrusion_layer.hpp index d4655bd726f..ef692e57081 100644 --- a/include/mbgl/style/layers/fill_extrusion_layer.hpp +++ b/include/mbgl/style/layers/fill_extrusion_layer.hpp @@ -24,6 +24,7 @@ class FillExtrusionLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Paint properties diff --git a/include/mbgl/style/layers/fill_layer.hpp b/include/mbgl/style/layers/fill_layer.hpp index 17dd66859cc..174758a78e6 100644 --- a/include/mbgl/style/layers/fill_layer.hpp +++ b/include/mbgl/style/layers/fill_layer.hpp @@ -24,6 +24,7 @@ class FillLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Layout properties diff --git a/include/mbgl/style/layers/heatmap_layer.hpp b/include/mbgl/style/layers/heatmap_layer.hpp index ae3eb222140..0b740c470ba 100644 --- a/include/mbgl/style/layers/heatmap_layer.hpp +++ b/include/mbgl/style/layers/heatmap_layer.hpp @@ -25,6 +25,7 @@ class HeatmapLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Paint properties diff --git a/include/mbgl/style/layers/hillshade_layer.hpp b/include/mbgl/style/layers/hillshade_layer.hpp index 4c52cd9a222..184e7c390d7 100644 --- a/include/mbgl/style/layers/hillshade_layer.hpp +++ b/include/mbgl/style/layers/hillshade_layer.hpp @@ -24,6 +24,7 @@ class HillshadeLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Paint properties diff --git a/include/mbgl/style/layers/line_layer.hpp b/include/mbgl/style/layers/line_layer.hpp index 9f0882765f4..cef18d9fa8b 100644 --- a/include/mbgl/style/layers/line_layer.hpp +++ b/include/mbgl/style/layers/line_layer.hpp @@ -27,6 +27,7 @@ class LineLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Layout properties diff --git a/include/mbgl/style/layers/raster_layer.hpp b/include/mbgl/style/layers/raster_layer.hpp index 50e9d6d20c1..b1aa3a65b9f 100644 --- a/include/mbgl/style/layers/raster_layer.hpp +++ b/include/mbgl/style/layers/raster_layer.hpp @@ -24,6 +24,7 @@ class RasterLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Paint properties diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index 86208699283..2cffd2294ad 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -26,6 +26,7 @@ class SymbolLayer : public Layer { optional setProperty(const std::string& name, const conversion::Convertible& value) final; StyleProperty getProperty(const std::string& name) const final; + Value serialize() const final; // Layout properties diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index 68b07cba3ca..0b7f0afe4ff 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -148,6 +148,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 6u; + enum class Property : uint8_t { BackgroundColor, BackgroundOpacity, @@ -169,8 +171,46 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"background-color-transition", toUint8(Property::BackgroundColorTransition)}, {"background-opacity-transition", toUint8(Property::BackgroundOpacityTransition)}, {"background-pattern-transition", toUint8(Property::BackgroundPatternTransition)}}); + +StyleProperty getLayerProperty(const BackgroundLayer& layer, Property property) { + switch (property) { + case Property::BackgroundColor: + return makeStyleProperty(layer.getBackgroundColor()); + case Property::BackgroundOpacity: + return makeStyleProperty(layer.getBackgroundOpacity()); + case Property::BackgroundPattern: + return makeStyleProperty(layer.getBackgroundPattern()); + case Property::BackgroundColorTransition: + return makeStyleProperty(layer.getBackgroundColorTransition()); + case Property::BackgroundOpacityTransition: + return makeStyleProperty(layer.getBackgroundOpacityTransition()); + case Property::BackgroundPatternTransition: + return makeStyleProperty(layer.getBackgroundPatternTransition()); + } + return {}; +} + +StyleProperty getLayerProperty(const BackgroundLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value BackgroundLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional BackgroundLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -236,26 +276,7 @@ optional BackgroundLayer::setProperty(const std::string& name, const Conv } StyleProperty BackgroundLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::BackgroundColor: - return makeStyleProperty(getBackgroundColor()); - case Property::BackgroundOpacity: - return makeStyleProperty(getBackgroundOpacity()); - case Property::BackgroundPattern: - return makeStyleProperty(getBackgroundPattern()); - case Property::BackgroundColorTransition: - return makeStyleProperty(getBackgroundColorTransition()); - case Property::BackgroundOpacityTransition: - return makeStyleProperty(getBackgroundOpacityTransition()); - case Property::BackgroundPatternTransition: - return makeStyleProperty(getBackgroundPatternTransition()); - } - return {}; + return getLayerProperty(*this, name); } Mutable BackgroundLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index 7de6fef4823..ca2f93306fc 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -364,6 +364,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 22u; + enum class Property : uint8_t { CircleBlur, CircleColor, @@ -417,8 +419,78 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"circle-stroke-width-transition", toUint8(Property::CircleStrokeWidthTransition)}, {"circle-translate-transition", toUint8(Property::CircleTranslateTransition)}, {"circle-translate-anchor-transition", toUint8(Property::CircleTranslateAnchorTransition)}}); + +StyleProperty getLayerProperty(const CircleLayer& layer, Property property) { + switch (property) { + case Property::CircleBlur: + return makeStyleProperty(layer.getCircleBlur()); + case Property::CircleColor: + return makeStyleProperty(layer.getCircleColor()); + case Property::CircleOpacity: + return makeStyleProperty(layer.getCircleOpacity()); + case Property::CirclePitchAlignment: + return makeStyleProperty(layer.getCirclePitchAlignment()); + case Property::CirclePitchScale: + return makeStyleProperty(layer.getCirclePitchScale()); + case Property::CircleRadius: + return makeStyleProperty(layer.getCircleRadius()); + case Property::CircleStrokeColor: + return makeStyleProperty(layer.getCircleStrokeColor()); + case Property::CircleStrokeOpacity: + return makeStyleProperty(layer.getCircleStrokeOpacity()); + case Property::CircleStrokeWidth: + return makeStyleProperty(layer.getCircleStrokeWidth()); + case Property::CircleTranslate: + return makeStyleProperty(layer.getCircleTranslate()); + case Property::CircleTranslateAnchor: + return makeStyleProperty(layer.getCircleTranslateAnchor()); + case Property::CircleBlurTransition: + return makeStyleProperty(layer.getCircleBlurTransition()); + case Property::CircleColorTransition: + return makeStyleProperty(layer.getCircleColorTransition()); + case Property::CircleOpacityTransition: + return makeStyleProperty(layer.getCircleOpacityTransition()); + case Property::CirclePitchAlignmentTransition: + return makeStyleProperty(layer.getCirclePitchAlignmentTransition()); + case Property::CirclePitchScaleTransition: + return makeStyleProperty(layer.getCirclePitchScaleTransition()); + case Property::CircleRadiusTransition: + return makeStyleProperty(layer.getCircleRadiusTransition()); + case Property::CircleStrokeColorTransition: + return makeStyleProperty(layer.getCircleStrokeColorTransition()); + case Property::CircleStrokeOpacityTransition: + return makeStyleProperty(layer.getCircleStrokeOpacityTransition()); + case Property::CircleStrokeWidthTransition: + return makeStyleProperty(layer.getCircleStrokeWidthTransition()); + case Property::CircleTranslateTransition: + return makeStyleProperty(layer.getCircleTranslateTransition()); + case Property::CircleTranslateAnchorTransition: + return makeStyleProperty(layer.getCircleTranslateAnchorTransition()); + } + return {}; +} + +StyleProperty getLayerProperty(const CircleLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value CircleLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional CircleLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -584,58 +656,7 @@ optional CircleLayer::setProperty(const std::string& name, const Converti } StyleProperty CircleLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::CircleBlur: - return makeStyleProperty(getCircleBlur()); - case Property::CircleColor: - return makeStyleProperty(getCircleColor()); - case Property::CircleOpacity: - return makeStyleProperty(getCircleOpacity()); - case Property::CirclePitchAlignment: - return makeStyleProperty(getCirclePitchAlignment()); - case Property::CirclePitchScale: - return makeStyleProperty(getCirclePitchScale()); - case Property::CircleRadius: - return makeStyleProperty(getCircleRadius()); - case Property::CircleStrokeColor: - return makeStyleProperty(getCircleStrokeColor()); - case Property::CircleStrokeOpacity: - return makeStyleProperty(getCircleStrokeOpacity()); - case Property::CircleStrokeWidth: - return makeStyleProperty(getCircleStrokeWidth()); - case Property::CircleTranslate: - return makeStyleProperty(getCircleTranslate()); - case Property::CircleTranslateAnchor: - return makeStyleProperty(getCircleTranslateAnchor()); - case Property::CircleBlurTransition: - return makeStyleProperty(getCircleBlurTransition()); - case Property::CircleColorTransition: - return makeStyleProperty(getCircleColorTransition()); - case Property::CircleOpacityTransition: - return makeStyleProperty(getCircleOpacityTransition()); - case Property::CirclePitchAlignmentTransition: - return makeStyleProperty(getCirclePitchAlignmentTransition()); - case Property::CirclePitchScaleTransition: - return makeStyleProperty(getCirclePitchScaleTransition()); - case Property::CircleRadiusTransition: - return makeStyleProperty(getCircleRadiusTransition()); - case Property::CircleStrokeColorTransition: - return makeStyleProperty(getCircleStrokeColorTransition()); - case Property::CircleStrokeOpacityTransition: - return makeStyleProperty(getCircleStrokeOpacityTransition()); - case Property::CircleStrokeWidthTransition: - return makeStyleProperty(getCircleStrokeWidthTransition()); - case Property::CircleTranslateTransition: - return makeStyleProperty(getCircleTranslateTransition()); - case Property::CircleTranslateAnchorTransition: - return makeStyleProperty(getCircleTranslateAnchorTransition()); - } - return {}; + return getLayerProperty(*this, name); } Mutable CircleLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index 2de27f39035..c9819f66f17 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -283,6 +283,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 16u; + enum class Property : uint8_t { FillExtrusionBase, FillExtrusionColor, @@ -324,8 +326,66 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"fill-extrusion-translate-transition", toUint8(Property::FillExtrusionTranslateTransition)}, {"fill-extrusion-translate-anchor-transition", toUint8(Property::FillExtrusionTranslateAnchorTransition)}, {"fill-extrusion-vertical-gradient-transition", toUint8(Property::FillExtrusionVerticalGradientTransition)}}); + +StyleProperty getLayerProperty(const FillExtrusionLayer& layer, Property property) { + switch (property) { + case Property::FillExtrusionBase: + return makeStyleProperty(layer.getFillExtrusionBase()); + case Property::FillExtrusionColor: + return makeStyleProperty(layer.getFillExtrusionColor()); + case Property::FillExtrusionHeight: + return makeStyleProperty(layer.getFillExtrusionHeight()); + case Property::FillExtrusionOpacity: + return makeStyleProperty(layer.getFillExtrusionOpacity()); + case Property::FillExtrusionPattern: + return makeStyleProperty(layer.getFillExtrusionPattern()); + case Property::FillExtrusionTranslate: + return makeStyleProperty(layer.getFillExtrusionTranslate()); + case Property::FillExtrusionTranslateAnchor: + return makeStyleProperty(layer.getFillExtrusionTranslateAnchor()); + case Property::FillExtrusionVerticalGradient: + return makeStyleProperty(layer.getFillExtrusionVerticalGradient()); + case Property::FillExtrusionBaseTransition: + return makeStyleProperty(layer.getFillExtrusionBaseTransition()); + case Property::FillExtrusionColorTransition: + return makeStyleProperty(layer.getFillExtrusionColorTransition()); + case Property::FillExtrusionHeightTransition: + return makeStyleProperty(layer.getFillExtrusionHeightTransition()); + case Property::FillExtrusionOpacityTransition: + return makeStyleProperty(layer.getFillExtrusionOpacityTransition()); + case Property::FillExtrusionPatternTransition: + return makeStyleProperty(layer.getFillExtrusionPatternTransition()); + case Property::FillExtrusionTranslateTransition: + return makeStyleProperty(layer.getFillExtrusionTranslateTransition()); + case Property::FillExtrusionTranslateAnchorTransition: + return makeStyleProperty(layer.getFillExtrusionTranslateAnchorTransition()); + case Property::FillExtrusionVerticalGradientTransition: + return makeStyleProperty(layer.getFillExtrusionVerticalGradientTransition()); + } + return {}; +} + +StyleProperty getLayerProperty(const FillExtrusionLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value FillExtrusionLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional FillExtrusionLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -463,46 +523,7 @@ optional FillExtrusionLayer::setProperty(const std::string& name, const C } StyleProperty FillExtrusionLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::FillExtrusionBase: - return makeStyleProperty(getFillExtrusionBase()); - case Property::FillExtrusionColor: - return makeStyleProperty(getFillExtrusionColor()); - case Property::FillExtrusionHeight: - return makeStyleProperty(getFillExtrusionHeight()); - case Property::FillExtrusionOpacity: - return makeStyleProperty(getFillExtrusionOpacity()); - case Property::FillExtrusionPattern: - return makeStyleProperty(getFillExtrusionPattern()); - case Property::FillExtrusionTranslate: - return makeStyleProperty(getFillExtrusionTranslate()); - case Property::FillExtrusionTranslateAnchor: - return makeStyleProperty(getFillExtrusionTranslateAnchor()); - case Property::FillExtrusionVerticalGradient: - return makeStyleProperty(getFillExtrusionVerticalGradient()); - case Property::FillExtrusionBaseTransition: - return makeStyleProperty(getFillExtrusionBaseTransition()); - case Property::FillExtrusionColorTransition: - return makeStyleProperty(getFillExtrusionColorTransition()); - case Property::FillExtrusionHeightTransition: - return makeStyleProperty(getFillExtrusionHeightTransition()); - case Property::FillExtrusionOpacityTransition: - return makeStyleProperty(getFillExtrusionOpacityTransition()); - case Property::FillExtrusionPatternTransition: - return makeStyleProperty(getFillExtrusionPatternTransition()); - case Property::FillExtrusionTranslateTransition: - return makeStyleProperty(getFillExtrusionTranslateTransition()); - case Property::FillExtrusionTranslateAnchorTransition: - return makeStyleProperty(getFillExtrusionTranslateAnchorTransition()); - case Property::FillExtrusionVerticalGradientTransition: - return makeStyleProperty(getFillExtrusionVerticalGradientTransition()); - } - return {}; + return getLayerProperty(*this, name); } Mutable FillExtrusionLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index 757738dfefd..914a23d96b8 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -272,6 +272,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 14u; + enum class Property : uint8_t { FillAntialias, FillColor, @@ -287,7 +289,7 @@ enum class Property : uint8_t { FillPatternTransition, FillTranslateTransition, FillTranslateAnchorTransition, - FillSortKey, + FillSortKey = kPaintPropertyCount, }; template @@ -311,8 +313,64 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"fill-translate-transition", toUint8(Property::FillTranslateTransition)}, {"fill-translate-anchor-transition", toUint8(Property::FillTranslateAnchorTransition)}, {"fill-sort-key", toUint8(Property::FillSortKey)}}); + +StyleProperty getLayerProperty(const FillLayer& layer, Property property) { + switch (property) { + case Property::FillAntialias: + return makeStyleProperty(layer.getFillAntialias()); + case Property::FillColor: + return makeStyleProperty(layer.getFillColor()); + case Property::FillOpacity: + return makeStyleProperty(layer.getFillOpacity()); + case Property::FillOutlineColor: + return makeStyleProperty(layer.getFillOutlineColor()); + case Property::FillPattern: + return makeStyleProperty(layer.getFillPattern()); + case Property::FillTranslate: + return makeStyleProperty(layer.getFillTranslate()); + case Property::FillTranslateAnchor: + return makeStyleProperty(layer.getFillTranslateAnchor()); + case Property::FillAntialiasTransition: + return makeStyleProperty(layer.getFillAntialiasTransition()); + case Property::FillColorTransition: + return makeStyleProperty(layer.getFillColorTransition()); + case Property::FillOpacityTransition: + return makeStyleProperty(layer.getFillOpacityTransition()); + case Property::FillOutlineColorTransition: + return makeStyleProperty(layer.getFillOutlineColorTransition()); + case Property::FillPatternTransition: + return makeStyleProperty(layer.getFillPatternTransition()); + case Property::FillTranslateTransition: + return makeStyleProperty(layer.getFillTranslateTransition()); + case Property::FillTranslateAnchorTransition: + return makeStyleProperty(layer.getFillTranslateAnchorTransition()); + case Property::FillSortKey: + return makeStyleProperty(layer.getFillSortKey()); + } + return {}; +} + +StyleProperty getLayerProperty(const FillLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value FillLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional FillLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -442,44 +500,7 @@ optional FillLayer::setProperty(const std::string& name, const Convertibl } StyleProperty FillLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::FillAntialias: - return makeStyleProperty(getFillAntialias()); - case Property::FillColor: - return makeStyleProperty(getFillColor()); - case Property::FillOpacity: - return makeStyleProperty(getFillOpacity()); - case Property::FillOutlineColor: - return makeStyleProperty(getFillOutlineColor()); - case Property::FillPattern: - return makeStyleProperty(getFillPattern()); - case Property::FillTranslate: - return makeStyleProperty(getFillTranslate()); - case Property::FillTranslateAnchor: - return makeStyleProperty(getFillTranslateAnchor()); - case Property::FillAntialiasTransition: - return makeStyleProperty(getFillAntialiasTransition()); - case Property::FillColorTransition: - return makeStyleProperty(getFillColorTransition()); - case Property::FillOpacityTransition: - return makeStyleProperty(getFillOpacityTransition()); - case Property::FillOutlineColorTransition: - return makeStyleProperty(getFillOutlineColorTransition()); - case Property::FillPatternTransition: - return makeStyleProperty(getFillPatternTransition()); - case Property::FillTranslateTransition: - return makeStyleProperty(getFillTranslateTransition()); - case Property::FillTranslateAnchorTransition: - return makeStyleProperty(getFillTranslateAnchorTransition()); - case Property::FillSortKey: - return makeStyleProperty(getFillSortKey()); - } - return {}; + return getLayerProperty(*this, name); } Mutable FillLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp index ba645a4a182..bfac173d636 100644 --- a/src/mbgl/style/layers/heatmap_layer.cpp +++ b/src/mbgl/style/layers/heatmap_layer.cpp @@ -204,6 +204,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 10u; + enum class Property : uint8_t { HeatmapColor, HeatmapIntensity, @@ -233,8 +235,54 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"heatmap-opacity-transition", toUint8(Property::HeatmapOpacityTransition)}, {"heatmap-radius-transition", toUint8(Property::HeatmapRadiusTransition)}, {"heatmap-weight-transition", toUint8(Property::HeatmapWeightTransition)}}); + +StyleProperty getLayerProperty(const HeatmapLayer& layer, Property property) { + switch (property) { + case Property::HeatmapColor: + return makeStyleProperty(layer.getHeatmapColor()); + case Property::HeatmapIntensity: + return makeStyleProperty(layer.getHeatmapIntensity()); + case Property::HeatmapOpacity: + return makeStyleProperty(layer.getHeatmapOpacity()); + case Property::HeatmapRadius: + return makeStyleProperty(layer.getHeatmapRadius()); + case Property::HeatmapWeight: + return makeStyleProperty(layer.getHeatmapWeight()); + case Property::HeatmapColorTransition: + return makeStyleProperty(layer.getHeatmapColorTransition()); + case Property::HeatmapIntensityTransition: + return makeStyleProperty(layer.getHeatmapIntensityTransition()); + case Property::HeatmapOpacityTransition: + return makeStyleProperty(layer.getHeatmapOpacityTransition()); + case Property::HeatmapRadiusTransition: + return makeStyleProperty(layer.getHeatmapRadiusTransition()); + case Property::HeatmapWeightTransition: + return makeStyleProperty(layer.getHeatmapWeightTransition()); + } + return {}; +} + +StyleProperty getLayerProperty(const HeatmapLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value HeatmapLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional HeatmapLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -324,34 +372,7 @@ optional HeatmapLayer::setProperty(const std::string& name, const Convert } StyleProperty HeatmapLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::HeatmapColor: - return makeStyleProperty(getHeatmapColor()); - case Property::HeatmapIntensity: - return makeStyleProperty(getHeatmapIntensity()); - case Property::HeatmapOpacity: - return makeStyleProperty(getHeatmapOpacity()); - case Property::HeatmapRadius: - return makeStyleProperty(getHeatmapRadius()); - case Property::HeatmapWeight: - return makeStyleProperty(getHeatmapWeight()); - case Property::HeatmapColorTransition: - return makeStyleProperty(getHeatmapColorTransition()); - case Property::HeatmapIntensityTransition: - return makeStyleProperty(getHeatmapIntensityTransition()); - case Property::HeatmapOpacityTransition: - return makeStyleProperty(getHeatmapOpacityTransition()); - case Property::HeatmapRadiusTransition: - return makeStyleProperty(getHeatmapRadiusTransition()); - case Property::HeatmapWeightTransition: - return makeStyleProperty(getHeatmapWeightTransition()); - } - return {}; + return getLayerProperty(*this, name); } Mutable HeatmapLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/hillshade_layer.cpp b/src/mbgl/style/layers/hillshade_layer.cpp index 26ecfadfcc4..bfbd3d1d14c 100644 --- a/src/mbgl/style/layers/hillshade_layer.cpp +++ b/src/mbgl/style/layers/hillshade_layer.cpp @@ -229,6 +229,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 12u; + enum class Property : uint8_t { HillshadeAccentColor, HillshadeExaggeration, @@ -262,8 +264,58 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"hillshade-illumination-anchor-transition", toUint8(Property::HillshadeIlluminationAnchorTransition)}, {"hillshade-illumination-direction-transition", toUint8(Property::HillshadeIlluminationDirectionTransition)}, {"hillshade-shadow-color-transition", toUint8(Property::HillshadeShadowColorTransition)}}); + +StyleProperty getLayerProperty(const HillshadeLayer& layer, Property property) { + switch (property) { + case Property::HillshadeAccentColor: + return makeStyleProperty(layer.getHillshadeAccentColor()); + case Property::HillshadeExaggeration: + return makeStyleProperty(layer.getHillshadeExaggeration()); + case Property::HillshadeHighlightColor: + return makeStyleProperty(layer.getHillshadeHighlightColor()); + case Property::HillshadeIlluminationAnchor: + return makeStyleProperty(layer.getHillshadeIlluminationAnchor()); + case Property::HillshadeIlluminationDirection: + return makeStyleProperty(layer.getHillshadeIlluminationDirection()); + case Property::HillshadeShadowColor: + return makeStyleProperty(layer.getHillshadeShadowColor()); + case Property::HillshadeAccentColorTransition: + return makeStyleProperty(layer.getHillshadeAccentColorTransition()); + case Property::HillshadeExaggerationTransition: + return makeStyleProperty(layer.getHillshadeExaggerationTransition()); + case Property::HillshadeHighlightColorTransition: + return makeStyleProperty(layer.getHillshadeHighlightColorTransition()); + case Property::HillshadeIlluminationAnchorTransition: + return makeStyleProperty(layer.getHillshadeIlluminationAnchorTransition()); + case Property::HillshadeIlluminationDirectionTransition: + return makeStyleProperty(layer.getHillshadeIlluminationDirectionTransition()); + case Property::HillshadeShadowColorTransition: + return makeStyleProperty(layer.getHillshadeShadowColorTransition()); + } + return {}; +} + +StyleProperty getLayerProperty(const HillshadeLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value HillshadeLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional HillshadeLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -364,38 +416,7 @@ optional HillshadeLayer::setProperty(const std::string& name, const Conve } StyleProperty HillshadeLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::HillshadeAccentColor: - return makeStyleProperty(getHillshadeAccentColor()); - case Property::HillshadeExaggeration: - return makeStyleProperty(getHillshadeExaggeration()); - case Property::HillshadeHighlightColor: - return makeStyleProperty(getHillshadeHighlightColor()); - case Property::HillshadeIlluminationAnchor: - return makeStyleProperty(getHillshadeIlluminationAnchor()); - case Property::HillshadeIlluminationDirection: - return makeStyleProperty(getHillshadeIlluminationDirection()); - case Property::HillshadeShadowColor: - return makeStyleProperty(getHillshadeShadowColor()); - case Property::HillshadeAccentColorTransition: - return makeStyleProperty(getHillshadeAccentColorTransition()); - case Property::HillshadeExaggerationTransition: - return makeStyleProperty(getHillshadeExaggerationTransition()); - case Property::HillshadeHighlightColorTransition: - return makeStyleProperty(getHillshadeHighlightColorTransition()); - case Property::HillshadeIlluminationAnchorTransition: - return makeStyleProperty(getHillshadeIlluminationAnchorTransition()); - case Property::HillshadeIlluminationDirectionTransition: - return makeStyleProperty(getHillshadeIlluminationDirectionTransition()); - case Property::HillshadeShadowColorTransition: - return makeStyleProperty(getHillshadeShadowColorTransition()); - } - return {}; + return getLayerProperty(*this, name); } Mutable HillshadeLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index caa7f44e0c6..69c0af09589 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -441,6 +441,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 22u; + enum class Property : uint8_t { LineBlur, LineColor, @@ -464,7 +466,7 @@ enum class Property : uint8_t { LineTranslateTransition, LineTranslateAnchorTransition, LineWidthTransition, - LineCap, + LineCap = kPaintPropertyCount, LineJoin, LineMiterLimit, LineRoundLimit, @@ -504,8 +506,88 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"line-miter-limit", toUint8(Property::LineMiterLimit)}, {"line-round-limit", toUint8(Property::LineRoundLimit)}, {"line-sort-key", toUint8(Property::LineSortKey)}}); + +StyleProperty getLayerProperty(const LineLayer& layer, Property property) { + switch (property) { + case Property::LineBlur: + return makeStyleProperty(layer.getLineBlur()); + case Property::LineColor: + return makeStyleProperty(layer.getLineColor()); + case Property::LineDasharray: + return makeStyleProperty(layer.getLineDasharray()); + case Property::LineGapWidth: + return makeStyleProperty(layer.getLineGapWidth()); + case Property::LineGradient: + return makeStyleProperty(layer.getLineGradient()); + case Property::LineOffset: + return makeStyleProperty(layer.getLineOffset()); + case Property::LineOpacity: + return makeStyleProperty(layer.getLineOpacity()); + case Property::LinePattern: + return makeStyleProperty(layer.getLinePattern()); + case Property::LineTranslate: + return makeStyleProperty(layer.getLineTranslate()); + case Property::LineTranslateAnchor: + return makeStyleProperty(layer.getLineTranslateAnchor()); + case Property::LineWidth: + return makeStyleProperty(layer.getLineWidth()); + case Property::LineBlurTransition: + return makeStyleProperty(layer.getLineBlurTransition()); + case Property::LineColorTransition: + return makeStyleProperty(layer.getLineColorTransition()); + case Property::LineDasharrayTransition: + return makeStyleProperty(layer.getLineDasharrayTransition()); + case Property::LineGapWidthTransition: + return makeStyleProperty(layer.getLineGapWidthTransition()); + case Property::LineGradientTransition: + return makeStyleProperty(layer.getLineGradientTransition()); + case Property::LineOffsetTransition: + return makeStyleProperty(layer.getLineOffsetTransition()); + case Property::LineOpacityTransition: + return makeStyleProperty(layer.getLineOpacityTransition()); + case Property::LinePatternTransition: + return makeStyleProperty(layer.getLinePatternTransition()); + case Property::LineTranslateTransition: + return makeStyleProperty(layer.getLineTranslateTransition()); + case Property::LineTranslateAnchorTransition: + return makeStyleProperty(layer.getLineTranslateAnchorTransition()); + case Property::LineWidthTransition: + return makeStyleProperty(layer.getLineWidthTransition()); + case Property::LineCap: + return makeStyleProperty(layer.getLineCap()); + case Property::LineJoin: + return makeStyleProperty(layer.getLineJoin()); + case Property::LineMiterLimit: + return makeStyleProperty(layer.getLineMiterLimit()); + case Property::LineRoundLimit: + return makeStyleProperty(layer.getLineRoundLimit()); + case Property::LineSortKey: + return makeStyleProperty(layer.getLineSortKey()); + } + return {}; +} + +StyleProperty getLayerProperty(const LineLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value LineLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional LineLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -716,68 +798,7 @@ optional LineLayer::setProperty(const std::string& name, const Convertibl } StyleProperty LineLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::LineBlur: - return makeStyleProperty(getLineBlur()); - case Property::LineColor: - return makeStyleProperty(getLineColor()); - case Property::LineDasharray: - return makeStyleProperty(getLineDasharray()); - case Property::LineGapWidth: - return makeStyleProperty(getLineGapWidth()); - case Property::LineGradient: - return makeStyleProperty(getLineGradient()); - case Property::LineOffset: - return makeStyleProperty(getLineOffset()); - case Property::LineOpacity: - return makeStyleProperty(getLineOpacity()); - case Property::LinePattern: - return makeStyleProperty(getLinePattern()); - case Property::LineTranslate: - return makeStyleProperty(getLineTranslate()); - case Property::LineTranslateAnchor: - return makeStyleProperty(getLineTranslateAnchor()); - case Property::LineWidth: - return makeStyleProperty(getLineWidth()); - case Property::LineBlurTransition: - return makeStyleProperty(getLineBlurTransition()); - case Property::LineColorTransition: - return makeStyleProperty(getLineColorTransition()); - case Property::LineDasharrayTransition: - return makeStyleProperty(getLineDasharrayTransition()); - case Property::LineGapWidthTransition: - return makeStyleProperty(getLineGapWidthTransition()); - case Property::LineGradientTransition: - return makeStyleProperty(getLineGradientTransition()); - case Property::LineOffsetTransition: - return makeStyleProperty(getLineOffsetTransition()); - case Property::LineOpacityTransition: - return makeStyleProperty(getLineOpacityTransition()); - case Property::LinePatternTransition: - return makeStyleProperty(getLinePatternTransition()); - case Property::LineTranslateTransition: - return makeStyleProperty(getLineTranslateTransition()); - case Property::LineTranslateAnchorTransition: - return makeStyleProperty(getLineTranslateAnchorTransition()); - case Property::LineWidthTransition: - return makeStyleProperty(getLineWidthTransition()); - case Property::LineCap: - return makeStyleProperty(getLineCap()); - case Property::LineJoin: - return makeStyleProperty(getLineJoin()); - case Property::LineMiterLimit: - return makeStyleProperty(getLineMiterLimit()); - case Property::LineRoundLimit: - return makeStyleProperty(getLineRoundLimit()); - case Property::LineSortKey: - return makeStyleProperty(getLineSortKey()); - } - return {}; + return getLayerProperty(*this, name); } Mutable LineLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index 97c67de2996..3222eebd737 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -283,6 +283,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 16u; + enum class Property : uint8_t { RasterBrightnessMax, RasterBrightnessMin, @@ -324,8 +326,66 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"raster-opacity-transition", toUint8(Property::RasterOpacityTransition)}, {"raster-resampling-transition", toUint8(Property::RasterResamplingTransition)}, {"raster-saturation-transition", toUint8(Property::RasterSaturationTransition)}}); + +StyleProperty getLayerProperty(const RasterLayer& layer, Property property) { + switch (property) { + case Property::RasterBrightnessMax: + return makeStyleProperty(layer.getRasterBrightnessMax()); + case Property::RasterBrightnessMin: + return makeStyleProperty(layer.getRasterBrightnessMin()); + case Property::RasterContrast: + return makeStyleProperty(layer.getRasterContrast()); + case Property::RasterFadeDuration: + return makeStyleProperty(layer.getRasterFadeDuration()); + case Property::RasterHueRotate: + return makeStyleProperty(layer.getRasterHueRotate()); + case Property::RasterOpacity: + return makeStyleProperty(layer.getRasterOpacity()); + case Property::RasterResampling: + return makeStyleProperty(layer.getRasterResampling()); + case Property::RasterSaturation: + return makeStyleProperty(layer.getRasterSaturation()); + case Property::RasterBrightnessMaxTransition: + return makeStyleProperty(layer.getRasterBrightnessMaxTransition()); + case Property::RasterBrightnessMinTransition: + return makeStyleProperty(layer.getRasterBrightnessMinTransition()); + case Property::RasterContrastTransition: + return makeStyleProperty(layer.getRasterContrastTransition()); + case Property::RasterFadeDurationTransition: + return makeStyleProperty(layer.getRasterFadeDurationTransition()); + case Property::RasterHueRotateTransition: + return makeStyleProperty(layer.getRasterHueRotateTransition()); + case Property::RasterOpacityTransition: + return makeStyleProperty(layer.getRasterOpacityTransition()); + case Property::RasterResamplingTransition: + return makeStyleProperty(layer.getRasterResamplingTransition()); + case Property::RasterSaturationTransition: + return makeStyleProperty(layer.getRasterSaturationTransition()); + } + return {}; +} + +StyleProperty getLayerProperty(const RasterLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value RasterLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional RasterLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -441,46 +501,7 @@ optional RasterLayer::setProperty(const std::string& name, const Converti } StyleProperty RasterLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::RasterBrightnessMax: - return makeStyleProperty(getRasterBrightnessMax()); - case Property::RasterBrightnessMin: - return makeStyleProperty(getRasterBrightnessMin()); - case Property::RasterContrast: - return makeStyleProperty(getRasterContrast()); - case Property::RasterFadeDuration: - return makeStyleProperty(getRasterFadeDuration()); - case Property::RasterHueRotate: - return makeStyleProperty(getRasterHueRotate()); - case Property::RasterOpacity: - return makeStyleProperty(getRasterOpacity()); - case Property::RasterResampling: - return makeStyleProperty(getRasterResampling()); - case Property::RasterSaturation: - return makeStyleProperty(getRasterSaturation()); - case Property::RasterBrightnessMaxTransition: - return makeStyleProperty(getRasterBrightnessMaxTransition()); - case Property::RasterBrightnessMinTransition: - return makeStyleProperty(getRasterBrightnessMinTransition()); - case Property::RasterContrastTransition: - return makeStyleProperty(getRasterContrastTransition()); - case Property::RasterFadeDurationTransition: - return makeStyleProperty(getRasterFadeDurationTransition()); - case Property::RasterHueRotateTransition: - return makeStyleProperty(getRasterHueRotateTransition()); - case Property::RasterOpacityTransition: - return makeStyleProperty(getRasterOpacityTransition()); - case Property::RasterResamplingTransition: - return makeStyleProperty(getRasterResamplingTransition()); - case Property::RasterSaturationTransition: - return makeStyleProperty(getRasterSaturationTransition()); - } - return {}; + return getLayerProperty(*this, name); } Mutable RasterLayer::mutableBaseImpl() const { diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 39c2f2a052e..7154bffff22 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -1061,6 +1061,8 @@ using namespace conversion; namespace { +constexpr uint8_t kPaintPropertyCount = 28u; + enum class Property : uint8_t { IconColor, IconHaloBlur, @@ -1090,7 +1092,7 @@ enum class Property : uint8_t { TextOpacityTransition, TextTranslateTransition, TextTranslateAnchorTransition, - IconAllowOverlap, + IconAllowOverlap = kPaintPropertyCount, IconAnchor, IconIgnorePlacement, IconImage, @@ -1208,8 +1210,172 @@ MAPBOX_ETERNAL_CONSTEXPR const auto layerProperties = mapbox::eternal::hash_map< {"text-transform", toUint8(Property::TextTransform)}, {"text-variable-anchor", toUint8(Property::TextVariableAnchor)}, {"text-writing-mode", toUint8(Property::TextWritingMode)}}); + +StyleProperty getLayerProperty(const SymbolLayer& layer, Property property) { + switch (property) { + case Property::IconColor: + return makeStyleProperty(layer.getIconColor()); + case Property::IconHaloBlur: + return makeStyleProperty(layer.getIconHaloBlur()); + case Property::IconHaloColor: + return makeStyleProperty(layer.getIconHaloColor()); + case Property::IconHaloWidth: + return makeStyleProperty(layer.getIconHaloWidth()); + case Property::IconOpacity: + return makeStyleProperty(layer.getIconOpacity()); + case Property::IconTranslate: + return makeStyleProperty(layer.getIconTranslate()); + case Property::IconTranslateAnchor: + return makeStyleProperty(layer.getIconTranslateAnchor()); + case Property::TextColor: + return makeStyleProperty(layer.getTextColor()); + case Property::TextHaloBlur: + return makeStyleProperty(layer.getTextHaloBlur()); + case Property::TextHaloColor: + return makeStyleProperty(layer.getTextHaloColor()); + case Property::TextHaloWidth: + return makeStyleProperty(layer.getTextHaloWidth()); + case Property::TextOpacity: + return makeStyleProperty(layer.getTextOpacity()); + case Property::TextTranslate: + return makeStyleProperty(layer.getTextTranslate()); + case Property::TextTranslateAnchor: + return makeStyleProperty(layer.getTextTranslateAnchor()); + case Property::IconColorTransition: + return makeStyleProperty(layer.getIconColorTransition()); + case Property::IconHaloBlurTransition: + return makeStyleProperty(layer.getIconHaloBlurTransition()); + case Property::IconHaloColorTransition: + return makeStyleProperty(layer.getIconHaloColorTransition()); + case Property::IconHaloWidthTransition: + return makeStyleProperty(layer.getIconHaloWidthTransition()); + case Property::IconOpacityTransition: + return makeStyleProperty(layer.getIconOpacityTransition()); + case Property::IconTranslateTransition: + return makeStyleProperty(layer.getIconTranslateTransition()); + case Property::IconTranslateAnchorTransition: + return makeStyleProperty(layer.getIconTranslateAnchorTransition()); + case Property::TextColorTransition: + return makeStyleProperty(layer.getTextColorTransition()); + case Property::TextHaloBlurTransition: + return makeStyleProperty(layer.getTextHaloBlurTransition()); + case Property::TextHaloColorTransition: + return makeStyleProperty(layer.getTextHaloColorTransition()); + case Property::TextHaloWidthTransition: + return makeStyleProperty(layer.getTextHaloWidthTransition()); + case Property::TextOpacityTransition: + return makeStyleProperty(layer.getTextOpacityTransition()); + case Property::TextTranslateTransition: + return makeStyleProperty(layer.getTextTranslateTransition()); + case Property::TextTranslateAnchorTransition: + return makeStyleProperty(layer.getTextTranslateAnchorTransition()); + case Property::IconAllowOverlap: + return makeStyleProperty(layer.getIconAllowOverlap()); + case Property::IconAnchor: + return makeStyleProperty(layer.getIconAnchor()); + case Property::IconIgnorePlacement: + return makeStyleProperty(layer.getIconIgnorePlacement()); + case Property::IconImage: + return makeStyleProperty(layer.getIconImage()); + case Property::IconKeepUpright: + return makeStyleProperty(layer.getIconKeepUpright()); + case Property::IconOffset: + return makeStyleProperty(layer.getIconOffset()); + case Property::IconOptional: + return makeStyleProperty(layer.getIconOptional()); + case Property::IconPadding: + return makeStyleProperty(layer.getIconPadding()); + case Property::IconPitchAlignment: + return makeStyleProperty(layer.getIconPitchAlignment()); + case Property::IconRotate: + return makeStyleProperty(layer.getIconRotate()); + case Property::IconRotationAlignment: + return makeStyleProperty(layer.getIconRotationAlignment()); + case Property::IconSize: + return makeStyleProperty(layer.getIconSize()); + case Property::IconTextFit: + return makeStyleProperty(layer.getIconTextFit()); + case Property::IconTextFitPadding: + return makeStyleProperty(layer.getIconTextFitPadding()); + case Property::SymbolAvoidEdges: + return makeStyleProperty(layer.getSymbolAvoidEdges()); + case Property::SymbolPlacement: + return makeStyleProperty(layer.getSymbolPlacement()); + case Property::SymbolSortKey: + return makeStyleProperty(layer.getSymbolSortKey()); + case Property::SymbolSpacing: + return makeStyleProperty(layer.getSymbolSpacing()); + case Property::SymbolZOrder: + return makeStyleProperty(layer.getSymbolZOrder()); + case Property::TextAllowOverlap: + return makeStyleProperty(layer.getTextAllowOverlap()); + case Property::TextAnchor: + return makeStyleProperty(layer.getTextAnchor()); + case Property::TextField: + return makeStyleProperty(layer.getTextField()); + case Property::TextFont: + return makeStyleProperty(layer.getTextFont()); + case Property::TextIgnorePlacement: + return makeStyleProperty(layer.getTextIgnorePlacement()); + case Property::TextJustify: + return makeStyleProperty(layer.getTextJustify()); + case Property::TextKeepUpright: + return makeStyleProperty(layer.getTextKeepUpright()); + case Property::TextLetterSpacing: + return makeStyleProperty(layer.getTextLetterSpacing()); + case Property::TextLineHeight: + return makeStyleProperty(layer.getTextLineHeight()); + case Property::TextMaxAngle: + return makeStyleProperty(layer.getTextMaxAngle()); + case Property::TextMaxWidth: + return makeStyleProperty(layer.getTextMaxWidth()); + case Property::TextOffset: + return makeStyleProperty(layer.getTextOffset()); + case Property::TextOptional: + return makeStyleProperty(layer.getTextOptional()); + case Property::TextPadding: + return makeStyleProperty(layer.getTextPadding()); + case Property::TextPitchAlignment: + return makeStyleProperty(layer.getTextPitchAlignment()); + case Property::TextRadialOffset: + return makeStyleProperty(layer.getTextRadialOffset()); + case Property::TextRotate: + return makeStyleProperty(layer.getTextRotate()); + case Property::TextRotationAlignment: + return makeStyleProperty(layer.getTextRotationAlignment()); + case Property::TextSize: + return makeStyleProperty(layer.getTextSize()); + case Property::TextTransform: + return makeStyleProperty(layer.getTextTransform()); + case Property::TextVariableAnchor: + return makeStyleProperty(layer.getTextVariableAnchor()); + case Property::TextWritingMode: + return makeStyleProperty(layer.getTextWritingMode()); + } + return {}; +} + +StyleProperty getLayerProperty(const SymbolLayer& layer, const std::string& name) { + const auto it = layerProperties.find(name.c_str()); + if (it == layerProperties.end()) { + return {}; + } + return getLayerProperty(layer, static_cast(it->second)); +} + } // namespace +Value SymbolLayer::serialize() const { + auto result = Layer::serialize(); + assert(result.getObject()); + for (const auto& property : layerProperties) { + auto styleProperty = getLayerProperty(*this, static_cast(property.second)); + if (styleProperty.getKind() == StyleProperty::Kind::Undefined) continue; + serializeProperty(result, styleProperty, property.first.c_str(), property.second < kPaintPropertyCount); + } + return result; +} + optional SymbolLayer::setProperty(const std::string& name, const Convertible& value) { const auto it = layerProperties.find(name.c_str()); if (it == layerProperties.end()) { @@ -1707,152 +1873,7 @@ optional SymbolLayer::setProperty(const std::string& name, const Converti } StyleProperty SymbolLayer::getProperty(const std::string& name) const { - const auto it = layerProperties.find(name.c_str()); - if (it == layerProperties.end()) { - return {}; - } - - switch (static_cast(it->second)) { - case Property::IconColor: - return makeStyleProperty(getIconColor()); - case Property::IconHaloBlur: - return makeStyleProperty(getIconHaloBlur()); - case Property::IconHaloColor: - return makeStyleProperty(getIconHaloColor()); - case Property::IconHaloWidth: - return makeStyleProperty(getIconHaloWidth()); - case Property::IconOpacity: - return makeStyleProperty(getIconOpacity()); - case Property::IconTranslate: - return makeStyleProperty(getIconTranslate()); - case Property::IconTranslateAnchor: - return makeStyleProperty(getIconTranslateAnchor()); - case Property::TextColor: - return makeStyleProperty(getTextColor()); - case Property::TextHaloBlur: - return makeStyleProperty(getTextHaloBlur()); - case Property::TextHaloColor: - return makeStyleProperty(getTextHaloColor()); - case Property::TextHaloWidth: - return makeStyleProperty(getTextHaloWidth()); - case Property::TextOpacity: - return makeStyleProperty(getTextOpacity()); - case Property::TextTranslate: - return makeStyleProperty(getTextTranslate()); - case Property::TextTranslateAnchor: - return makeStyleProperty(getTextTranslateAnchor()); - case Property::IconColorTransition: - return makeStyleProperty(getIconColorTransition()); - case Property::IconHaloBlurTransition: - return makeStyleProperty(getIconHaloBlurTransition()); - case Property::IconHaloColorTransition: - return makeStyleProperty(getIconHaloColorTransition()); - case Property::IconHaloWidthTransition: - return makeStyleProperty(getIconHaloWidthTransition()); - case Property::IconOpacityTransition: - return makeStyleProperty(getIconOpacityTransition()); - case Property::IconTranslateTransition: - return makeStyleProperty(getIconTranslateTransition()); - case Property::IconTranslateAnchorTransition: - return makeStyleProperty(getIconTranslateAnchorTransition()); - case Property::TextColorTransition: - return makeStyleProperty(getTextColorTransition()); - case Property::TextHaloBlurTransition: - return makeStyleProperty(getTextHaloBlurTransition()); - case Property::TextHaloColorTransition: - return makeStyleProperty(getTextHaloColorTransition()); - case Property::TextHaloWidthTransition: - return makeStyleProperty(getTextHaloWidthTransition()); - case Property::TextOpacityTransition: - return makeStyleProperty(getTextOpacityTransition()); - case Property::TextTranslateTransition: - return makeStyleProperty(getTextTranslateTransition()); - case Property::TextTranslateAnchorTransition: - return makeStyleProperty(getTextTranslateAnchorTransition()); - case Property::IconAllowOverlap: - return makeStyleProperty(getIconAllowOverlap()); - case Property::IconAnchor: - return makeStyleProperty(getIconAnchor()); - case Property::IconIgnorePlacement: - return makeStyleProperty(getIconIgnorePlacement()); - case Property::IconImage: - return makeStyleProperty(getIconImage()); - case Property::IconKeepUpright: - return makeStyleProperty(getIconKeepUpright()); - case Property::IconOffset: - return makeStyleProperty(getIconOffset()); - case Property::IconOptional: - return makeStyleProperty(getIconOptional()); - case Property::IconPadding: - return makeStyleProperty(getIconPadding()); - case Property::IconPitchAlignment: - return makeStyleProperty(getIconPitchAlignment()); - case Property::IconRotate: - return makeStyleProperty(getIconRotate()); - case Property::IconRotationAlignment: - return makeStyleProperty(getIconRotationAlignment()); - case Property::IconSize: - return makeStyleProperty(getIconSize()); - case Property::IconTextFit: - return makeStyleProperty(getIconTextFit()); - case Property::IconTextFitPadding: - return makeStyleProperty(getIconTextFitPadding()); - case Property::SymbolAvoidEdges: - return makeStyleProperty(getSymbolAvoidEdges()); - case Property::SymbolPlacement: - return makeStyleProperty(getSymbolPlacement()); - case Property::SymbolSortKey: - return makeStyleProperty(getSymbolSortKey()); - case Property::SymbolSpacing: - return makeStyleProperty(getSymbolSpacing()); - case Property::SymbolZOrder: - return makeStyleProperty(getSymbolZOrder()); - case Property::TextAllowOverlap: - return makeStyleProperty(getTextAllowOverlap()); - case Property::TextAnchor: - return makeStyleProperty(getTextAnchor()); - case Property::TextField: - return makeStyleProperty(getTextField()); - case Property::TextFont: - return makeStyleProperty(getTextFont()); - case Property::TextIgnorePlacement: - return makeStyleProperty(getTextIgnorePlacement()); - case Property::TextJustify: - return makeStyleProperty(getTextJustify()); - case Property::TextKeepUpright: - return makeStyleProperty(getTextKeepUpright()); - case Property::TextLetterSpacing: - return makeStyleProperty(getTextLetterSpacing()); - case Property::TextLineHeight: - return makeStyleProperty(getTextLineHeight()); - case Property::TextMaxAngle: - return makeStyleProperty(getTextMaxAngle()); - case Property::TextMaxWidth: - return makeStyleProperty(getTextMaxWidth()); - case Property::TextOffset: - return makeStyleProperty(getTextOffset()); - case Property::TextOptional: - return makeStyleProperty(getTextOptional()); - case Property::TextPadding: - return makeStyleProperty(getTextPadding()); - case Property::TextPitchAlignment: - return makeStyleProperty(getTextPitchAlignment()); - case Property::TextRadialOffset: - return makeStyleProperty(getTextRadialOffset()); - case Property::TextRotate: - return makeStyleProperty(getTextRotate()); - case Property::TextRotationAlignment: - return makeStyleProperty(getTextRotationAlignment()); - case Property::TextSize: - return makeStyleProperty(getTextSize()); - case Property::TextTransform: - return makeStyleProperty(getTextTransform()); - case Property::TextVariableAnchor: - return makeStyleProperty(getTextVariableAnchor()); - case Property::TextWritingMode: - return makeStyleProperty(getTextWritingMode()); - } - return {}; + return getLayerProperty(*this, name); } Mutable SymbolLayer::mutableBaseImpl() const { From eb0098143db7ead4a5d5206541a2c870e6d4c0c3 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 12:29:04 +0200 Subject: [PATCH 3/8] [core] Fix Color serialization --- include/mbgl/style/conversion_impl.hpp | 9 ++++++--- include/mbgl/util/color.hpp | 1 + src/mbgl/style/expression/value.cpp | 11 +---------- src/mbgl/util/color.cpp | 11 +++++++++++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/mbgl/style/conversion_impl.hpp b/include/mbgl/style/conversion_impl.hpp index 73d83302a0f..30aa132ce0c 100644 --- a/include/mbgl/style/conversion_impl.hpp +++ b/include/mbgl/style/conversion_impl.hpp @@ -318,7 +318,7 @@ struct ValueFactory { template <> struct ValueFactory { - static Value make(const Color& color) { return color.toObject(); } + static Value make(const Color& color) { return color.serialize(); } }; template @@ -358,11 +358,14 @@ Value makeValue(T&& arg) { template StyleProperty makeStyleProperty(const PropertyValue& value) { return value.match([](const Undefined&) -> StyleProperty { return {}; }, - [](const T& t) -> StyleProperty { - return {makeValue(t), StyleProperty::Kind::Constant}; + [](const Color& c) -> StyleProperty { + return {makeValue(c), StyleProperty::Kind::Expression}; }, [](const PropertyExpression& fn) -> StyleProperty { return {fn.getExpression().serialize(), StyleProperty::Kind::Expression}; + }, + [](const auto& t) -> StyleProperty { + return {makeValue(t), StyleProperty::Kind::Constant}; }); } diff --git a/include/mbgl/util/color.hpp b/include/mbgl/util/color.hpp index 1ff44ce0856..8a03abfcdb3 100644 --- a/include/mbgl/util/color.hpp +++ b/include/mbgl/util/color.hpp @@ -41,6 +41,7 @@ class Color { std::string stringify() const; std::array toArray() const; mbgl::Value toObject() const; + mbgl::Value serialize() const; }; inline bool operator==(const Color& colorA, const Color& colorB) { diff --git a/src/mbgl/style/expression/value.cpp b/src/mbgl/style/expression/value.cpp index aac1c616550..110844f4212 100644 --- a/src/mbgl/style/expression/value.cpp +++ b/src/mbgl/style/expression/value.cpp @@ -126,16 +126,7 @@ Value ValueConverter::toExpressionValue(const mbgl::Value& value) { mbgl::Value ValueConverter::fromExpressionValue(const Value& value) { return value.match( - [&](const Color& color) -> mbgl::Value { - std::array array = color.toArray(); - return std::vector{ - std::string("rgba"), - array[0], - array[1], - array[2], - array[3], - }; - }, + [&](const Color& color) -> mbgl::Value { return color.serialize(); }, [&](const Collator&) -> mbgl::Value { // fromExpressionValue can't be used for Collator values, // because they have no meaningful representation as an mbgl::Value diff --git a/src/mbgl/util/color.cpp b/src/mbgl/util/color.cpp index 44f815e8b8e..5d30d252445 100644 --- a/src/mbgl/util/color.cpp +++ b/src/mbgl/util/color.cpp @@ -48,4 +48,15 @@ mbgl::Value Color::toObject() const { return mapbox::base::ValueObject{{"r", double(r)}, {"g", double(g)}, {"b", double(b)}, {"a", double(a)}}; } +mbgl::Value Color::serialize() const { + std::array array = toArray(); + return std::vector{ + std::string("rgba"), + array[0], + array[1], + array[2], + array[3], + }; +} + } // namespace mbgl From dedb769230f500544e0bd818bf995ebb5db6e3c7 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 11:02:07 +0200 Subject: [PATCH 4/8] [core] Fix TransitionOptions serialization --- include/mbgl/style/conversion_impl.hpp | 11 +++-------- include/mbgl/style/transition_options.hpp | 13 +++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/mbgl/style/conversion_impl.hpp b/include/mbgl/style/conversion_impl.hpp index 30aa132ce0c..9606c7b58d7 100644 --- a/include/mbgl/style/conversion_impl.hpp +++ b/include/mbgl/style/conversion_impl.hpp @@ -306,14 +306,7 @@ struct ValueFactory { template <> struct ValueFactory { - static Value make(const TransitionOptions& value) { - return mapbox::base::ValueArray{ - {std::chrono::duration_cast(value.duration.value_or(mbgl::Duration::zero())) - .count(), - std::chrono::duration_cast(value.delay.value_or(mbgl::Duration::zero())) - .count(), - value.enablePlacementTransitions}}; - } + static Value make(const TransitionOptions& value) { return value.serialize(); } }; template <> @@ -370,10 +363,12 @@ StyleProperty makeStyleProperty(const PropertyValue& value) { } inline StyleProperty makeStyleProperty(const TransitionOptions& value) { + if (!value.isDefined()) return {}; return {makeValue(value), StyleProperty::Kind::Transition}; } inline StyleProperty makeStyleProperty(const ColorRampPropertyValue& value) { + if (value.isUndefined()) return {}; return {makeValue(value), StyleProperty::Kind::Expression}; } diff --git a/include/mbgl/style/transition_options.hpp b/include/mbgl/style/transition_options.hpp index 9cb5c1f575e..69479afaadc 100644 --- a/include/mbgl/style/transition_options.hpp +++ b/include/mbgl/style/transition_options.hpp @@ -3,6 +3,8 @@ #include #include +#include + namespace mbgl { namespace style { @@ -30,6 +32,17 @@ class TransitionOptions { bool isDefined() const { return duration || delay; } + + mapbox::base::Value serialize() const { + mapbox::base::ValueObject result; + if (duration) { + result.emplace("duration", std::chrono::duration_cast(*duration).count()); + } + if (delay) { + result.emplace("delay", std::chrono::duration_cast(*delay).count()); + } + return result; + } }; } // namespace style From 5649d7e0279675ed3c0d2b2b9510835e0889aebd Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 10:48:17 +0200 Subject: [PATCH 5/8] [core] Add unit test for layer serialization --- test/style/conversion/layer.test.cpp | 96 +++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/test/style/conversion/layer.test.cpp b/test/style/conversion/layer.test.cpp index d65644b91be..aae5d3495c9 100644 --- a/test/style/conversion/layer.test.cpp +++ b/test/style/conversion/layer.test.cpp @@ -4,6 +4,8 @@ #include #include +#include + using namespace mbgl; using namespace mbgl::style; using namespace mbgl::style::conversion; @@ -11,7 +13,17 @@ using namespace std::literals::chrono_literals; std::unique_ptr parseLayer(const std::string& src) { Error error; - return std::move(*convertJSON>(src, error)); + auto layer = convertJSON>(src, error); + if (layer) return std::move(*layer); + return nullptr; +} + +std::string stringifyLayer(const Value& value) { + rapidjson::StringBuffer s; + rapidjson::PrettyWriter writer(s); + writer.SetIndent(' ', 2u); + stringify(writer, value); + return s.GetString(); } TEST(StyleConversion, LayerTransition) { @@ -31,3 +43,85 @@ TEST(StyleConversion, LayerTransition) { ASSERT_EQ(500ms, *static_cast(layer.get())->impl().paint .get().options.delay); } + +TEST(StyleConversion, SerializeDefaults) { + auto layer = parseLayer(R"JSON({ + "type": "background", + "id": "background" + })JSON"); + + EXPECT_NE(nullptr, layer); + auto value = layer->serialize(); + EXPECT_NE(nullptr, value.getObject()); + EXPECT_EQ(2u, value.getObject()->size()); +} + +TEST(StyleConversion, RoundtripWithTransitions) { + auto layer = parseLayer(R"JSON({ + "type": "background", + "id": "background", + "paint": { + "background-color-transition": { + "duration": 400, + "delay": 500 + } + } + })JSON"); + + EXPECT_NE(nullptr, layer); + auto value = layer->serialize(); + EXPECT_NE(nullptr, value.getObject()); + EXPECT_EQ(3u, value.getObject()->size()); + + auto roundTripped = parseLayer(stringifyLayer(value)); + EXPECT_NE(nullptr, roundTripped); + auto roundTrippedValue = roundTripped->serialize(); + EXPECT_NE(nullptr, roundTrippedValue.getObject()); + EXPECT_EQ(3u, roundTrippedValue.getObject()->size()); +} + +TEST(StyleConversion, OverrideDefaults) { + auto layer = parseLayer(R"JSON({ + "type": "symbol", + "id": "symbol", + "source": "composite", + "source-layer": "landmarks", + "filter": ["has", "monuments"], + "minzoom": 12, + "maxzoom": 18, + "layout": { + "visibility": "none", + "text-field": ["format", + "Hello", + ["image", ["get", "world"]], + "Example", {"text-color": "rgba(128, 255, 39, 1)"} + ], + "icon-image": ["image", ["get", "landmark_image"]], + "text-size": 24 + }, + "paint": { + "text-color": "turquoise", + "text-color-transition": { + "duration": 300, + "delay": 100 + } + } + })JSON"); + + EXPECT_NE(nullptr, layer); + auto value = layer->serialize(); + EXPECT_NE(nullptr, value.getObject()); + const auto& object = *(value.getObject()); + EXPECT_EQ(9u, object.size()); + EXPECT_EQ(4u, object.at("layout").getObject()->size()); + EXPECT_EQ(2u, object.at("paint").getObject()->size()); + + auto roundTripped = parseLayer(stringifyLayer(value)); + EXPECT_NE(nullptr, roundTripped); + auto roundTrippedValue = roundTripped->serialize(); + const auto& roundTrippedObject = *(roundTrippedValue.getObject()); + EXPECT_NE(nullptr, roundTrippedValue.getObject()); + EXPECT_EQ(9u, roundTrippedObject.size()); + EXPECT_EQ(4u, roundTrippedObject.at("layout").getObject()->size()); + EXPECT_EQ(2u, roundTrippedObject.at("paint").getObject()->size()); +} From d770910701a2edae5b80b8bad261229b56164d71 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 15:00:37 +0200 Subject: [PATCH 6/8] [core] Update Map.UniversalStyleGetter test --- test/map/map.test.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 41501e38a45..8f7270529f2 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -1035,7 +1035,11 @@ TEST(Map, UniversalStyleGetter) { "paint": { "line-color": "red", "line-opacity": 0.5, - "line-width": ["get", "width"] + "line-width": ["get", "width"], + "line-opacity-transition": { + "duration": 400, + "delay": 500 + } }, "layout": { "line-cap": "butt" @@ -1056,13 +1060,15 @@ TEST(Map, UniversalStyleGetter) { StyleProperty lineColor = lineLayer->getProperty("line-color"); ASSERT_TRUE(lineColor.getValue()); - EXPECT_EQ(StyleProperty::Kind::Constant, lineColor.getKind()); - ASSERT_TRUE(lineColor.getValue().getObject()); - const auto& color = *(lineColor.getValue().getObject()); - EXPECT_EQ(1.0, *color.at("r").getDouble()); - EXPECT_EQ(0.0, *color.at("g").getDouble()); - EXPECT_EQ(0.0, *color.at("b").getDouble()); - EXPECT_EQ(1.0, *color.at("a").getDouble()); + EXPECT_EQ(StyleProperty::Kind::Expression, lineColor.getKind()); + ASSERT_TRUE(lineColor.getValue().getArray()); + const auto& color = *(lineColor.getValue().getArray()); + EXPECT_EQ(5u, color.size()); + EXPECT_EQ("rgba", *color[0].getString()); + EXPECT_EQ(255.0, *color[1].getDouble()); + EXPECT_EQ(0.0, *color[2].getDouble()); + EXPECT_EQ(0.0, *color[3].getDouble()); + EXPECT_EQ(1.0, *color[4].getDouble()); StyleProperty lineOpacity = lineLayer->getProperty("line-opacity"); ASSERT_TRUE(lineOpacity.getValue()); @@ -1073,8 +1079,11 @@ TEST(Map, UniversalStyleGetter) { StyleProperty lineOpacityTransition = lineLayer->getProperty("line-opacity-transition"); ASSERT_TRUE(lineOpacityTransition.getValue()); EXPECT_EQ(StyleProperty::Kind::Transition, lineOpacityTransition.getKind()); - ASSERT_TRUE(lineOpacityTransition.getValue().getArray()); - EXPECT_EQ(3u, lineOpacityTransition.getValue().getArray()->size()); + ASSERT_TRUE(lineOpacityTransition.getValue().getObject()); + EXPECT_EQ(2u, lineOpacityTransition.getValue().getObject()->size()); + + StyleProperty lineColorTransition = lineLayer->getProperty("line-color-transition"); + EXPECT_EQ(StyleProperty::Kind::Undefined, lineColorTransition.getKind()); StyleProperty lineWidth = lineLayer->getProperty("line-width"); ASSERT_TRUE(lineWidth.getValue()); From 01c2c9588316535a006a2467a7bb6796148fefdc Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 18:55:36 +0200 Subject: [PATCH 7/8] [core] Update baselines for gl-native tools --- metrics/binary-size/linux-gcc8/metrics.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/metrics/binary-size/linux-gcc8/metrics.json b/metrics/binary-size/linux-gcc8/metrics.json index 0563028058a..c827674a66a 100644 --- a/metrics/binary-size/linux-gcc8/metrics.json +++ b/metrics/binary-size/linux-gcc8/metrics.json @@ -3,17 +3,17 @@ [ "mbgl-glfw", "/tmp/attach/install/linux-gcc8-release/bin/mbgl-glfw", - 7598440 + 7672168 ], [ "mbgl-offline", "/tmp/attach/install/linux-gcc8-release/bin/mbgl-offline", - 6684904 + 6758632 ], [ "mbgl-render", "/tmp/attach/install/linux-gcc8-release/bin/mbgl-render", - 7483752 + 7549288 ] ] } \ No newline at end of file From 88ccea8c02b510df8a9ced6c9f34b8d4a51e6dd9 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 25 Feb 2020 19:03:04 +0200 Subject: [PATCH 8/8] [core] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cb88ec665e..d65b89eb38c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ This is a back porting from GL JS [#9333](https://github.com/mapbox/mapbox-gl-js/pull/9333) +- [core] Add Layer::serialize() method ([#16231](https://github.com/mapbox/mapbox-gl-native/pull/16231)) + + New method allows serialization of a layer into a Value type, including all modifications done via runtime style API. New method is also an enabler for Style object serialization (sources, layers, etc). + ## maps-v1.2.0 (2020.02-release-vanillashake) ### ✨ New features