【发布时间】:2015-12-16 06:46:21
【问题描述】:
我有一个动态创建的 GeoJSON 文件,其中包含具有特定纬度/经度、时间戳和类型信息的数据。这些数据会不断更新,需要在谷歌地图上实时显示。这是一个sn-p:
{ "type": "FeatureCollection","features": [
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [149.522, -30.3603]},
"properties": {
"id": "20447637",
"lat": "-30.3603",
"long": "149.522",
"timestamp": "1450247155",
"strokeType": "0",
"mag": "19.9"
}
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [149.555, -30.3647]},
"properties": {
"id": "20451255",
"lat": "-30.3647",
"long": "149.555",
"timestamp": "1450247646",
"strokeType": "3",
"mag": "0"
}
},...
我目前正在使用 ajax 调用从数据库生成所需数据的 php 脚本导入此 geojson 文件,这一切都很好并且是响应式的。问题是当我尝试设置这些项目的样式时,它可能会导致浏览器崩溃(可能有数千个)。这是我目前用来设置样式的代码:
function styleFeature(feature) {
var seconds = new Date().getTime() / 1000;
var timeElapsed = seconds - feature.getProperty('timestamp');
var fraction = timeElapsed/(TimeScale/255);
var color = 'rgb(' + Math.round((255 - fraction)) + ', 0, ' + Math.round(0 + fraction) + ')';
if(timeElapsed<15) { var stkWeight = 2; var stkColor = "#000"; } else { var stkWeight = 0.5; var stkColor = "#fff"; }
if(feature.getProperty('strokeType')==0) {
if(feature.getProperty('mag')>0) {
return {
icon: {
path: 'm5.219986,29.697235l23.795303,0l0,-25.117241l24.409424,0l0,25.117241l23.795288,0l0,25.765518l-23.795288,0l0,25.117264l-24.409424,0l0,-25.117264l-23.795303,0l0,-25.765518z',
strokeWeight: stkWeight,
strokeColor: stkColor,
fillColor: color,
fillOpacity: 0.5,
scale: 0.12 * scale
},
};
} else {
return {
icon: {
path: google.maps.SymbolPath.BACKWARD_OPEN_ARROW,
strokeWeight: stkWeight,
strokeColor: stkColor,
fillColor: color,
fillOpacity: 0.5,
scale: 1.5 * scale
},
};
}
} else {
return {
icon: {
path: google.maps.SymbolPath.CIRCLE,
strokeWeight: stkWeight,
strokeColor: stkColor,
fillColor: color,
fillOpacity: 0.5,
scale: 2 * scale
},
};
}
}
有 3 种不同类型的图标,其中两种是 Google 的默认图标,一种是自定义 + 形状。 geojson 文件中的每个特征的样式如下:
- 图标的颜色取决于它的时间戳(红色是最新的,蓝色是旧的)
- “strokeType”和“mag”字段决定使用哪个图标(圆形、三角形、加号)
- 最后 x 秒内的新图标被赋予更粗的黑色边框
这都是从map.data.setStyle(styleFeature);直接调用的map.data.addGeoJson(geoJSONDataFromAjaxCall);之后
然后每隔 x 秒调用一次此脚本以检索更新的信息,然后该信息还需要与其他信息一起绘制在地图上。需要删除超过预定时间(例如 60 分钟或 3600 秒)的数据,并且每个标记都需要随着时间的推移而改变颜色。
我已经能够实现上述所有功能,但是当视口中的图标超过几百个时,浏览器会堵塞并可能崩溃。如果我使用标准标记而不对其进行样式设置,则效果很好。我正在寻找一种在不使浏览器崩溃的情况下设置这些图标样式的方法,我猜我这样做的方式非常耗费资源。
【问题讨论】:
-
您是否在所有标记(又名数千?)上运行 styleFeature() 函数。在每个功能上重新计算函数的第 2-5 行可以从函数中取出并显着减少计算/资源。我会根据 single responsibility principle 将该函数分解为多个。
-
尝试在
map.data.addGeoJson()之前调用map.data.setStyle(styleFeature);,否则API需要循环2次数据 -
@TheBrofessor 不幸的是,每个标记都需要进行计算才能确定它的颜色和类型。如果在 styleFeature 函数之外进行计算会更快吗?我不确定在 Javascript/jQuery 中运行代码的最快方式。
-
@Dr.Molle 感谢您的建议,但似乎收效甚微。
标签: javascript html google-maps