如何编写一个考虑缩放、特征状态和数据驱动样式的 Mapbox 绘制表达式?
Posted
技术标签:
【中文标题】如何编写一个考虑缩放、特征状态和数据驱动样式的 Mapbox 绘制表达式?【英文标题】:How to write a Mapbox paint expression that accounts for zoom, feature-state, and data-driven styling? 【发布时间】:2020-07-16 03:22:54 【问题描述】:我有一个图层可以将 geojson 源中的点要素呈现为圆圈。以下是其中一项功能的示例:
type: 'Feature',
properties:
color: 'red',
red: true,
green: false
,
geometry:
type: 'Point',
coordinates: [-77.038659, 38.931567]
;
我希望圆形不透明度是 3 个因素的乘积(特征上的一些属性、地图缩放以及特征状态中是否应该隐藏该特征的布尔值)。我想不出一种方法来编写一个解释所有这三个的表达式。围绕缩放规则的限制似乎是个问题。
这是我要写的逻辑:
if (feature-state.hidden)
opacity = 0;
else if (properties.red)
opacity = 1;
else if (properties.green and zoom >= 10)
opacity = 1;
else if (zoom >= 15)
opacity = 1;
else
opacity = 0;
我试着写一个这样的不透明表达式:
'circle-opacity': [
'case',
['to-boolean', ['feature-state', 'hidden']], 0,
['to-boolean', ['get', 'red']], 1,
['to-boolean', ['get', 'green']], ['case', ['>=', ['zoom'], 10], 1, 0], // I could also write a permutation of this using an ['all'] rule
['>=', ['zoom'], 15], 1,
0,
],
这被拒绝并显示以下消息:“错误:layers.places.paint.circle-opacity: “zoom”表达式只能用作***“step”或“interpolate”表达式的输入。”
然后我尝试了这样的事情:
'circle-opacity': [
'step',
['zoom'],
0,
[
'case',
['to-boolean', ['get', 'red'], false], 1,
['to-boolean', ['get', 'green'], false], 10,
15
],
1
]
这被拒绝并显示以下消息:“错误:layers.places.paint.circle-opacity[3]:“step”表达式的输入/输出对必须使用输入的文字数值(非计算表达式)定义值。”
如您所见,我什至还没有开始添加功能状态检查。
这是一个可以玩的 JSFiddle:https://jsfiddle.net/rognstad/px4c8tbe/17/
我想我可以通过使用 minZoom 属性将每种颜色分成自己的层,然后只对特征状态使用不透明度表达式来使其工作,但这感觉非常笨拙并且会导致性能更差。
似乎必须有更好的方法。您对如何实现这一目标有更好的建议吗?谢谢!
【问题讨论】:
【参考方案1】:你真的很亲密。您收到此错误:
错误:layers.places.paint.circle-opacity[3]:“step”表达式的输入/输出对必须使用输入值的文字数值(非计算表达式)来定义。
因为您的 ['step']
表达式中的参数顺序略有错误。它需要去:
['step', ['zoom'], <value at zoom 0>, <X>, <value at zoom X>, <Y>, <value at zoom Y>
所以你不想要第一个 0
那里。
如果我们稍微重构一下你的伪代码,你应该能够到达那里:
step
zoom
// zoom 0 to 10
if (!feature-state.hidden && properties.red)
1
else
0
10 // zoom level 10+
if (!feature-state.hidden && (properties.red || properties.green)
1
else
0
15 // zoom level 15+
if (!feature-state.hidden)
1
else
0
表达式代码看起来像这样。您可能必须添加适当的类型转换。 (我没有测试过)。
['step', ['zoom'],
['case', ['all', ['!', ['feature-state', 'hidden']], ['get', 'red'], 1, 0],
10,
['case', ['all', ['!', ['feature-state', 'hidden']], ['any', ['get', 'red'], ['get', 'green']], 1, 0],
15,
['case', [['!', ['feature-state', 'hidden']], 1, 0]],
【讨论】:
谢谢!这完全有效!在进行所有类型转换后,这是一个更新的工作规则:jsfiddle.net/rognstad/px4c8tbe/36以上是关于如何编写一个考虑缩放、特征状态和数据驱动样式的 Mapbox 绘制表达式?的主要内容,如果未能解决你的问题,请参考以下文章