mapboxgl 互聯網地圖糾偏插件(一)

以前寫過一個 leaflet 互聯網地圖糾偏插件,引用插件後一行代碼都不用寫,就能解決國內互聯網地圖瓦片的偏移問題。html

最近想對 mapboxgl 也寫一個這樣的插件。git

緣由是本身發佈的OSM矢量瓦片地圖精度不夠高,當須要放大地圖查看詳細信息時,就能夠拿百度、高德的柵格瓦片作個補充。而使用它們的第一步就是要先糾偏。github

去研究了 mapboxgl 的底層代碼,發現不少都看不懂。因而去惡補了 webgl 的知識,再去看 mapboxgl 的源碼,哈哈,萬變不離其宗,GIS知識仍是那些,只是計算機繪製圖形的方式變了而已。web

研究後,把目標鎖定在了 transform.js 文件上,這個文件主要用來處理各類座標轉換問題,包括經緯度座標、墨卡託座標、屏幕座標、webgl座標等,還負責生成瓦片的編號。編程

文件中的 coveringTiles 方法就是用來計算瓦片的 x、y、z 編號的,它會返回當前比例尺和可視範圍內的全部瓦片編號。webgl

根據 x、y、z 瓦片編號請求到互聯網地圖瓦片後,會在 calculatePosMatrix 方法裏計算瓦片顯示的屏幕位置。url

mapboxgl 和 leaflet 的顯示原理不一樣,mapboxgl 是三維座標系,使用webgl繪圖,增長了一個維度後,多出了不少東西要處理,二維座標系加載瓦片時,只須要考慮瓦片的 x、y 位置,三維座標系在此基礎上還要考慮傾斜和透視。.net

webgl 的座標都是經過位置變換矩陣來表示的,這一點和leaflet的差異很大。插件

上面的 calculatePosMatrix 方法就是根據瓦片的 x、y、z 編號,計算出瓦片在 webgl 中顯示的位置變換矩陣。這裏分別將瓦片的平移矩陣、縮放矩陣和視圖+投影矩陣進行了相乘,獲得了最終的位置變換矩陣。3d

> 看這個方法時我有些疑惑,它是如何根據瓦片的 x、y、z 編號來計算位置變換矩陣的,去研究了xyz協議後,才明白xyz座標和經緯度座標是有一套互轉公式的,瓦片編號轉經緯度時返回的座標是瓦片左上角的經緯度。詳見:https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

> 關於 webgl 變換矩陣的知識能夠參考這篇文章 https://www.cnblogs.com/charlee44/p/11623502.html《WebGL編程指南》,我更推薦後者,由於後者講的更系統更容易理解。

不得不說,webgl 的位置變換矩陣計算仍是有一些複雜的,因此就想看看 mapboxgl 中有沒有內置經緯度座標和 webgl 座標互轉的方法,查看後發現,只有經緯度座標、墨卡託座標和屏幕座標三者互轉的方法,沒有 webgl 的。

那就曲線救國,先將經緯度轉成屏幕座標,再本身寫個方法把屏幕座標轉成 webgl 座標。

實現思路:

  1. 根據瓦片編號和經緯度的互轉公式,計算出瓦片左上角的經緯度
  2. 對瓦片左上角的經緯度進行糾偏,獲得 wgs84 座標的經緯度
  3. 將糾偏前、後的經緯度分別轉爲屏幕座標,再將轉換後的屏幕座標相減,得出瓦片屏幕座標的偏移量
  4. 將瓦片屏幕座標的偏移量換算成 webgl 座標的偏移量
  5. 在瓦片的平移矩陣中加上剛纔計算出的 webgl 座標偏移量,理論上就能實現對瓦片的糾偏

在實現過程當中,將 一、二、3 步搞定之後,由於暫時尚未想好怎麼實現第4步,因而就先將第 3 步的結果屏幕座標偏移量,直接加到了第 5 步的平移矩陣中,結果很讓人意外。

實現代碼:

實現效果:

以天安門國旗爲參照,糾偏前

糾偏後

哈哈,難道就這麼搞定了?

難道平移矩陣中的數值都是按屏幕像素來計算的?

至少目前看來是的。

正當我開心的不要不要時,咦?邊上爲何會有空白,瓦片沒有請求過來?我接着放大地圖,白邊愈來愈大了

嗯~ 這個好解決,應該是由於 mapboxgl 只顯示當前範圍的瓦片,當屏幕邊緣的瓦片被糾偏到屏幕中間時,邊緣就會出現空隙。

只要將當前顯示範圍向外擴展一些就能搞定。

正當我在開心的研究如何向外擴展顯示範圍時,無心中把地圖傾斜了一下,個人媽呀!這是什麼鬼

看到這個,我當時的心情瞬間就很差了。

~~ 容我整理下心情 ~~

好了,我的猜測,緣由多是,在地圖旋轉時,瓦片根據 webgl 座標的中心點計算要旋轉的角度和移動的距離,如今瓦片糾偏後位置發生了偏移,但計算旋轉座標時,仍是根據webgl的中心點,因此旋轉時就出問題了。

具體我也沒想明白呢,感受仍是對瓦片糾偏後,須要對某個中心點也須要糾偏一下。若是有技術大牛看到這篇文章也能夠給留言指導一下。

總結:

  1. 目前搞定了垂直視角下的瓦片糾偏
  2. 後續須要解決糾偏後屏幕邊緣出現的空白區域問題。
  3. 地圖傾斜和旋轉時瓦片會出現錯位,須要繼續研究。

最後,mapboxgl糾偏插件尚未徹底搞定,就不放代碼了,後續有新進展會再跟你們分享,等徹底搞定之後再向之前同樣跟你們分享插件。

<br>


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

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

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

相關文章
相關標籤/搜索