底圖
ExpTech 提供三組底圖圖磚,都附 TileJSON,可以直接當作 MapLibre GL JS 的 source 使用:
| 圖磚 | 格式 | 內容 |
|---|---|---|
| 行政區底圖 | 向量(.pbf) |
世界陸地、臺灣縣市與鄉鎮市區界線、海嘯警報沿海區段 |
| 地形 | 點陣(.png,Terrain-RGB) |
臺灣高程,可畫山影(hillshade)或 3D 地形 |
| 街道建築 | 向量(.pbf,OpenMapTiles 格式) |
臺灣道路、建築、水系、地名、興趣點等,資料來自 OpenStreetMap |
這三組圖磚不依時間變動,不需要時間列表。
- 行政區底圖、地形註明來源・可商用
建議標示資料來源:ExpTech Studio(exptech.dev)
- 街道建築註明來源・可商用
建議標示資料來源:© OpenStreetMap contributors、© OpenMapTiles、ExpTech Studio(exptech.dev)
- OpenStreetMap:OpenStreetMap 資料以 ODbL 授權:地圖上須顯示「© OpenStreetMap contributors」並連到 https://www.openstreetmap.org/copyright 。
- OpenMapTiles:使用 OpenMapTiles 圖層架構的圖磚須標示「© OpenMapTiles」。
標示位置、範例與商業使用申請見資料授權與來源標示。
目前不需要 API Token。回應帶 Access-Control-Allow-Origin: *,可以直接在瀏覽器跨網域載入。
curl "https://lb.exptech.dev/api/v1/map/tiles/tiles.json"const res = await fetch("https://lb.exptech.dev/api/v1/map/tiles/tiles.json");if (!res.ok) throw new Error(`HTTP ${res.status}`);const data = await res.json();console.log(data);import requests
res = requests.get("https://lb.exptech.dev/api/v1/map/tiles/tiles.json", timeout=10)res.raise_for_status()print(res.json())TileJSON 2.0.0(節錄)
{ "tilejson": "2.0.0", "name": "ExpTech Studio Map", "format": "pbf", "minzoom": 0, "maxzoom": 12, "bounds": [ -180, -85.051129, 180, 83.634101 ], "attribution": "ExpTech Studio Map", "tiles": [ "https://lb.exptech.dev/api/v1/map/tiles/{z}/{x}/{y}.pbf" ]}試試看
z縮放層級,範圍見 TileJSON 的 minzoom / maxzoom。
xXYZ 圖磚欄號。
yXYZ 圖磚列號(由北往南)。
curl -o output.pbf --compressed "https://lb.exptech.dev/api/v1/map/tiles/<z>/<x>/<y>.pbf"const res = await fetch("https://lb.exptech.dev/api/v1/map/tiles/<z>/<x>/<y>.pbf");if (!res.ok) throw new Error(`HTTP ${res.status}`);const blob = await res.blob();import requests
res = requests.get( "https://lb.exptech.dev/api/v1/map/tiles/<z>/<x>/<y>.pbf", timeout=10,)res.raise_for_status()with open("output.pbf", "wb") as f: f.write(res.content)Mapbox Vector Tile(Content-Type: application/octet-stream);部分圖磚以 gzip 傳回(Content-Encoding: gzip)binary MVT
這個位置沒有圖磚(無內容)沒有回應本文
試試看
圖層(source-layer)
Section titled “圖層(source-layer)”| source-layer | 幾何 | 內容 |
|---|---|---|
global |
面 | 世界陸地 |
city |
面 | 臺灣縣市 |
town |
面 | 臺灣鄉鎮市區 |
tsunami |
線 | 海嘯警報的沿海區段 |
各圖層的屬性欄位目前沒有正式規格,可能變更。
curl "https://lb.exptech.dev/api/v1/map/terrain/terrain.json"const res = await fetch("https://lb.exptech.dev/api/v1/map/terrain/terrain.json");if (!res.ok) throw new Error(`HTTP ${res.status}`);const data = await res.json();console.log(data);import requests
res = requests.get("https://lb.exptech.dev/api/v1/map/terrain/terrain.json", timeout=10)res.raise_for_status()print(res.json())TileJSON 2.0.0(節錄)
{ "tilejson": "2.0.0", "name": "ExpTech Studio Terrain", "format": "png", "encoding": "mapbox", "minzoom": 0, "maxzoom": 12, "bounds": [ 120.0166, 21.8939, 122.0096, 25.3015 ], "attribution": "ExpTech Studio Map", "tiles": [ "https://lb.exptech.dev/api/v1/map/terrain/{z}/{x}/{y}.png" ]}試試看
z縮放層級,範圍見 TileJSON 的 minzoom / maxzoom。
xXYZ 圖磚欄號。
yXYZ 圖磚列號(由北往南)。
curl -o output.png "https://lb.exptech.dev/api/v1/map/terrain/<z>/<x>/<y>.png"const res = await fetch("https://lb.exptech.dev/api/v1/map/terrain/<z>/<x>/<y>.png");if (!res.ok) throw new Error(`HTTP ${res.status}`);const blob = await res.blob();import requests
res = requests.get( "https://lb.exptech.dev/api/v1/map/terrain/<z>/<x>/<y>.png", timeout=10,)res.raise_for_status()with open("output.png", "wb") as f: f.write(res.content)image/png,512 × 512 Terrain-RGB;沒有資料的位置回海平面(0 m)的純色圖binary image/png
試試看
圖磚是 512 × 512 的 Terrain-RGB PNG(mapbox 編碼),高程(公尺):
const elevation = -10000 + (r * 256 * 256 + g * 256 + b) * 0.1;範圍外或沒有資料的位置不回 204,而是回一張代表海平面(0 m)的 512 × 512 圖,MapLibre 的 raster-dem 可以直接處理。
curl "https://lb.exptech.dev/api/v1/map/gsi/gsi.json"const res = await fetch("https://lb.exptech.dev/api/v1/map/gsi/gsi.json");if (!res.ok) throw new Error(`HTTP ${res.status}`);const data = await res.json();console.log(data);import requests
res = requests.get("https://lb.exptech.dev/api/v1/map/gsi/gsi.json", timeout=10)res.raise_for_status()print(res.json())TileJSON 2.0.0(節錄)
{ "tilejson": "2.0.0", "name": "ExpTech Studio GSI (Taiwan roads & buildings)", "format": "pbf", "minzoom": 0, "maxzoom": 14, "bounds": [ 114.28579, 10.32677, 122.3283, 26.43722 ], "attribution": "© OpenStreetMap contributors © OpenMapTiles", "tiles": [ "https://lb.exptech.dev/api/v1/map/gsi/{z}/{x}/{y}.pbf" ]}試試看
z縮放層級,範圍見 TileJSON 的 minzoom / maxzoom。
xXYZ 圖磚欄號。
yXYZ 圖磚列號(由北往南)。
curl -o output.pbf --compressed "https://lb.exptech.dev/api/v1/map/gsi/<z>/<x>/<y>.pbf"const res = await fetch("https://lb.exptech.dev/api/v1/map/gsi/<z>/<x>/<y>.pbf");if (!res.ok) throw new Error(`HTTP ${res.status}`);const blob = await res.blob();import requests
res = requests.get("https://lb.exptech.dev/api/v1/map/gsi/<z>/<x>/<y>.pbf", timeout=10)res.raise_for_status()with open("output.pbf", "wb") as f: f.write(res.content)Mapbox Vector Tile(Content-Type: application/octet-stream);部分圖磚以 gzip 傳回(Content-Encoding: gzip)binary MVT
這個位置沒有圖磚(無內容)沒有回應本文
試試看
依 OpenMapTiles 圖層架構,從 OpenStreetMap 臺灣資料產生,只含臺灣範圍。常用的 source-layer:
transportation、transportation_name、building、water、waterway、water_name、landcover、landuse、park、aeroway、aerodrome_label、boundary、place、poi、mountain_peak、housenumber。
各圖層的屬性見 OpenMapTiles 文件。使用時必須標示「© OpenStreetMap contributors © OpenMapTiles」。
TileJSON 欄位
Section titled “TileJSON 欄位”| 欄位 | 類型 | 說明 |
|---|---|---|
tilejson | string | TileJSON 規格版本,目前為 2.0.0。 |
name | string | 圖磚集名稱。 |
format | string | pbf(向量)或 png(地形)。 |
encoding | string | 只有地形有,值為 mapbox(Terrain-RGB 編碼)。 |
minzoom | integer | 最小縮放層級。 |
maxzoom | integer | 最大縮放層級;超過時請放大這一層的圖磚。 |
bounds | number[4] | 涵蓋範圍 [西, 南, 東, 北],度。 |
center | number[3] | 建議的初始中心 [經度, 緯度, 縮放]。 |
attribution | string | 需要標示的來源文字。 |
tiles | string[] | 圖磚網址模板(完整網址)。 |
在一份 MapLibre GL JS 樣式裡同時使用三組圖磚。用 TileJSON 的 url 建立 source,縮放範圍與涵蓋範圍會自動讀取。TileJSON 裡的 attribution 不含完整的建議標示,請像下面一樣在 source 自行設定 attribution(會取代 TileJSON 的值):
const MAP = "https://lb.exptech.dev";
const map = new maplibregl.Map({ container: "map", center: [121, 23.7], zoom: 7, style: { version: 8, sources: { // 行政區底圖:global / city / town / tsunami exptech: { type: "vector", url: `${MAP}/api/v1/map/tiles/tiles.json`, attribution: "資料來源:ExpTech Studio(exptech.dev)" }, // 地形:Terrain-RGB(mapbox 編碼) terrain: { type: "raster-dem", url: `${MAP}/api/v1/map/terrain/terrain.json`, tileSize: 512, encoding: "mapbox", attribution: "資料來源:ExpTech Studio(exptech.dev)" }, // 臺灣街道建築:OpenMapTiles 格式 gsi: { type: "vector", url: `${MAP}/api/v1/map/gsi/gsi.json`, attribution: "資料來源:© OpenStreetMap contributors、© OpenMapTiles、ExpTech Studio(exptech.dev)" }, }, layers: [ { id: "background", type: "background", paint: { "background-color": "#1f2329" } }, { id: "land", type: "fill", source: "exptech", "source-layer": "global", paint: { "fill-color": "#3e4147" } }, { id: "county", type: "fill", source: "exptech", "source-layer": "city", paint: { "fill-color": "#4b4e55" } }, { id: "hillshade", type: "hillshade", source: "terrain", paint: { "hillshade-exaggeration": 0.3 } }, { id: "roads", type: "line", source: "gsi", "source-layer": "transportation", paint: { "line-color": "#8a8f98", "line-width": 1 } }, { id: "buildings", type: "fill", source: "gsi", "source-layer": "building", minzoom: 13, paint: { "fill-color": "#5a5e66" } }, { id: "town-line", type: "line", source: "exptech", "source-layer": "town", paint: { "line-color": "#a9b4bc", "line-width": 0.4 } }, { id: "county-line", type: "line", source: "exptech", "source-layer": "city", paint: { "line-color": "#a9b4bc", "line-width": 1 } }, ], },});- 請用 TileJSON 的
tiles網址。 它是完整網址,主機名稱可能與 TileJSON 本身不同,不要自行替換。 - 向量圖磚(
.pbf)沒有資料時回 204(無內容),不是 404;MapLibre 會自動略過。 - 部分向量圖磚以
Content-Encoding: gzip傳回。瀏覽器與 MapLibre 會自動解壓縮;其他用戶端請自行處理(curl 加--compressed)。 - 地形圖磚是 512 × 512,MapLibre 的
raster-demsource 請設定tileSize: 512。 - 縮放範圍、涵蓋範圍以 TileJSON 回傳的值為準,本頁的節錄可能與實際值不同。
- 回應沒有
Cache-Control。這些圖磚很少變動,可以在用戶端自行快取。
