MapLibre/Martin | 使用Martin釋出MBTiles地圖切片包

GoJun發表於2024-07-16

什麼是 Martin

Martin 是一個高效能的地圖切片伺服器,使用Rust編寫,支援PostGISMBTilesPMTiles

什麼是 MBTiles

MBTiles 是個sqlite檔案,也就是說MBTiles檔案是個單檔案資料庫。截至本文寫作時,最新標準是1.3.
MBTIles利用了資料庫的索引機制,避免相同內容的切片重複佔用空間,同時也有了 SQLITE 資料庫單檔案的優點,非常方便傳輸與利用。

Tiles 表

CREATE TABLE tiles (
    zoom_level  INTEGER, -- Z
    tile_column INTEGER, -- Y
    tile_row    INTEGER, -- X
    tile_data   BLOB);   -- 切片資料

CREATE UNIQUE INDEX tile_index on tiles (
    zoom_level, tile_column, tile_row);

Metadata 表

CREATE TABLE metadata (name text, value text);

元資訊欄位

  • name
  • format
  • bounds
  • center
  • minzoom
  • maxzoom
  • attribution
  • description
  • type
  • version
  • json

為什麼使用 MBTiles

  • 單檔案,就是爽(對比下 ArcGIS 生成的 Bundles中無數個小切片檔案...🥶)
  • 緊湊,配合索引機制,可以避免相同內容的切片重複出現,節省磁碟空間
  • MBTiles 本質上還是個 SQLITE 資料庫,解析利用都非常方便,生態良好,有大量的配套軟體
MBTiles PMTiles ArcGIS Bundle(即 raster-tiles-compactcache) COG(Cloud Optimized GeoTIFF)
單檔案 😄 😄 🥶 😄
支援無伺服器(serverless)的方式使用 🥶 😄 🥶 😄
向量 😄 😄 🥶 🥶
柵格 😄 😄 😄 😄
開源社群生態 😄 😄 🥶 😄

PS: 可以使用NavicatDBeaver(有社群版,開源免費)等資料庫管理軟體開啟 MBTiles 檔案,直接檢視其內部表結構,加深對 MBTiles 檔案格式的理解。也可以試用QGIS載入切片資料,檢視地圖。

開始實驗(WINDOWS)

本實驗用到的所有內容地址:https://gitee.com/mapnote/blog_demo_data

準備實驗資料

  • 實驗資料:world_cities.mbtiles
  • 實驗軟體:martin.exe

釋出服務

  1. 新建資料夾: martin_demo
  2. world_cities.mbtiles 放到 martin_demo 資料夾中
  3. martin.exe 放到 martin_demo 資料夾中
  4. 按住 SHIFT 鍵不放,在資料夾內右擊,點選“在此處開啟 Powershell 視窗
  5. 在 Powershell 視窗內輸入.\martin.exe .\world_cities.mbtiles
.\martin.exe .\world_cities.mbtiles

執行該命令後,martin 會在您電腦的 3000 埠上啟動地圖服務。如果需要修改埠,可以用--listen-addresses 修改埠號。(完整的啟動命令引數請參閱官方文件

.\martin.exe .\world_cities.mbtiles --listen-addresses *:5000

檢視服務資訊

服務目錄

訪問http://localhost:3000/catalog檢視切片服務目錄

{
  "tiles": {
    "world_cities": {
      //切片服務名稱,即SourceID
      "content_type": "application/x-protobuf", //切片格式的MIME,application/x-protobuf表示是MVT(mapbox vector tile)
      "content_encoding": "gzip", // 是否壓縮及其用到的壓縮編碼
      "name": "Major cities from Natural Earth data",
      "description": "Major cities from Natural Earth data"
    }
  },
  "sprites": {},
  "fonts": {}
}

tiles 下就是所有的切片服務目錄了,根據以上屬性資訊可以知道:

  1. 只發布了一個切片服務,它的服務名稱(SourceId)是 world_cities
  2. content_typeapplication/x-protobuf,表明切片格式 MVT

服務 TileJson

切片服務跟客戶端主要是用 TileJson 溝通,TileJson 中詳細寫明瞭 OpenLayer、Mapbox、MapLibre 等客戶端切片服務需要了解的引數,要檢視 Martin 釋出的服務的 tiljeson,只需要訪問 http://ip 地址:埠/服務名稱

在這次實驗中,對應的地址就是 http://localhost:3000/world_cities

會返回如下 Json

{
  "tilejson": "3.0.0",
  "tiles": [
    "http://localhost:3000/world_cities/{z}/{x}/{y}" //切片服務地址,OpenLayers等客戶端要用
  ],
  "vector_layers": [
    {
      "id": "cities", // 要素ID欄位名
      "fields": {
        // 要素中所有的欄位
        "name": "String"
      },
      "description": "",
      "maxzoom": 6,
      "minzoom": 0
    }
  ],
  "bounds": [
    //切片資料的地理覆蓋範圍
    -123.12359, -37.818085, 174.763027, 59.352706
  ],
  "center": [
    // 切片資料的中心點
    -75.9375, 38.788894, 6
  ],
  "description": "Major cities from Natural Earth data",
  "maxzoom": 6, // 最大縮放層級
  "minzoom": 0, // 最小縮放層級
  "name": "Major cities from Natural Earth data",
  "version": "2",
  "format": "pbf"
}

使用 QGIS 檢視服務

  1. 可以使用 QGIS 快速檢視這次實驗釋出的切片,開啟 QGIS
  2. 右擊左側的 Vector Tiles,點選新建,
  3. 名稱任意填寫,我填的是 world_cities
  4. URL 地址填寫 TileJson 中的地址 http://localhost:3000/world_cities/{z}/{x}/{y}
  5. 最小縮放層級填寫 0
  6. 最大縮放層級填寫 6
  7. 填寫完成後點選確定
  8. 雙擊自己新建的服務,後會自動載入到地圖

使用 OpenLayers 載入服務

  1. martin_demo 資料夾內新建一個資料夾ol用來編寫我們的前端程式碼

  2. 使用 vscode 開啟我們的 ol 資料夾

  3. 開啟命令列輸入 npm create ol-app,等待命令執行完成

  4. 刪除 main.js 中所有內容,輸入以下內容。

    import "./style.css";
    import { Map, View } from "ol";
    import MVT from "ol/format/MVT.js";
    import TileLayer from "ol/layer/Tile";
    import OSM from "ol/source/OSM";
    import VectorTileLayer from "ol/layer/VectorTile.js";
    import VectorTileSource from "ol/source/VectorTile.js";
    
    let my_layer = new VectorTileLayer({
      source: new VectorTileSource({
        format: new MVT(),
        url: "http://localhost:3000/world_cities/{z}/{x}/{y}",
      }),
    });
    
    const map = new Map({
      target: "map",
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
        my_layer,
      ],
      view: new View({
        center: [0, 0],
        zoom: 2,
      }),
    });
    
  5. vscode 的命令列中輸入npm install,安裝所有依賴

  6. vscode 的命令列中輸入npm start執行前端程式碼服務

  7. 命令列中會提示服務地址,我這裡是http://localhost:5174/,訪問該地址即可看到效果。

相關文章