Mapbox GL JS:缩小时无法正确呈现聚类圆

Mapbox GL JS: Clustering circle not rendered properly upon zooming out

我正在构建一个在地图上呈现圆圈的网站。如果 ["feature-state", "value] 属性 >= 1,则圆圈为绿色,如果 ["feature-state", "value"] 属性 为 0 或 null,则圆圈为红色(默认值为 0) .当我的地图足够放大时,圆圈会正确呈现(所有 ["feature-state", "value] >= 1 的圆圈都呈现为绿色)。但是,当我缩小时,包含 children features/circles 和 ["feature-state", "value] 的群集圆呈现为红色而不是绿色。如果 children 的 ["feature-state", "value] 的总和 >= 1,是否有任何方法可以确保将群集呈现为绿色?

下面是我的渲染代码:

map.addSource('cities', {
    "type": "geojson",
    "data": "cities.geojson",
    "cluster": true,
    "clusterMaxZoom": 14,
    "clusterRadius": 80
});

map.addLayer({
    "id": "cities",
    "type": "circle",
    "source": "cities",
    "paint": {
        "circle-color": [ 
        "case",
            ["==", ["feature-state", "value"], null], "#ff4d4d",
            [">=", ["feature-state", "value"], 1], "#33cc33",
            "#ff4d4d"
        ],
        "circle-radius": [ 
            "case",
                ["==", ["feature-state", "value"], null], 9,
                [">=", ["feature-state", "value"], 1], 12,
                6
            ],
        "circle-opacity" : [
            "case",
                ["==", ["feature-state", "value"], null], 0.7,
                [">=", ["feature-state", "value"], 1], 1,
                0.7
        ]
    },
});

下面是我如何设置 "feature-state":

map.setFeatureState({source: "cities", id : 124312}, {value: 1});

这是正确放大后的地图截图:

这是缩小时的地图截图(标有白色标记的区域中的红色圆圈应呈现为绿色):

这可以通过源对象的 clusterProperties 选项来完成,该选项采用自定义表达式来聚合聚类点的属性。

注意:clusterProperties 选项不支持特征状态聚合,只能与属性一起使用。我将在下面的步骤中对其进行解释,底部还附有一个代码笔示例。

  1. 首先,定义一个表达式,聚合构成集群的要素属性。
{
  cluster: true,
  clusterMaxZoom: 14,
  clusterRadius: 80,
  clusterProperties: {
    /*
      get the property numUser, then cast it to number or 0,
      then sum it, then store the sum as cluster's numUser property
    */
    numUsers: ["+", ["number", ["get", "numUsers"], 0]] 
  },
  type: "geojson",
  data: geojson,
}
  1. 更新样式表达式以使用要素属性而不是 feature-state:
paint: {
  "circle-color": [
    "case",
    ["==", ["get", "numUsers"], null], "#ff4d4d",
    [">=", ["get", "numUsers"], 1], "#33cc33",
    "#ff4d4d"
  ],
  "circle-radius": [
    "case",
    ["==", ["get", "numUsers"], null], 9,
    [">=", ["get", "numUsers"], 1], 12,
    6
  ],
  "circle-opacity": [
    "case",
    ["==", ["get", "numUsers"], null], 0.7,
    [">=", ["get", "numUsers"], 1], 1,
    0.7
  ]
}
  1. 更新 GeoJSON 属性:
// Update after 2 seconds
setTimeout(() => {
  const newGeojson = {
    ...geojson,
    features: geojson.features.map(feature => {
      if ([0, 1].includes(feature.id)) { // update features selectively
        feature.properties.numUsers = 1;
      }
      return feature;
    })
  };
  map.getSource('geom').setData(newGeojson);
}, 2000);

这是一个可用的代码笔:https://codepen.io/manishraj/full/wvwmNKR

这里有一个相关的例子,来自 mapbox:https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/