前段時間寫了篇《leaflet如何載入10萬資料》的文章,有同學反應其中的Canvas-Markers外掛不支援DivIcon。我們今天就來聊一聊,為什麼這個外掛不支援DivIcon,以及如何用H5的Canvas特性,做出以前用DivIcon才能實現的 標籤 和 文字標註 功能。
老規矩,先上效果圖:
標籤功能
文字標註功能
為什麼不支援DivIcon
Canvas-Markers外掛的創作目的是為了解決,大批量資料展示的效能問題,它通過使用H5中Canvas的繪圖方式繪製Marker,提升了展示效能。但該外掛目前只支援Icon,不支援DivIcon。
之所以不支援,是因為DivIcon的實現原理是在HTML頁面中新增DOM元素,並在地圖平移、縮放時不斷的修改DOM元素的屬性,而大量新增和修改DOM元素會拉低瀏覽器的顯示效能,出現卡頓等現象。
如果使用Canvas-Markers後還在繼續使用DivIcon,就相當於網路升級了千兆頻寬以後,還在用之前的百兆路由器。這時的DivIcon就會和那個百兆路由器一樣,成為整個通道中最為狹窄的地方,變成瓶頸。
如果不用DivIcon這個老路由器,有沒有新路由器呢?
有!但要分情況。
平時工作中,用DivIcon通常是為了實現 標籤功能 和 文字標註 功能
標籤功能:
文字標註功能:
針對這兩種情況,leaflet都有Canvas方式的解決方案。
標籤功能
上文提到,Canvas-Markers外掛目前只支援Icon型別的圖示,翻看它的程式碼會發現,其實,它用Icon也只是把Icon當成一個Object來用, 只用來傳參,並沒有去用Icon內部的功能。因為Icon的內部,也是建立了一個img型別的DOM元素,它和DivIcon一樣,大量新增會影響瀏覽器的顯示效能。
Canvas-Markers外掛通過Icon獲取圖片的地址和圖片的偏移位置等引數,然後用Canvas的方式繪製圖片。
標籤由兩部分組成,背景框和文字,背景框通常是一個圖片。Canvas-Markers外掛已經可以載入圖片,我們只要讓它再支援文字,並能控制文字的樣式和位置,就可以實現標籤功能了。
開啟Canvas-Markers外掛的程式碼,在下圖位置增加一個繪製文字的方法。
再在下圖中的三個位置,增加上面新增方法的呼叫
這樣就可以實現標籤功能了,看效果
效能方面,最大支援10萬條資料左右。
文字標註功能
我在github上搜尋leaflet+text關鍵字,翻看了結果中的前20個程式碼庫,找到了 LabelTextCollision 這個外掛。
LabelTextCollision外掛創作的目的,是為了實現的文字標註的自動避讓功能,實現方式是Canvas,文字標註功能是它順帶解決的問題。
測試時,發現了它一個問題,1萬條資料,在縮小地圖時,顯示很流暢,但放大地圖時,會出現卡頓的現象,而且地圖越放大,卡頓的就越厲害。
通常在載入大資料量時,都是越縮小地圖越卡頓,越放大地圖越流暢。但這個外掛剛好相反,這是為啥呢?
個人推測,出現這種問題,多半是因為沒有根據螢幕顯示範圍對資料做篩選造成的,不做篩選就會把螢幕顯示範圍外的資料也加上。
這個外掛因為它做了文字顯示的避讓,越縮小地圖,資料在螢幕上顯示的就越集中,自動避讓掉的文字就越多,顯示的文字就越少,展示就越流暢。
越放大地圖,資料在螢幕上顯示的就越分散,自動避讓的文字就越少,顯示的文字就越多,這時如果沒有做篩選,展示就會越來越卡頓。
看了下它的程式碼,證實了我的推測,確實沒有發現,對螢幕區域外顯示內容進行限制的程式碼。
那我們就來給它加上,在下圖中的兩個地方新增對螢幕顯示範圍的判斷,只顯示當前能看到的資料。
再試一下,哈哈,搞定
測試了下,優化後,可以載入5萬條資料左右。
更多場景
上面列舉了DivIcon常見的兩種使用場景,以及如何使用Canvas方式提高展示效能的解決方案,如果你那還有DivIcon的其它使用場景,可以在下方留言,我們一起討論解決方法。
總結
- Canvas-Markers外掛的目的是為了解決,大批量資料展示時的效能問題。
- DivIcon實現的原理是在HTML頁面中新增DOM元素,大量新增和修改DOM元素會拉低瀏覽器展示效能。
- 從提高展示效能的出發點考慮,Canvas-Markers外掛不應該去支援DivIcon。
- 用DivIcon,通常是為了實現標籤功能和文字標註功能,這兩個功能都有Canvas方式的解決方案。
- 對Canvas-Markers外掛進行優化,增加文字介面,可以替代DivIcon實現標籤功能。
- LabelTextCollision外掛可以實現文字標註的自動避讓功能,它是用Canvas方式實現,可以替代DivIcon實現文字標註功能。
- 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/),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。