[core] Enable text-variable-anchor property
This commit is contained in:
@@ -34,6 +34,11 @@ struct Converter<T, typename std::enable_if_t<std::is_enum<T>::value>> {
|
||||
optional<T> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct Converter<std::vector<T>, typename std::enable_if_t<std::is_enum<T>::value>> {
|
||||
optional<std::vector<T>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<Color> {
|
||||
optional<Color> operator()(const Convertible& value, Error& error) const;
|
||||
|
||||
@@ -134,6 +134,10 @@ public:
|
||||
PropertyValue<TextJustifyType> getTextJustify() const;
|
||||
void setTextJustify(PropertyValue<TextJustifyType>);
|
||||
|
||||
static PropertyValue<std::vector<TextVariableAnchorType>> getDefaultTextVariableAnchor();
|
||||
PropertyValue<std::vector<TextVariableAnchorType>> getTextVariableAnchor() const;
|
||||
void setTextVariableAnchor(PropertyValue<std::vector<TextVariableAnchorType>>);
|
||||
|
||||
static PropertyValue<SymbolAnchorType> getDefaultTextAnchor();
|
||||
PropertyValue<SymbolAnchorType> getTextAnchor() const;
|
||||
void setTextAnchor(PropertyValue<SymbolAnchorType>);
|
||||
|
||||
@@ -98,6 +98,8 @@ enum class SymbolAnchorType : uint8_t {
|
||||
BottomRight
|
||||
};
|
||||
|
||||
using TextVariableAnchorType = SymbolAnchorType;
|
||||
|
||||
enum class TextTransformType : uint8_t {
|
||||
None,
|
||||
Uppercase,
|
||||
|
||||
@@ -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<String[]> 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<Expression> textVariableAnchor(Expression value) {
|
||||
return new LayoutPropertyValue<>("text-variable-anchor", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the text placed closest to the anchor.
|
||||
*
|
||||
|
||||
@@ -469,6 +469,18 @@ public class SymbolLayer extends Layer {
|
||||
return (PropertyValue<String>) new PropertyValue("text-justify", nativeGetTextJustify());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TextVariableAnchor property
|
||||
*
|
||||
* @return property wrapper value around String[]
|
||||
*/
|
||||
@NonNull
|
||||
@SuppressWarnings("unchecked")
|
||||
public PropertyValue<String[]> getTextVariableAnchor() {
|
||||
checkThread();
|
||||
return (PropertyValue<String[]>) 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();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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[] {';
|
||||
|
||||
@@ -88,6 +88,17 @@ struct Converter<jni::Local<jni::Object<>>, T, typename std::enable_if_t<std::is
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct Converter<jni::Local<jni::Object<>>, std::vector<T>, typename std::enable_if_t<std::is_enum<T>::value>> {
|
||||
Result<jni::Local<jni::Object<>>> operator()(jni::JNIEnv& env, const std::vector<T>& value) const {
|
||||
auto result = jni::Array<jni::String>::New(env, value.size());
|
||||
for (std::size_t i = 0; i < value.size(); ++i) {
|
||||
result.Set(env, i, jni::Make<jni::String>(env, Enum<T>::toString(value.at(i))));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -176,6 +176,11 @@ namespace android {
|
||||
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextJustify()));
|
||||
}
|
||||
|
||||
jni::Local<jni::Object<>> SymbolLayer::getTextVariableAnchor(jni::JNIEnv& env) {
|
||||
using namespace mbgl::android::conversion;
|
||||
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextVariableAnchor()));
|
||||
}
|
||||
|
||||
jni::Local<jni::Object<>> SymbolLayer::getTextAnchor(jni::JNIEnv& env) {
|
||||
using namespace mbgl::android::conversion;
|
||||
return std::move(*convert<jni::Local<jni::Object<>>>(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"),
|
||||
|
||||
@@ -80,6 +80,8 @@ public:
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getTextJustify(jni::JNIEnv&);
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getTextVariableAnchor(jni::JNIEnv&);
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getTextAnchor(jni::JNIEnv&);
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getTextMaxAngle(jni::JNIEnv&);
|
||||
|
||||
@@ -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}`)
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
spec.layout_symbol['text-offset'].requires.splice(1, 1); // { "!": "text-radial-offset" }
|
||||
|
||||
@@ -49,6 +49,27 @@ optional<T> Converter<T, typename std::enable_if_t<std::is_enum<T>::value>>::ope
|
||||
return *result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto Converter<std::vector<T>, typename std::enable_if_t<std::is_enum<T>::value>>::operator()(const Convertible& value, Error& error) const -> optional<std::vector<T>> {
|
||||
if (!isArray(value)) {
|
||||
error.message = "value must be an array";
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
std::vector<T> result;
|
||||
result.reserve(arrayLength(value));
|
||||
|
||||
for (std::size_t i = 0; i < arrayLength(value); ++i) {
|
||||
optional<T> enumItem = Converter<T>{}(arrayMember(value, i), error);
|
||||
if (!enumItem) {
|
||||
return nullopt;
|
||||
}
|
||||
result.push_back(*enumItem);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template optional<AlignmentType> Converter<AlignmentType>::operator()(const Convertible&, Error&) const;
|
||||
template optional<CirclePitchScaleType> Converter<CirclePitchScaleType>::operator()(const Convertible&, Error&) const;
|
||||
template optional<HillshadeIlluminationAnchorType> Converter<HillshadeIlluminationAnchorType>::operator()(const Convertible&, Error&) const;
|
||||
@@ -64,6 +85,7 @@ template optional<TextJustifyType> Converter<TextJustifyType>::operator()(const
|
||||
template optional<TextTransformType> Converter<TextTransformType>::operator()(const Convertible&, Error&) const;
|
||||
template optional<TranslateAnchorType> Converter<TranslateAnchorType>::operator()(const Convertible&, Error&) const;
|
||||
template optional<VisibilityType> Converter<VisibilityType>::operator()(const Convertible&, Error&) const;
|
||||
template optional<std::vector<TextVariableAnchorType>> Converter<std::vector<TextVariableAnchorType>>::operator()(const Convertible&, Error&) const;
|
||||
|
||||
optional<Color> Converter<Color>::operator()(const Convertible& value, Error& error) const {
|
||||
optional<std::string> string = toString(value);
|
||||
@@ -125,6 +147,11 @@ optional<std::vector<float>> Converter<std::vector<float>>::operator()(const Con
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
optional<std::vector<std::string>> Converter<std::vector<std::string>>::operator()(const Convertible& value, Error& error) const {
|
||||
if (!isArray(value)) {
|
||||
error.message = "value must be an array";
|
||||
|
||||
@@ -136,6 +136,8 @@ template optional<PropertyExpression<std::vector<std::string>>>
|
||||
convertFunctionToExpression<std::vector<std::string>>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<SymbolAnchorType>>
|
||||
convertFunctionToExpression<SymbolAnchorType>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<std::vector<TextVariableAnchorType>>>
|
||||
convertFunctionToExpression<std::vector<TextVariableAnchorType>>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<SymbolPlacementType>>
|
||||
convertFunctionToExpression<SymbolPlacementType>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<SymbolZOrderType>>
|
||||
|
||||
@@ -73,6 +73,7 @@ template optional<PropertyValue<LineJoinType>> Converter<PropertyValue<LineJoinT
|
||||
template optional<PropertyValue<Position>> Converter<PropertyValue<Position>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<RasterResamplingType>> Converter<PropertyValue<RasterResamplingType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<SymbolAnchorType>> Converter<PropertyValue<SymbolAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<std::vector<TextVariableAnchorType>>> Converter<PropertyValue<std::vector<TextVariableAnchorType>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<SymbolPlacementType>> Converter<PropertyValue<SymbolPlacementType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<SymbolZOrderType>> Converter<PropertyValue<SymbolZOrderType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<TextJustifyType>> Converter<PropertyValue<TextJustifyType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
|
||||
@@ -329,6 +329,9 @@ template struct ValueConverter<std::vector<float>>;
|
||||
template type::Type valueTypeToExpressionType<std::vector<std::string>>();
|
||||
template struct ValueConverter<std::vector<std::string>>;
|
||||
|
||||
template type::Type valueTypeToExpressionType<std::vector<TextVariableAnchorType>>();
|
||||
template struct ValueConverter<std::vector<TextVariableAnchorType>>;
|
||||
|
||||
template type::Type valueTypeToExpressionType<AlignmentType>();
|
||||
template struct ValueConverter<AlignmentType>;
|
||||
|
||||
|
||||
@@ -492,6 +492,22 @@ void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) {
|
||||
baseImpl = std::move(impl_);
|
||||
observer->onLayerChanged(*this);
|
||||
}
|
||||
PropertyValue<std::vector<TextVariableAnchorType>> SymbolLayer::getDefaultTextVariableAnchor() {
|
||||
return TextVariableAnchor::defaultValue();
|
||||
}
|
||||
|
||||
PropertyValue<std::vector<TextVariableAnchorType>> SymbolLayer::getTextVariableAnchor() const {
|
||||
return impl().layout.get<TextVariableAnchor>();
|
||||
}
|
||||
|
||||
void SymbolLayer::setTextVariableAnchor(PropertyValue<std::vector<TextVariableAnchorType>> value) {
|
||||
if (value == getTextVariableAnchor())
|
||||
return;
|
||||
auto impl_ = mutableImpl();
|
||||
impl_->layout.get<TextVariableAnchor>() = value;
|
||||
baseImpl = std::move(impl_);
|
||||
observer->onLayerChanged(*this);
|
||||
}
|
||||
PropertyValue<SymbolAnchorType> SymbolLayer::getDefaultTextAnchor() {
|
||||
return TextAnchor::defaultValue();
|
||||
}
|
||||
@@ -1325,6 +1341,7 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
TextLineHeight,
|
||||
TextLetterSpacing,
|
||||
TextJustify,
|
||||
TextVariableAnchor,
|
||||
TextAnchor,
|
||||
TextMaxAngle,
|
||||
TextRotate,
|
||||
@@ -1364,6 +1381,7 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
{ "text-line-height", static_cast<uint8_t>(Property::TextLineHeight) },
|
||||
{ "text-letter-spacing", static_cast<uint8_t>(Property::TextLetterSpacing) },
|
||||
{ "text-justify", static_cast<uint8_t>(Property::TextJustify) },
|
||||
{ "text-variable-anchor", static_cast<uint8_t>(Property::TextVariableAnchor) },
|
||||
{ "text-anchor", static_cast<uint8_t>(Property::TextAnchor) },
|
||||
{ "text-max-angle", static_cast<uint8_t>(Property::TextMaxAngle) },
|
||||
{ "text-rotate", static_cast<uint8_t>(Property::TextRotate) },
|
||||
@@ -1674,6 +1692,18 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
}
|
||||
|
||||
if (property == Property::TextVariableAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::vector<TextVariableAnchorType>>> typedValue = convert<PropertyValue<std::vector<TextVariableAnchorType>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
setTextVariableAnchor(*typedValue);
|
||||
return nullopt;
|
||||
|
||||
}
|
||||
|
||||
if (property == Property::TextTransform) {
|
||||
Error error;
|
||||
optional<PropertyValue<TextTransformType>> typedValue = convert<PropertyValue<TextTransformType>>(value, error, true, false);
|
||||
|
||||
@@ -147,6 +147,11 @@ struct TextJustify : DataDrivenLayoutProperty<TextJustifyType> {
|
||||
static TextJustifyType defaultValue() { return TextJustifyType::Center; }
|
||||
};
|
||||
|
||||
struct TextVariableAnchor : LayoutProperty<std::vector<TextVariableAnchorType>> {
|
||||
static constexpr const char *name() { return "text-variable-anchor"; }
|
||||
static std::vector<TextVariableAnchorType> defaultValue() { return { }; }
|
||||
};
|
||||
|
||||
struct TextAnchor : DataDrivenLayoutProperty<SymbolAnchorType> {
|
||||
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,
|
||||
|
||||
@@ -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" }
|
||||
|
||||
Reference in New Issue
Block a user