博客 / 詳情

返回

JSAPIThree 加載 WMS、WMTS 和通用柵格圖學習筆記:標準地圖服務與切圖規則

在實際項目中,我們經常需要加載各種標準地圖服務,比如 WMS、WMTS,或者自定義的 XYZ 格式瓦片。今天就來學習一下如何在 mapvthree 中使用這些服務,以及理解不同的瓦片切圖規則。

瞭解標準地圖服務

在 GIS 領域,有幾種常見的地圖服務標準:

  • WMS(Web Map Service):Web 地圖服務,通過 HTTP 請求獲取地圖圖片
  • WMTS(Web Map Tile Service):Web 地圖瓦片服務,提供預切好的瓦片
  • XYZ:通用的瓦片格式,通過 URL 模板直接訪問瓦片

我的理解:WMS 是動態生成地圖圖片,WMTS 和 XYZ 是使用預切好的瓦片,性能更好。

第一步:加載 WMS 服務

WMS 是 OGC 標準的 Web 地圖服務,通過參數化的 HTTP 請求獲取地圖圖片。

基本使用

import * as mapvthree from '@baidumap/mapv-three';

const container = document.getElementById('container');

const engine = new mapvthree.Engine(container, {
    map: {
        center: [120.628, 27.786],
        range: 500000,
        provider: null,
        projection: 'EPSG:3857',
    },
});

// 添加 WMS 服務
const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMSImageryTileProvider({
        url: 'https://ows.mundialis.de/services/service',
        params: {
            LAYERS: 'TOPO-WMS,OSM-Overlay-WMS',
            SRS: 'EPSG:3857',
            VERSION: '1.1.1',
            WIDTH: 256,
            HEIGHT: 256,
        },
    }),
}));

我的發現:WMS 需要配置服務 URL 和請求參數,包括圖層名稱、座標系、版本等。

參數説明

  • url:WMS 服務地址
  • params.LAYERS:要加載的圖層名稱,多個圖層用逗號分隔
  • params.SRS:空間參考系統,常用 EPSG:3857(Web 墨卡託)或 EPSG:4326(WGS84)
  • params.VERSION:WMS 版本,常用 1.1.11.3.0
  • params.WIDTHparams.HEIGHT:請求圖片的尺寸,通常為 256

第二步:加載 WMTS 服務

WMTS 是 OGC 標準的 Web 地圖瓦片服務,提供預切好的瓦片,性能比 WMS 更好。

基本使用

const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMTSImageryTileProvider({
        url: 'https://mrdata.usgs.gov/mapcache/wmts?LAYER=sgmc2&TILEMATRIX={z}',
        params: {
            STYLE: 'default',
            TILEMATRIXSET: 'GoogleMapsCompatible',
            VERSION: '1.0.0',
            FORMAT: 'image/png',
        },
    }),
}));

我的發現:WMTS 的 URL 中可以使用 {z} 佔位符,引擎會自動替換為對應的縮放級別。

參數説明

  • url:WMTS 服務地址,可以使用 {z}{x}{y} 佔位符
  • params.STYLE:圖層樣式
  • params.TILEMATRIXSET:瓦片矩陣集,常用 GoogleMapsCompatible
  • params.VERSION:WMTS 版本,通常為 1.0.0
  • params.FORMAT:圖片格式,如 image/pngimage/jpeg

我的理解

  • WMTS 使用預切好的瓦片,加載速度更快
  • URL 中的佔位符會在請求時被替換為實際的瓦片座標
  • 不同的 WMTS 服務可能有不同的參數要求

第三步:加載 XYZ 格式瓦片

XYZ 是最通用的瓦片格式,通過 URL 模板直接訪問瓦片,支持各種自定義瓦片服務。

基本使用

const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
        url: 'https://server.arcgisonline.com/ArcGIS/rest/services/' +
              'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    }),
}));

我的發現:XYZ 格式使用 {z}/{y}/{x} 佔位符,分別代表縮放級別、行號、列號。

切圖規則:y 和 reverseY

不同的瓦片服務可能使用不同的切圖規則,主要體現在 Y 軸的起始位置:

  • y(默認):Y 軸從左上角開始,向下遞增(如谷歌地圖)
  • reverseY:Y 軸從左下角開始,向上遞增(如 TMS 標準)
// 使用 y 規則(左上角為原點)
const mapView1 = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
        url: 'https://example.com/tiles/{z}/{x}/{y}.png',
        // 默認使用 y 規則
    }),
}));

// 使用 reverseY 規則(左下角為原點,TMS 標準)
const mapView2 = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
        url: 'https://example.com/tms/{z}/{x}/{reverseY}.png',
        // 使用 reverseY 佔位符
    }),
}));

我的理解

  • 如果瓦片服務使用左上角為原點(Y 向下遞增),使用 {y}
  • 如果瓦片服務使用左下角為原點(Y 向上遞增,TMS 標準),使用 {reverseY}
  • 使用錯誤的規則會導致瓦片位置錯亂

TMS 示例

const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
        url: 'https://mapopen-pub-jsapigl.bj.bcebos.com/tms-bj/{z}/{x}/{reverseY}.png',
        startLevel: 7,
        maxLevel: 12,
    }),
}));

我的發現:可以設置 startLevelmaxLevel 來限制瓦片的縮放級別範圍。

第四步:理解切圖規則

作為一個初學者,理解切圖規則很重要,這決定了瓦片能否正確顯示。

座標系和原點

地圖瓦片通常使用兩種座標系:

  1. 屏幕座標系(左上角原點)

    • X 軸:從左到右遞增
    • Y 軸:從上到下遞增
    • 原點在左上角
    • 如:谷歌地圖、OpenStreetMap
  2. 地理座標系(左下角原點)

    • X 軸:從左到右遞增
    • Y 軸:從下到上遞增
    • 原點在左下角
    • 如:TMS(Tile Map Service)標準

如何判斷使用哪種規則

我的經驗

  1. 查看服務文檔,通常會説明使用的切圖規則
  2. 如果文檔沒有説明,可以嘗試兩種規則,看哪種顯示正確
  3. 常見的服務:
    • 谷歌地圖、OpenStreetMap:使用 y
    • TMS 標準服務:使用 reverseY

瓦片座標計算

我的理解

  • z:縮放級別,數值越大,地圖越詳細
  • x:瓦片的列號,從 0 開始
  • y:瓦片的行號,從 0 開始
  • 在縮放級別 z 下,總共有 2^z × 2^z 個瓦片

第五步:完整示例

我想寫一個完整的示例,展示三種服務的使用:

import * as mapvthree from '@baidumap/mapv-three';

const container = document.getElementById('container');

const engine = new mapvthree.Engine(container, {
    map: {
        center: [120.628, 27.786],
        range: 500000,
        provider: null,
        projection: 'EPSG:3857',
    },
});

// 示例 1:WMS 服務
const wmsMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMSImageryTileProvider({
        url: 'https://ows.mundialis.de/services/service',
        params: {
            LAYERS: 'TOPO-WMS',
            SRS: 'EPSG:3857',
            VERSION: '1.1.1',
            WIDTH: 256,
            HEIGHT: 256,
        },
    }),
}));

// 示例 2:WMTS 服務
const wmtsMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMTSImageryTileProvider({
        url: 'https://mrdata.usgs.gov/mapcache/wmts?LAYER=sgmc2&TILEMATRIX={z}',
        params: {
            STYLE: 'default',
            TILEMATRIXSET: 'GoogleMapsCompatible',
            VERSION: '1.0.0',
            FORMAT: 'image/png',
        },
    }),
}));

// 示例 3:XYZ 格式(y 規則)
const xyzMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
        url: 'https://server.arcgisonline.com/ArcGIS/rest/services/' +
              'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    }),
}));

// 示例 4:XYZ 格式(reverseY 規則,TMS)
const tmsMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
        url: 'https://mapopen-pub-jsapigl.bj.bcebos.com/tms-bj/{z}/{x}/{reverseY}.png',
        startLevel: 7,
        maxLevel: 12,
    }),
}));

我的感受:掌握了這三種服務的使用方法,就可以加載各種標準地圖服務了!

第六步:踩過的坑

作為一個初學者,我踩了不少坑,記錄下來避免再犯:

坑 1:WMS 地圖不顯示

原因:參數配置錯誤,比如圖層名稱不對、座標系不匹配。

解決

  1. 檢查 WMS 服務的 GetCapabilities 文檔,確認正確的參數
  2. 確保 SRS 參數與引擎的投影設置一致
  3. 確認 LAYERS 參數中的圖層名稱正確

坑 2:WMTS 瓦片位置錯亂

原因:URL 佔位符使用錯誤,或者 TILEMATRIXSET 不匹配。

解決

  1. 確認 URL 中的佔位符格式正確({z}{x}{y}
  2. 檢查 TILEMATRIXSET 是否與服務提供的一致
  3. 查看服務的 GetCapabilities 文檔

坑 3:XYZ 瓦片上下顛倒

原因:切圖規則選擇錯誤,應該用 y 卻用了 reverseY,或者相反。

解決

  1. 查看服務文檔,確認使用的切圖規則
  2. 如果文檔沒有説明,嘗試兩種規則,看哪種顯示正確
  3. 記住:左上角原點用 y,左下角原點用 reverseY

坑 4:瓦片加載很慢

原因:服務地址訪問慢,或者網絡問題。

解決

  1. 檢查服務地址是否可訪問
  2. 考慮使用 CDN 加速
  3. 對於自定義服務,確保服務器性能足夠

坑 5:某些縮放級別沒有瓦片

原因:服務只提供了特定縮放級別的瓦片。

解決:使用 startLevelmaxLevel 限制縮放級別範圍。

我的學習總結

經過這一天的學習,我掌握了:

  1. WMS 服務:動態生成地圖圖片,需要配置服務 URL 和請求參數
  2. WMTS 服務:使用預切好的瓦片,性能更好,支持 URL 佔位符
  3. XYZ 格式:最通用的瓦片格式,支持自定義服務
  4. 切圖規則:理解 yreverseY 的區別,正確選擇切圖規則
  5. 參數配置:瞭解各種服務的參數含義和配置方法

我的感受:標準地圖服務雖然配置有點複雜,但是用起來其實不難。關鍵是要理解不同服務的特點,然後正確配置參數和切圖規則!

下一步計劃

  1. 學習更多地圖服務的配置選項
  2. 嘗試創建自定義的瓦片服務
  3. 做一個完整的地圖展示項目

學習筆記就到這裏啦!作為一個初學者,我覺得標準地圖服務雖然配置有點複雜,但是用起來其實不難。關鍵是要理解不同服務的特點,然後正確配置參數和切圖規則!希望我的筆記能幫到其他初學者!大家一起加油!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.