圖片來源:Mapbox
使用 Style 渲染地圖時,除了文字以外,還能透過圖示來呈現資料。圖層可以在 layout
中使用 icon-image
屬性來指定要渲染的圖示,例如以下有關機場標籤的圖層:
{
"id":"airport-label",
"type":"symbol",
...
"layout":{
"text-padding":2,
"icon-image":"airport_11",
"text-field":"{name:latin}\n{name:nonlatin}",
...
},
"paint":{
....
}
},
就可以在地圖上同時顯示中英文及相關圖示:
可以使用圖示的屬性,除了上述的 icon-image
還有:
background-pattern
: 用於背景的重覆圖標fill-pattern
: 用於填充多邊形line-pattern
: 用於將圖示描繪為線段fill-extrusion-pattern
: 用於3D投影的紋理貼圖。至於今天要介紹的 sprite,正如封面圖一下,是 Style 檔案中所有可用圖示的集合體,它會和同一目錄下的 JSON 檔案搭配,來讓 Style 檔案讀取正確的切片。
使用 Demo Tiles 的 osm-bright-gl Style 來舉例,在 Style 檔案中會有如下設定:
{
...
"sprite":"https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite"
...
}
這樣在渲染時,前端就會知道要使用後綴,去查找 sprite 本體圖片,以及用於描述內容的 JSON 檔案。在高解析度的裝置上,Style 會優先使用有 @2x
後綴的檔案進行渲染。一般來說,目錄結構如下:
// 目錄為 https://demotiles.maplibre.org/styles/osm-bright-gl-style/
.
├── sprite@2x.json
├── sprite@2x.png
├── sprite.json
└── sprite.png
在 JSON 文件中,會用以下的格式定義資料:
{
"poi": {
"width": 32,
"height": 32,
"x": 0,
"y": 0,
"pixelRatio": 1
}
...
}
意思並不難懂,一個名叫 poi
的圖示,需要從 sprite 的左上角,以寬高 32 pixel 的方式切下,並且維持原比例。
這樣在圖層中,我們就可以用 icon-image
的方式來指定圖片了,可以使用"icon-image": "poi"
,或者利用物件的屬性來表示:"icon-image": "{icon}"
。這樣只要物件的 icon
屬性為 poi
,該圖示就會被選中。
Sprite 的原理並不複雜,僅僅只是將圖片合併,並用 JSON 檔案來紀錄相關資訊。若您熟悉 imagemagick 等 CLI 工具,或許也能自己寫一個腳本出來。
目前便於製作適用於 Maplibre 的 Sprite 工具有好幾個,這邊先使用 Mapbox 開發的 spritezero-cli。它使用 JS 撰寫,不過較久沒有更新,目前安裝時需要指定 npm 版板:
nvm install 8
nvm use 8
npm install -g @mapbox/spritezero-cli
前幾天提到過,困難路線除了顏色以外,也可以使用圖示來加強警告意味。另外我們也可以為一級三角點加上特別標示。這邊我們就使用以下兩個圖示:
首先,將它們放在 input 資料夾中
input/
├── skull.svg
└── trig.svg
接著,使用 spritezero 指令即可產製出 sprite.png
和 sprite.json
兩個檔案
spritezero sprite input
依邏輯加入相關圖層後,就可以在地圖上顯示圖示了:
參考資料:
Custom map icons (sprites): https://documentation.maptiler.com/hc/en-us/articles/360020805997-Custom-map-icons-sprites-