向量金字塔技術研究

拂衣志發表於2024-05-04

前言

在影像切片時代,多層次模型依靠的是影響金字塔。得益於影像柵格資料解析度的特點,基於影像金字塔可以較好的實現多解析度模型。但是在向量切片時代中,就無法直接從影像金字塔技術獲利了,因為向量資料不具有解析度這個特性,而是採用向量金字塔技術來實現多層次、多尺度模型。

影像金字塔(分層)

影像金字塔技術透過影像重取樣方法,建立一系列不同解析度的影像圖層,每個圖層分割儲存,並建立相應的空間索引機制,從而提高縮放瀏覽影像時的顯示速度。如下圖所示的影像金字塔,底部是影像的原始最高解析度的表示,為512×512影像解析度,越往上的影像的解析度越小,分別為256×256,128×128,頂部是影像金字塔的最低解析度的影像64×64,因此這個影像金字塔共有4層,即4個等級的解析度。顯然影像的影像解析度越高,影像金字塔的等級越多。

HasPyramid

從給出的定義與圖示來看,好像與我們目前使用的瓦片地圖有一定的差別。是的,這是因為影像金字塔負責的內容僅僅是構建多解析度層次,也就是每一層都是對應完整資料範圍的一塊資料,也就是我們常說的分層(柵格資料是均衡的,可以透過解析度來作為尺度描述,所以多解析度層級也就對應著多尺度層級)。

瓦片金字塔(分塊)

節選自《高效能影像資料瓦片化關鍵技術研究-劉世永-2016》

要實現現如今使用的瓦片地圖模型,還需要瓦片金字塔配合完成。

瓦片金字塔模型是當前應用最廣的多層次地圖資料組織模型,透過瓦片金字塔模型,前端在進行放大和縮小操作時,可以有效地減少資料讀取的空間查詢時間。透過只載入可視區域範圍內的瓦片,可以減少資料載入量,降低網路傳輸壓力,提高前端的資料視覺化速度。

也就是說,瓦片金字塔實在影像金字塔的基礎上,基於特定規格大小對每層影像進行切割。此操作也就是對應著我們常說的分塊。

資料原始解析度並不是標準化的,分層結果即不夠標準化,也不夠細緻。所以在此基礎上再次分片,既是減少了資料量使得傳輸與載入效率提升,同時也是給出了標準,相容性更好。

瓦片金字塔的主要原理為:基於某個特定的地圖投影座標系(常規是Web墨卡託),將曲面的地球投影到二維平面,而後將該二維平面進行多尺度地劃分,即相當於製作了多個不同解析度層級的數字地圖。各層級對應相應編碼,層級越高地圖所對應的解析度越高;而後對每一層級的全球空間範圍地圖按照某種空間劃分方法進行格網劃分,劃分成若干行和列的固定尺寸的正方形柵格圖片,這些切分出來的規整的單個格網單元稱為瓦片,各層級的劃分方法都是相同的。

瓦片劃分方法需滿足以下條件:

  • 每個層級下的所有瓦片可以無縫拼合成一張全球空間範圍的世界地圖
  • 每個瓦片都有唯一編碼,根據編碼可以解算該瓦片對應的空間範圍
  • 在某一層級下給定一座標點可以根據其空間座標解算其所在瓦片的編號

每一層級瓦片對應一層金字塔分層,所有層級的瓦片便構成了整個瓦片金字塔模型。每一層中的瓦片劃分方法一般採用均勻四分的劃分方法,即以赤道和中央經線的交點為初始中心,不斷地對地圖進行四分,直到每個格網的大小為tilesize * tilesize為止,其中tilesize表示單個瓦片的邊長。基於此種劃分方法,第0層金字塔(金字塔頂層)用一個瓦片就能表示整張世界地圖,第1層要用4^z個瓦片來表示整個世界地圖,z為當前瓦片的金字塔層級。

金字塔示意圖1

瓦片投影座標系

瓦片金字塔模型中的投影座標系可以有多種,目前最廣泛採用的是Web Mercator投影,它是Mercator投影的一種變體。

瓦片座標系

所有瓦片的編碼都是基於瓦片座標系下進行的,瓦片座標系的原點一般都在左上角或者左下角,TMS規範中是在左下角(GeoWebCache遵循該規範),但是現有的Google、Mapnik切片系統都是選用左上角作為原點,本文主要以原點在左上角的瓦片座標系進行說明。
瓦片的編碼方式如下圖所示,層級用z表示,瓦片經線方向(指瓦片經度發生變化的方法,即東西向,東向為正)上編號為x,緯線方向(指瓦片維度發生變化的方向,即南北向,南向為正)上編號為y,因此每一個瓦片都可以透過一個三維元組(x,y,z)來唯一描述。

瓦片座標系1
瓦片座標系2
瓦片座標系3

總的來說,如今我們所說的影像(柵格)金字塔大多指代的是影像金字塔與瓦片金字塔的結合體或是瓦片金字塔(預設含有分層),而不是單獨指代分層或者單獨指代分塊。

向量金字塔

影像金字塔是為柵格資料服務的,也是影像切片時代的核心產物。但是到了向量切片時代後,由於向量資料並不具備解析度的特性,且向量資料不同於柵格資料,它有著疏密不一致、分佈不均與的特點,所以無法直接利用影像金字塔技術。不過瓦片金字塔是基於分層金字塔的基礎上構建的,所以對資料型別並沒有要求,在向量切片中是可以直接複用的。總而言之,在向量切片時代中,需要一個符合向量資料特點的分層模型,作為向量資料來源與瓦片金字塔之間溝通的橋樑。同時考慮到應用上的相容性,所以最終基於金字塔理論之上進行分層模型的定義,謂之:向量金字塔。

對於向量資料的分層,將使用比例尺作為尺度描述,建立一系列不同比例尺的分層。不同於柵格金字塔的多解析度層級,向量資料金字塔沒有解析度的概念,但是不同層級之間的資料詳盡程度也是不同的。隨著比例尺的由小到大,向量要素也變得越來越詳細;而隨著比例尺由大到小,向量要素也將變得精簡與概化,以符合人們的使用要求。

總而言之,向量金字塔的的目的就是解決在小比例尺下大資料量(或高密度區域)向量資料聚集度高、要素重疊和顯示速度慢的問題。(其實就是向量資料的製圖綜合問題,向量金字塔不過是其中的一個解而已)

注:我們此處所談向量金字塔,只是向量資料分層金字塔,只是分層。

向量分層

為了達成人們的使用要求,則需要對資料進行處理,以符合給定比例尺級別下保持相應的詳盡程度。

與柵格資料不同,向量資料通常都具有空間特徵與屬性資訊。空間特徵體現在資料的空間座標系、空間分佈以及幾何特徵;屬性資訊則是資料實體相關的一些資訊。那麼向量資料的空間特徵與屬性資訊則可作為分層的依據,首要對資料的屬性資訊進行處理,而後再基於空間特徵進行處理。

屬性分類分級

對於資料的屬性特徵處理主要是對屬性資訊進行分類和分級兩種情況。分類是根據屬性資訊劃分類別;分級即根據屬性資訊按照其重要程度劃分不同的級別,並且賦予不同的權重值。

空間特徵處理

基於空間特徵的處理則就多種多樣了,比如可以基於資料的分佈(密度)抽稀、基於周長或面積進行選取、基於幾何形狀進行簡化。在處理的同時,還需要是實際情況考慮是否維持資料的拓撲關係。

總而言之,可將上述的分層處理方法抽象為兩種:

  • 選取(Filter):屬性分類分級,基於密度、周長、面積的處理都屬於選取
  • 簡化(Simplify):基於空間幾何形狀的處理屬於簡化

當然,上述兩種只是最基礎的分層處理方法,後續還可以有更多處理方法,比如合併、融合、誇大等。但我想來,如果能夠比較合理的完成上述兩個操作,應該也是達到了基本可用層次。

不同行業的資料具有著不同的重點或側重點,分層不僅需要結合向量資料模型的特點,還需要結合行業背景與應用場景綜合考慮。

此處再借用公謹(遙想公瑾當年)的一句描述進行佐證:

所謂的向量金字塔模型,即基於製圖綜合的知識,分別設定海量資料在不同zoom下是否顯示,是否簡化,是否融合的一種策略,當動態提取切片時,根據這個策略選擇資料,實際撈取的資料就非常少,有效解決了向量切片不能解決資料太密集集中的問題。

向量金字塔 → 向量資料的多尺度表達 → 向量資料的自動製圖綜合(保證綜合前後要素內部及要素之間的拓撲關係是向量地圖正確顯示的基本需求 😯)

注:此處所述分層,並不是比例尺等級。而是在不同比例尺層級下,向量資料的詳盡程度。而分層處理,即為透過一定的手段來控制資料的詳盡程度。

技術實現

在技術實現上,目前我看到的都是以瓦片金字塔結構為基礎,疊加分層處理手段的方式實現的。因為瓦片金字塔是在分層金字塔的基礎之上,而分層可分為兩個部分:

  1. 尺度分級定義 → 一系列的比例尺等級
  2. 分層分級處理(綜合運算元) → 一系列的處理運算元(如:Filter、Simplify)

OGC TileMatrixSet 定義

而尺度分級定義不論是在分層金字塔還是瓦片金字塔中都是一致的,也就是將分層分級處理(綜合運算元)剝離出來單獨實現,在最終的瓦片生產流程中,接入瓦片金字塔即可。

ogc-tilematrixset-def

ogc-tilematrixset-uml

GeoWebCache 實現

  • 瓦片金字塔結構
public class GridSet {
	
    private String name;

    // 投影座標系
    private SRS srs;

    // 瓦片寬, such as 256
    private int tileWidth;

    // 瓦片高, such as 256
    private int tileHeight;

    /**
     * Whether the y-coordinate of {@link #tileOrigin()} is at the top (true) or at the bottom
     * (false)
     */
    protected boolean yBaseToggle = false;

    /**
     * By default the coordinates are {x,y}, this flag reverses the output for WMTS getcapabilities
     */
    private boolean yCoordinateFirst = false;

    private boolean scaleWarning = false;

    // 將座標參考系統 (CRS) 單位轉換為米的係數
    // 也就是說,這個參數列示的是給定的CRS中一個單元轉換為米的係數。換句話說,也就是在指定的CRS中,一個單元表示多少米。
    // 目前常用的就兩種投影,一是以米為單位的(即metersPerUnit為1);其次是以度為單位的經緯度投影(metersPerUnit表示為1度代表多少米,即:360/赤道周長,不同CRS使用不同的橢球體,所以其赤道周長也會存在一定差異。)
    private double metersPerUnit;

    // 畫素大小, 通常給定0.28mm
    private double pixelSize;

    // 範圍, 通常是投影座標系的最大範圍
    private BoundingBox originalExtent;
 
    // 所有的金字塔層次集合
    private Grid[] gridLevels;

    private String description;

    /**
     * {@code true} if the resolutions are preserved and the scaleDenominators calculated, {@code
     * false} if the resolutions are calculated based on the sacale denominators.
     */
    private boolean resolutionsPreserved;
}
  • 單層金字塔模型實現
public class Grid {

    // 當前層橫向上瓦片數量
    private long numTilesWide;

    // 當前層縱向上瓦片數量
    private long numTilesHigh;

    // 當前層的解析度
    private double resolution;
    // 當前層的比例尺分母
    private double scaleDenom;

    private String name;
}

現如今,不論是向量還是柵格,在基於已有標準(比如電子地圖資料規範中的地圖分級)的情況下,已經給出了一個瓦片金字塔的框架結構,缺少的是金字塔每層的資料,也就是需要自行進行資料分層並放入給定的層級結構中。就拿GeoServer來說,預設情況下,他就直接套用了給定的瓦片金字塔層級結構,且僅做了幾何形狀的Simplify(無法處理密度問題),那麼就會出現大資料量或高密度區域在小比例尺下瓦片尺寸很大,爆炸的大的情況 ☹️

對於分層操作,一般情況下可以先對資料進行屬性分類(如:河流&境區)和分級(如:一級河流、二級河流),再結合比例尺分層處理(綜合運算元集中實現)。
注:行業不同資料也不同,資料不同處理方式也不同,所以就沒有標準的處理規則,但理論終歸是相通的。

感想

感覺GIS在應用上的知識還是比較封閉的,不像計算機相關的應用知識一般,很容易就能獲取到,或者是獲取的渠道很清晰。從我目前走過的道路來看,我獲取這些知識的途徑大概分為四種,收益從上到下:

  • 研究開源GIS應用軟體原始碼
  • 實際專案應用中的探索
  • 理論書籍、論文
  • 各位大佬的文章

不知道是不是我還沒有獲取到更正確的途徑,總感覺比較封閉,新來的人不容易進入(像我已經工作接近6年了)。可能還是從業的人太少了 🙄

參考

  • 影像金字塔原理
  • 《高效能影像資料瓦片化關鍵技術研究-劉世永-2016》
  • 《向量資料金字塔結構設計-董濱-2016》
  • WebGIS資料不切片或是時代必然
  • GeoWebCache
  • Gridsets and Gridsubsets
  • Tiles à la Google Maps Coordinates, Tile Bounds and Projection
  • OGC Two Dimensional Tile Matrix Set and Tile Set Metadata

相關文章