leaflet如何加載10萬數據

leaflet如何加載10萬數據

標籤:leaflet、svg、Canvas、插件、海量點、海量數據、Canvas-Markers、Leaflet.Canvas-Markers、性能css


做爲一名GIS開發者,你工做中必定遇到過這種問題,根據業務設計,須要在地圖上添加1萬+條數據,數據或是點、或是線、或是面。但無論哪一種,當你添加到5000條時,地圖操做就會出現明顯的卡頓。當你添加超過1萬條時,數據加載就會卡頓,瀏覽器出現卡死的狀態,地圖加載後,每挪動一下地圖,都要耐心的等待上幾秒鐘。html

這種交互體驗,用戶是確定接受不了的,解決方法一般分兩種,一種是去作深刻的用戶需求分析,看用戶想一次性加載這麼多數據是爲了看什麼,想看的這個東西,經過其它技術方式能不能實現。另外一種就是死磕技術,研究如何提高地圖性能。咱們今天只討論第二種狀況。git

canvas渲染方式

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-Markers
dom

Leaflet.Canvas-Markers 插件

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>

總結

  1. leaflet支持兩種渲染方式,svg 和 canvas,canvas的顯示性能要明顯優於svg。
  2. IE9以前版本瀏覽器不支持canvas方式渲染。
  3. 默認是svg方式渲染,要手動切換成canvas方式。
  4. 渲染方式設置成canvas後,加載矢量圖形性能會提高,加載圖片標記的效率仍然低。
  5. 經過Leaflet.Canvas-Markers插件來提高圖片標記的顯示效率。
  6. Leaflet.Canvas-Markers插件在縮放地圖時有bug,須要在github上找已經解決此bug的版本。


本篇文章由一文多發平臺ArtiPub自動發佈

相關文章
相關標籤/搜索