Javascript Mapbox GL Js-source.setData可以';在querySourceFeatures中看不到

Javascript Mapbox GL Js-source.setData可以';在querySourceFeatures中看不到,javascript,mapbox,mapbox-gl-js,Javascript,Mapbox,Mapbox Gl Js,我使用mapbox来绘制标记和簇,并使用querySourceFeatures()来实现这一点 我的设置基于blogpost by Mapbox() 但是在我更新源代码(使用setData)之后,querySourceFeatures不会更新,因此我看不到地图上显示的新数据 这是我的代码,有点简化: const createData = ( ) => { markersToGenerate += 10; const totalFeatures = [{

我使用mapbox来绘制标记和簇,并使用
querySourceFeatures
()来实现这一点

我的设置基于blogpost by Mapbox()

但是在我更新源代码(使用
setData
)之后,
querySourceFeatures
不会更新,因此我看不到地图上显示的新数据

这是我的代码,有点简化:

const createData = (  ) => {
        markersToGenerate += 10;

        const totalFeatures = [{ "type": "Feature", "properties": { "id": "ak16994521", "mag": 2.3, "time": 1507425650893, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5129, 63.1016, 0.0 ] } }, 
 /** repeat this for 1200 times **/
];

        const splicedFeatures = totalFeatures.splice(0, markersToGenerate);

        return {
            'type': 'geojson',
            'data': {
                "type": "FeatureCollection",
                "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
                "features": splicedFeatures
            },
            'cluster': true,
            'clusterRadius': 80,
            'clusterProperties': {
                // keep separate counts for each magnitude category in a cluster
                'mag1': ['+', ['case', mag1, 1, 0]],
                'mag2': ['+', ['case', mag2, 1, 0]],
                'mag3': ['+', ['case', mag3, 1, 0]],
                'mag4': ['+', ['case', mag4, 1, 0]],
                'mag5': ['+', ['case', mag5, 1, 0]]
            }
        }
    }

map.on('load', function() {

        // add a clustered GeoJSON source for a sample set of earthquakes
        map.addSource('earthquakes', createData());

        // circle and symbol layers for rendering individual earthquakes (unclustered points)

map.addLayer({
            'id': 'earthquake_circle',
            'type': 'circle',
            'source': 'earthquakes',
            'filter': ['!=', 'cluster', true],
            'paint': {
                'circle-color': [
                    'case',
                    mag1,
                    colors[0],
                    mag2,
                    colors[1],
                    mag3,
                    colors[2],
                    mag4,
                    colors[3],
                    colors[4]
                ],
                'circle-opacity': 0.6,
                'circle-radius': 12
            }
        });
        map.addLayer({
            'id': 'earthquake_label',
            'type': 'symbol',
            'source': 'earthquakes',
            'filter': ['!=', 'cluster', true],
            'layout': {
                'text-field': [
                    'number-format',
                    ['get', 'mag'],
                    { 'min-fraction-digits': 1, 'max-fraction-digits': 1 }
                ],
                'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],
                'text-size': 10
            },
            'paint': {
                'text-color': [
                    'case',
                    ['<', ['get', 'mag'], 3],
                    'black',
                    'white'
                ]
            }
        });

        // every 5 seconds add a marker to the source and set that
        setInterval( () => {
            console.log('Update source');

            map.getSource('earthquakes').setData(createData());
        }, 5000)

        // objects for caching and keeping track of HTML marker objects (for performance)
        var markers = {};
        var markersOnScreen = {};

        function updateMarkers() {
            console.log("# updateMarkers called")

            var features = map.querySourceFeatures('earthquakes');

            // There are more features retrieved - since some are displayed on multiple tiles ... so they are counted double. The point here is to show the count isn't increasing.

console.log("Total features displayed = " + features.reduce( (totalCount, feature) => {
                if (feature.properties.cluster) {
                    return totalCount + feature.properties.point_count;
                } else {
                    return totalCount + 1;
                }
            }, 0));
      }
const createData=()=>{
标记生成+=10;
const totalFeatures=[{“类型”:“特征”,“属性”:{“id”:“ak16994521”,“mag”:2.3,“时间”:1507425650893,“感觉”:null,“海啸”:0},“几何”:{“类型”:“点”,“坐标”:[-151.5129,63.1016,0.0]},
/**重复此操作1200次**/
];
常量拼接特征=总特征。拼接(0,标记生成);
返回{
'type':'geojson',
“数据”:{
“类型”:“FeatureCollection”,
“crs”:{“类型”:“名称”,“属性”:{“名称”:“urn:ogc:def:crs:ogc:1.3:CRS84”},
“特征”:拼接特征
},
“集群”:正确,
“群集半径”:80,
“clusterProperties”:{
//为集群中的每个震级类别保留单独的计数
'mag1':['+',['case',mag1,1,0]],
‘mag2’:['+',['case',mag2,1,0]],
‘mag3’:['+',['case',mag3,1,0]],
‘mag4’:['+',['case',mag4,1,0]],
‘mag5’:['+',['case',mag5,1,0]]
}
}
}
map.on('load',function()){
//为地震样本集添加群集GeoJSON源
map.addSource('地震',createData());
//用于渲染单个地震的圆和符号层(未聚集点)
map.addLayer({
“id”:“地震圈”,
“类型”:“圆”,
"来源":"地震",,
“筛选器”:['!=',“群集”,true],
“油漆”:{
“圆形颜色”:[
“案例”,
mag1,
颜色[0],
mag2,
颜色[1],
mag3,
颜色[2],
mag4,
颜色[3],
颜色[4]
],
“圆形不透明度”:0.6,
“圆半径”:12
}
});
map.addLayer({
“id”:“地震标签”,
“类型”:“符号”,
"来源":"地震",,
“筛选器”:['!=',“群集”,true],
“布局”:{
“文本字段”:[
“数字格式”,
['get','mag'],
{“最小分数位数”:1,“最大分数位数”:1}
],
“文本字体”:[“Open Sans Semibold”,“Arial Unicode MS Bold”],
“文本大小”:10
},
“油漆”:{
“文本颜色”:[
“案例”,
[' {
if(feature.properties.cluster){
返回totalCount+feature.properties.point\u count;
}否则{
返回totalCount+1;
}
}, 0));
}
有关完整(实际运行)代码,请检查此代码笔:

一些额外的解释,我是如何测试的:

我添加了一个名为
createData
的方法,该方法将生成一个新的GeoJson,并将其用于
setData
调用。我还添加了一个
setInterval
以每5秒添加10个标记

我唯一能让它工作的方法是删除源,然后重新添加它们。这是可行的…但会导致闪烁,因为层已完全删除


我做错了什么?

在求助于官方Gitlab for Mapbox GL JS将此作为一个bug发布后,解决方案变得非常简单:使用
setData
只需要获取GeoJSON的数据部分,而不需要重新获取完整的GeoJSON对象

因此,只有设置数据才能解决此问题。希望其他人可以使用此信息

以我自己为例:

   map.getSource('earthquakes').setData(createData().data); 

   // The .data part is important here!
   // We don't want to use the complete GeoJSON, but only the data part in it