开放层 3 - 修改集群层的功能
OpenLayer 3 - modify features of Cluster layer
以下问题已经在"OL3 Dev"上提出,但已移至StackOverflow以符合组策略。
我已经使用 OpenLayers 3 一段时间了,并实现了一个简单的测试应用程序,在那里我模拟了地图上几个对象的移动。我使用矢量图层和相应的矢量源。
假设我有大约 1000 个具有 ol.geom.Point 几何的特征,每 20-30 秒更新一次。
我可以通过修改几何坐标获得相当好的结果,结果很流畅并且工作正常。
现在,我尝试使用群集功能对已关闭的功能进行分组。不幸的是,在这种情况下,结果非常缓慢且不规则。我认为问题是由于每次更改单个特征的几何形状时都会触发 change() 事件,所以我想知道:
有没有办法防止集群立即考虑对要素的修改,并仅在特定时间间隔触发它?
在下面,您可以找到两个示例,第一个没有集群源,第二个示例带有集群源。
-
无群集: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);
-
集群: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 个特征的位置。在第一种情况下,与地图的交互是平滑的,而在第二种情况下,它经常停止或减慢。
关于如何避免这种情况的任何线索或建议?
提前致谢
现在这是一个旧链接,但是由于我遇到了完全相同的问题,我想我会发布我的解决方法。
这个想法是削弱集群源中的违规事件处理程序,并且仅在每帧呈现时触发相同的代码。
请注意,显示的代码:
- 真的是一个相当黑客,因为它在搞砸私人功能。
- 由于上述原因,它可能需要针对不同的非调试版本进行修改。
- 使用比 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);
如您所见,即使更新时间为 1000 毫秒,这也可以轻松处理 100 个功能。
- 如何修改此功能以获得最受欢迎的视频?(YouTube API v3)
- 有没有一种方法可以修改在使用javascript的媒体功能的媒体查询下创建的样式
- 开放层 3 - 修改集群层的功能
- JqueryUI访问修改拖拽功能
- 修改公共 npm 包中的某些功能
- 太妃糖数据库和文档修改功能
- 修改地板/天花板功能以处理 1 以外的数字
- 和服:修改数据、分解字符串和添加新属性的功能
- 修改单页滚动功能 - 重叠而不是向上滑动
- Jquery脚本修改以添加淡入/淡出功能
- 我将如何获取此.scrollTop代码并对其进行修改以在鼠标悬停或滚动时暂停其功能
- 在高图中启用“向下钻取”功能,无需修改序列
- 我如何修改我的保存功能,既保存用户/编辑用户
- 如何修改此函数以同时包含上升和下降功能?
- jQuery修改CSS的功能
- 修改删除/退格键的功能
- Parse.com云功能-在发送到客户端之前手动修改对象字段
- jQuery文档修改功能
- 请根据其他事件修改ng-click的功能
- 修改网站默认选项卡功能