OGC WebGIS 常用服務標準(WMS/WMTS/TMS/WFS)速查

2022-07-19 06:01:10

本文只介紹實際工作中常用的 WMS、WMTS、WFS、TMS 四種,WCS、WPS 等其它 OGC WebService 型別請自行查閱官方資料。



0. 引數傳遞方式

  • 鍵值對
  • RESTful API
  • SOAP

三種方式對於下文列舉的服務並不是全都存在的,例如 WMS 就只有第一種。

本文不介紹 SOAP 方式(因為太複雜了)。

1. WMS 速查

1.1.0 版本為參考。

1.1. 能力

  • GetCapabilities
  • GetMap
  • GetFeatureInfo

1.2. 獲取地圖圖片舉例(GetMap)

以這樣一個請求地址為例:

http://localhost:4800/geoserver/spatial_base/wms?<queryString>

queryString 即查詢字串,我把它列成表格:

param value desc
service WMS 服務型別
version 1.1.0 服務版本
request GetMap 方法
layers spatial_base:guangxi_cities 哪個圖層
bbox 104.450889587402,20.8992862701416,112.061851501465,26.3855667114258 要多大範圍
width 768 要返回的影象畫素寬
height 553 要返回的影象畫素高
srs EPSG:4326 用哪個座標系
styles "" 用什麼樣式,預設要給空字串
format image/png 格式

GeoServer 的 layers 引數,是「工作空間名:圖層名」這樣的組合。

那麼,它返回的就是一張圖:

這是最常規的使用「鍵值對」,也就是 queryString 來請求地圖的 WMS 用法。

1.3. 在 CesiumJS 和 OpenLayers6 中使用 GeoServer WMS

在 CesiumJS 中:

new Cesium.WebMapServiceImageryProvider({
  url: 'http://localhost:4800/geoserver/spatial_base/ows',
  layers: 'spatial_base:guangxi_cities',
  parameters: {
    transparent: true,
    format: 'image/png',
  },
})

只需要保證座標系合適即可,當然,url 的 ows 也可以改為 wms

OWS 只是 GeoServer 上的一個萬用字元,如果你知道你想用的是什麼服務,可以不寫 ows,例如本例,可以直接寫 'http://localhost:4800/geoserver/spatial_base/wms'

在 OpenLayers6 中:

import TileLayer from 'ol/layer/Tile'
import TileWMS from 'ol/source/TileWMS'

new TileLayer({
  extent: [104.4509, 20.8993, 112.0619, 26.3856], // 座標系保持與 View 一致
  source: new TileWMS({
    url: 'http://localhost:4800/geoserver/spatial_base/wms',
    params: {
      'LAYERS': 'spatial_base:guangxi_cities',
    },
    serverType: 'geoserver', // 有好幾種地理伺服器,要明確指定
  }),
})

// View 座標系的設定
import { View } from 'ol'
new View({
  // ...
  projection: get('EPSG:4326') // 返回一個 Projection 範例即可
})

根據 OpenLayers 的檔案:

At least a LAYERS param is required. STYLES is '' by default. VERSION is 1.3.0 by default. WIDTHHEIGHTBBOX and CRS (SRS for WMS version < 1.3.0) will be set dynamically.

也就是至少要設定 LAYERS 引數。如果請求的圖層的座標系與 View 的一致,則不需要設定 SRS

1.4. 獲取要素資訊

WMS 雖然主要的用途是請求地圖圖片,是一種經典的伺服器渲染服務,但是也保留了基本的要素查詢功能,也就是 GetFeatureInfo,舉例:

http://localhost:4800/geoserver/spatial_base/ows
?service=WMS
&version=1.1.1
&request=GetFeatureInfo
&layers=spatial_base:guangxi_cities
&bbox=101.25,22.5,112.50,33.75
&width=256
&height=256
&srs=EPSG:4326
&query_layers=spatial_base:guangxi_cities
&info_format=application/json
&x=181
&y=199

GetFeatureInfo 是一個可選的功能,GeoServer 有這個功能。簡單解釋一下,引數 widthheight 是引數 bbox 範圍生成的一小塊圖片,然後去查詢這塊圖片中畫素位置是 xy 的要素資訊,其它引數不難理解。

2. WMTS 速查

2.1. 軸向

WMTS 的軸朝向如下圖所示。

2.2. 能力

  • GetCapabilities(獲取WMTS後設資料檔案,也叫獲取能力檔案)
  • GetTile(獲取一張瓦片)
  • GetFeatureInfo (可選能力)

2.3. 示意圖

WMTS 的行列號、瓦片陣(TileMatrix,類似層級的概念,參考第 5 節)是從 0 開始算的,例如 TileMatrix=EPSG:4326:0&TileCol=0&TileRow=0

2.4. 請求瓦片舉例(GetTile)

以 2.3 小節中的「TileRow=55 & TileCol=103」這張瓦片為例:

它的請求地址是:

http://localhost:4800/geoserver/gwc/service/wmts?layer=spatial_base%3Aguangxi_cities&style=&tilematrixset=EPSG%3A900913&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix=EPSG%3A900913%3A7&TileCol=103&TileRow=55

把 queryString 列成表格即:

param value desc
layer spatial_base:guangxi_cities 與 WMS 的 layers 意義一致
style "" 與 WMS 的 style 意義一致
tilematrixset EPSG:900913 瓦片陣集,見本文第5節
TileMatrix EPSG:900913:7 當前級別的瓦片陣,見本文第5節
TileCol 103 瓦片列號
TileRow 55 瓦片行號
Service WMTS 與 WMS 的 service 意義一致
Request GetTile 與 WMS 的 request 意義一致
Version 1.0.0 與 WMS 的 version 意義一致
Format image/png 與 WMS 的 format 意義一致

聰明的你應該注意到了,引數的名稱是大小寫任意的,但是引數值部分大小寫敏感,例如 「EPSG:900913」寫成「epsg:900913」是請求不到的(至少 GeoServer 是這樣);但是「GetTile」寫成「gettile」又是可以的。

2.5. 請求瓦片舉例(GetTile)使用 RESTful

圖與上一小節返回的是一樣的,使用 RESTful 風格的請求是這樣的:

http://localhost:4800/geoserver/gwc/service/wmts/rest/spatial_base:guangxi_cities/polygon/EPSG:900913/EPSG:900913:7/55/103?format=image/png

2.6. 關於 GeoServer 兩種獲取瓦片的介面風格

  • 鍵值對:在 GeoServer 中使用 OpenLayers 預覽,使用瀏覽器開發者工具檢視網路請求,此處的介面風格即鍵值對形式,使用 queryString;
  • RESTful:請求 WMTS 的能力檔案,搜尋 ResourceURL 標籤,此處的地址是 REST 風格的。

2.7. 在 CesiumJS 和 OpenLayers6 中使用 GeoServer WMTS

在 CesiumJS 中,你要十分小心每一級「TileMatrix」的名稱,因為 CesiumJS 使用的是 REST 風格的請求地址,這就意味著,TileMatrix 必須與能力檔案中對應圖層的 TileMatrix 名稱一致,才能拼湊出正確的 URL。

CesiumJS 預設 WMTS 每一級的 TileMatrix 名稱就是簡單的「0、1、2、3、4...」,但是 GeoServer 預設的 900913 和 4326 這兩個 TileMatrixSet 的名稱卻是 「EPSG:4326:0、EPSG:4326:1、EPSG:4326:2...」和「EPSG:900913:0、EPSG:900913:1、EPSG:900913:2...」,面對這種情況也好辦,我們可以用 JavaScript 快速生成這樣一個有規律的 TileMatrixLabels 陣列:

const maxLevel = 3 // 別忘了改成你的 WMTS 支援的最大等級,此處演示寫個 3
const tileMatrixID = 'EPSG:900913'
const tileMatrixLabels = Object.keys(new Array(maxLevel).fill(0)).map(v => `${tileMatrixID}:${v}`)
// tileMatrixLabels 即 ['EPSG:900913:0', 'EPSG:900913:1', 'EPSG:900913:2']

現在,你可以用這個 tileMatrixLabels 陣列建立 WebMapTileServiceImageryProvider

new Cesium.WebMapTileServiceImageryProvider({
  url: 'http://localhost:4800/geoserver/gwc/service/wmts/rest/spatial_base:guangxi_cities/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
  style: 'polygon', // 改 'default' 就是預設的樣式
  layer: 'spatial_base:guangxi_cities',
  tileMatrixLabels: tileMatrixLabels,
  tileMatrixSetID: 'EPSG:900913',
  rectangle: Cesium.Rectangle.fromDegrees(104.450889587402,20.8992862701416,112.061851501465,26.3855667114258),
})

你甚至可以封裝一個函數獲取這些 TileMatrix 的名稱:

/**
 * 建立 TileMatrix 的名稱
 * @param {string} tileMatrixID 即 `TileMatrixSet` 的名稱
 * @param {number} maxLevel 即 WMTS 的最大等級
 * @returns {string[]}
 */
const createTileMatrixLabels = (tileMatrixID, maxLevel) => 
  Object.keys(new Array(maxLevel).fill(0)).map(v => `${tileMatrixID}:${v}`)

至於 OpenLayers6 載入 WMTS,也是需要計算解析度、TileMatrixIDs 的,略嫌麻煩,以 EPSG:4326 為例,你需要計算圖層的解析度列表、TileMatrix 名稱列表:

// 計算 22 級別,夠用就行
const resolutions = new Array(22)
// EPSG:4326 一級寬度跨 2 個 256 畫素的瓦片
const firstLevelPixelWidth = 360 / (256 * 2)
for (let z = 0; z < 22; ++z) {
  // 逐級除以 2
  resolutions[z] = firstLevelPixelWidth / Math.pow(2, z)
}
const tileMatrixLabels = createTileMatrixLabels('EPSG:4326', 22)

隨後,你就可以用 resolutionstileMatrixLabels 建立一個 WMTSTileGrid,進而建立 WMTS 圖層了:

const wmtsTileGrid = new WMTSTileGrid({
  origin: [-180, 90], // origin 即當前座標系的的左上角
  resolutions: resolutions,
  matrixIds: tileMatrixLabels,
})

new TileLayer({
  extent: [104.4509, 20.8993, 112.0619, 26.3856],
  source: new WMTS({
    // 和 CesiumJS 不太一樣,這裡不用到模板那麼細
    url: 'http://localhost:4800/geoserver/gwc/service/wmts',
    layer: 'spatial_base:guangxi_cities',
    matrixSet: 'EPSG:4326', // 與能力檔案中此圖層的 TileMatrixSet 一致
    format: 'image/png',
    // 也可以用 `ol/proj` 包匯出的 get('EPSG:4326'),返回 Projection 範例即可
    projection: 'EPSG:4326',
    tileGrid: wmtsTileGrid,
    style: 'polygon',
    wrapX: true,
  }),
})

而如果是 EPSG:3857,也即 EPSG:900913,那麼你的 originextentfirstLevelPixelWidth 就要隨之改變了:

const origin = [-20037508.34, 2003708.34]
const extent = [11627419.84177403,2379873.5953122815,12474668.246494522,3046913.9333698303]
const firstLevelPixelWidth = 40075016.68557849 / 256

至於為什麼是這幾個數位,請檢視 GeoServer 中相關 Gridset 的數值吧,需要有 Web 墨卡託座標系相關的基礎。

3. TMS 速查

TMS 是一種非常接近靜態資源的地圖瓦片資料集,常見的瓦片格式有 jpegpngpbf 等。這個標準比較舊了,但是勝在簡單。

3.1. 軸向

TMS 軸朝向如下圖所示。

3.2. 後設資料 XML 檔案

一般來說,TMS 的地址會指向一個名稱是 tilemapresource.xml 的檔案。當然,GeoServer 就比較例外,僅僅是返回 XML 檔案而地址並不指向 XML 檔案。

這個 XML 檔案是 TMS 最顯著的特徵,記錄了這個瓦片地圖集的後設資料:

<TileMap version="1.0.0" tilemapservice="...">
  <!-->...<-->
</TileMap>

3.3. 請求瓦片舉例

請求地址:

http://localhost:4800/geoserver/gwc/service/tms/1.0.0
/spatial_base:guangxi_cities@EPSG:900913@png
/7/103/72.png

如下圖所示:

3.3. 在 QGIS 中載入 GeoServer 的 TMS

新增一個 XYZ 圖層即可,但是在模板連結中要填寫的是 {z}/{x}/{-y}.imageExt,而不是 {z}/{x}/{y}.imageExt

3.4. 在 CesiumJS 和 OpenLayers6 中使用 GeoServer 的 TMS

CesiumJS 在測試中發現對非全範圍的 EPSG4326 或 3857 座標系的 TMS 載入是存在問題的。GeoServer 釋出的圖層一般沒有這個問題。

舉例:

new Cesium.TileMapServiceImageryProvider({
  url: "http://localhost:4800/geoserver/gwc/service/tms/1.0.0/spatial_base%3Aguangxi_cities@EPSG%3A900913@png",
  minimumLevel: 0,
  maximumLevel: 15,
  rectangle: Cesium.Rectangle.fromDegrees(104.450889587402,20.8992862701416,112.061851501465,26.3855667114258)
})

如果使用的是 TileMapServiceImageryProvider 這個類,那麼它是遵循正確的 z、x、y 順序的。如果使用的是 UrlTemplateImageryProvider,那麼你需要把模板中的 {y} 改成 {reverseY}

new Cesium.UrlTemplateImageryProvider({
  url: "http://localhost:4800/geoserver/gwc/service/tms/1.0.0/spatial_base%3Aguangxi_cities@EPSG%3A900913@png/{z}/{x}/{reverseY}.png",
  minimumLevel: 0,
  maximumLevel: 15,
  rectangle: Cesium.Rectangle.fromDegrees(104.450889587402,20.8992862701416,112.061851501465,26.3855667114258)
})

CesiumJS 會判斷預設的 TMS 描述檔案「tilemapresource.xml」,請求失敗則降級成 {z}/{x}/{reverseY}.imageExt

而在 OpenLayers6 中,使用 TMS 則是通過 XYZ 實現的:

new TileLayer({
  source: new XYZ({
    url: 'http://localhost:4800/geoserver/gwc/service/tms/1.0.0/spatial_base%3Aguangxi_cities@EPSG%3A900913@png/{z}/{x}/{y}.png'
  }),
})

這只是最簡單的用法,即預設是 EPSG:3857EPSG:900913 切片方案的 TMS,否則要指定其它的引數,例如 projectiontileGridtileSize 等,具體參考官方檔案。如果不想控制檯報沒瓦片的地方找不到瓦片的錯誤,則還要加上 extent 引數給 ol/layer/Tile 類:

import TileLayer from 'ol/layer/Tile'

const tmslayer = new TileLayer({
  extent: [11627419.84177403,2379873.5953122815,12474668.246494522,3046913.9333698303],
  // ...
})

3.5. GeoServer 是否可以掛接已有的 TMS

暫時不可以。

參考:Can I use external TMS service as a store in Geoserver?

GeoServer 目前只能掛接其它伺服器的 WMS 和 WMTS,TMS 作為一種比較靜態的瓦片資料服務,建議直接使用 Web 伺服器釋出即可,不需要再經過 GeoServer。

4. WFS 速查

WFS 即使到了 2.0.0 版本,仍然只能用這兩種方式發起請求:

  • 使用鍵值對的簡單型別請求,通常用 Get 請求,也能用 Post 請求
  • 使用 XML 體的複雜資料請求,只能用 Post 請求

這是有問題的,前端的朋友們熟悉什麼?他們要什麼?JSON 啊!

若不加以限制,WFS 返回的是基於 XML 的 GML 格式。總之,

4.1. 能力

  • GetFeature:獲取向量要素資料
  • DescribeFeatureType:查詢向量圖層的後設資料
  • GetCapabilities:獲取能力檔案
  • Transaction:發起向量圖形互動事務,例如增刪改等

這只是主要的能力,2.0.0 還新增了其它的能力,有興趣的可以去看規範,也可以直接參考 GeoServer 的幫助手冊,十分詳細:

我只是好奇,為什麼 GeoServer 本地不能整合一份幫助檔案呢?

4.2. 獲取要素(GetFeature)及常用引數

這裡以 WFS 2.0.0 為例。

一個最簡單的獲取全部向量要素的請求如下:

http://localhost:4800/geoserver/spatial_base/ows
?service=WFS
&version=2.0.0
&request=GetFeature
&typeNames=spatial_base:guangxi_cities
&outputFormat=application/json

引數 outputFormat 的指定非常重要,若不指定,預設返回的是 GML 格式資料。

幾個常用的引數如下

引數名 值型別 描述
count int 限制返回的個數,取前 count 個
featureid string 指定要素的 ID 來查詢,格式是「圖層名.id」
typeNames string 要查詢哪個「圖層」,GeoServer 是「工作空間」:「圖層名」
propertyName string 需要返回什麼屬性欄位,用英文逗號連線
filter string 一個 XML 文字,即查詢資訊
outputFormat string 要返回資料的格式型別,能力檔案中有

其中,filter 的 XML 就是 WFS 較為詬病的一點,因為這個 XML 構造起來比較麻煩。

4.3. 獲取要素時使用過濾(Filtering)

以一個簡單的框選查詢為例,你需要構造如下的 XML:

<Filter xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
  <Intersects>
    <PropertyName>geom</PropertyName>
    <gml:Envelope srsName="EPSG:4326">
      <gml:lowerCorner>109 20</gml:lowerCorner>
      <gml:upperCorner>120 30</gml:upperCorner>
    </gml:Envelope>
  </Intersects>
</Filter>

對於我這份資料來說,這樣一個框選查詢能返回 11 個要素。注意,<Intersects> 下的 <PropertyName> 的值,即 "geom",指的是要素圖層的待相交查詢的幾何欄位名稱。如果是 Shapefile,它的幾何欄位可能是 "SHAPE" 或其它。

關於這個 filter 能進行什麼空間查詢,請參考:


上述的 XML 過濾引數,是通過 GET 請求,傳送 QueryString 的方式傳遞到 WFS 的。如果這個過濾的 XML 體積過大,超出了 GET 請求的最大大小(因瀏覽器而異,普遍較小),那麼就需要改成 POST 請求,把這個 XML 作為請求體傳送到伺服器。

請求路徑:

POST http://localhost:4800/geoserver/spatial_base/ows

請求體和上面的 filter 略有不同,要把其它的請求引數也帶上:

<?xml version='1.0' encoding='UTF-8'?>
<wfs:GetFeature 
  service="WFS"
  version="2.0.0"
  outputFormat="json"
  xmlns:wfs="http://www.opengis.net/wfs/2.0"
  xmlns:fes="http://www.opengis.net/fes/2.0"
  xmlns:gml="http://www.opengis.net/gml/3.2"
  xmlns:sf="http://www.openplans.org/spearfish"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/wfs/2.0
                      http://schemas.opengis.net/wfs/2.0/wfs.xsd
                      http://www.opengis.net/gml/3.2
                      http://schemas.opengis.net/gml/3.2.1/gml.xsd"
>
  <wfs:Query typeNames='spatial_base:guangxi_cities'>
  <wfs:PropertyName>geom</wfs:PropertyName>
  <wfs:PropertyName>name</wfs:PropertyName>
    <fes:Filter>
      <fes:PropertyIsEqualTo matchAction="OR">
        <fes:ValueReference>name</fes:ValueReference>
        <fes:Literal>梧州市</fes:Literal>
      </fes:PropertyIsEqualTo>
    </fes:Filter>
  </wfs:Query>
</wfs:GetFeature>

WFS 1.0.0 和 1.1.0 的又略有不同,詳見:

WFS 參考資料之複雜,中文教學、例子之少,其實講究效率的年代不願意用它也是情有可原的。

官方的例子,在標準檔案的 Annex B 章節(附件B)中。

線上的檔案,則可以參考 OGC Standard Examples 頁面,找到 WFS 目錄即可。

4.4. 簡述事務(Transaction)

WFS 的事務允許你向伺服器上的資料進行增刪改,能增刪改的除了屬性資料,當然還包括圖形資料。

在 WFS 2.0.0 中,事務支援如下幾個動作(Action):

  • delete
  • insert
  • replace
  • update

以更新為例,仍然是請求 4.3 小節中的地址,傳送的 XML 請求體則是:

<?xml version='1.0' encoding='UTF-8'?>
<wfs:Transaction 
  version="2.0.0"
  service="WFS"
  xmlns:fes="http://www.opengis.net/fes/2.0"
  xmlns:wfs="http://www.opengis.net/wfs/2.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
  <!-->要 Update 的要素是 spatial_base:guangxi_cities<-->
  <wfs:Update typeName="spatial_base:guangxi_cities">
    <!-->更新名稱屬性為「梧州市_重新命名」<-->
    <wfs:Property>
      <wfs:ValueReference>name</wfs:ValueReference>
      <wfs:Value>梧州市_重新命名</wfs:Value>
    </wfs:Property>
    <!-->使用 Filtering 只修改第4個要素<-->
    <fes:Filter>
      <fes:ResourceId rid="guangxi_cities.4"/>
    </fes:Filter>
  </wfs:Update>
</wfs:Transaction>

有時候你無法傳送 Transaction 請求,返回的錯誤是「XXX is readonly」,應該是 GeoServer 對編輯請求作了限制,你可以到管理頁面的「Security - Data」下,將「*.*.w」的規則(也就是寫規則)賦予合適的角色,即可得到編輯寫入的許可權。

更多例子請參考文末給的例子連結,或者直接查閱對應 WFS 版本的標準檔案中的 Examples 內容。

4.5. 推薦與不推薦

WFS 的要務並不是拿來顯示大量向量資料的,大量的向量圖形資料對網路傳輸、瀏覽器渲染的效能要求非常高,甚至瀏覽器超過 1000 個常規的 JavaScript 物件就難以把持 rAF 程式的流暢性(一是遍歷效能可能不足,二是瀏覽器可用作業系統記憶體可能不夠)。

所以,不推薦 WFS 用來全量顯示向量圖形資料

針對「既需要顯示、又需要查詢」的需求,可將任務分解:

  • 使用 WMTS/TMS/VectorTiles 顯示圖形;
  • 使用 WMS/WMTS 的 GetFeatureInfo 或獨立儲存非空間資料,另寫請求介面進行查詢非空間資料;
  • 有空間圖形分析或複雜空間查詢需求的,請使用地理資料庫;
  • 有編輯需求的,不太推薦使用 WFS 的 Transaction 操作,建議使用地理資料庫 + 可客製化的後端查詢介面

OpenLayers6 有幾個 WFS 的例子,其使用 JavaScript 函數拼接請求引數之複雜令人困擾,實在令人提不起用標準 WFS 的慾望。

而 CesiumJS 則直接不考慮這個 OGC 服務,讓使用者自己選擇向量圖形資料的載入與否(可請求向量圖形資料後使用 GeoJsonDataSource 來載入)。

5. 什麼是 TileMatrixSet / TileMatrix

你在 WMTS 能力檔案中,一定能看到這兩個東西。但是我覺得官方檔案廢話太多,索性把自己的理解寫了出來。

TileMatrixSet 筆者譯為「瓦片陣集」,而 TileMatrix 即「瓦片陣」。

很多人也許第一次看到這個詞,一時半會兒想不通為什麼是「Matrix」。直譯來說,「Matrix」即矩陣:

假如這個矩陣的每個元素塊上填充的是地圖瓦片,那就能理解了。

所以,TileMatrix 指的就是某個層級的所有瓦片;自然而然,TileMatrixSet 就是所有層級的 TileMatrix 「集」。

舉例,GeoServer 中的內建瓦片陣集有一個是 EPSG:4326,那麼第 7 級瓦片陣即 EPSG:4326:7

在 GeoServer 中還有個類似的詞是 Gridset,在 TileCaching - Gridsets 下可以找到。

6. 常見地圖服務介面的軸朝向

① 使用 Z-order 降維編碼的微軟必應地圖

Z-order,有時候又叫 莫頓曲線,參考 wiki - Z-orderwikigis - Z-order

在微軟 Bing 地圖瓦片的編號中使用了這個曲線。這個曲線通常用於四元樹的編碼。

② 類似 WMTS 的谷歌和 OSM

瓦片的軸和原點均與 WMTS 一樣,只不過有一個語意上的等價關係:

  • TileCol → x(列 Col 值,即橫方向)
  • TileRow → y(行 Row 值,即縱方向)
  • TileMatrix = z(當前瓦片陣,即瓦片層級)

如下圖所示:

OSM 和 谷歌地圖 的 Z、X、Y 也與 WMTS 一樣,是從 0 開始算的。

以 WMTS 的 TileMatrix=EPSG:900913:7TileCol=103TileRow=55 瓦片為例,那麼 OSM 的瓦片應為:

https://a.tile.openstreetmap.org/7/103/55.png

得到的瓦片:

而對應的谷歌地圖瓦片連結為:

http://mt2.google.com/vt/lyrs=m@167000000&hl=zh-CN&gl=cn&x=103&y=55&z=7

得到的圖:

再把原來 WMTS的瓦片搬來看看:

可以說位置上是一致的。

③ 百度地圖

原點在 0 度經度、0 度緯度:

百度的 X 和 Y 值如上圖所示,有正有負。

瓦片層級,從 3 級起算,最大 21 級。

關於百度的 N 種座標,參考此文 百度地圖API詳解之地圖座標系統,業務上對高德、百度、騰訊等 LBS 廠商用得不多,故不再列舉,有需要的朋友可自行在網路上查詢。

參考資料