Leaflet

一个开源的 JavaScript 库
用于移动友好的交互式地图

← 返回博客文章列表

Leaflet.MarkerCluster 0.1 发布

这是一篇来自 Dave Leaver 的客座文章,他是 Leaflet 的活跃贡献者(特别是,他实现了 0.4 版缩放动画改进),也是目前最好的标记聚类插件的作者,该插件将在本文中介绍。

几乎任何拥有地图和标记的人最终都会遇到标记重叠的问题。在我的日常工作中,在 Smartrak 公司,我们经常有客户在地图上拥有成千上万的点。当您缩小地图时,这些标记会重叠,使地图看起来杂乱无章。在某些情况下,即使在最大缩放级别上,标记也会重叠,这使得与它们进行交互变得不可能。此外,在地图上放置大量标记通常会导致性能降低到不可接受的水平。

为了改善这种情况,许多网站使用标记聚类,这是一种在每个缩放级别上将彼此靠近的标记分组在一起的技术。一个很好的例子是 Redfin。我们需要类似的东西,但在 Leaflet 中。本着开源的精神,我们开发并发布了我们的解决方案,以便每个人都能从中受益。因此,我们自豪地向大家介绍 Leaflet.MarkerCluster

特性

聚类器具有各种很棒的内置行为

用法

使用标记聚类器很简单,只需将您现有的 LayerGroup 用法替换为 L.MarkerClusterGroup

var markers = new L.MarkerClusterGroup();

markers.addLayer(L.marker([175.3107, -37.7784]));
// add more markers here...

map.addLayer(markers);

您还可以对单个标记和聚类使用所有 FeatureGroup 事件(以及 clusterclick)。

markers.on('clusterclick', function (a) { alert('Cluster Clicked'); });
markers.on('click', function (a) { alert('Marker Clicked'); });

最佳实践

获取它

您可以在 github 下载页面 上下载最新版本。

技术细节

底层的聚类算法 (MarkerClusterGroup._cluster) 是简单的贪婪聚类。

foreach marker
    if there is a cluster within the clustering distance, join it.
    else if there is an unclustered marker within the clustering distance, form a cluster with it.

我们对最大(最底层)缩放级别执行的第一个聚类步骤,然后我们对所有生成的标记和聚类进行聚类,以生成下一个更高的缩放级别,以此类推,直到我们到达顶部。这些聚类存储在一个树中(一个聚类包含其子聚类),具有良好的地理空间特性。我们使用这棵树来优化识别在任何特定缩放级别上屏幕上的标记和聚类。

L.DistanceGrid

L.DistanceGrid 在聚类时提供了一些不错的优化(由 Leaflet 维护者 Vladimir 贡献)。

为了对标记进行聚类,我们需要将每个标记与其他所有标记进行比较,以尝试形成聚类。为了加快这个过程,我们需要减少需要比较的标记集。 DistanceGrid 通过将所有标记放在与我们需要搜索的距离相同的网格上,来实现这一点。然后,当寻找要聚类的标记时,我们只需要查看我们所在的网格方块及其相邻的网格方块中的标记。这可能是一个很大的性能提升,因为我们只查看可能形成聚类的标记。 (查看最初的 PR 以获取数据)

结语

我希望您喜欢使用聚类器并从中学到您想要的一切。如果您在公共网站上使用它,请 给我发电子邮件,以便我查看它,并可能将其链接到 github 网站上。

如果您有任何问题,请在 github 页面 上提交错误报告。

享受!
Dave Leaver。