在谷歌地图上加载 100-200K 标记

Posted

技术标签:

【中文标题】在谷歌地图上加载 100-200K 标记【英文标题】:Loading 100-200K markers on google map 【发布时间】:2015-12-10 12:32:33 【问题描述】:

目前我正在使用 Google Maps v.3 API 在地图上绘制标记。 我总共有大约 500 个标记。

出于显示目的,我在浏览器的客户端使用 markerCluster 并使用此工具对标记进行分组。

但是,我计划扩大位置数量,并假设它可以快速增长到 100K 甚至 200K。

我做了一些压力测试,发现当前的解决方案基本上会杀死浏览器和大约 10-20K 标记。

所以我的问题是绘制这么多标记的最佳方法是什么(不需要谷歌地图)?

我读过类似问题的帖子,例如:

Showing many markers in Google Maps

Best solution for too many pins on google maps

基本上人们建议使用一些集群器来显示,我已经使用了。

或者使用融合表来检索数据,这不是一个选项,因为数据必须保留在我的服务器上。另外我假设显示功能受限于融合表。

我正在考虑实现以下场景:

在每个页面缩放/加载 - 发送带有显示视图边界的 ajax 请求,在所有边添加大约 30% 并检索标记,这些标记仅属于该地理区域。 添加 30% 以防用户缩小,以便我可以快速显示周围的其他标记,然后在后台进一步检索周围的其余标记(更广阔的领域)

当标记的数量超过 50 时,我计划应用聚类来进行显示。但是由于javascript中的markerCluster非常慢,即不是markerCluster而是google本身,因为它仍然应用所有标记的位置,我计划通过将显示地图的边界分割成大约15 * 15网格在服务器端进行聚类并将标记放入特定的单元格,然后基本上发送到带有内部标记数量的客户端集群(例如,对于热图)。然后将簇显示为标记。

您能否提供一些类似的见解。一般说得通吗。或者这是一种愚蠢的方法,因为 ajax 请求将在每次地图缩放和移动时发送到服务器,并且基本上会因冗余请求而使服务器过载?

我想要实现的是在大型标记数据集上获得良好的用户体验(在 2 秒内加载)。

【问题讨论】:

改为通过ajax调用批量带marker,批量绘制 @sunil 你能详细说明一下吗?因此,为特定区域加载批次并逐个区域绘制它们 - 我认为这对用户来说将是一团糟。 另一种思考方案的方式是,您在服务器上有多级矢量切片 - 就像地图切片一样,但这些“切片”是区域内标记/集群位置的位置。前端根据缩放级别和范围请求此类“图块”。客户端可以缓存这样的“图块”,因此可能不需要在每次缩放和平移时重新加载。 【参考方案1】:

你的方法是可靠的。如果可能的话,您需要预先计算集群并将它们缓存在服务器端,它们的更新策略取决于底层数据集更改的频率。

Google 地图有大约 20 个缩放级别,具体取决于您在地球上的位置。根据您的数据的聚类程度,如果您总共有 200,000 个标记并且愿意在给定时间在地图上显示大约 500 个,计算所有群集位置和原始标记,您最终只会存储大约 2n = 400,000 个位置服务器-side 结合了所有缩放级别。

可能的集群更新策略:

更新每个添加的新标记。如果您需要高度的数据及时性,则可能适用于具有少量写入的读取繁重的应用程序。 按计划更新 如果((自上次聚类传递以来有任何新标记 && 缓存早于 X)|| 自上次聚类传递以来有超过 Y 个新标记),则启动更新

将这些标记存储在本地支持地理数据的数据库中可能是有益的。这允许类似 SQL 的语句查询位置。

在客户端,我会考虑在任一侧获取 50% 的保证金,而不是 30%。 Google 放大 2 的幂。这将允许您显示一个完整的缩放级别。

接下来,如果这个应用程序会被大量使用并且值得优化,我会在客户端放大时记录服务器端。尝试分析您的使用情况,以便确定用户是否经常放大和缩小。使用实心数字(例如“70% 的用户在检索初始结果后放大,20% 缩小”),您可以确定是否值得为您的用户预加载下一层缩放数据,以获得 UI响应能力。

【讨论】:

感谢您的准确回答!它指导我构建我们的解决方案,并且我写了一篇关于如果对更多细节感兴趣的人的博客文章:how I cached map clusters and achieved a ~50x speedup 不错。那是你写的一篇非常详尽的文章,其中有很多关于你使用 Redis 的方法的详细信息。感谢分享。

以上是关于在谷歌地图上加载 100-200K 标记的主要内容,如果未能解决你的问题,请参考以下文章

如何在谷歌地图android上设置多个标记?

怎么在谷歌地图上做标记呀

如何在谷歌地图上放置标记

无法在谷歌地图上看到多个标记

如何设置Map(),setVisible()4000/5000的标记而不会在谷歌地图api V3中失去性能?

在谷歌地图标记上显示信息