標籤:leaflet、svg、Canvas、插件、海量點、海量數據、Canvas-Markers、Leaflet.Canvas-Markers、性能css
做爲一名GIS開發者,你工做中必定遇到過這種問題,根據業務設計,須要在地圖上添加1萬+條數據,數據或是點、或是線、或是面。但無論哪一種,當你添加到5000條時,地圖操做就會出現明顯的卡頓。當你添加超過1萬條時,數據加載就會卡頓,瀏覽器出現卡死的狀態,地圖加載後,每挪動一下地圖,都要耐心的等待上幾秒鐘。html
這種交互體驗,用戶是確定接受不了的,解決方法一般分兩種,一種是去作深刻的用戶需求分析,看用戶想一次性加載這麼多數據是爲了看什麼,想看的這個東西,經過其它技術方式能不能實現。另外一種就是死磕技術,研究如何提高地圖性能。咱們今天只討論第二種狀況。git
leaflet支持兩種渲染方式,svg 和 canvas,默認是svg渲染,這樣能夠兼容低版本的IE瀏覽器。canvas渲染須要IE9+,或谷歌、火狐的高版本瀏覽器。canvas比svg性能好,我本身作了簡單的測試,svg模式加載5000個圖片標記時出現的卡頓狀況,用canvas模式,加載10萬條數據時纔會出現。github
下面講如何徹底切換到canvas模式,共兩步:canvas
一,在初始化地圖時,設置map的 preferCanvas 屬性爲 true,代碼以下:api
var map = L.map('map', { center: [39.905963, 116.390813], zoom: 13, preferCanvas: true });
這個設置只針對繼承了Path類的矢量圖層有效,包括圓點(CircleMarker)、線(Polyline)、面(Polygon)、圓(Circle)、矩形(Rectangle)。針對圖片標記(Marker)沒有做用。瀏覽器
2、藉助插件 Leaflet.Canvas-Markers,提高Marker的顯示性能。插件git地址:https://github.com/eJuke/Leaflet.Canvas-Markersdom
Leaflet.Canvas-Markers 插件提供了一個 L.canvasIconLayer
類,這個類是一個圖層,將 Marker 添加到這個圖層中時,這個圖層會以 canvas 方式渲染 Marker 中的圖片。svg
在html中引入插件性能
<script src="leaflet.canvas-markers.js"></script>
建立canvasIconLayer圖層,把圖層添加到地圖,給圖層添加圖片標記。
// 建立圖層,添加到 map var ciLayer = L.canvasIconLayer({}).addTo(map); // 定義 Marker var marker = L.marker([58.5578, 29.0087], {icon: icon}); // 把 Marker 添加到圖層 ciLayer.addMarker(marker);
這個插件有個問題,就是地圖縮放時,添加的數據不跟着同步縮放,而是等到縮放完成後,再去縮放。這樣感受縮放時,數據在飄着。
不過已經有人對這個問題提出瞭解決方案,而且解決了(連接),只是代碼一直沒有被合併。不過這都沒有關係,咱們能夠去用那份兒已經解決的代碼(連接)
解決之後的效果:
注意:這份代碼由於是引用的在線地址,因此存在上文中說的縮放地圖時感受飄的問題,
<!DOCTYPE html> <html> <head> <title>leaflet-canvas-marker</title> <meta charset="utf-8" /> <!-- 引入leafletapi --> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" /> <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script> <!-- 引入leaflet-canvas-marker插件 --> <script src="https://unpkg.com/leaflet-canvas-marker@0.2.0"></script> <style> body { margin: 0; } .map {position: absolute; height: 100%; right: 0; left: 0; } </style> </head> <body> <div class="map" id="map"></div> <script> var map = L.map('map',{ center: [39.905963, 116.390813], zoom: 14, preferCanvas: true //使用canvas模式渲染矢量圖形 }); //添加底圖 var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map); //使用canvas模式渲染marker var ciLayer = L.canvasIconLayer({}).addTo(map); var icon = L.icon({ iconUrl: 'https://ejuke.github.io/Leaflet.Canvas-Markers/examples/img/pothole.png', iconSize: [20, 18], iconAnchor: [10, 9] }); for (var i = 0; i < 10000; i++) { var lat = 39.905963 + (Math.random()-Math.random()) * 3; var lng = 116.390813 + (Math.random()-Math.random()) * 3; var marker = L.marker([lat, lng], { icon: icon }) .bindPopup("I Am " + i); //綁定氣泡窗口 ciLayer.addLayer(marker); } </script> </body> </html>
本篇文章由一文多發平臺ArtiPub自動發佈