summaryrefslogtreecommitdiff
path: root/include/mbgl/style
diff options
context:
space:
mode:
Diffstat (limited to 'include/mbgl/style')
-rw-r--r--include/mbgl/style/conversion/constant.hpp49
-rw-r--r--include/mbgl/style/conversion/layer.hpp3
-rw-r--r--include/mbgl/style/conversion/light.hpp122
-rw-r--r--include/mbgl/style/conversion/position.hpp29
-rw-r--r--include/mbgl/style/layer.hpp2
-rw-r--r--include/mbgl/style/light.hpp52
-rw-r--r--include/mbgl/style/position.hpp68
-rw-r--r--include/mbgl/style/types.hpp5
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