maplibre-terrain-rendering について
DEM 地形を描画する MapLibre 開発者向けのガイドです。陰影起伏、高度による着色、実行時の等高線、3D 地形と空の設定、性能上の注意点を説明します。
主な機能
- 01陰影起伏の設定
- 02標高に応じた地形の着色
- 03maplibre-contour による等高線生成
- 043D 地形、カメラ、空の設定
- 05地形描画の負荷の把握
活用シーン
- 01地形陰影の強さの調整
- 02標高別に着色したマップの作成
- 03実行時の等高線描画
- 04カメラ傾斜時の地形や空の表示調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ maplibre/ maplibre-agent-skills --skill maplibre-terrain-renderingインストール後、Claude Code で/maplibre-terrain-renderingを入力して読み込まれたか確認します。
詳細
MapLibre の地形レンダリング
raster-dem ソースは画像ではなく標高データです。これを描画する方法は4種類あり、それぞれ独自のレイヤータイプまたは API を使います。また、ここで見られる誤った回答の多くは、MapLibre には存在しなかった Mapbox GL JS のプロパティです。
このスキルを使う場面
原因がわかる前に、次のような症状が見られる場合に使います。
- ヒルシェードのコントラストが強すぎる: 黒白の尾根、白飛びした斜面、白っぽい谷が見られる、またはコントラストを和らげるために複数のヒルシェードレイヤーが重ねられている(1つのレイヤーで
hillshade-method: "multidirectional"を使います)。 - 標高に応じた動的な色付け: 事前レンダリング済みタイルを使わず、クライアント側で高さに応じて地図を色付けする必要がある(
rasterレイヤーのraster-colorではなく、["elevation"]を使うcolor-reliefレイヤーです)。 - 実行時の等高線: 事前生成した等高線タイルセットを使わず、
raster-demソースから直接等高線を描画する(手書きの marching-squares パイプラインではなく、maplibre-contourを使います)。 - 平坦な3D地形:
map.setTerrain()を有効にしても何も隆起しない(カメラのpitch: 0が原因です。exaggerationを上げても解決しません)。 - 何も表示されない地平線: カメラを傾けると、地形の上にページの背景が何もない状態で表示される(ルートレベルの
skyオブジェクトもmap.setSky()もありません。MapLibre にtype: "sky"レイヤーはありません)。 - プロパティの設定が黙って失敗する: ヒルシェード、空、または地形の色付けに関するプロパティを設定しても何も起きず、エラーも発生しない(MapLibre には存在しなかった Mapbox GL JS のプロパティです)。
- 地形の遅延やフレーム落ち: 地形を有効にした状態でパンや傾きを変えるとカクつく(ヒルシェードの描画パスが重なっている、ドレープされたレイヤーが密集している)。
このスキルの対象外です。 標高値の誤り、スパイク状の値や反転、標高タイルセットの選択、encoding、DEM タイルの生成については、スタイル仕様の raster-dem ソースのページを参照してください。
https://maplibre.org/maplibre-style-spec/sources/#raster-dem。スタイル内でヒルシェードを他のレイヤーのどこに配置するかについては、maplibre-cartography を参照してください。
必要な描画方法
| 目的 | 描画方法 |
|---|---|
| 2D 地図の下に陰影起伏を表示する | hillshade レイヤー。setTerrain は不要です。両者は独立しています |
| 高さに応じて色付けする(段彩表現) | color-relief レイヤー(GL JS 5.6) |
| タイルセットを事前生成せずに等高線を表示する | vector ソースにデータを渡す maplibre-contour ライブラリ |
| 傾斜した立体表面の上を飛ぶように移動する | map.setTerrain() とカメラのピッチ |
4種類すべてが同じ raster-dem ソースを読み込みます。1つのソースをすべてに利用できます。
ヒルシェードと、レイヤーを重ねないコントラストの改善方法
hillshade-* プロパティはすべてペイントプロパティです。[1] 押さえておきたいデフォルト値は、hillshade-exaggeration が 0.5、hillshade-illumination-direction が 335、hillshade-illumination-anchor が viewport(光源は画面の上端に固定されるため、map を設定しない限り地図の方位に合わせて回転しません)、hillshade-shadow-color が #000000、hillshade-highlight-color が #FFFFFF です。
出力のコントラストが強すぎる場合、たいてい原因は色ではなくシェーディングの方式です。hillshade-method(GL JS 5.5)では、standard(デフォルト)、basic、combined、igor、multidirectional を指定できます。[1] multidirectional は1回の描画パスで複数の独立した方向から地表を照らし、igor はその下に描画された地物への影響を抑えます。どちらも1つのレイヤーで地形を柔らかく表現できます。
{
"id": "hillshade",
"type": "hillshade",
"source": "terrain-dem",
"paint": {
"hillshade-method": "multidirectional",
"hillshade-exaggeration": 0.4,
"hillshade-illumination-anchor": "map",
"hillshade-shadow-color": "rgba(30,40,80,0.45)",
"hillshade-highlight-color": "rgba(255,240,200,0.4)"
}
}
照射方向を変えた複数の hillshade レイヤーを重ねないでください。 GL JS 5.5 以前は、多方向の陰影を得る唯一の方法でした。それ以降は、同じ DEM に対する追加の描画パスを N 回行う代わりに、1つのペイントプロパティで実現できます。真っ黒な影と真っ白なハイライトも、コントラストを強める要因です。どちらにもアルファ値を設定し、画像上では暖色系のハイライトと寒色系の影を使いましょう。
カラーレリーフ:標高による色分け
color-relief(GL JS 5.6)は、raster-dem ソースをクライアント側で直接着色します。事前レンダリングの手順はなく、raster レイヤーも使用しません。ペイントプロパティは color-relief-color、color-relief-opacity(デフォルトは 1)、および GL JS 5.20 から追加された resampling です。[1] カラースケールは ["elevation"] に対する interpolate 式です。この値は DEM の垂直基準面からの標高をメートル単位で返し、color-relief-color 内でのみ有効です。[2]
{
"id": "hypsometric",
"type": "color-relief",
"source": "terrain-dem",
"paint": {
"color-relief-color": [
"interpolate",
["linear"],
["elevation"],
0,
"#2c7bb6",
500,
"#abd9e9",
1500,
"#ffffbf",
2500,
"#fdae61",
4000,
"#ffffff"
],
"color-relief-opacity": 0.8
}
}
MapLibre には raster-color、raster-value、raster-color-mix はありません。これらは別のレンダラーのプロパティであり、不明なプロパティとして破棄されます。DEM を指定した raster レイヤーには、色合いではなくパックされた RGB が表示されます。
ランタイムでの等高線
maplibre-contour は、同じ DEM タイルから Web Worker 内でベクター等高線タイルを生成し、登録済みプロトコルを通じて提供します。等高線タイルセットを作成する必要はありません。[3]
import mlcontour from 'maplibre-contour';
const demSource = new mlcontour.DemSource({
url: 'https://tiles.mapterhorn.com/{z}/{x}/{y}.webp',
encoding: 'terrarium',
maxzoom: 12,
worker: true
});
demSource.setupMaplibre(maplibregl);
map.addSource('contours', {
type: 'vector',
tiles: [
demSource.contourProtocolUrl({
thresholds: { 11: [200, 1000], 12: [100, 500], 14: [50, 200] },
elevationKey: 'ele',
levelKey: 'level',
contourLayer: 'contours'
})
],
maxzoom: 15
});
map.addLayer({
id: 'contour-lines',
type: 'line',
source: 'contours',
'source-layer': 'contours',
paint: { 'line-color': 'rgba(0,0,0,0.4)', 'line-width': ['match', ['get', 'level'], 1, 1.2, 0.6] }
});
thresholds はズームごとに [minor, major] の間隔をメートル単位で指定します。level は主要な等高線で 1 となり、線幅やラベルレイヤーのキーとして使用されます。[3] ここでの encoding は、スタイルのソースで指定したものと完全に一致させる必要があります。
3D 地形、カメラ、空
map.addSource('terrain-dem', { type: 'raster-dem', url: 'https://tiles.mapterhorn.com/tilejson.json' });
map.setTerrain({ source: 'terrain-dem', exaggeration: 1 });
map.setSky({
'sky-color': '#199EF3',
'sky-horizon-blend': 0.5,
'horizon-color': '#ffffff',
'horizon-fog-blend': 0.5,
'fog-color': '#0000ff',
'fog-ground-blend': 0.5
});
terrainが受け取るのはsourceとexaggerationのみです(デフォルトは1)。[4] スタイルのルートレベルにあるオブジェクトで、スタイル内またはmap.setTerrain()で設定します。無効にするにはmap.setTerrain(null)を呼び出します。- 地形を見えるようにするのはピッチです。
pitch: 0では、押し出された地表を真上から見るため、平坦に見えます。地形に問題があると判断する前に、マップのpitchを設定する(またはmap.easeTo({ pitch: 60 })を呼び出す)必要があります。平坦に見えるマップを直すためにexaggerationを上げるのではなく、カメラを傾けてから上げてください。 - MapLibre に
skyレイヤータイプはありません。 レイヤータイプはfill、line、symbol、circle、heatmap、fill-extrusion、raster、hillshade、color-relief、backgroundです。[1] Sky はルートレベルのskyオブジェクト、またはmap.setSky()で設定します。プロパティはsky-color、horizon-color、fog-color、sky-horizon-blend、horizon-fog-blend、fog-ground-blend、atmosphere-blendです。[5]sky-type、sky-atmosphere-sun、sky-atmosphere-sun-intensityは Mapbox GL JS のプロパティであり、ここでは機能しません。fog-colorには 3D 地形が必要です。[5] - Fog は
skyの一部です。 MapLibre GL JS にはsetFogメソッドもルートレベルのfogオブジェクトもありません。かすみはskyのfog-color、horizon-fog-blend、fog-ground-blendで設定します。[5] [6] - 地形が有効になると、
map.queryTerrainElevation(lngLat)は指定した位置の標高を返します。[6]
コスト。 地形では DEM タイルをデコードしてメッシュを構築し、その上にドレープされたすべてのレイヤーを再描画するため、このページで最も負荷の高い処理です。低性能のデバイスでは、高ズームかつ高ピッチで特に顕著になります。地形のレイヤースタックは小さく保ち、共有する raster-dem ソースを 1 つ、標高レイヤーを 1~2 つ、必要なオーバーレイのみを使用してください。
関連スキル
- maplibre-cartography — ヒルシェードレイヤーをレイヤー順のどこに配置するか、およびレリーフ上でも見やすい配色について説明します。
- maplibre-pmtiles-patterns — 1 つの PMTiles ファイルから DEM タイルと画像タイルを配信する方法について説明します。
参考資料
- スタイル仕様:レイヤー —
hillshadeとcolor-reliefのペイントプロパティ、デフォルト値、hillshade-methodの値、およびレイヤータイプの完全な一覧 — https://maplibre.org/maplibre-style-spec/layers/ - スタイル仕様:式 —
["elevation"]。color-relief-colorでのみ有効です — https://maplibre.org/maplibre-style-spec/expressions/ maplibre-contour—DemSource、setupMaplibre、contourProtocolUrl— https://github.com/onthegomap/maplibre-contour- スタイル仕様:地形 — https://maplibre.org/maplibre-style-spec/terrain/
- スタイル仕様:空 — https://maplibre.org/maplibre-style-spec/sky/
- GL JS
MapAPI —setTerrain、setSky、queryTerrainElevation— https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/ - 例 — 3D 地形、空、フォグ、地形、カラーリリーフ、等高線、多方向ヒルシェード
このスキルはスナップショットです。 主要な情報源(上記の参考資料、MapLibre の最新ドキュメント、または MapLibre の実行時の挙動)と内容が矛盾する場合は、そちらを優先してください。その情報源に従ったうえで、情報源と MapLibre のバージョンを明記して不一致を報告してください。インストール済みのコピーを編集してもほかの人の役には立たず、次回の更新で上書きされます。