Leaflet.MarkerCluster 0.1 發佈
這是一篇來自 Dave Leaver 的客座文章,他是 Leaflet 的活躍貢獻者(尤其是,他實作了 0.4 版本縮放動畫的改進),也是目前最佳標記叢集外掛的作者,而這篇文章將介紹這個外掛。
幾乎所有在地圖上標記的人最終都會遇到這些標記重疊的問題。在我在 Smartrak 的日常工作中,我們經常有客戶在地圖上有數千個點。當您縮小時,這些標記都會重疊,使地圖看起來雜亂無章。在某些情況下,即使在最大縮放級別下,標記也會重疊,這使得與它們的互動變得不可能。此外,在地圖上放置大量標記通常會使效能降低到無法接受的程度。
為了改善這一點,許多網站使用標記叢集,這是一種將每個縮放級別上彼此靠近的標記分組在一起的技術。一個很好的例子是 Redfin。我們需要類似的東西,但使用 Leaflet。本著開源的精神,我們開發並發布了我們的解決方案,以便每個人都可以利用它。因此,我們自豪地推出 Leaflet.MarkerCluster。
功能
這個叢集器內建了各種很棒的行為
- 所有東西都使用了精美的動畫。當您放大和縮小時,可以邏輯地看到哪些叢集變成了哪些標記。
- 它速度非常快,例如,叢集 50,000 個點 並不是問題。此外,所有繁重的計算都發生在初始頁面載入時,之後地圖會平穩運作。
- 不需要叢集的標記不會被叢集,並且在相關的縮放級別中會可見。
- 當您將滑鼠懸停在叢集上時,會顯示該叢集內標記的範圍。
- 點擊叢集會將您放大到其子元素的範圍。
- 在最底部的縮放級別,如果仍然有叢集,您可以點擊它們以「蜘蛛化」它們,這使得與叢集內單個標記的互動成為可能(基於 jawj 的 Overlapping MarkerSpidifer)。
- 距離可視區域螢幕寬度以外的叢集和標記會從地圖中移除,以提高效能。
- 與核心 Leaflet 一樣,所有東西都可以在行動裝置和桌面瀏覽器上運作,並且經過測試可回溯到 IE6。
- 支援在新增到地圖後新增和移除標記(請參閱下面的「最佳實務」!)。
- 它具有高度可自訂性,可讓您輕鬆更改叢集的外觀、停用某些功能,以及在叢集互動時新增自訂行為。
用法
使用標記叢集器很簡單,只需將您現有的 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'); });
最佳實務
- 為了從叢集器獲得最佳效能,您應該在將所有標記加入地圖之前將它們加入叢集器(就像我們在範例中所做的那樣)。
- 如果您要移動 L.MarkerClusterGroup 中的標記,您必須先移除它,然後移動它,然後重新新增它。如果您在它位於 MarkerClusterGroup 中時移動它,我們將無法追蹤它,並且該標記會遺失。
- 雖然叢集器支援在它位於地圖上時新增和移除標記,但其效能不如在它不在地圖上時新增它們。如果您需要對
MarkerClusterGroup
中的標記進行大型更新,您可能需要將它從地圖中移除、更改標記,然後重新加入它。
取得
您可以在 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。