mcpField
M
maplibre-terrain-rendering

maplibre-terrain-rendering

github.com/maplibreデザイン・UI155207 回インストール今日更新
リポジトリ

maplibre-terrain-rendering について

DEM 地形を描画する MapLibre 開発者向けのガイドです。陰影起伏、高度による着色、実行時の等高線、3D 地形と空の設定、性能上の注意点を説明します。

主な機能

  1. 01陰影起伏の設定
  2. 02標高に応じた地形の着色
  3. 03maplibre-contour による等高線生成
  4. 043D 地形、カメラ、空の設定
  5. 05地形描画の負荷の把握

活用シーン

  1. 01地形陰影の強さの調整
  2. 02標高別に着色したマップの作成
  3. 03実行時の等高線描画
  4. 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 タイルと画像タイルを配信する方法について説明します。

参考資料

  1. スタイル仕様:レイヤー — hillshade と color-relief のペイントプロパティ、デフォルト値、hillshade-method の値、およびレイヤータイプの完全な一覧 — https://maplibre.org/maplibre-style-spec/layers/
  2. スタイル仕様:式 — ["elevation"]。color-relief-color でのみ有効です — https://maplibre.org/maplibre-style-spec/expressions/
  3. maplibre-contour — DemSource、setupMaplibre、contourProtocolUrl — https://github.com/onthegomap/maplibre-contour
  4. スタイル仕様:地形 — https://maplibre.org/maplibre-style-spec/terrain/
  5. スタイル仕様:空 — https://maplibre.org/maplibre-style-spec/sky/
  6. GL JS Map API — setTerrain、setSky、queryTerrainElevation — https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/
  7. 例 — 3D 地形、空、フォグ、地形、カラーリリーフ、等高線、多方向ヒルシェード

このスキルはスナップショットです。 主要な情報源(上記の参考資料、MapLibre の最新ドキュメント、または MapLibre の実行時の挙動)と内容が矛盾する場合は、そちらを優先してください。その情報源に従ったうえで、情報源と MapLibre のバージョンを明記して不一致を報告してください。インストール済みのコピーを編集してもほかの人の役には立たず、次回の更新で上書きされます。

コメント