如何使用 Mapbox 表达式切换图层 class 样式

How to use Mapbox expressions to toggle layer class styles

我有一个带有可见层的 Mapbox 地图,该层显示了代表不同类型位置的多个圆圈。这些循环存储在单个 Mapbox 图层中。我的 React 应用程序中有一些功能允许我将这些圆圈的不透明度更改为 00.5,结果效果是打开或关闭。

我编写了一些非常粗略的代码,允许我切换每个圆圈的样式,但必须为每个排列创建一个 if 语句是不可行的。

这是我目前所拥有的,仅实现 2 个圆 classes(CR),其中最终版本将包括 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);