系列目录
Types
Lookup
Decision
Math
String
Color
Zoom
Heatmap
Feature data
Variable binding
Ramps, scales, curves
本篇目录
1.通过以下方法是对我们放入的值包装成Expression对象。
前言
Expression在mapbox中使用非常广泛,我们可以借助它高度自定义Layer属性的变化。此系列就介绍了Expression的一些常见使用方式与场景。
一、Expression是什么?
Expression是可以将任何布局属性,绘画属性或过滤器的值指定为表达式。
表达式定义了一个公式,用于使用以下描述的运算符来计算属性的值。
二、Mapbox提供的Expression运算符集有哪些?
1.元素
- Mathematical operators : 用于对数值执行算术和其他运算的数学运算符
- Logical operators : 逻辑运算符用于操作布尔值和进行条件决策的
- String operators: 用于操作字符串的字符串运算符
- Data operators: 数据运算符,提供对源要素属性的访问权限
- Camera operators: 相机运算符,提供对定义当前地图视图的参数的访问权限
2.表达式表示为JSON数组
表达式数组的第一个元素是命名表达式运算符的字符串,例如“*”或“case”。后续元素(如果有)是表达式的参数。
每个参数都是文字值(字符串,数字,布尔值或null)或另一个表达式数组。
- 数据表达式(Data expression):数据表达式是访问要素数据的任何表达式-也就是说,使用数据运算符之一的任何表达式:get,has,id,geometry-type, or properties。 数据表达式允许功能的属性确定其外观。 它们可用于区分同一层中的要素并创建数据可视化。
- 摄影机表达式(Camera expression):摄影机表达式是使用缩放运算符的任何表达式。 这些表达式使图层的外观随地图的缩放级别而变化。 相机表达式可用于创建深度外观并控制数据密度。
- 组成(Composition): 单个表达式可以混合使用数据运算符,相机运算符和其他运算符。 这种复合表达式允许通过缩放级别和单个要素属性的组合来确定图层的外观。
三、Expression按Types分类
1.通过以下方法是对我们放入的值包装成Expression对象。
Create a literal xxx expression
Expression literal(@NonNull Number number)
Expression literal(@NonNull String string)
Expression literal(@NonNull boolean bool)
Expression literal(@NonNull Object object)
Expression literal(@NonNull Object[] array)
2.试图将Expression转为XXX类型
Expression.toXXX(@NonNull Expression input)
/**
* to-string
* 将输入值转换为字符串。如果输入为空,则结果为""。
* 如果输入为布尔值,则结果为"true"或"false"。
* 如果输入是数字,则将其转换为ECMAScript语言规范的"NumberToString"算法指定的字符串。
* 如果输入是颜色,则将其转换为格式为"rgba(r,g,b,a)"的字符串
(其中r,g和b是从0到255的数字,范围是从0到255的数字和a的范围是0到1)。
* 否则,输入将转换为ECMAScript语言规范的JSON.stringify函数指定的格式的字符串。
* <p>
* ["to-string", value]: string
*/
Expression toString(@NonNull Expression input)
/**
* to-number
* 如果可能,将输入值转换为数字。如果输入为null或false,则结果为0。如果输入为true,则结果为1。
* 如果输入为字符串,则将其转换为由“应用于字符串类型的ToNumber”算法指定的数字。
* ECMAScript语言规范。如果提供了多个值,则会依次评估每个值,直到获得第一个成功的转换为止。
* 如果没有任何输入可以转换,则该表达式为错误。
* <p>
* ["to-number", value, fallback: value, fallback: value, ...]: number
*/
Expression.toNumber(@NonNull Expression input)
/**
* to-boolean
* 将输入值转换为布尔值。当输入为空字符串,0,false,null或NaN时,结果为false。否则是真的。
* <p>
* ["to-boolean", value]: boolean
*/
Expression.toBool(@NonNull Expression input)
/**
* to-color
* 将输入值转换为颜色。如果提供了多个值,则会依次评估每个值,直到获得第一个成功的转换为止。
* 如果没有任何输入可以转换,则该表达式为错误。
* <p>
* ["to-color", value, fallback: value, fallback: value, ...]: color
*/
Expression.toColor(@NonNull Expression input)
3. 获取表达式类型
/**
* typeof
* 返回描述给定值类型的字符串。
* <p>
* ["typeof", value]: string
*/
Expression typeOf(@NonNull Expression input)
4.断言
/**
* string
* 断言输入值是一个字符串。如果提供了多个值,则会依次评估每个值,直到获得一个字符串为止。
* 如果所有输入都不是字符串,则表达式为错误。
* <p>
* ["string", value]: string
* ["string", value, fallback: value, fallback: value, ...]: string
*/
Expression string(@NonNull Expression... input)
/**
* number
* 断言输入值是一个数字。如果提供多个值,则依次评估每个值,直到获得一个数字。如果所有输入都不是数字,
* 则表达式为错误。
* <p>
* ["number", value]: number
* ["number", value, fallback: value, fallback: value, ...]: number
*/
Expression number(@NonNull Expression... input)
/**
* boolean
* 断言输入值是布尔值。如果提供了多个值,则会依次评估每个值,直到获得布尔值为止。如果所有输入都不是布尔值,
*则该表达式为错误。
* <p>
* ["boolean", value]: boolean
* ["boolean", value, fallback: value, fallback: value, ...]: boolean
*/
Expression bool(@NonNull Expression... input)
/**
* object
* 断言输入值是一个对象。如果提供多个值,则依次评估每个值,直到获得一个对象。如果所有输入都不是对象,
* 则表达式为错误。
* <p>
* ["object", value]: object
* ["object", value, fallback: value, fallback: value, ...]: object
*/
Expression.object(@NonNull Expression... input)
/**
* array
* 断言输入是一个数组(可以选择具有特定项目类型和长度的数组)。如果在计算输入表达式时,它不是断言类型,
* 则此断言将导致整个表达式被中止。
* <p>
* ["array", value]: array
* ["array", type: "string" | "number" | "boolean", value]: array<type>
* ["array", type: "string" | "number" | "boolean", N: number (literal),value]: array<type,N>
*/
Expression array(@NonNull Expression input)
5.Format
/**
* format
* 返回一个格式化的字符串,用于在text-field属性中显示混合格式的文本。
* 输入可以包含字符串文字或表达式,包括“图像”表达式。
* 字符串后面可以跟随一个支持以下属性的样式覆盖对象:
* <p>
* "text-font": Overrides the font stack specified by the root layout property.
* "text-color": Overrides the color specified by the root paint property.
* "font-scale": Applies a scaling factor on text-size as specified by the root layout property.
* ["format",input_1: string | image, options_1: { "font-scale": number, "text-font": array<string>, "text-color": color }, ...,input_n: string | image, options_n: { "font-scale": number, "text-font": array<string>, "text-color": color }]: formatted
*/
Expression format(@NonNull FormatEntry... formatEntries)
示例
下图演示了修改Text的颜色与缩放。
代码在这,可以自己修改一下,体验体验。
private static final String SOURCE_ID = "source-id";
private static final String LAYER_ID = "layer-id";
private static final String LAYER_TEXT = "layer-text";
private GeoJsonSource geoJsonSource;
private SymbolLayer symbolLayer;
private final List<Feature> featureList = new ArrayList<>();
private static final double LATITUDE = 39.9;
private static final double LONGITUDE = 119.6;
@Override
public void onMapLoaded() {
super.onMapLoaded();
//初始化源等
initTextSource();
//批量添加文字
addTextsOnMap();
findViewById(R.id.btn_change_color).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
symbolLayer.setProperties(
textColor(
match(get(LAYER_TEXT),
literal("10000"), color(Color.RED),
literal("10001"), rgb(0.0f, 0.0f, 255.0f),
rgba(0.0f, 255.0f, 0.0f, 1.0f)
))
);
}
});
findViewById(R.id.btn_change_text_size).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
symbolLayer.setProperties(
textField(
match(get(LAYER_TEXT),
literal("10000"), format(
formatEntry(
get(LAYER_TEXT),
Expression.FormatOption.formatFontScale(1.5)
)
),
format(
formatEntry(
get(LAYER_TEXT),
Expression.FormatOption.formatFontScale(1.0)
)
)
)
)
);
}
});
}
private void addTextsOnMap() {
for (int i = 0; i < 3; i++) {
//feature
Point point = Point.fromLngLat(LONGITUDE + i * 0.002, LATITUDE + i * 0.002);
Feature feature = Feature.fromGeometry(point);
feature.addStringProperty(LAYER_TEXT, String.valueOf(10000 + i));
featureList.add(feature);
}
//刷新数据源
geoJsonSource.setGeoJson(FeatureCollection.fromFeatures(featureList));
//移动地图视角
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(LATITUDE, LONGITUDE), 12));
}
private void initTextSource() {
//添加源
FeatureCollection deviceFeatureCollection = FeatureCollection.fromFeatures(featureList);
geoJsonSource = new GeoJsonSource(SOURCE_ID, deviceFeatureCollection);
style.addSource(geoJsonSource);
//添加Layer
symbolLayer = new SymbolLayer(LAYER_ID, SOURCE_ID);
symbolLayer.withProperties(
textSize(18f),
textColor(Color.YELLOW),
textField(get(LAYER_TEXT)),
textAllowOverlap(true)
);
style.addLayer(symbolLayer);
}