mcpField
M
mapbox-google-maps-migration

mapbox-google-maps-migration

github.com/mapbox開発831.4k 回インストール4 週間前に更新
リポジトリ

mapbox-google-maps-migration について

Google Maps Platform から Mapbox GL JS へ移行する開発者向けのガイドです。API 対応表、実装パターンの変換、移行手順、注意点をまとめています。

主な機能

  1. 01Google Maps と Mapbox の API 対応表
  2. 02イベントと座標変換の解説
  3. 03マーカー、ポップアップ、レイヤーの移行
  4. 04段階的な移行とテストの指針
  5. 05注意点とパフォーマンス改善の案内

活用シーン

  1. 01既存アプリの Google Maps を置き換える
  2. 02マーカー、ポップアップ、イベント処理を変換する
  3. 03座標順序とデータレイヤー更新に対応する
  4. 04移行範囲を把握してテストを計画する

インストール

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

$npx skills add https://github.com/mapbox/mapbox-agent-skills --skill mapbox-google-maps-migration

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

AGENTS.md
evals/
evals.json
references/
api-services.md
clustering-styling.md
data-performance.md
directions-controls.md
shapes-geocoding.md

詳細

Mapbox Google Maps 移行スキル

Google Maps Platform から Mapbox GL JS への移行に関する包括的なガイダンスです。API の対応関係、パターンの変換、移行を成功させるための戦略を提供します。

中核となる考え方の違い

Google Maps:命令型・オブジェクト指向
  • オブジェクト(Marker、Polygon など)を作成します
  • .setMap(map) でマップに追加します
  • セッターでプロパティを更新します
  • オブジェクトインスタンスに大きく依存します
Mapbox GL JS:宣言型・データ駆動型
  • データソースを追加します
  • レイヤー(視覚表現)を定義します
  • JSON でスタイルを設定します
  • オブジェクトのプロパティではなく、データを更新します

重要なポイント: Mapbox では、個々のオブジェクトではなく、すべてをデータとスタイルの組み合わせとして扱います。

マップの初期化

Google Maps
const map = new google.maps.Map(document.getElementById('map'), {
  center: { lat: 37.7749, lng: -122.4194 },
  zoom: 12,
  mapTypeId: 'roadmap' // or 'satellite', 'hybrid', 'terrain'
});
Mapbox GL JS
mapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN';
const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12', // or satellite-v9, outdoors-v12
  center: [-122.4194, 37.7749], // [lng, lat] - note the order!
  zoom: 12
});

主な違い:

  • 座標の順序: Google では {lat, lng}、Mapbox では [lng, lat] を使用します
  • 認証: Google ではスクリプトタグに API キーを指定し、Mapbox ではコード内でアクセストークンを使用します
  • スタイル設定: Google ではマップタイプを使用し、Mapbox ではスタイル URL 全体を使用します

API 対応表

マップのメソッド
Google MapsMapbox GL JS備考
map.setCenter(latLng)map.setCenter([lng, lat])座標の順序が逆です
map.getCenter()map.getCenter()LngLat オブジェクトを返します
map.setZoom(zoom)map.setZoom(zoom)動作は同じです
map.getZoom()map.getZoom()動作は同じです
map.panTo(latLng)map.panTo([lng, lat])アニメーション付きの移動
map.fitBounds(bounds)map.fitBounds([[lng,lat],[lng,lat]])境界の形式が異なります
map.setMapTypeId(type)map.setStyle(styleUrl)アプローチがまったく異なります
map.getBounds()map.getBounds()類似しています
マップイベント
Google MapsMapbox GL JS備考
google.maps.event.addListener(map, 'click', fn)map.on('click', fn)より簡潔な構文
event.latLngevent.lngLatイベントのプロパティ名
'center_changed''move' / 'moveend'イベント名が異なります
'zoom_changed''zoom' / 'zoomend'イベント名が異なります
'bounds_changed''moveend'直接対応するものはありません
'mousemove''mousemove'同じです
'mouseout''mouseleave'名前が異なります

マーカーとポイント

シンプルなマーカー

Google Maps:

const marker = new google.maps.Marker({
  position: { lat: 37.7749, lng: -122.4194 },
  map: map,
  title: 'San Francisco',
  icon: 'custom-icon.png'
});

// Remove marker
marker.setMap(null);

Mapbox GL JS:

// Create marker
const marker = new mapboxgl.Marker()
  .setLngLat([-122.4194, 37.7749])
  .setPopup(new mapboxgl.Popup().setText('San Francisco'))
  .addTo(map);

// Remove marker
marker.remove();
複数のマーカー

Google Maps:

const markers = locations.map(
  (loc) =>
    new google.maps.Marker({
      position: { lat: loc.lat, lng: loc.lng },
      map: map
    })
);

Mapbox GL JS(同等の方法):

// Same object-oriented approach
const markers = locations.map((loc) => new mapboxgl.Marker().setLngLat([loc.lng, loc.lat]).addTo(map));

Mapbox GL JS(データ駆動型の方法 — 100 個以上のポイントに推奨):

// Add as GeoJSON source + layer (uses WebGL, not DOM)
map.addSource('points', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: locations.map((loc) => ({
      type: 'Feature',
      geometry: { type: 'Point', coordinates: [loc.lng, loc.lat] },
      properties: { name: loc.name }
    }))
  }
});

map.addLayer({
  id: 'points-layer',
  type: 'circle', // or 'symbol' for icons
  source: 'points',
  paint: {
    'circle-radius': 8,
    'circle-color': '#ff0000'
  }
});

パフォーマンス上の利点: Google Maps では、Data Layer を使用する場合でも、すべてのマーカーが DOM 要素として描画されるため、500 個を超えるマーカーでは処理が遅くなります。Mapbox の円レイヤーとシンボルレイヤーは WebGL で描画されるため、大規模なデータセット(1,000~10,000 個以上のポイント)をより高速に処理できます。多数のポイントを扱うアプリケーションの構築において、これは大きな利点です。

情報ウィンドウ/ポップアップ

Google Maps
const infowindow = new google.maps.InfoWindow({
  content: '<h3>Title</h3><p>Content</p>'
});

marker.addListener('click', () => {
  infowindow.open(map, marker);
});
Mapbox GL JS
// Option 1: Attach to marker
const marker = new mapboxgl.Marker()
  .setLngLat([-122.4194, 37.7749])
  .setPopup(new mapboxgl.Popup().setHTML('<h3>Title</h3><p>Content</p>'))
  .addTo(map);

// Option 2: On layer click (for data-driven markers)
map.on('click', 'points-layer', (e) => {
  const coordinates = e.features[0].geometry.coordinates.slice();
  const description = e.features[0].properties.description;

  new mapboxgl.Popup().setLngLat(coordinates).setHTML(description).addTo(map);
});

移行戦略

ステップ 1:現在の実装を監査する

使用している Google Maps の機能をすべて特定します。

  • 基本的な地図とマーカー
  • 情報ウィンドウ/ポップアップ
  • ポリゴン/ポリライン
  • ジオコーディング
  • ルート案内
  • クラスタリング
  • カスタムスタイル
  • 描画ツール
  • ストリートビュー(Mapbox に相当する機能はありません)
  • その他の高度な機能
ステップ 2:Mapbox をセットアップする

<script src="https://api.mapbox.com/mapbox-gl-js/v3.18.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v3.18.1/mapbox-gl.css" rel="stylesheet" />
ステップ 3:基本的な地図を変換する

まず、基本的な地図の初期化から始めます。

  1. new google.maps.Map() を new mapboxgl.Map() に置き換えます
  2. 座標の順序を修正します(lat,lng → lng,lat)
  3. ズームと中心を更新します
ステップ 4:機能を 1 つずつ変換する

複雑さに応じて優先順位を付けます。

  1. 簡単: 地図コントロール、基本的なマーカー
  2. 中程度: ポップアップ、ポリゴン、線
  3. 複雑: クラスタリング、カスタムスタイル、データ更新
ステップ 5:イベントハンドラーを更新する

イベント構文を変更します。

  • google.maps.event.addListener() → map.on()
  • イベントのプロパティ名を更新します(latLng → lngLat)
ステップ 6:Mapbox 向けに最適化する

Mapbox の機能を活用します。

  • 複数のマーカーをデータ駆動型レイヤーに変換します
  • クラスタリング(組み込み)を使用します
  • ベクタータイルを活用してカスタムスタイルを設定します
  • 動的なスタイル設定には式を使用します
ステップ 7:徹底的にテストする
  • クロスブラウザーでのテスト
  • モバイルでのレスポンシブ対応
  • 実際のデータ量でのパフォーマンス
  • タッチ/ジェスチャー操作

注意点とよくある問題

座標の順序
// Google Maps
{ lat: 37.7749, lng: -122.4194 }

// Mapbox (REVERSED!)
[-122.4194, 37.7749]

座標の順序は必ず再確認してください!

イベントのプロパティ
// Google Maps
map.on('click', (e) => {
  console.log(e.latLng.lat(), e.latLng.lng());
});

// Mapbox
map.on('click', (e) => {
  console.log(e.lngLat.lat, e.lngLat.lng);
});
タイミングの問題
// Google Maps - immediate
const marker = new google.maps.Marker({ map: map });

// Mapbox - wait for load
map.on('load', () => {
  map.addSource(...);
  map.addLayer(...);
});
機能の削除
// Google Maps
marker.setMap(null);

// Mapbox - must remove both
map.removeLayer('layer-id');
map.removeSource('source-id');
ちらつきを抑えてデータを更新する

データを更新するために、レイヤーを削除して再追加することは絶対に避けてください。これにより WebGL リソースが再初期化され、目に見えるちらつきが発生します。代わりに、次の方法を使用します。

// ✅ Update data in place (no flash)
map.getSource('stores').setData(newGeoJSON);

// ✅ Filter existing data (GPU-side, fastest)
map.setFilter('stores-layer', ['==', ['get', 'category'], 'coffee']);

// ❌ BAD: remove + re-add causes flash
map.removeLayer('stores-layer');
map.removeSource('stores');
map.addSource('stores', { ... });
map.addLayer({ ... });

移行しないほうがよい場合

次の場合は、Google Maps を引き続き使用することを検討してください。

  • ストリートビューが不可欠な場合 — Mapbox に相当する機能はありません
  • Google Workspace との緊密な連携が必要な場合 — Places API が深く統合されています
  • すでに十分に最適化されている場合 — 移行コストがメリットを上回ります
  • チームの専門知識が十分でない場合 — 再トレーニングのコストが高すぎます
  • 短期プロジェクトの場合 — 移行にかける労力に見合いません

クイックリファレンス:左右に並べた比較

// GOOGLE MAPS
const map = new google.maps.Map(el, {
  center: { lat: 37.7749, lng: -122.4194 },
  zoom: 12
});

const marker = new google.maps.Marker({
  position: { lat: 37.7749, lng: -122.4194 },
  map: map
});

google.maps.event.addListener(map, 'click', (e) => {
  console.log(e.latLng.lat(), e.latLng.lng());
});

// MAPBOX GL JS
mapboxgl.accessToken = 'YOUR_TOKEN';
const map = new mapboxgl.Map({
  container: el,
  center: [-122.4194, 37.7749], // REVERSED!
  zoom: 12,
  style: 'mapbox://styles/mapbox/streets-v12'
});

const marker = new mapboxgl.Marker()
  .setLngLat([-122.4194, 37.7749]) // REVERSED!
  .addTo(map);

map.on('click', (e) => {
  console.log(e.lngLat.lat, e.lngLat.lng);
});

重要: Mapbox では lng, lat の順序です!

追加リソース

他のスキルとの連携

連携するスキル:

  • mapbox-web-integration-patterns:フレームワーク固有の移行ガイダンス
  • mapbox-web-performance-patterns:移行後の最適化
  • mapbox-token-security:Mapbox トークンを適切に保護する方法
  • mapbox-geospatial-operations:Mapbox の地理空間ツールを効果的に使用する方法
  • mapbox-search-patterns:ジオコーディング/検索機能の移行

参照ファイル

以下の参照ファイルには、特定のトピックに関する詳細な移行ガイドが記載されています。該当する領域で作業する際に読み込んでください。

  • references/shapes-geocoding.md — ポリゴン、ポリライン、カスタムアイコン、ジオコーディング
  • references/directions-controls.md — ルート案内/ルーティング、コントロール
  • references/clustering-styling.md — クラスタリング、スタイル/外観
  • references/data-performance.md — データ更新、パフォーマンス、一般的な移行パターン(店舗検索、描画ツール、ヒートマップ)
  • references/api-services.md — API サービスの比較、料金、プラグイン、フレームワーク連携、テスト、移行チェックリスト

参照ファイルを読み込むには、次のように、このスキルのディレクトリからの相対パスでファイルを読み込みます。

Load references/shapes-geocoding.md

コメント