另一个选择是热力图。
https://developers.google.com/maps/documentation/javascript/heatmaplayer
有些事情我必须提醒自己(我注意到原始问题是来自2014年),那就是JavaScript很快。实际上,经常当我认为JS有问题时,其实往往是DOM的问题。
在2022年,在一个常量中保存1,000,000个数据点并不算不合理。然后问题就变成了渲染问题。我发现,热力图只要数据不变,就可以非常快速地渲染。
不过,即使到了2022年,我也难以相信您可以在不到15秒的时间内加载1,000,000条记录。我想,如果用户登录仪表板并开始异步加载,一旦用户到达页面,它会看起来比较快。许多聪明的应用程序在幕后聪明地预加载,利用了速度感知。
使用这种技术的方法是为当前边界+ 100英里半径呈现标记/热力图。然后随着用户的缩放/拖动,您可以按需切分1,000,000个项目数组。
(async function () {
let Points = [];
let Bounds = {};
let Map;
let Heatmap;
let BoundTimeout;
async function getPoints(page = 1) {
let response;
try {
response = await fetch(myRestUrl, { body: JSON.stringify(Bounds) });
} catch (e) {
console.error(e);
}
if (response) {
Points = response;
}
}
function generateGoogleMap() {
Map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(37.782, -122.447),
zoom: 13,
mapTypeId: 'satellite',
});
Map.addListener('bounds_changed', BoundChange);
BoundChange();
}
function BuildHeatmap() {
if (Heatmap) {
Heatmap.setMap(null);
Heatmap = null;
}
Heatmap = new google.maps.visualization.HeatmapLayer({
data: Points.map(
(P) => new google.maps.LatLng(P.coordinates[1], P.coordinates[0])
),
});
Heatmap.setMap(Map);
}
function BoundChange() {
clearTimeout(BoundTimeout);
const MapBounds = Map.getBounds();
const sw = MapBounds.getSouthWest();
const ne = MapBounds.getNorthEast();
Bounds = {
type: 'Polygon',
coordinates: [
[
[sw.lng(), sw.lat()],
[ne.lng(), sw.lat()],
[ne.lng(), ne.lat()],
[sw.lng(), ne.lat()],
[sw.lng(), sw.lat()],
],
],
};
BoundTimeout = setTimeout(async () => {
await getPoints();
BuildHeatmap();
}, 1000);
}
await getPoints();
generateGoogleMap();
})();
以上示例未考虑100英里半径,但我建议在服务器上进行转换。另一个想法是使用Web套接字 - 如果您希望用户将窗口保持打开状态作为仪表板(例如),则可以更快。上面的示例还未考虑库、DOM或加载顺序,因此不能简单地复制和粘贴,仅提供它作为示例。