diff options
Diffstat (limited to 'include/mbgl/style')
-rw-r--r-- | include/mbgl/style/conversion/constant.hpp | 49 | ||||
-rw-r--r-- | include/mbgl/style/conversion/layer.hpp | 3 | ||||
-rw-r--r-- | include/mbgl/style/conversion/light.hpp | 122 | ||||
-rw-r--r-- | include/mbgl/style/conversion/position.hpp | 29 | ||||
-rw-r--r-- | include/mbgl/style/layer.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/style/light.hpp | 52 | ||||
-rw-r--r-- | include/mbgl/style/position.hpp | 68 | ||||
-rw-r--r-- | include/mbgl/style/types.hpp | 5 |
8 files changed, 295 insertions, 35 deletions
diff --git a/include/mbgl/style/conversion/constant.hpp b/include/mbgl/style/conversion/constant.hpp index 1e1fdc2ee8..07c0a35fae 100644 --- a/include/mbgl/style/conversion/constant.hpp +++ b/include/mbgl/style/conversion/constant.hpp @@ -4,6 +4,7 @@ #include <mbgl/util/optional.hpp> #include <mbgl/util/color.hpp> #include <mbgl/util/enum.hpp> +#include <mbgl/util/string.hpp> #include <array> #include <string> @@ -92,45 +93,25 @@ struct Converter<Color> { } }; -template <> -struct Converter<std::array<float, 2>> { +template <size_t N> +struct Converter<std::array<float, N>> { template <class V> - optional<std::array<float, 2>> operator()(const V& value, Error& error) const { - if (!isArray(value) || arrayLength(value) != 2) { - error = { "value must be an array of two numbers" }; + optional<std::array<float, N>> operator()(const V& value, Error& error) const { + if (!isArray(value) || arrayLength(value) != N) { + error = { "value must be an array of " + util::toString(N) + " numbers" }; return {}; } - optional<float> first = toNumber(arrayMember(value, 0)); - optional<float> second = toNumber(arrayMember(value, 1)); - if (!first || !second) { - error = { "value must be an array of two numbers" }; - return {}; - } - - return std::array<float, 2> {{ *first, *second }}; - } -}; - -template <> -struct Converter<std::array<float, 4>> { - template <class V> - optional<std::array<float, 4>> operator()(const V& value, Error& error) const { - if (!isArray(value) || arrayLength(value) != 4) { - error = { "value must be an array of four numbers" }; - return {}; - } - - optional<float> first = toNumber(arrayMember(value, 0)); - optional<float> second = toNumber(arrayMember(value, 1)); - optional<float> third = toNumber(arrayMember(value, 2)); - optional<float> fourth = toNumber(arrayMember(value, 3)); - if (!first || !second) { - error = { "value must be an array of four numbers" }; - return {}; + std::array<float, N> result; + for (size_t i = 0; i < N; i++) { + optional<float> n = toNumber(arrayMember(value, i)); + if (!n) { + error = { "value must be an array of " + util::toString(N) + " numbers" }; + return {}; + } + result[i] = *n; } - - return std::array<float, 4> {{ *first, *second, *third, *fourth }}; + return result; } }; diff --git a/include/mbgl/style/conversion/layer.hpp b/include/mbgl/style/conversion/layer.hpp index efb1df8fef..3a64c36bf5 100644 --- a/include/mbgl/style/conversion/layer.hpp +++ b/include/mbgl/style/conversion/layer.hpp @@ -4,6 +4,7 @@ #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/line_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/symbol_layer.hpp> @@ -92,6 +93,8 @@ public: 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") { diff --git a/include/mbgl/style/conversion/light.hpp b/include/mbgl/style/conversion/light.hpp new file mode 100644 index 0000000000..631ed04ccb --- /dev/null +++ b/include/mbgl/style/conversion/light.hpp @@ -0,0 +1,122 @@ +#pragma once + +#include <mbgl/style/light.hpp> +#include <mbgl/style/conversion.hpp> +#include <mbgl/style/conversion/position.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +template <> +struct Converter<Light> { +public: + template <class V> + optional<Light> operator()(const V& value, Error& error) const { + if (!isObject(value)) { + error = { "light must be an object" }; + return {}; + } + + Light light; + + const auto anchor = objectMember(value, "anchor"); + if (anchor) { + optional<PropertyValue<LightAnchorType>> convertedAnchor = + convert<PropertyValue<LightAnchorType>>(*anchor, error); + + if (convertedAnchor) { + light.get<LightAnchor>().value = *convertedAnchor; + } else { + return {}; + } + } + + const auto anchorTransition = objectMember(value, "anchor-transition"); + if (anchorTransition) { + optional<TransitionOptions> transition = + convert<TransitionOptions>(*anchorTransition, error); + if (transition) { + light.get<LightAnchor>().transition = *transition; + } else { + return {}; + } + } + + const auto color = objectMember(value, "color"); + if (color) { + optional<PropertyValue<Color>> convertedColor = + convert<PropertyValue<Color>>(*color, error); + + if (convertedColor) { + light.get<LightColor>().value = *convertedColor; + } else { + return {}; + } + } + + const auto colorTransition = objectMember(value, "color-transition"); + if (colorTransition) { + optional<TransitionOptions> transition = + convert<TransitionOptions>(*colorTransition, error); + if (transition) { + light.get<LightColor>().transition = *transition; + } else { + return {}; + } + } + + const auto position = objectMember(value, "position"); + if (position) { + optional<PropertyValue<Position>> convertedPosition = + convert<PropertyValue<Position>>(*position, error); + + if (convertedPosition) { + light.get<LightPosition>().value = *convertedPosition; + } else { + return {}; + } + } + + const auto positionTransition = objectMember(value, "position-transition"); + if (positionTransition) { + optional<TransitionOptions> transition = + convert<TransitionOptions>(*positionTransition, error); + if (transition) { + light.get<LightPosition>().transition = *transition; + } else { + return {}; + } + } + + const auto intensity = objectMember(value, "intensity"); + if (intensity) { + optional<PropertyValue<float>> convertedIntensity = + convert<PropertyValue<float>>(*intensity, error); + + if (convertedIntensity) { + light.get<LightIntensity>().value = *convertedIntensity; + } else { + return {}; + } + } + + const auto intensityTransition = objectMember(value, "intensity-transition"); + if (intensityTransition) { + optional<TransitionOptions> transition = + convert<TransitionOptions>(*intensityTransition, error); + if (transition) { + light.get<LightIntensity>().transition = *transition; + } else { + return {}; + } + } + return { light }; + }; +}; + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/conversion/position.hpp b/include/mbgl/style/conversion/position.hpp new file mode 100644 index 0000000000..7036b03822 --- /dev/null +++ b/include/mbgl/style/conversion/position.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include <mbgl/style/conversion.hpp> +#include <mbgl/style/position.hpp> +#include <mbgl/util/optional.hpp> + +#include <array> + +namespace mbgl { +namespace style { +namespace conversion { + +template <> +struct Converter<Position> { + template <class V> + optional<Position> operator()(const V& value, Error& error) const { + optional<std::array<float, 3>> spherical = convert<std::array<float, 3>>(value, error); + + if (!spherical) { + return {}; + } + + return Position(*spherical); + } +}; + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp index f09eb0165a..56f2c48fa7 100644 --- a/include/mbgl/style/layer.hpp +++ b/include/mbgl/style/layer.hpp @@ -66,7 +66,7 @@ public: // Convenience method for dynamic dispatch on the concrete layer type. Using // method overloading, this allows consolidation of logic common to vector-based - // layers (Fill, Line, Circle, or Symbol). For example: + // layers (Fill, FillExtrusion, Line, Circle, or Symbol). For example: // // struct Visitor { // void operator()(CustomLayer&) { ... } diff --git a/include/mbgl/style/light.hpp b/include/mbgl/style/light.hpp new file mode 100644 index 0000000000..bec8e6ddeb --- /dev/null +++ b/include/mbgl/style/light.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include <mbgl/style/property_value.hpp> +#include <mbgl/style/transition_options.hpp> +#include <mbgl/style/types.hpp> +#include <mbgl/style/position.hpp> +#include <mbgl/util/color.hpp> +#include <mbgl/util/indexed_tuple.hpp> + +namespace mbgl { +namespace style { + +template <class T> +class LightProperty { +public: + using Type = T; + using ValueType = PropertyValue<T>; + + PropertyValue<T> value; + TransitionOptions transition; +}; + +struct LightAnchor : LightProperty<LightAnchorType> { + static LightAnchorType defaultValue() { + return LightAnchorType::Viewport; + } +}; + +struct LightPosition : LightProperty<Position> { + static Position defaultValue() { + std::array<float, 3> default_ = { { 1.15, 210, 30 } }; + return Position{ { default_ } }; + } +}; + +struct LightColor : LightProperty<Color> { + static Color defaultValue() { + return Color::white(); + } +}; + +struct LightIntensity : LightProperty<float> { + static float defaultValue() { + return 0.5; + } +}; + +using LightProperties = TypeList<LightAnchor, LightPosition, LightColor, LightIntensity>; +class Light : public IndexedTuple<LightProperties, LightProperties> {}; + +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/position.hpp b/include/mbgl/style/position.hpp new file mode 100644 index 0000000000..3be8d1c55e --- /dev/null +++ b/include/mbgl/style/position.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include <mbgl/util/constants.hpp> + +#include <array> + +namespace mbgl { +namespace style { +class Position { +public: + Position() = default; + Position(std::array<float, 3>& position_) + : radial(position_[0]), azimuthal(position_[1]), polar(position_[2]) { + calculateCartesian(); + }; + + friend bool operator==(const Position& lhs, const Position& rhs) { + return lhs.radial == rhs.radial && lhs.azimuthal == rhs.azimuthal && lhs.polar == rhs.polar; + // TODO this doesn't address wrapping, which would be better addressed by comparing cartesian coordinates but being calculated floats are ont to be trusted. + } + + friend bool operator!=(const Position& lhs, const Position& rhs) { + return !(lhs == rhs); + } + + const std::array<float, 3> getCartesian() const { + return { { x, y, z } }; + }; + + const std::array<float, 3> getSpherical() const { + return { { radial, azimuthal, polar } }; + }; + + void set(std::array<float, 3>& position_) { + radial = position_[0]; + azimuthal = position_[1]; + polar = position_[2]; + calculateCartesian(); + }; + + // Utility function to be used only during interpolation; this leaves spherical coordinates undefined. + void setCartesian(std::array<float, 3>& position_) { + x = position_[0]; + y = position_[1]; + z = position_[2]; + } + +private: + float radial; + float azimuthal; + float polar; + float x; + float y; + float z; + + void calculateCartesian() { + // We abstract "north"/"up" (compass-wise) to be 0° when really this is 90° (π/2): we + // correct for that here + const float _a = (azimuthal + 90) * util::DEG2RAD; + const float _p = polar * util::DEG2RAD; + + x = radial * std::cos(_a) * std::sin(_p); + y = radial * std::sin(_a) * std::sin(_p); + z = radial * std::cos(_p); + }; +}; +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index 1f2f5c3105..e0436efb67 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -92,5 +92,10 @@ enum class IconTextFitType : uint8_t { Height }; +enum class LightAnchorType: bool { + Map, + Viewport +}; + } // namespace style } // namespace mbgl |