mapboxgl 網際網路地圖糾偏外掛(一)

GIS兵器庫發表於2021-06-18

之前寫過一個 leaflet 網際網路地圖糾偏外掛,引用外掛後一行程式碼都不用寫,就能解決國內網際網路地圖瓦片的偏移問題。

最近想對 mapboxgl 也寫一個這樣的外掛。

原因是自己釋出的OSM向量瓦片地圖精度不夠高,當需要放大地圖檢視詳細資訊時,就可以拿百度、高德的柵格瓦片做個補充。而使用它們的第一步就是要先糾偏。

去研究了 mapboxgl 的底層程式碼,發現很多都看不懂。於是去惡補了 webgl 的知識,再去看 mapboxgl 的原始碼,哈哈,萬變不離其宗,GIS知識還是那些,只是計算機繪製圖形的方式變了而已。

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

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

根據 x、y、z 瓦片編號請求到網際網路地圖瓦片後,會在 calculatePosMatrix 方法裡計算瓦片顯示的螢幕位置。

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

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

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

看這個方法時我有些疑惑,它是如何根據瓦片的 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 座標偏移量,理論上就能實現對瓦片的糾偏

在實現過程中,將 1、2、3 步搞定以後,因為暫時還沒有想好怎麼實現第4步,於是就先將第 3 步的結果螢幕座標偏移量,直接加到了第 5 步的平移矩陣中,結果很讓人意外。

實現程式碼:

實現效果:

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

糾偏後

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

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

至少目前看來是的。

正當我開心的不要不要時,咦?邊上為什麼會有空白,瓦片沒有請求過來?我接著放大地圖,白邊越來越大了

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

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

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

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

~~ 容我整理下心情 ~~

好了,個人猜想,原因可能是,在地圖旋轉時,瓦片根據 webgl 座標的中心點計算要旋轉的角度和移動的距離,現在瓦片糾偏後位置發生了偏移,但計算旋轉座標時,還是根據webgl的中心點,所以旋轉時就出問題了。

具體我也沒想明白呢,感覺還是對瓦片糾偏後,需要對某個中心點也需要糾偏一下。如果有技術大牛看到這篇文章也可以給留言指導一下。

總結:

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

最後,mapboxgl糾偏外掛還沒有完全搞定,就不放程式碼了,後續有新進展會再跟大家分享,等完全搞定以後再向以前一樣跟大家分享外掛。



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

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

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

相關文章