H5時代leaflet中還在用DivIcon?

GIS兵器庫發表於2020-11-25

前段時間寫了篇《leaflet如何載入10萬資料》的文章,有同學反應其中的Canvas-Markers外掛不支援DivIcon。我們今天就來聊一聊,為什麼這個外掛不支援DivIcon,以及如何用H5的Canvas特性,做出以前用DivIcon才能實現的 標籤文字標註 功能。

老規矩,先上效果圖:

標籤功能

canvas

文字標註功能

為什麼不支援DivIcon

Canvas-Markers外掛的創作目的是為了解決,大批量資料展示的效能問題,它通過使用H5中Canvas的繪圖方式繪製Marker,提升了展示效能。但該外掛目前只支援Icon,不支援DivIcon。

之所以不支援,是因為DivIcon的實現原理是在HTML頁面中新增DOM元素,並在地圖平移、縮放時不斷的修改DOM元素的屬性,而大量新增和修改DOM元素會拉低瀏覽器的顯示效能,出現卡頓等現象。

如果使用Canvas-Markers後還在繼續使用DivIcon,就相當於網路升級了千兆頻寬以後,還在用之前的百兆路由器。這時的DivIcon就會和那個百兆路由器一樣,成為整個通道中最為狹窄的地方,變成瓶頸。

如果不用DivIcon這個老路由器,有沒有新路由器呢?

有!但要分情況。

平時工作中,用DivIcon通常是為了實現 標籤功能文字標註 功能

標籤功能:

image-20201121164957140

文字標註功能:

image-20201121165508761

針對這兩種情況,leaflet都有Canvas方式的解決方案。

標籤功能

上文提到,Canvas-Markers外掛目前只支援Icon型別的圖示,翻看它的程式碼會發現,其實,它用Icon也只是把Icon當成一個Object來用, 只用來傳參,並沒有去用Icon內部的功能。因為Icon的內部,也是建立了一個img型別的DOM元素,它和DivIcon一樣,大量新增會影響瀏覽器的顯示效能。

Canvas-Markers外掛通過Icon獲取圖片的地址和圖片的偏移位置等引數,然後用Canvas的方式繪製圖片。

標籤由兩部分組成,背景框和文字,背景框通常是一個圖片。Canvas-Markers外掛已經可以載入圖片,我們只要讓它再支援文字,並能控制文字的樣式和位置,就可以實現標籤功能了。

開啟Canvas-Markers外掛的程式碼,在下圖位置增加一個繪製文字的方法。

image-20201121172659282

再在下圖中的三個位置,增加上面新增方法的呼叫

image-20201121173254912

這樣就可以實現標籤功能了,看效果

canvasicon2

效能方面,最大支援10萬條資料左右。

文字標註功能

我在github上搜尋leaflet+text關鍵字,翻看了結果中的前20個程式碼庫,找到了 LabelTextCollision 這個外掛。

LabelTextCollision外掛創作的目的,是為了實現的文字標註的自動避讓功能,實現方式是Canvas,文字標註功能是它順帶解決的問題。

image-20201121182405099

測試時,發現了它一個問題,1萬條資料,在縮小地圖時,顯示很流暢,但放大地圖時,會出現卡頓的現象,而且地圖越放大,卡頓的就越厲害。

通常在載入大資料量時,都是越縮小地圖越卡頓,越放大地圖越流暢。但這個外掛剛好相反,這是為啥呢?

個人推測,出現這種問題,多半是因為沒有根據螢幕顯示範圍對資料做篩選造成的,不做篩選就會把螢幕顯示範圍外的資料也加上。

這個外掛因為它做了文字顯示的避讓,越縮小地圖,資料在螢幕上顯示的就越集中,自動避讓掉的文字就越多,顯示的文字就越少,展示就越流暢。

越放大地圖,資料在螢幕上顯示的就越分散,自動避讓的文字就越少,顯示的文字就越多,這時如果沒有做篩選,展示就會越來越卡頓。

看了下它的程式碼,證實了我的推測,確實沒有發現,對螢幕區域外顯示內容進行限制的程式碼。

那我們就來給它加上,在下圖中的兩個地方新增對螢幕顯示範圍的判斷,只顯示當前能看到的資料。

image-20201121193759514

再試一下,哈哈,搞定

測試了下,優化後,可以載入5萬條資料左右。

更多場景

上面列舉了DivIcon常見的兩種使用場景,以及如何使用Canvas方式提高展示效能的解決方案,如果你那還有DivIcon的其它使用場景,可以在下方留言,我們一起討論解決方法。

總結

  1. Canvas-Markers外掛的目的是為了解決,大批量資料展示時的效能問題。
  2. DivIcon實現的原理是在HTML頁面中新增DOM元素,大量新增和修改DOM元素會拉低瀏覽器展示效能。
  3. 從提高展示效能的出發點考慮,Canvas-Markers外掛不應該去支援DivIcon。
  4. 用DivIcon,通常是為了實現標籤功能和文字標註功能,這兩個功能都有Canvas方式的解決方案。
  5. 對Canvas-Markers外掛進行優化,增加文字介面,可以替代DivIcon實現標籤功能。
  6. LabelTextCollision外掛可以實現文字標註的自動避讓功能,它是用Canvas方式實現,可以替代DivIcon實現文字標註功能。
  7. LabelTextCollision外掛在地圖放大時,最多隻能展示1萬條資料左右,優化後可以達到5萬條資料左右。

線上示例

標籤功能 http://gisarmory.xyz/blog/index.html?demo=diviconError-CanvasMarker

文字標註功能 http://gisarmory.xyz/blog/index.html?demo=diviconError-LabelTextCollision

原始碼

標籤功能 http://gisarmory.xyz/blog/index.html?source=diviconError-CanvasMarker

文字標註功能 http://gisarmory.xyz/blog/index.html?source=diviconError-LabelTextCollision


原文地址:http://gisarmory.xyz/blog/index.html?blog=diviconError

關注《GIS兵器庫》公眾號, 第一時間獲得更多高質量GIS文章。

本文章採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名《GIS兵器庫》(包含連結:  http://gisarmory.xyz/blog/),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。

相關文章