實現 Leaflet 多類型點位標記與聚合功能的實戰經驗分享

????????在現代的地理信息系統(GIS)應用中,地圖功能是不可或缺的一部分。無論是展示商業網點、旅游景點還是公共服務設施,地圖都能以直觀的方式呈現數據。然而,當數據量較大時,地圖上可能會出現大量的標記點,這不僅會影響用戶體驗,還會導致性能問題。因此,我們需要一種方法來智能地聚合這些標記點,同時允許用戶在需要時查看詳細信息。

Leaflet 是一個輕量級的開源 JavaScript 地圖庫,它提供了豐富的 API 和插件支持,非常適合實現這種功能。結合 Leaflet.markercluster 插件,我們可以輕松實現標記點的聚合和動態顯示。

項目背景

在最近開發中,我遇到了一個有趣的需求:實現基于 Leaflet 的地圖功能,支持多類型點位標記和聚合。這個功能需要展示不同類型的數據點,并在地圖縮放時智能聚合,以避免地圖過于擁擠。經過一番努力,我成功實現了這一功能,并在此分享我的經驗和代碼實現。

實現思路

1. 數據結構設計

在實現功能之前,我們需要定義清晰的數據結構,以便更好地管理和展示不同類型的數據點。以下是點位數據的格式示例:

markerData: [{latitude: "23.131828",longitude: "113.326821",name: "麥當勞(正佳廣場五樓店)",address: "廣州市天河區天河南街道天河路228號正佳廣場五樓561鋪",type: "fast_food"},{latitude: "23.116523",longitude: "113.390699",name: "肯德基(車陂南店)",address: "廣州市天河區車陂路6號一層",type: "fast_food"}...
]

此外,我們還需要定義支持的標記點類型和對應的樣式配置:

markerType: ["fast_food","coffee","landmark","tourist","shopping","entertainment","transport"
],typeList: [{name: "全部",type: "all",color: "#000000",iconUrl: require("../../assets/img/all.png")},{name: "快餐店",type: "fast_food",color: "blue",iconUrl: require("../../assets/img/fast_food.png")},{name: "咖啡店",type: "coffee",color: "green",iconUrl: require("../../assets/img/coffee.png")},{name: "城市地標",type: "landmark",color: "orange",iconUrl: require("../../assets/img/landmark.png")},{name: "旅游景點",type: "tourist",color: "red",iconUrl: require("../../assets/img/tourist.png")},{name: "購物中心",type: "shopping",color: "purple",iconUrl: require("../../assets/img/shopping.png")},{name: "娛樂場所",type: "entertainment",color: "yellow",iconUrl: require("../../assets/img/entertainment.png")},{name: "交通設施",type: "transport",color: "teal",iconUrl: require("../../assets/img/transport.png")}
]

2. 地圖初始化

首先,我們需要初始化地圖。Leaflet 提供了簡單易用的 API 來創建地圖實例,并設置中心點、縮放級別等基本參數。在我們的項目中,我們使用了天地圖(Tianditu)作為地圖源,這需要通過 WMTS 服務加載矢量地圖和影像地圖圖層。

this.map = L.map("mapRef", {center: [23.111532, 113.324357], // 地圖中心zoom: 13, // 縮放比例zoomControl: false, // 是否顯示縮放按鈕doubleClickZoom: false, // 是否雙擊放大attributionControl: false, // 是否顯示右下角 Leaflet 標識minZoom: 3, // 最小縮放級別
});

3. 添加地圖圖層

我們使用了天地圖的矢量地圖和影像地圖圖層。需要注意的是,天地圖的訪問需要一個有效的 API 密鑰(tk),并且圖層的 URL 需要按照 WMTS 服務的規范進行拼接。

const tiandiKey = "YOUR_TIANDITU_API_KEY"; // 替換為你的天地圖 API 密鑰
const mapUrl = `http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tiandiKey}`;
const cvaLayer = L.tileLayer(`http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tiandiKey}`
);this.map.addLayer(L.tileLayer(mapUrl)); // 添加矢量地圖圖層
this.map.addLayer(cvaLayer); // 添加影像地圖圖層

注意:如果你在加載天地圖時遇到問題,請檢查 API 密鑰是否有效,以及 URL 拼接是否正確。如果問題仍然存在,可能是網絡問題或鏈接本身的問題,建議適當重試或聯系天地圖官方支持。

4. 創建聚合圖層

為了實現標記點的聚合,我們使用了 Leaflet.markercluster 插件。該插件可以將大量的標記點智能地聚合在一起,形成可點擊的群組。當用戶放大地圖時,這些群組會自動拆分成更小的子集或單個標記點。

我們為每種類型的標記點創建了一個獨立的聚合圖層,并通過 iconCreateFunction 動態設置聚合圖標的顏色和樣式。

this.markerType.forEach((type) => {const iconCreateFunction = (cluster) => {const dynamicClassName = `custom-marker cluster-icon-${type}`;return L.divIcon({html: `<div class="${dynamicClassName}"><span>${cluster.getChildCount()}</span></div>`,className: `custom-marker cluster-icon-${type}`,iconSize: L.point(40, 40),});};this.markerClusters[type] = L.markerClusterGroup({iconCreateFunction: iconCreateFunction,});
});

5. 添加標記點

標記點的數據通常以數組的形式存儲,每個數據項包含類型、名稱、地址和坐標等信息,可以點擊展示點位信息。我們根據數據項的類型,將其添加到對應的聚合圖層中。

this.markerData.forEach((item) => {const [longitude, latitude] = gcoord.transform([item.longitude, item.latitude],gcoord.GCJ02,gcoord.WGS84);const marker = L.marker([latitude, longitude], {icon: icons[item.type],});marker.bindPopup(`<b>${item.name}</b><br>${item.address}`);this.markerClusters[item.type].addLayer(marker);
});Object.values(this.markerClusters).forEach((cluster) => {this.map.addLayer(cluster);
});

6. 動態過濾標記點

為了提升用戶體驗,我們允許用戶通過點擊按鈕來篩選特定類型的標記點。當用戶點擊按鈕時,我們移除所有聚合圖層,并根據用戶的選擇重新添加對應的圖層。

filterType(item) {Object.values(this.markerClusters).forEach((cluster) => {this.map.removeLayer(cluster);});if (item.type === "all") {Object.values(this.markerClusters).forEach((cluster) => {this.map.addLayer(cluster);});} else {if (this.markerClusters[item.type]) {this.map.addLayer(this.markerClusters[item.type]);}}
}

性能優化

在處理大量標記點時,性能優化是至關重要的。Leaflet.markercluster 插件本身已經對性能進行了優化,但我們仍然可以通過以下方式進一步提升性能:

  1. 限制標記點數量:在地圖縮放級別較低時,可以隱藏一些不重要的標記點。

  2. 使用緩存:對于重復加載的數據,可以使用緩存機制減少重復請求。

  3. 異步加載數據:如果標記點數據量較大,可以采用分頁或懶加載的方式動態加載數據。

總結

通過 Leaflet 和 Leaflet.markercluster 插件,我們成功實現了一個支持多類型點位標記和聚合的地圖功能。這個功能不僅提升了用戶體驗,還為地圖應用提供了更強大的數據展示能力。在開發過程中,我們需要注意地圖圖層的加載、聚合圖標的動態設置以及性能優化等方面,以確保應用的穩定性和流暢性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71144.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71144.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71144.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

企微審批中MySQL字段TEXT類型被截斷的排查與修復實踐

在MySQL中&#xff0c;TEXT類型字段常用于存儲較大的文本數據&#xff0c;但在一些應用場景中&#xff0c;當文本內容較大時&#xff0c;TEXT類型字段可能無法滿足需求&#xff0c;導致數據截斷或插入失敗。為了避免這種問題&#xff0c;了解不同文本類型&#xff08;如TEXT、M…

【常見BUG】Spring Boot 和 Springfox(Swagger)版本兼容問題

???歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學習,不斷總結,共同進步,活到老學到老…

HTTP 協議的發展歷程:從 HTTP/1.0 到 HTTP/2.0

HTTP 協議的發展歷程&#xff1a;從 HTTP/1.0 到 HTTP/2.0 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是 Web 的基礎協議&#xff0c;用于客戶端和服務器之間的通信。從 HTTP/1.0 到 HTTP/2.0&#xff0c;HTTP 協議經歷了多次重大改…

apload-lab打靶場

1.提示顯示所以關閉js 上傳<?php phpinfo(); ?>的png形式 抓包&#xff0c;將png改為php 然后放包上傳成功 2.提示說檢查數據類型 抓包 將數據類型改成 image/jpeg 上傳成功 3.提示 可以用phtml&#xff0c;php5&#xff0c;php3 4.先上傳.htaccess文件&#xff0…

金融支付行業技術側重點

1. 合規問題 第三方支付系統的平穩運營&#xff0c;嚴格遵循《非銀行支付機構監督管理條例》的各項條款是基礎與前提&#xff0c;其中第十八條的規定堪稱重中之重&#xff0c;是支付機構必須牢牢把握的關鍵準則。 第十八條明確指出&#xff0c;非銀行支付機構需構建起必要且獨…

Cherry Studio + 火山引擎 構建個人AI智能知識庫

&#x1f349;在信息化時代&#xff0c;個人知識庫的構建對于提高工作效率、知識管理和信息提取尤為重要。尤其是當這些知識庫能結合人工智能來智能化地整理、分類和管理數據時&#xff0c;效果更為顯著。我最近嘗試通過 Cherry Studio 和 火山引擎 來搭建個人智能知識庫&#…

LeetCode 2 - 兩數相加

LeetCode 2 - 兩數相加 是一道經典鏈表操作問題&#xff0c;經常作為面試中基礎題的變體被考察。掌握多種解法及其變體&#xff0c;并熟悉其核心思路和模板代碼&#xff0c;可以快速備戰相關鏈表或大數計算問題。 題目描述 給定兩個非空鏈表&#xff0c;它們代表兩個非負整數&…

Qt之QStateMachine等待

在項目中經常需要等待&#xff0c;我們模擬0-30的數&#xff0c;假如我們其中5&#xff0c; 25的數需要進行等待&#xff0c;等待用戶處理完自己事情后&#xff0c;按下按鈕繼續&#xff0c;找Qt的項目中有一個 QStateMachineqstatemmachine類提供了一個分層有限狀態機。 QSta…

elpis全棧課程學習之elpis-core學習總結

elpis全棧課程學習之elpis-core學習總結 核心原理 elpis-core是全棧框架elpis的服務端內核&#xff0c;主要應用于服務端接口的開發以及頁面的SSR渲染&#xff0c;elpis-core基于約定優于配置的原理&#xff0c;通過一系列的loader來加載對應的文件&#xff0c;大大節約用戶的…

ChatGPT與DeepSeek:開源與閉源的AI模型之爭

目錄 一、模型架構與技術原理 二、性能能力與應用場景 三、用戶體驗與部署靈活性 四、成本與商業模式 五、未來展望與市場影響 六、總結 隨著人工智能技術的飛速發展&#xff0c;ChatGPT和DeepSeek作為兩大領先的AI語言模型&#xff0c;成為了行業內外關注的焦點。它們在…

在筆記本電腦上用DeepSeek搭建個人知識庫

最近DeepSeek爆火&#xff0c;試用DeepSeek的企業和個人越來越多。最常見的應用場景就是知識庫和知識問答。所以本人也試用了一下&#xff0c;在筆記本電腦上部署DeepSeek并使用開源工具搭建一套知識庫&#xff0c;實現完全在本地環境下使用本地文檔搭建個人知識庫。操作過程共…

DeepSeek蒸餾TinyLSTM實操指南

一、硬件準備 階段推薦配置最低要求訓練階段NVIDIA A100 80GB 4RTX 3090 24GB 1量化階段Intel Xeon Gold 6248R CPUi7-12700K + 64GB RAM部署階段Jetson Xavier NX開發套件Raspberry Pi 4B 8GB二、軟件環境搭建 # 創建Python虛擬環境 conda create -n distil python=3.9 conda…

Linux ls 命令

Linux ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于顯示指定工作目錄下之內容&#xff08;列出目前工作目錄所含的文件及子目錄)。 語法 ls [-alrtAFR] [name...] 參數 : -a 顯示所有文件及目錄 (. 開頭的隱藏文件也會列出)-d 只列出目…

LeetCode 熱題 100 53. 最大子數組和

LeetCode 熱題 100 | 53. 最大子數組和 大家好&#xff0c;今天我們來解決一道經典的算法題——最大子數組和。這道題在 LeetCode 上被標記為中等難度&#xff0c;要求我們找出一個具有最大和的連續子數組&#xff0c;并返回其最大和。下面我將詳細講解解題思路&#xff0c;并…

【計算機網絡入門】初學計算機網絡(九)

目錄 1.令牌傳遞協議 2. 局域網&IEEE802 2.1 局域網基本概念和體系結構 3. 以太網&IEEE802.3 3.1 MAC層標準 3.1.1 以太網V2標準 ?編輯 3.2 單播廣播 3.3 沖突域廣播域 4. 虛擬局域網VLAN 1.令牌傳遞協議 先回顧一下令牌環網技術&#xff0c;多個主機形成…

Java 大視界 -- Java 大數據中的時間序列數據異常檢測算法對比與實踐(103)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

Android Activity棧關系解析

在 Android 系統中&#xff0c;這些類共同構成了 Activity 任務棧管理的核心架構。它們的關系可以類比為一棟大樓的管理體系&#xff0c;每個類負責不同層級的任務。以下是它們的詳細解釋和實際場景示例&#xff1a; 1. ActivityRecord&#xff08;活動記錄&#xff09; 是什么…

【0011】HTML其他文本格式化標簽詳解(em標簽、strong標簽、b標簽、i標簽、sup標簽、sub標簽......)

如果你覺得我的文章寫的不錯&#xff0c;請關注我喲&#xff0c;請點贊、評論&#xff0c;收藏此文章&#xff0c;謝謝&#xff01; 本文內容體系結構如下&#xff1a; 本文旨在深入探討HTML中其他的文本格式化標簽&#xff0c;主要有<em> 標簽、<strong> 標簽、…

華為AP 4050DN-HD的FIT AP模式改為FAT AP,家用FAT基本配置

在某魚買了兩臺華為AP 4050DN-HD , AP是二手的 , 在AC上上過線 , 所以就不能開機自選為FIP模式了 我沒有AC無線控制器 , 就是買一個自己玩 , AP又是FIT瘦AP模式 ,所以我就想把AP的瘦AP模式改為FAT胖AP模式 1. 準備工作 1.1下載好對應軟件&#xff0c;進入到 企業業務網站去下…

【Linux網絡-HTTP協議】HTTP基礎概念+構建HTTP

代碼定位&#xff1a;南毅c/Linux - Gitee.com HTTP協議 介紹 雖然我們說&#xff0c;應用層協議是我們程序猿自己定的.但實際上,已經有大佬們定義了一些現成的,又非常好用的應用層協議,供我們直接參考使用。HTTP(超文本傳輸協議)就是其中之一。 在互聯網世界中&#xff0c…