From 9616f8911d8b0407f2e2a6aa283d4e0e0f2ea64a Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Thu, 7 Mar 2019 18:34:45 +0200 Subject: [core] Enable text-variable-anchor property --- include/mbgl/style/conversion/constant.hpp | 5 ++++ include/mbgl/style/layers/symbol_layer.hpp | 4 +++ include/mbgl/style/types.hpp | 2 ++ .../mapboxsdk/style/layers/PropertyFactory.java | 20 +++++++++++++++ .../mapbox/mapboxsdk/style/layers/SymbolLayer.java | 16 ++++++++++++ .../mapboxsdk/testapp/style/SymbolLayerTest.java | 13 ++++++++++ platform/android/scripts/generate-style-code.js | 1 + platform/android/src/conversion/constant.hpp | 11 ++++++++ platform/android/src/style/layers/symbol_layer.cpp | 6 +++++ platform/android/src/style/layers/symbol_layer.hpp | 2 ++ scripts/generate-style-code.js | 2 +- scripts/style-spec.js | 3 +-- src/mbgl/style/conversion/constant.cpp | 27 +++++++++++++++++++ src/mbgl/style/conversion/function.cpp | 2 ++ src/mbgl/style/conversion/property_value.cpp | 1 + src/mbgl/style/expression/value.cpp | 3 +++ src/mbgl/style/layers/symbol_layer.cpp | 30 ++++++++++++++++++++++ src/mbgl/style/layers/symbol_layer_properties.hpp | 6 +++++ src/mbgl/style/types.cpp | 2 +- 19 files changed, 152 insertions(+), 4 deletions(-) diff --git a/include/mbgl/style/conversion/constant.hpp b/include/mbgl/style/conversion/constant.hpp index 40657528c4..3a5833be64 100644 --- a/include/mbgl/style/conversion/constant.hpp +++ b/include/mbgl/style/conversion/constant.hpp @@ -34,6 +34,11 @@ struct Converter::value>> { optional operator()(const Convertible& value, Error& error) const; }; +template +struct Converter, typename std::enable_if_t::value>> { + optional> operator()(const Convertible& value, Error& error) const; +}; + template <> struct Converter { optional operator()(const Convertible& value, Error& error) const; diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index 764f1585f6..46935ef535 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -134,6 +134,10 @@ public: PropertyValue getTextJustify() const; void setTextJustify(PropertyValue); + static PropertyValue> getDefaultTextVariableAnchor(); + PropertyValue> getTextVariableAnchor() const; + void setTextVariableAnchor(PropertyValue>); + static PropertyValue getDefaultTextAnchor(); PropertyValue getTextAnchor() const; void setTextAnchor(PropertyValue); diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index ed875733c7..a472c4fcec 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -98,6 +98,8 @@ enum class SymbolAnchorType : uint8_t { BottomRight }; +using TextVariableAnchorType = SymbolAnchorType; + enum class TextTransformType : uint8_t { None, Uppercase, diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java index 3d8b921a79..88770b10af 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java @@ -2275,6 +2275,26 @@ public class PropertyFactory { return new LayoutPropertyValue<>("text-justify", value); } + /** + * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the `text-radial-offset` instead of the two-dimensional {@link PropertyFactory#textOffset}. + * + * @param value a String[] value + * @return property wrapper around String[] + */ + public static PropertyValue textVariableAnchor(String[] value) { + return new LayoutPropertyValue<>("text-variable-anchor", value); + } + + /** + * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the `text-radial-offset` instead of the two-dimensional {@link PropertyFactory#textOffset}. + * + * @param value a String[] value + * @return property wrapper around String[] + */ + public static PropertyValue textVariableAnchor(Expression value) { + return new LayoutPropertyValue<>("text-variable-anchor", value); + } + /** * Part of the text placed closest to the anchor. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java index ab45cb04f2..4b5e755f7d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java @@ -469,6 +469,18 @@ public class SymbolLayer extends Layer { return (PropertyValue) new PropertyValue("text-justify", nativeGetTextJustify()); } + /** + * Get the TextVariableAnchor property + * + * @return property wrapper value around String[] + */ + @NonNull + @SuppressWarnings("unchecked") + public PropertyValue getTextVariableAnchor() { + checkThread(); + return (PropertyValue) new PropertyValue("text-variable-anchor", nativeGetTextVariableAnchor()); + } + /** * Get the TextAnchor property * @@ -1185,6 +1197,10 @@ public class SymbolLayer extends Layer { @Keep private native Object nativeGetTextJustify(); + @NonNull + @Keep + private native Object nativeGetTextVariableAnchor(); + @NonNull @Keep private native Object nativeGetTextAnchor(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java index 149064d684..67260f9b3c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java @@ -577,6 +577,19 @@ public class SymbolLayerTest extends BaseLayerTest { assertEquals(layer.getTextJustify().getExpression(), expression); } + @Test + @UiThreadTest + public void testTextVariableAnchorAsConstant() { + Timber.i("text-variable-anchor"); + assertNotNull(layer); + assertNull(layer.getTextVariableAnchor().getValue()); + + // Set and Get + String[] propertyValue = [undefined]; + layer.setProperties(textVariableAnchor(propertyValue)); + assertEquals(layer.getTextVariableAnchor().getValue(), propertyValue); + } + @Test @UiThreadTest public void testTextAnchorAsConstant() { diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index 56e7511362..6f64a38a67 100755 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -197,6 +197,7 @@ global.defaultValueJava = function(property) { case 'array': switch (property.value) { case 'string': + case 'enum': return '[' + property['default'] + "]"; case 'number': var result ='new Float[] {'; diff --git a/platform/android/src/conversion/constant.hpp b/platform/android/src/conversion/constant.hpp index 4def670f3c..839e6e84dc 100644 --- a/platform/android/src/conversion/constant.hpp +++ b/platform/android/src/conversion/constant.hpp @@ -88,6 +88,17 @@ struct Converter>, T, typename std::enable_if_t +struct Converter>, std::vector, typename std::enable_if_t::value>> { + Result>> operator()(jni::JNIEnv& env, const std::vector& value) const { + auto result = jni::Array::New(env, value.size()); + for (std::size_t i = 0; i < value.size(); ++i) { + result.Set(env, i, jni::Make(env, Enum::toString(value.at(i)))); + } + return result; + } +}; + } // namespace conversion } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/layers/symbol_layer.cpp b/platform/android/src/style/layers/symbol_layer.cpp index 61e4d59326..e9b149eaf3 100644 --- a/platform/android/src/style/layers/symbol_layer.cpp +++ b/platform/android/src/style/layers/symbol_layer.cpp @@ -176,6 +176,11 @@ namespace android { return std::move(*convert>>(env, toSymbolLayer(layer).getTextJustify())); } + jni::Local> SymbolLayer::getTextVariableAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + return std::move(*convert>>(env, toSymbolLayer(layer).getTextVariableAnchor())); + } + jni::Local> SymbolLayer::getTextAnchor(jni::JNIEnv& env) { using namespace mbgl::android::conversion; return std::move(*convert>>(env, toSymbolLayer(layer).getTextAnchor())); @@ -514,6 +519,7 @@ namespace android { METHOD(&SymbolLayer::getTextLineHeight, "nativeGetTextLineHeight"), METHOD(&SymbolLayer::getTextLetterSpacing, "nativeGetTextLetterSpacing"), METHOD(&SymbolLayer::getTextJustify, "nativeGetTextJustify"), + METHOD(&SymbolLayer::getTextVariableAnchor, "nativeGetTextVariableAnchor"), METHOD(&SymbolLayer::getTextAnchor, "nativeGetTextAnchor"), METHOD(&SymbolLayer::getTextMaxAngle, "nativeGetTextMaxAngle"), METHOD(&SymbolLayer::getTextRotate, "nativeGetTextRotate"), diff --git a/platform/android/src/style/layers/symbol_layer.hpp b/platform/android/src/style/layers/symbol_layer.hpp index f52597ef6f..c93961f70a 100644 --- a/platform/android/src/style/layers/symbol_layer.hpp +++ b/platform/android/src/style/layers/symbol_layer.hpp @@ -80,6 +80,8 @@ public: jni::Local> getTextJustify(jni::JNIEnv&); + jni::Local> getTextVariableAnchor(jni::JNIEnv&); + jni::Local> getTextAnchor(jni::JNIEnv&); jni::Local> getTextMaxAngle(jni::JNIEnv&); diff --git a/scripts/generate-style-code.js b/scripts/generate-style-code.js index 72f4857a96..2622ae5ef6 100755 --- a/scripts/generate-style-code.js +++ b/scripts/generate-style-code.js @@ -72,7 +72,7 @@ global.evaluatedType = function (property) { if (property.length) { return `std::array<${evaluatedType({type: property.value})}, ${property.length}>`; } else { - return `std::vector<${evaluatedType({type: property.value})}>`; + return `std::vector<${evaluatedType({type: property.value, name: property.name})}>`; } default: throw new Error(`unknown type for ${property.name}`) } diff --git a/scripts/style-spec.js b/scripts/style-spec.js index 4bbd453a86..695b5b7a59 100644 --- a/scripts/style-spec.js +++ b/scripts/style-spec.js @@ -5,7 +5,6 @@ delete spec.layout_symbol['symbol-sort-key']; delete spec.layout_symbol['symbol-z-order'].values['auto']; spec.layout_symbol['symbol-z-order'].default = 'viewport-y'; -delete spec.layout_symbol['text-variable-anchor']; delete spec.layout_symbol['text-radial-offset']; delete spec.layout_symbol['text-justify'].values['auto']; -spec.layout_symbol['text-offset'].requires.splice(1, 1); // { "!": "text-radial-offset" } \ No newline at end of file +spec.layout_symbol['text-offset'].requires.splice(1, 1); // { "!": "text-radial-offset" } diff --git a/src/mbgl/style/conversion/constant.cpp b/src/mbgl/style/conversion/constant.cpp index bdc6371722..1942779aaa 100644 --- a/src/mbgl/style/conversion/constant.cpp +++ b/src/mbgl/style/conversion/constant.cpp @@ -49,6 +49,27 @@ optional Converter::value>>::ope return *result; } +template +auto Converter, typename std::enable_if_t::value>>::operator()(const Convertible& value, Error& error) const -> optional> { + if (!isArray(value)) { + error.message = "value must be an array"; + return nullopt; + } + + std::vector result; + result.reserve(arrayLength(value)); + + for (std::size_t i = 0; i < arrayLength(value); ++i) { + optional enumItem = Converter{}(arrayMember(value, i), error); + if (!enumItem) { + return nullopt; + } + result.push_back(*enumItem); + } + + return result; +} + template optional Converter::operator()(const Convertible&, Error&) const; template optional Converter::operator()(const Convertible&, Error&) const; template optional Converter::operator()(const Convertible&, Error&) const; @@ -64,6 +85,7 @@ template optional Converter::operator()(const template optional Converter::operator()(const Convertible&, Error&) const; template optional Converter::operator()(const Convertible&, Error&) const; template optional Converter::operator()(const Convertible&, Error&) const; +template optional> Converter>::operator()(const Convertible&, Error&) const; optional Converter::operator()(const Convertible& value, Error& error) const { optional string = toString(value); @@ -125,6 +147,11 @@ optional> Converter>::operator()(const Con return result; } + +namespace { + +} // namespace + optional> Converter>::operator()(const Convertible& value, Error& error) const { if (!isArray(value)) { error.message = "value must be an array"; diff --git a/src/mbgl/style/conversion/function.cpp b/src/mbgl/style/conversion/function.cpp index 79ad2fc7d8..df4decc73e 100644 --- a/src/mbgl/style/conversion/function.cpp +++ b/src/mbgl/style/conversion/function.cpp @@ -136,6 +136,8 @@ template optional>> convertFunctionToExpression>(const Convertible&, Error&, bool); template optional> convertFunctionToExpression(const Convertible&, Error&, bool); +template optional>> + convertFunctionToExpression>(const Convertible&, Error&, bool); template optional> convertFunctionToExpression(const Convertible&, Error&, bool); template optional> diff --git a/src/mbgl/style/conversion/property_value.cpp b/src/mbgl/style/conversion/property_value.cpp index ff038908b6..6e1d747324 100644 --- a/src/mbgl/style/conversion/property_value.cpp +++ b/src/mbgl/style/conversion/property_value.cpp @@ -73,6 +73,7 @@ template optional> Converter> Converter>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional> Converter>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional> Converter>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional>> Converter>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional> Converter>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional> Converter>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional> Converter>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; diff --git a/src/mbgl/style/expression/value.cpp b/src/mbgl/style/expression/value.cpp index 436ed83ecd..46b554d4e7 100644 --- a/src/mbgl/style/expression/value.cpp +++ b/src/mbgl/style/expression/value.cpp @@ -324,6 +324,9 @@ template struct ValueConverter>; template type::Type valueTypeToExpressionType>(); template struct ValueConverter>; +template type::Type valueTypeToExpressionType>(); +template struct ValueConverter>; + template type::Type valueTypeToExpressionType(); template struct ValueConverter; diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 75ed881058..2195f703d7 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -492,6 +492,22 @@ void SymbolLayer::setTextJustify(PropertyValue value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } +PropertyValue> SymbolLayer::getDefaultTextVariableAnchor() { + return TextVariableAnchor::defaultValue(); +} + +PropertyValue> SymbolLayer::getTextVariableAnchor() const { + return impl().layout.get(); +} + +void SymbolLayer::setTextVariableAnchor(PropertyValue> value) { + if (value == getTextVariableAnchor()) + return; + auto impl_ = mutableImpl(); + impl_->layout.get() = value; + baseImpl = std::move(impl_); + observer->onLayerChanged(*this); +} PropertyValue SymbolLayer::getDefaultTextAnchor() { return TextAnchor::defaultValue(); } @@ -1325,6 +1341,7 @@ optional SymbolLayer::setLayoutProperty(const std::string& name, const Co TextLineHeight, TextLetterSpacing, TextJustify, + TextVariableAnchor, TextAnchor, TextMaxAngle, TextRotate, @@ -1364,6 +1381,7 @@ optional SymbolLayer::setLayoutProperty(const std::string& name, const Co { "text-line-height", static_cast(Property::TextLineHeight) }, { "text-letter-spacing", static_cast(Property::TextLetterSpacing) }, { "text-justify", static_cast(Property::TextJustify) }, + { "text-variable-anchor", static_cast(Property::TextVariableAnchor) }, { "text-anchor", static_cast(Property::TextAnchor) }, { "text-max-angle", static_cast(Property::TextMaxAngle) }, { "text-rotate", static_cast(Property::TextRotate) }, @@ -1674,6 +1692,18 @@ optional SymbolLayer::setLayoutProperty(const std::string& name, const Co } + if (property == Property::TextVariableAnchor) { + Error error; + optional>> typedValue = convert>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setTextVariableAnchor(*typedValue); + return nullopt; + + } + if (property == Property::TextTransform) { Error error; optional> typedValue = convert>(value, error, true, false); diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index 8645823cac..8ccad4efec 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -147,6 +147,11 @@ struct TextJustify : DataDrivenLayoutProperty { static TextJustifyType defaultValue() { return TextJustifyType::Center; } }; +struct TextVariableAnchor : LayoutProperty> { + static constexpr const char *name() { return "text-variable-anchor"; } + static std::vector defaultValue() { return { }; } +}; + struct TextAnchor : DataDrivenLayoutProperty { static constexpr const char *name() { return "text-anchor"; } static SymbolAnchorType defaultValue() { return SymbolAnchorType::Center; } @@ -284,6 +289,7 @@ class SymbolLayoutProperties : public Properties< TextLineHeight, TextLetterSpacing, TextJustify, + TextVariableAnchor, TextAnchor, TextMaxAngle, TextRotate, diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp index 51174cf152..48016ce76a 100644 --- a/src/mbgl/style/types.cpp +++ b/src/mbgl/style/types.cpp @@ -76,7 +76,7 @@ MBGL_DEFINE_ENUM(SymbolAnchorType, { { SymbolAnchorType::BottomLeft, "bottom-left" }, { SymbolAnchorType::BottomRight, "bottom-right" } }); - + MBGL_DEFINE_ENUM(SymbolZOrderType, { { SymbolZOrderType::ViewportY, "viewport-y" }, { SymbolZOrderType::Source, "source" } -- cgit v1.2.1