關於向量瓦片技術支援前端渲染帶來的思考

拂衣志發表於2024-05-04

前言

書接上回,此前提到地圖瓦片切片技術的發展。向量切片技術將瓦片的渲染由服務端遷移到客戶端,此操作帶來的影響力不可謂不大,基於此,完全可以隨心所欲的定義地圖的表達。那麼在實際的應用當中,當渲染從服務端遷移後客戶端後,是否會帶來一些其他的問題?

超20M的瓦片資料

此事發生在2023年,當時我們的技術組合是:空間資料庫+GeoServer(vector tile plugin)+ Mapbox GL JS,基於此提供向量瓦片服務。某一天,在某位心細如髮的大佬的察覺下,突然發現提供的地圖服務在層級為10級時,出現一個大小大於20M的瓦片,頓感驚人。經過多次核對後,確定在該份資料下,GeoServer在小比例尺下(約莫10級往下)生產的大部分瓦片尺寸都比較大,而資料密度越大的地方尤其嚴重。最終,我們認為:是由於GeoServer沒有提供向量分層抽稀簡化的能力,所以導致在小比例尺+高密度的雙重疊加下,瓦片大小暴增。

在一段時間後,為了快速處理該問題,我曾提出。可以基於目前配圖的思想(解析配圖檔案),在服務端去往資料庫讀取資料的時候便進行資料過濾(其實就是分層分級),避免大量不需要的資料經查詢、傳輸、編碼再傳輸帶來的影響。比如我們按照口徑進行約定,在13級往下,只顯示大於xx口徑的資料的資料,那麼此時所有小於該口徑的資料都不需要被傳遞

但我們前端配圖人員提出一個說法:說如果你這般處理,那麼意味著配圖的時候資料就不是完整的,我無法自行選擇資料,不同的專案需求也不盡相同,靈活性自然大打折扣。同時,也就意味著該項配置與瓦片快取是繫結的,一旦存在配圖項的變更,便意味著此前快取均是失效的。

配圖的邊界

時至今日,已過半年。目前想來,這裡確定存在這麼幾個問題:

  • 到底什麼是配圖,配圖配的又是什麼?
  • 資料釋出過程中,配圖應該處於什麼階段?

對於什麼是配圖,我目前還給不出一個十分恰當的回答,因為此前確定沒有做過這方面的內容。但私以為狹義情況下,地圖的符號化過程應該稱之為配圖。配圖內容如下:

  • 要素符號化
  • 文字標註

那麼分層顯示控制能力(屬性分級)是否應該歸屬到配圖中呢?在影像切片時代中,想來配圖都是提前確定好的,而且受益於影像金字塔自帶多層次解析度的能力,所以在配圖中壓根不需要考慮分級問題(假定資料都是柵格資料)。但是向量資料並沒有解析度的說法,所以無法從影像金字塔模型獲利。在面對大資料量或高密度區域的情況時,需自行處理分級問題。

對於向量資料來說,在向量瓦片技術出現之前,所有瓦片都是在服務端渲染,那麼屬性分級控制也是在服務端進行的。而在向量瓦片技術出現之後,完全可以直接在客戶端實現屬性分層控制了。且目前開源GIS技術方案大多都選擇:GeoServer+Mapbox,但在實際使用中感覺GeoServer並不理會什麼屬性分級和空間特徵簡化,而是一股腦的將資料丟給客戶端,客戶端自己篩選。

從結果來看,好像在應用上確實是行得通的。實際上確實如此,或許大多數公司都是這樣做的吧。但是我認為這是有問題的,這就好像是得益於向量瓦片渲染能力後移的特點,服務端將原本應該自己管控的資料一股腦的丟到了客戶端,由客戶端自行控制。

那麼問題來了,資料的分層分級控制權到底應該給誰,是瓦片生產端還是客戶端呢?

我認為應該優先釐清整個生產流程,明確各節點能力邊界

  1. 資料的分類、分層肯定是在最前面,且分類、分層與金字塔分層息息相關。且應該形成公知,瓦片的生產段與應用的客戶端都應該清晰的知道【資料分層分級控制策略 → 向量金字塔分層規則定義】
  2. 其次是向量資料的釋出,此中應該完整的實現向量資料分層,即形成向量金字塔結構【向量金字塔模型實現】
  3. 因向量瓦片技術帶來的配圖後置,資料的符號化在此處完成【地圖符號化】

其次,可以想一下資料分層控制許可權歸屬到客戶端後會帶來什麼樣的影響:

  • 在大資料量或高密度區域的情況下,小比例尺級別瓦片尺寸可能爆炸
  • 計算資源、儲存資源(快取)佔用增多
  • 對頻寬要求高,移動端的話流量嗖嗖的跑
  • 客戶端效能下降

所以我認為,資料控制能力應該歸屬於瓦片生產端,客戶端可以支援分層控制能力,但其對於資料的控制只能在全域性統計的分類、分層策略所提供的範圍內活動。也就是說客戶端可以實現的分層範圍時全域性規定的範圍的子集。

對於目前在配圖中進行全域性資料的分層分級行為,我認為是向量瓦片技術帶來的配圖動作後置產生的影響。同時在GeoServer + Mapbox 客戶端控制資料操作的長期影響下,給後來人一種錯覺便是資料控制也變更到客戶端控制。

論GeoServer的正確使用?

最近在自己實現一個向量瓦片服務,由於自己目前只會寫Java,所以不得不對GeoServer進行借鑑,所以就進一步的研究了GeoServer的原始碼。

GeoServer可以看作是GeoTools,GeoWebCache以及OGC API Implement的結合體。其中,GeoWebCache提供了金字塔結構的定義和快取能力;GeoTools提供了空間資料相關的定義和操作。在本次研究後,我確定我需要向GeoServer道歉。在此前的描述中,我認為GeoServer是沒有提供資料分層和空間簡化的能力的,但是我錯了。

我拉取的是GeoServer的2.22.x分支,應為這個版本用的比較多,相對而言更具有代表性,所以沒有選擇最新版本。

空間簡化能力

也就是說,在GeoServer vector tile的生產過程中,已經整合了Simplify功能。

geoserver-vector-tile-simplify-1

geoserver-vector-tile-simplify2

geoserver-vector-tile-simplify-3

還有一個情況,其實GeoServer Vector Tile Plugin採用的向量瓦片編碼器(java-vector-tile)中其實也提供了Simplify的功能,只不過預設是關閉的。

資料分層(屬性分級)

GeoServer的vector tile實現中,居然是嘗試從Style(SLD)中獲取到Filter的資訊,用以減少資料的檢索(資料庫中的Filter比Java基於記憶體的Filter更高效),同時還提供了一個將Mapbox style轉換為SLD的擴充模組。

看到這裡的我很激動,感覺找到了知己一般,哈哈哈。

geoserver-vector-tile-filter-1

在明白真相之後的我,只能是感嘆GeoServer的歷史包袱太重了,但應該被敬佩。

而此時再次回頭看我之前提出解析配圖檔案的想法,發現這種做法也是有問題的。

  • 向量瓦片技術出現,實現了一套瓦片資料可以有N種配圖方案
  • 向量瓦片技術完美的分離了資料與渲染,邊界清晰

所以,基於配圖剝離屬性分級的方式不就又將渲染與資料耦合起來,配圖也就會和快取繫結了,也就是一種配圖方案一套瓦片資料了(若一旦涉及到分級部分的變化),自然是有問題的。

結論

綜上所述,私以為:

在向量切片技術下,資料當有資料本身的分層規則,不應該依賴於配圖,也不應該由配圖來定義。

  • 分層控制當屬於資料控制許可權,應該歸屬於瓦片的生產端控制
  • 在向量瓦片時代,配圖就是地圖符號化的過程,對應向量切片技術下,渲染後移到客戶端的部分
  • 全域性分層分級策略應該是首先定義的,且應該形成公知的形態。服務端的資料控制應當嚴格遵循該策略,客戶端可控分層範圍時該策略的子集

參考

  • GeoServer Branch 2.22.x

相關文章