如何使用 Mapbox 表达式切换图层 class 样式
How to use Mapbox expressions to toggle layer class styles
我有一个带有可见层的 Mapbox 地图,该层显示了代表不同类型位置的多个圆圈。这些循环存储在单个 Mapbox 图层中。我的 React 应用程序中有一些功能允许我将这些圆圈的不透明度更改为 0
或 0.5
,结果效果是打开或关闭。
我编写了一些非常粗略的代码,允许我切换每个圆圈的样式,但必须为每个排列创建一个 if 语句是不可行的。
这是我目前所拥有的,仅实现 2 个圆 classes(C
和 R
),其中最终版本将包括 9 个不同的 classes 和这么多 if 语句我不想解决。
map.current.on('idle', () => {
if (filters.C.visible && filters.R.visible) {
map.current.setLayoutProperty('type', 'visibility', 'visible');
map.current.setPaintProperty('type', 'circle-opacity', 0.1);
} else if (filters.C.visible) {
map.current.setLayoutProperty('type', 'visibility', 'visible');
map.current.setPaintProperty('type', 'circle-opacity', [
'match',
['get', 'class'],
'C', 0.5,
'R', 0,
0, // everything else
]);
} else if (filters.R.visible) {
map.current.setLayoutProperty('type', 'visibility', 'visible');
map.current.setPaintProperty('type', 'circle-opacity', [
'match',
['get', 'class'],
'C', 0,
'R', 0.5,
0, // everything else
]);
} else {
map.current.setLayoutProperty('type', 'visibility', 'none');
}
});
理想情况下,我想在不影响任何其他 class 的情况下更改一个 class 的样式,因此我可以创建一个开关并保持代码整洁,但是 match
表达式需要导致我出现问题的第 4 0, // everything else
行。
有没有人有任何聪明的想法我可以如何实现这一目标?我唯一能想到的就是将单层拆分为多个层并改为切换层,但我不确定这还会影响什么。
重构它的简单方法如下:
const opacities = {
C: filters.C.visible ? 0.5 : 0,
R: filters.R.visible ? 0.5 : 0,
// ...
}
map.current.setPaintProperty('type', 'circle-opacity', [
'match',
['get', 'class'],
'C', opacities.C,
'R', opacities.R,
// ...
0, // everything else
]);
如果您想进一步重构以尽量减少重复并处理大量 类:
const classes = ['C', 'R'];
const expression = ['match', ['get', 'class']];
classes.forEach(c => expression.push(c, filters[c].visible ? 0.5 : 0));
expression.push(0); // "default" case
map.current.setPaintProperty('type', 'circle-opacity', expression);
我有一个带有可见层的 Mapbox 地图,该层显示了代表不同类型位置的多个圆圈。这些循环存储在单个 Mapbox 图层中。我的 React 应用程序中有一些功能允许我将这些圆圈的不透明度更改为 0
或 0.5
,结果效果是打开或关闭。
我编写了一些非常粗略的代码,允许我切换每个圆圈的样式,但必须为每个排列创建一个 if 语句是不可行的。
这是我目前所拥有的,仅实现 2 个圆 classes(C
和 R
),其中最终版本将包括 9 个不同的 classes 和这么多 if 语句我不想解决。
map.current.on('idle', () => {
if (filters.C.visible && filters.R.visible) {
map.current.setLayoutProperty('type', 'visibility', 'visible');
map.current.setPaintProperty('type', 'circle-opacity', 0.1);
} else if (filters.C.visible) {
map.current.setLayoutProperty('type', 'visibility', 'visible');
map.current.setPaintProperty('type', 'circle-opacity', [
'match',
['get', 'class'],
'C', 0.5,
'R', 0,
0, // everything else
]);
} else if (filters.R.visible) {
map.current.setLayoutProperty('type', 'visibility', 'visible');
map.current.setPaintProperty('type', 'circle-opacity', [
'match',
['get', 'class'],
'C', 0,
'R', 0.5,
0, // everything else
]);
} else {
map.current.setLayoutProperty('type', 'visibility', 'none');
}
});
理想情况下,我想在不影响任何其他 class 的情况下更改一个 class 的样式,因此我可以创建一个开关并保持代码整洁,但是 match
表达式需要导致我出现问题的第 4 0, // everything else
行。
有没有人有任何聪明的想法我可以如何实现这一目标?我唯一能想到的就是将单层拆分为多个层并改为切换层,但我不确定这还会影响什么。
重构它的简单方法如下:
const opacities = {
C: filters.C.visible ? 0.5 : 0,
R: filters.R.visible ? 0.5 : 0,
// ...
}
map.current.setPaintProperty('type', 'circle-opacity', [
'match',
['get', 'class'],
'C', opacities.C,
'R', opacities.R,
// ...
0, // everything else
]);
如果您想进一步重构以尽量减少重复并处理大量 类:
const classes = ['C', 'R'];
const expression = ['match', ['get', 'class']];
classes.forEach(c => expression.push(c, filters[c].visible ? 0.5 : 0));
expression.push(0); // "default" case
map.current.setPaintProperty('type', 'circle-opacity', expression);