mcpField
M
maplibre-source-wiring

maplibre-source-wiring

github.com/maplibre開発155270 回インストール今日更新
リポジトリ

maplibre-source-wiring について

MapLibre の開発者向けに、データソースとマップスタイルの接続方法を解説します。タイル参照、レイヤースキーマ、アセット設定に加え、空白マップなどの原因調査も扱います。

主な機能

  1. 01TileJSON URL とタイルテンプレートの選択
  2. 02ベクタータイルの source-layer 名の確認
  3. 03レイヤーの描画順序の制御
  4. 04グリフとスプライトの設定
  5. 05ラスタータイルとフィーチャーステートの診断
  6. 06クロスオリジンリクエストの確認

活用シーン

  1. 01空白マップや未描画レイヤーの調査
  2. 02カスタムデータのマップスタイルへの追加
  3. 03ベースマップの縮尺やレイヤー順序の修正
  4. 04アイコン欠落、ホバー状態、タイル読み込みの診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/maplibre/maplibre-agent-skills --skill maplibre-source-wiring

インストール後、Claude Code で/maplibre-source-wiringを入力して読み込まれたか確認します。

詳細

MapLibre ソースの接続

タイル URL またはデータファイルとスタイルがあるのに、地図が真っ白になる、縮尺が合わない、あるいは描画順序が正しくない場合があります。このスキルでは、ソースをスタイルに正しく接続する方法と、外から見ると同じように見えるさまざまな失敗モードを説明します。

このスキルを使う場面

ソースはすでに設定済みなのに、エラーが出ないまま地図が正しく表示されない場合に使います。原因が分かる前に確認できる症状は次のとおりです。

  • 地図が真っ白になる、または追加したレイヤーが何も描画せず、コンソールにもエラーがない
  • プロバイダー独自のスタイルでは動作するタイルソースに、カスタムスタイルを適用しても何も描画されない
  • ベースマップがぼやけている、または上に重ねたすべての要素と縮尺が異なる
  • 追加したデータが道路名を覆ってしまう
  • 地図のほかの部分は正常に描画されるのに、アイコンだけが表示されない
  • ホバーやクリックによるハイライトがまったく動作せず、エラーも発生しない
  • タイルエンドポイントはあるものの、どのソースタイプが必要なのか、あるいは tiles を手書きする代わりに url で TileJSON を指定するべきなのか分からない

このスキルの対象外です。 フォントが正しく表示されない、スクリプトが見つからない、glyph PBF をセルフホストする場合は、maplibre-fonts-glyphs を参照してください。設計中のスタイルの色、種類、描画順序を決める場合は、maplibre-cartography を参照してください。データセットを GeoJSON とベクタータイルのどちらで扱うべきかを決める場合は、maplibre-tile-sources を参照してください。

タイルの指定方法:url と tiles

タイルはズーム(Z)、列(X)、行(Y)で指定します。これはラスタータイルとベクタータイルのソースに共通する方式です。詳しくはOpenStreetMap の Wikiを参照してください。MapLibre のソースでは、tiles の URL テンプレートでタイルを直接指定するか、TileJSON エンドポイントを指す url を指定します。

TileJSON エンドポイントが利用できる場合は、url を優先してください。 MapLibre はドキュメントを取得し、タイル URL テンプレート、ズーム範囲、範囲、帰属表示、さらにベクタータイルの場合は利用可能な source-layer を自動的に読み込みます。Martin や tileserver-gl などのタイルサーバーは、配信する各タイルセットの TileJSON エンドポイントを生成します。多くのホスト型プロバイダーも同様です。

TileJSON エンドポイントがない場合、たとえば URL テンプレートを直接提供するラスタータイルサービスでは、tiles 配列を使い、minzoom、maxzoom、帰属表示などのメタデータをソース定義に自分で指定してください。

TileJSON エンドポイントを指す url:

{
  "type": "vector",
  "url": "https://example.com/tiles.json"
}

tiles 配列:

{
  "type": "vector",
  "tiles": ["https://example.com/tiles/{z}/{x}/{y}.pbf"],
  "minzoom": 0,
  "maxzoom": 14
}

{z}、{x}、{y} は、リクエストを行う前に MapLibre が各タイルのズーム、列、行に置き換えるトークンです。波括弧が残ったままのテンプレートをブラウザーに貼り付けても、実際のタイルはリクエストされないため、ステータスコードからサーバーの状態は分かりません。サーバーを手動で確認するには、/0/0/0.pbf のように、ソースのズーム範囲内にある実際のタイルをリクエストしてください。

tiles を手動で設定する場合の問題は、ズーム範囲を指定しないと MapLibre がその範囲を認識できず、maxzoom: 22 を前提にすることです。その結果、タイルセットに存在しないズームレベルをリクエストし、空のレスポンスが返されます。このため、TileJSON エンドポイントがある場合は url を使うのが基本です。(PMTiles でも同じルールが当てはまり、結果はさらに顕著になります。詳しくは maplibre-pmtiles-patterns を参照してください。)

何も表示されない場合:source-layerとタイルスキーマ

動作しているタイルソースにカスタムスタイルを適用しても何も表示されない場合、最もよくある原因はsource-layerの不一致です。

ベクタータイルソースには、transportation、water、landuseなどの名前付きレイヤーが含まれており、そのソースから描画するスタイルレイヤーには、いずれかの名前を正確に指定する必要があります。

{
  "id": "roads",
  "type": "line",
  "source": "basemap",
  "source-layer": "transportation"
}

ベクターソースではsource-layerが必須で、タイルスキーマと完全に一致している必要があります。入力ミスや別のスキーマのレイヤー名を指定しても、エラーも出力も発生せず、そのレイヤーは何も描画しません。

TileJSONで実際の名前を確認します。 ベクターソースの場合、TileJSONのvector_layersフィールドには、利用可能な各source-layer、その属性フィールド、ズーム範囲が記載されています。これは存在する場合に信頼できる参照先です。TileJSON 3.0ではベクタータイルセットに必須ですが、2.xのドキュメントはこの要件より前のものであり、プロバイダーによって提供状況にばらつきがあります。これがなくてもスキーマが存在しないわけではありません。スキーマ名(以下を参照)を特定し、公開されているレイヤー一覧を参照してください。プロバイダーの既成スタイルURLを使う場合、スキーマはすでに適切に設定されています。不一致が起きるのは、自分でレイヤーを記述した場合だけです。

定義済みのタイルスキーマ

カスタムスタイルを作成するには、タイルスキーマ、つまりソースレイヤー名とそのプロパティを把握する必要があります。一般的なスキーマは次のとおりです。

  • OpenMapTiles — OpenStreetMapデータを基にした、最も広く採用されているスキーマです。豊富で詳細な構成で、transportation、water、landuse、poiなどのソースレイヤーがあります。コミュニティスタイルのエコシステムが最も充実しており、多くのスタイルがこのスキーマを対象としています。
  • Shortbread — 特定のベンダーに依存しない、最小限で相互運用可能な設計のオープン標準です。OpenMapTilesよりもシンプルな構造で、スタイルをゼロから作成する場合のすっきりした基盤になります。
  • Protomaps — Protomaps PMTilesのベースマップエコシステム向けに特化して設計されています。earth、water、roads、placesなどのソースレイヤーを持つ、フラットでシンプルな構造で、サーバーレス配信に最適化されています。公開レイヤー一覧:docs.protomaps.com/basemaps/layers。

これらはいずれも、ドキュメントとしてレイヤー一覧を公開しています(「参考資料」を参照)。機械で読み取り可能なバージョンマーカーを備えたものはないため、スキーマを確認するにはページを再度読み込む必要があり、変更を定期的に確認することもできません。

Planetilerやtippecanoeでタイルを生成すると、出力ファイルのMBTilesまたはPMTilesにTileJSONメタデータが埋め込まれます。Martinのようなタイルサーバーはこのメタデータを読み取り、TileJSONエンドポイントとして自動的に公開します。

レイヤーの順序:ラベルの下に描画する

レイヤーは、スタイルに記述された順に下から上へ描画されます。第2引数なしでmap.addLayer()を呼び出すと、そのレイヤーはすべての要素の上に追加され、道路名も覆ってしまいます。そのため、この方法で追加したデータオーバーレイはベースマップのラベルを隠します。対処するには、最初のsymbolレイヤーのIDをaddLayerの第2引数に渡します。IDはハードコードせず、プログラムで取得してください(road-labelなどの名前はスキーマ固有のため、ベースマップを変更した時点で機能しなくなります)。ベクターレイヤーの後に追加したラスターレイヤーも、同じ理由でそれらを覆い隠します。

挿入パターンの詳しい説明と、スタイルをゼロから作成する場合の標準的なレイヤー順序については、maplibre-cartographyを参照してください。

ラベルとアイコンが表示されない場合:glyphs と sprite

スタイルルートの 2 つのプロパティで、シンボルレイヤーの描画に使用するアセットを指定します。

  • glyphs — フォントスタックの URL テンプレートです:"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf"
  • sprite — スプライトシートとメタデータのベース URL で、.json と .png の両方を提供します:"sprite": "https://example.com/sprites/basic"

ホスト型プロバイダーの既成スタイル URL には、これらが含まれています。カスタムスタイルを作成する場合やセルフホストする場合は、自分で指定する必要があります。

この 2 つは未設定時の挙動が異なり、その違いから症状を逆にたどって原因を特定できます。 GL JS 5.11.0 以降では、glyphs が未設定でもテキストは消えません。MapLibre は代わりにローカルのシステムフォントで描画するため、テキストが表示されないのではなく、異なる書体で表示されます。ラベルが表示されているものの見た目が違う場合は glyphs を確認してください。完全に表示されない場合は該当しません。sprite が未設定の場合、アイコンが見つからないたびにコンソール警告(Image "<id>" could not be loaded)が記録され、アイコンは一切描画されません。map.hasImage(id) はそれぞれ false を返します。sprite の URL の読み込みに失敗した場合も、エラーが記録されます。

フォールバックの仕組みと制限(GL JS のみが対象で、Native では引き続き PBF の配信が必要です)、フォントスタック、セルフホストと生成の違い、スクリプトの対応状況については、maplibre-fonts-glyphs を参照してください。

ラスターソース:tileSize と命名に関する落とし穴

ラスター固有の注意点が 2 つあります。どちらもエラーなしで設定できますが、誤った描画や誤った前提につながります。

tileSize のデフォルトは 512 です。従来の OSM タイルは 256 です。 tile.openstreetmap.org やその他の従来型スリッピーマップタイルサーバーは 256px のタイルを配信しますが、MapLibre のラスター tileSize のデフォルトは 512px です。256px のソースに tileSize: 256 を指定しなくてもエラーにはなりませんが、有効なズームレベルがずれて描画され、画像とラベルが 1 ズームレベルずれて表示されます。エラーや警告はありません。

{
  "type": "raster",
  "tiles": ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"],
  "tileSize": 256
}

ラスターエンドポイントの名前は、その種類を示すものではありません。 「hillshade」や「terrain」などの名前が付いたエンドポイントが、必ずしも raster-dem ソースとは限りません。raster-dem では、タイルが PNG または WebP 内にピクセルパックされた RGB として標高をエンコードしている必要があります(Mapbox または Terrarium エンコーディング)。TileJSON に encoding フィールドがある場合は、その値でエンコーディングの種類を確認できます。そのエンコーディングを保持できないタイル形式(たとえば JPEG)で、encoding フィールドもない場合、エンドポイント名にかかわらず通常の raster 画像です。「hillshade」エンドポイントは、多くの場合、MapLibre がクライアント側で陰影を付けるための生の標高データではなく、あらかじめレンダリングされた陰影起伏図の 画像 です。名前を raster-dem の根拠とする前に、タイル形式と encoding フィールドの有無を確認してください。

フィーチャーの状態:ソースには id が必要で、通常は promoteId で設定します

setFeatureState と feature-state 式は、フィーチャーの id(フィーチャーオブジェクトのトップレベルメンバーであり、properties 内の値ではありません)をキーにします。フィーチャーに id がないソースでは、setFeatureState が状態を紐付ける対象がないため、エラーが表面化せずに失敗します。コンソールエラーは出ず、ペイント式も実行されず、getFeatureState は空を返します。

すでにキーとして使っているプロパティを promoteId に設定してください。 MapLibre にそのプロパティをフィーチャーの id として使わせる設定であり、識別子が properties にある場合の正しい方法です。

map.addSource('parcels', {
  type: 'geojson',
  data: parcels,
  promoteId: 'parcel_id'
});
map.setFeatureState({ source: 'parcels', id: 'APN-1234' }, { hover: true });

ベクターソースでは、promoteId に、すべてのソースレイヤーに適用されるプロパティ名を指定するか、{<sourceLayer>: <propertyName>} 形式のオブジェクトを指定します。[9]

業務キーがある場合は、generateId や手書きの id を使わないでください。 どちらも解決策のように見えますが、今回のケースではどちらも機能しません。

  • generateId: true は features 配列内のインデックスに基づいて id を割り当て、既存の値は上書きします。[9] setData によって並べ替え、フィルタリング、追加が行われると id が安定しないため、更新後に状態が誤ったフィーチャーへ気づかないうちに紐付けられます。
  • トップレベルの id を記述する方法が機能するのは、整数の場合だけです。promoteId を使わない場合、フィーチャーの id は「整数、または整数にキャストできる文字列」である必要があります。[9] APN-1234 のようなキーは受け入れられますが、一致することはありません。promoteId を使えば、値には任意のプリミティブ型を指定できます。

CORS

タイル、グリフ、スプライトが別のオリジンにある場合、サーバーは CORS ヘッダー(Access-Control-Allow-Origin)を送信する必要があります。そうしないとブラウザーがリクエストをブロックし、地図が空になったり、ラベルが表示されなかったりします。

ホスト型プロバイダーでは、CORS は自動的に処理されます。セルフホスト型サーバーや静的ストレージでは、サーバーまたは CDN で CORS を設定してください。範囲リクエストを使うソース(PMTiles)では、さらに Access-Control-Allow-Headers: Range が必要です。

空白の地図を診断する

以下のリストを順に確認してください。各症状は重なり合うことがよくあります。

症状最初に確認する項目
何も表示されず、ネットワークに失敗したリクエストがあるCORS ヘッダー、タイル URL 自体(ネットワークタブの 404)
何も表示されず、ネットワークに 200 が表示されるsource-layer 名と TileJSON の vector_layers の照合
ズームインするとタイルが表示された後に消える手動で設定した tiles ソースにズーム範囲がない。代わりに url を使う
タイルは表示されるが、テキストのフォントが違うglyphs がない、またはその URL の読み込みに失敗している
タイルは表示されるが、テキストがまったく表示されないどのシンボルレイヤーにも text-field がない、または GL JS が 5.11 より古い
タイルは表示されるが、アイコンがないスタイルのルートに sprite がない
データは描画されるが、ラベルが隠れるレイヤーの順序。最初の symbol レイヤーより前に挿入する
ベクターソースは何も描画されないが、ラスタは正常source-layer がまったくない。ベクターソースでは必須
ラスタータイルのズームレベルが 1 段ずれる従来型の 256px ソースで tileSize: 256 がない(デフォルトは 512)
setFeatureState が何もせず、エラーも出ないフィーチャーに id がない。識別プロパティを promoteId に設定する

関連スキル

  • maplibre-tile-sources — データセットに GeoJSON とタイルのどちらを選ぶか。
  • maplibre-pmtiles-patterns — pmtiles:// プロトコルの登録と、PMTiles 固有のソース設定。
  • maplibre-fonts-glyphs — フォントスタック、グリフエンドポイント、文字体系のカバレッジ。
  • maplibre-sprites-icons — sprite URL の形式、複数のシートの読み込み、スプライトアセットのセルフホスト、ルートシールド。
  • maplibre-cartography — レイヤー注入パターンの詳細と、カスタムスタイルの標準的なレイヤー順序。

参考資料

  1. MapLibre スタイル仕様 — maplibre.org/maplibre-style-spec/
  2. TileJSON 仕様 — GitHub の仕様リポジトリ。バージョン 3.0(2021 年 8 月)では、ベクタータイルセットに vector_layers が必須になりました
  3. スリッピーマップのタイル命名規則(Z/X/Y 方式) — OpenStreetMap wiki
  4. OpenMapTiles スキーマ — openmaptiles.org/schema/
  5. Shortbread タイルスキーマ — shortbread-tiles.org
  6. Protomaps ベースマップレイヤー — docs.protomaps.com/basemaps/layers
  7. Martin タイルサーバー(TileJSON エンドポイント)— maplibre.org/martin/
  8. MapLibre GL JS ドキュメント — maplibre.org/maplibre-gl-js/docs/
  9. promoteId、generateId、feature-state — スタイル仕様:sources および expressions

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

コメント