gpt4 book ai didi

javascript - OpenLayer 3 - 修改 Cluster 层的特征

转载 作者:行者123 更新时间:2023-11-29 15:36:04 25 4
gpt4 key购买 nike

以下问题已在“OL3 Dev”上提出,但已移至 StackOverflow 以符合组策略。

我使用 OpenLayers 3 已经有一段时间了,并实现了一个简单的测试应用程序,我在其中模拟了 map 上多个对象的移动。我使用矢量层和相应的矢量源。

假设我有大约 1000 个具有 ol.geom.Point 几何图形的特征​​,每 20-30 秒更新一次。

我通过修改几何坐标得到了很好的结果,结果很平滑,工作正常。

现在我尝试使用集群功能,对封闭的功能进行分组。不幸的是,在这种情况下,结果非常缓慢且不规则。我认为问题是由于每次更改单个要素的几何形状时都会触发 change() 事件,所以我想知道:

有没有办法阻止集群立即考虑修改功能,并仅在特定时间间隔触发它?

您可以在下面找到两个示例,第一个没有集群源,第二个有集群源。

  1. 无集群:http://jsfiddle.net/sparezenny/dwLpmqvc/

    var mySource =  new ol.source.Vector({
    features : new Array()
    });

    var myLayer = new ol.layer.Vector({
    source: mySource,
    style: function(feature, resolution) {
    var myStyle = [new ol.style.Style({
    image: new ol.style.Circle({
    radius: 10,
    stroke: new ol.style.Stroke({
    color: '#fff'
    }),
    fill: new ol.style.Fill({
    color: '#3399CC'
    })
    })
    })];
    return myStyle;
    }
    });

    var map = new ol.Map({
    target: 'map',
    layers: [
    new ol.layer.Tile({
    source: new ol.source.MapQuest({layer: 'sat'})
    }),
    myLayer
    ],
    view: new ol.View({
    center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
    zoom: 4
    })
    });

    var positions = new Array();

    function Mock(id, longitude, latitude){
    this.id=id;
    this.latitude=latitude;
    this.longitude=longitude;
    };

    function updatePositions(mocks){
    var featuresToBeAdded = new Array();
    for (var i=0; i < mocks.length; i++){
    var mock = mocks[i];
    var id = mock.id;
    var previousPosition = positions[id];
    var resultFeature;
    var position;
    // new
    if (previousPosition==undefined || previousPosition==null){
    position = ol.proj.transform([ mock.longitude, mock.latitude ],
    'EPSG:4326', 'EPSG:3857');
    positions[id] = mock;
    resultFeature = new ol.Feature({
    geometry: new ol.geom.Point(position)
    });
    featuresToBeAdded.push(resultFeature);
    }
    // update
    else{
    resultFeature = positions[id].feature;
    positions[id] = mock;
    position = ol.proj.transform([ mock.longitude, mock.latitude ],
    'EPSG:4326', 'EPSG:3857');
    resultFeature.getGeometry().setCoordinates(position);
    }
    positions[id].feature = resultFeature;
    }

    if (featuresToBeAdded.length>0){
    mySource.addFeatures(featuresToBeAdded);
    }
    //map.render();
    }

    var myMocks = new Array(1000);
    for (var i=0; i<1000; i++){
    myMocks[i] = new Mock(i,
    37.41+(Math.random()>0.5?0.01:-0.01)*i,
    8.82 +(Math.random()>0.5?0.01:-0.01)*i);
    }

    setInterval(
    function(){
    var j = Math.round(Math.random()*980);
    for (var i=0; i<20; i++){
    myMocks[j+i].latitude = myMocks[j+i].latitude + (Math.random()>0.5?0.01:-0.01);
    myMocks[j+i].longitude = myMocks[j+i].longitude + (Math.random()>0.5?0.01:-0.01);
    }
    console.debug("updatePositions..");
    updatePositions(myMocks);
    }, 5000);
  2. 集群:http://jsfiddle.net/sparezenny/gh7ox9nj/

    var mySource =  new ol.source.Vector({
    features : new Array()
    });

    var clusterSource = new ol.source.Cluster({
    distance: 10,
    source: mySource
    });

    var myLayer = new ol.layer.Vector({
    source: clusterSource,
    style: function(feature, resolution) {
    var clusteredFeatures = feature.get('features');
    var size = feature.get('features').length;
    var myStyle = [new ol.style.Style({
    image: new ol.style.Circle({
    radius: 10,
    stroke: new ol.style.Stroke({
    color: '#fff'
    }),
    fill: new ol.style.Fill({
    color: '#3399CC'
    })
    }),
    text: new ol.style.Text({
    text: size.toString(),
    fill: new ol.style.Fill({
    color: '#fff'
    })
    })
    })];
    return myStyle;
    }
    });

    var map = new ol.Map({
    target: 'map',
    layers: [
    new ol.layer.Tile({
    source: new ol.source.MapQuest({layer: 'sat'})
    }),
    myLayer
    ],
    view: new ol.View({
    center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
    zoom: 4
    })
    });

    var positions = new Array();

    function Mock(id, longitude, latitude){
    this.id=id;
    this.latitude=latitude;
    this.longitude=longitude;
    };

    function updatePositions(mocks){
    var featuresToBeAdded = new Array();
    for (var i=0; i < mocks.length; i++){
    var mock = mocks[i];
    var id = mock.id;
    var previousPosition = positions[id];
    var resultFeature;
    var position;
    // new
    if (previousPosition==undefined || previousPosition==null){
    position = ol.proj.transform([ mock.longitude, mock.latitude ],
    'EPSG:4326', 'EPSG:3857');
    positions[id] = mock;
    resultFeature = new ol.Feature({
    geometry: new ol.geom.Point(position)
    });
    featuresToBeAdded.push(resultFeature);
    }
    // update
    else{
    resultFeature = positions[id].feature;
    positions[id] = mock;
    position = ol.proj.transform([ mock.longitude, mock.latitude ],
    'EPSG:4326', 'EPSG:3857');
    resultFeature.getGeometry().setCoordinates(position);
    }
    positions[id].feature = resultFeature;
    }

    if (featuresToBeAdded.length>0){
    mySource.addFeatures(featuresToBeAdded);
    }
    //map.render();
    }

    var myMocks = new Array(1000);
    for (var i=0; i<1000; i++){
    myMocks[i] = new Mock(i,
    37.41+(Math.random()>0.5?0.01:-0.01)*i,
    8.82 +(Math.random()>0.5?0.01:-0.01)*i);
    }

    setInterval(
    function(){
    var j = Math.round(Math.random()*980);
    for (var i=0; i<20; i++){
    myMocks[j+i].latitude = myMocks[j+i].latitude + (Math.random()>0.5?Math.random()*0.01:-Math.random()*0.01);
    myMocks[j+i].longitude = myMocks[j+i].longitude + (Math.random()>0.5?Math.random()*0.01:-Math.random()*0.01);
    }
    console.debug("updatePositions..");
    updatePositions(myMocks);
    }, 5000);

如您所见,我有 1000 个特征,我尝试每 5 秒更新其中 20 个特征的位置。在第一种情况下,与 map 的交互很流畅,而在第二种情况下,它经常停止或变慢。

关于如何避免这种情况的任何线索或建议?

提前致谢

最佳答案

现在这是一个旧链接,但由于我遇到了完全相同的问题,我想我应该发布我的解决方法。

这个想法是削弱集群源中的违规事件处理程序,并且只在每一帧渲染时触发相同的代码。

请注意所提供的代码:

  1. 确实是一个 hack,因为它在处理私有(private)函数。
  2. 由于上述原因,它可能需要针对不同的非调试版本进行修改。
  3. 使用比 OP 更新的 OL3 版本(另见第 2 点!)。

JSFiddle here

if (ol.source.Cluster.prototype.onSourceChange_)
{
// Make a new pointer to the old sourceChange function.
ol.source.Cluster.prototype.newSourceChange =
ol.source.Cluster.prototype.onSourceChange_;

// Nuke the old function reference.
ol.source.Cluster.prototype.onSourceChange_ = function() {};
}
if (ol.source.Cluster.prototype.Ra)
{
// As above, but for non-debug code.
ol.source.Cluster.prototype.newSourceChange =
ol.source.Cluster.prototype.Ra;
ol.source.Cluster.prototype.Ra = function() {};
}

// Later on..
map.on('postrender', clusterSource.newSourceChange, clusterSource);

如您所见,即使更新时间为 100 毫秒,这也能轻松处理 1000 个特征。

关于javascript - OpenLayer 3 - 修改 Cluster 层的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28944462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com