google-maps-api について
google-maps-apiは、Google Maps Platform REST APIを呼び出し、構造化JSONを取得するコマンドラインスキルです。地図、ルート、場所、環境、地理空間サービスを扱い、APIキーと対象APIの有効化が必要です。
主な機能
- 01住所や座標をジオコーディング
- 02場所を検索して詳細を取得
- 03ルートと距離マトリックスを取得
- 04天気、大気質、花粉を照会
- 05標高、太陽光、道路データを取得
- 06静的マップとStreet View画像を生成
活用シーン
- 01場所を探して詳細を確認
- 02ルートを計画し移動距離を比較
- 03地域の天気や環境状況を確認
- 04住所の検証とGPS軌跡の処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tivojn/ google-maps-api-skill --skill google-maps-apiインストール後、Claude Code で/google-maps-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.env.example.gitignoreREADME.md.claude-plugin/plugin.jsonexamples/trip-plan-example.htmlscripts/gmaps.py詳細
Google Maps Platform - Universal API Skill
重要な動作ルール
このスキルでは、以下のルールがほかのすべての指示に優先します:
-
問題が発生したら、すぐに伝えてください。 API 呼び出しが失敗した場合(403、REQUEST_DENIED、「有効化されていない」など)、処理を止め、何が起きたかを分かりやすい言葉でユーザーに伝えてください。ウェブ検索やほかの代替手段で、黙って回避してはいけません。Playwright を使って解決する方法を提案してください(下記の「API の有効化をガイドする」セクションを参照)。
-
HTML の生成前に確認してください。 ユーザーに確認せず、HTML ページの作成を始めてはいけません。ユーザーはテキストでの回答、JSON 出力、簡単な要約を求めているだけかもしれません。「これについてインタラクティブな HTML ページを作成しますか?それともテキストでの要約で十分ですか?」と尋ねてください。
-
出力形式を選ぶ前に確認してください。 ユーザーの依頼に対して、テキスト、JSON、ビジュアルページのいずれでも回答できる場合は、どれを希望するか尋ねてください。決めつけないでください。
概要
Google Maps Platform のすべての REST API に対応する、フル機能の CLI クライアントです。ブラウザベースの google-maps スキルとは異なり、このスキルは Google の API を直接呼び出すため、高速で構造化された JSON レスポンスを取得できます。マップ、ルート、場所、環境、地理空間サービスにわたる 20 以上の API に対応しています。
セットアップ
1. Google Maps API キーを取得する
- Google Cloud Console にアクセスします
- プロジェクトを作成するか、選択します
- 必要な API を有効にします(下記の API 一覧を参照)
- API とサービス > 認証情報に移動し、API キーを作成します
- (推奨)キーを必要な API のみに制限します
2. API キーを保存する
以下の場所のいずれかにある .env ファイルに追加します(上から順に検索されます):
# Option 1: Project directory .env
echo 'GOOGLE_MAPS_API_KEY=your_key_here' >> .env
# Option 2: Home directory .env
echo 'GOOGLE_MAPS_API_KEY=your_key_here' >> ~/.env
# Option 3: Environment variable
export GOOGLE_MAPS_API_KEY=your_key_here
3. 必要な API を有効にする
Google Cloud Console > API とサービス > ライブラリで、必要な API を有効にします:
| API 名 | コンソール上の名称 |
|---|---|
| ジオコーディング | Geocoding API |
| ルート | Routes API |
| 場所 | Places API (New) |
| 標高 | Elevation API |
| タイムゾーン | Time Zone API |
| 大気質 | Air Quality API |
| 花粉 | Pollen API |
| 太陽光 | Solar API |
| 天気 | Weather API |
| 住所検証 | Address Validation API |
| 道路 | Roads API |
| ストリートビュー | Street View Static API |
| 静的マップ | Maps Static API |
| 位置情報 | Geolocation API |
| 航空写真ビュー | Aerial View API |
| ルート最適化 | Route Optimization API |
| 場所の集計 | Places Insights API |
スクリプトの場所
~/.claude/skills/google-maps-api/scripts/gmaps.py
外部依存関係は不要です。Python 標準ライブラリ(urllib、json、ssl)のみを使用します。
API リファレンス全体
1. ジオコーディング
フォワードジオコーディング - 住所から座標を取得:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geocode "1600 Amphitheatre Parkway, Mountain View, CA"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geocode "Tokyo Tower" --language ja --region jp
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geocode "Paris" --components "country:FR"
リバースジオコーディング - 座標から住所を取得:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py reverse-geocode 37.4224 -122.0856
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py reverse-geocode 48.8584 2.2945 --language fr
2. ルートと経路案内
2 つの地点間の経路案内を取得:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "New York, NY" "Boston, MA"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "LAX" "SFO" --mode transit
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "Seattle" "Portland" --alternatives --avoid-tolls
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "A" "D" --waypoints "B" "C"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "Home" "Work" --mode bicycling --units imperial
距離マトリックス - 複数の出発地と目的地:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py distance-matrix \
--origins "New York" "Boston" \
--destinations "Philadelphia" "Washington DC"
3. 場所
テキスト検索 - クエリで場所を検索:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "best pizza in Chicago"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "pharmacy" --location "40.714,-74.006" --radius 1000
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "5-star hotels" --min-rating 4.5 --open-now
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "EV charging" --type "electric_vehicle_charging_station"
周辺検索 - 座標付近の場所を検索:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-nearby 40.7128 -74.0060 --type restaurant --radius 800
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-nearby 34.0522 -118.2437 --type cafe --max-results 5
場所の詳細 - 場所の詳しい情報:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py place-details ChIJN1t_tDeuEmsRUsoyG83frY4
オートコンプリート - 入力中に候補を表示:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py autocomplete "star" --location "37.7749,-122.4194"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py autocomplete "central p" --types "park"
場所の写真 - 写真の URL を取得:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py place-photo "places/PLACE_ID/photos/PHOTO_REF" --max-width 800
4. 大気質
現在の状況:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality 40.7128 -74.0060 --health --pollutants
過去のデータ(最大 30 日間):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality-history 40.7128 -74.0060 --hours 48
予報(最大 96 時間):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality-forecast 40.7128 -74.0060
5. 花粉
花粉予報(最大 5 日間、草本/雑草/樹木):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py pollen 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py pollen 34.0522 -118.2437 --days 5
返される情報:3 種類の植物タイプと 15 種の植物についての、世界花粉指数(UPI)。
6. 太陽光
建物の太陽光発電ポテンシャル:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py solar 37.4219 -122.0841
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py solar 37.4219 -122.0841 --quality HIGH
返される情報:屋根の面積、日照時間、最適なパネル配置、エネルギー/コストの見積もり。
太陽光データレイヤー(DSM、フラックス、日陰ラスター):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py solar-layers 37.4219 -122.0841 --radius 100
7. 天気
現在の状況:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode current
時間ごとの予報(最大 240 時間):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode hourly --hours 48
日ごとの予報(最大 10 日間):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode daily --days 7
直近の履歴(最大 24 時間):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode history --hours 12
8. 標高
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py elevation 39.7392 -104.9903
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py elevation --locations "39.7392,-104.9903|36.4555,-116.8666"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py elevation --path "36.578,-118.292|36.606,-118.099" --samples 20
9. タイムゾーン
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py timezone 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py timezone 35.6762 139.6503 --language ja
10. 住所検証
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py validate-address "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py validate-address "123 Main St" --region US --enable-usps
返される情報:配達可能性の判定、修正済み住所、住所構成要素ごとの確認、USPS CASS データ。
11. 道路
道路にスナップ - GPS の軌跡を道路に合わせる:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py snap-roads "60.170,-24.942|60.171,-24.941|60.172,-24.940"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py snap-roads "60.170,-24.942|60.172,-24.940" --interpolate
最寄りの道路:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py nearest-roads "60.170,-24.942|60.171,-24.941"
12. ストリートビュー
CLI でのデータ利用(サーバー側で画像をダウンロード、料金は 1,000 件あたり $7):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py streetview --lat 46.414 --lng 10.013 --heading 90
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py streetview --location "Eiffel Tower, Paris" --size 800x600
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py streetview --pano CAoSLEFGMVFpcE... --output paris_sv.jpg
HTML ページの場合 — 代わりに必ず Google マップへの直接リンクを使用してください(料金ゼロ、キーの露出ゼロ):
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat},{lng}&heading={heading}&pitch=0&fov=90
詳細については、下記の「HTML でのストリートビュー」セクションをご覧ください。
警告: 古い省略形式 @{lat},{lng},3a,75y,{heading}h,90t は使用しないでください。この形式は信頼性が低く、ストリートビューではなく、ズームアウトされた世界地図が表示されることがよくあります。必ず上記の map_action=pano 形式を使用してください。
13. 静的マップ
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py static-map --lat 40.714 --lng -74.006 --zoom 13
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py static-map --center "Tokyo" --maptype satellite --zoom 12
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py static-map --center "NYC" --markers "color:red|40.714,-74.006" --size 800x600
14. ジオロケーション
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geolocation
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geolocation --wifi "00:11:22:33:44:55,-65" "66:77:88:99:AA:BB,-72"
15. 航空ビュー(米国のみ)
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py aerial-view check --address "1600 Amphitheatre Pkwy, Mountain View"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py aerial-view render --address "1600 Amphitheatre Pkwy, Mountain View"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py aerial-view get --video-id VIDEO_ID
16. ルート最適化
車両ルーティング問題(VRP)を解決します:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py route-optimize problem.json --project my-gcp-project
入力 JSON 形式:Google Route Optimization API 仕様に準拠した {"model": {"shipments": [...], "vehicles": [...]}}。
17. Places Aggregate(インサイト)
エリア内でフィルターに一致する場所の数を数えるか、一覧表示します:
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-aggregate --location "40.714,-74.006" --radius 5000 --type restaurant
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-aggregate --location "34.052,-118.244" --type cafe --min-rating 4.0 --insight INSIGHT_PLACES
18. Maps Embed URL(無料)
埋め込み可能な地図 URL を生成します(無料、無制限):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode place --query "Eiffel Tower"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode directions --origin "NYC" --destination "Boston"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode streetview --lat 46.414 --lng 10.013
Claude の使用パターン
ユーザーが位置情報、地理、環境に関する質問をした場合は、適切なコマンドを使用してください。
| ユーザーの意図 | コマンド |
|---|---|
| 「……はどこですか?」 | geocode |
| 「……の住所は何ですか?」 | reverse-geocode |
| 「A から B へはどう行けばよいですか?」 | directions |
| 「A から B までの距離はどれくらいですか?」 | distance-matrix |
| 「……の近くにあるレストランを探して」 | places-search または places-nearby |
| 「……の営業時間は?」 | place-details |
| 「……の空気質は?」 | air-quality |
| 「今日は花粉が多いですか?」 | pollen |
| 「……の天気は?」 | weather |
| 「この住所は有効ですか?」 | validate-address |
| 「……の標高は?」 | elevation |
| 「……のタイムゾーンは?」 | timezone |
| 「……の地図を見せて」 | static-map |
| 「屋根にソーラーパネルを設置できますか?」 | solar |
| 「配送ルートを最適化して」 | route-optimize |
| 「エリア内にコーヒーショップはいくつありますか?」 | places-aggregate |
インタラクティブ HTML の出力
重要:HTML を生成する前に、必ずユーザーに確認してください。 ユーザーの明示的な承認なしに、HTML ファイルの作成を開始してはいけません。結果をテキストで提示した後、次のように尋ねてください。
「ブラウザーで開けるインタラクティブな HTML ページにまとめましょうか?デフォルトのテーマは Warm Stone Sunrise(明るく、暖色系のプレミアムなテーマ)です。」
ユーザーが「はい」と答えた場合(または HTML、ページ、地図を明示的に依頼した場合)は、生成してください。返答がない場合や「いいえ」と答えた場合は、テキストまたは JSON の結果のみを提示してください。
デフォルトでは、Google Maps の埋め込み iframe(output=embed)を使用して、キー不要の HTML ページを生成してください — API キーは不要で、キーが露出するリスクもありません。埋め込みでは対応できない高度なインタラクティブ機能(カスタムマーカー、ポリライン、クラスタリングなど)をユーザーが明示的に求めた場合に限り、Maps JavaScript API(<script src="https://maps.googleapis.com/maps/api/js?key=...">)を使用してください。
ゼロキーの埋め込み iframe(デフォルト)
マップには次の iframe 形式を使用してください。API キーは不要で、無料です。
場所/スポットのマップ:
<iframe src="https://maps.google.com/maps?q=Oahu+Hawaii&z=10&output=embed"
width="100%" height="400" style="border:0" allowfullscreen></iframe>
ルート案内マップ:
<iframe src="https://maps.google.com/maps?saddr=Los+Angeles+CA&daddr=San+Jose+CA&output=embed"
width="100%" height="400" style="border:0" allowfullscreen></iframe>
パラメーター:
q— 場所の名前または住所(URL エンコードし、スペースには+を使用)saddr/daddr— ルート案内の出発地/目的地z— ズームレベル(1~20、デフォルトは約12)output=embed— 必須。埋め込み可能にしますll— 任意の中心座標lat,lng
警告: Google Maps の埋め込み iframe では loading="lazy" を使用しないでください。遅延読み込みにより、画面外の iframe の読み込みが妨げられ、画面下部にあるマップが永久に空白で表示されることがあります。loading 属性は常に省略するか、loading="eager" を使用してください。
| 結果の種類 | デフォルトの HTML 要素 |
|---|---|
| ストリートビュー | Google Maps への直接リンク(map_action=pano)— 新しいタブでインタラクティブなストリートビューを全画面表示します。「HTML でのストリートビュー」セクションを参照してください。 |
| ルート案内 | saddr/daddr と output=embed を使った埋め込み iframe |
| 場所の検索 | q=place+name と output=embed、情報カードを使った埋め込み iframe |
| 周辺の検索 | 位置を中心にした埋め込み iframe とスポットカード |
| 静的マップ | q と z を使った埋め込み iframe(ズームとドラッグが可能) |
| 天気/空気質 | 位置の埋め込み iframe と気象状況カード、アイコン、グラフ |
| 標高 | 標高プロファイルのグラフと、経路マーカー付きの埋め込み iframe |
| 太陽光 | 建物の位置の埋め込み iframe と太陽光発電の可能性に関する統計 |
| 旅行プラン | 複数のセクションを組み合わせたページ:埋め込み iframe のマップ、スポットカード、天気ウィジェット |
HTML ページを生成する場合:
- 自己完結型の単一の
.htmlファイルを使用します(CSS/JS をインライン化し、外部依存関係は使用しません)。 - すべてのマップでデフォルトとしてゼロキーの埋め込み iframe(
output=embed)を使用します。HTML に API キーを含めないでください。 - **HTML ページで
google.maps.StreetViewPanoramaや Street View JS API を使用してはいけません。**ストリートビューには、常にmap_action=panoを指定した Google Maps への直接リンクを使用してください。これは厳守するルールです。 - ユーザーが高度なインタラクティブ機能を明示的に求めない限り、Google Maps JS API の
<script>タグを含めてはいけません。output=embedの iframe 方式なら、ほとんどの用途で API キーなしに対応できます。 - 説明的な名前を付けて現在の作業ディレクトリに保存します(例:
marea-streetview.html、nyc-trip-plan.html)。 - 作成後、
open <file>を使ってブラウザーで自動的に開きます(macOS)。
HTML でのストリートビュー — キーの露出ゼロ
厳守事項:HTML ページで JavaScript API または Embed API を使ってストリートビューを埋め込まないでください。 どちらの方法でも、クライアント側のコードに API キーが露出します。代わりに、ユーザーのブラウザーで完全なインタラクティブなストリートビューを開く Google マップへの直接リンクを必ず使用してください。費用も API キーの露出もありません。
直接リンクの形式(Google Maps URLs API — 信頼性の高い方法):
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat},{lng}&heading={heading}&pitch={pitch}&fov=90
パラメーター:
viewpoint={lat},{lng}— ストリートビューの場所の座標heading— 度数で指定する方位角(0=北、90=東、180=南、270=西)pitch— 仰角(-90=下、0=水平、90=上)fov— 度数で指定する視野角(10~100、デフォルトは90)map_action=pano— 必須 — ストリートビューのパノラマモードを明示的に起動します
警告: 古い省略形式 @{lat},{lng},3a,75y,{heading}h,{pitch}t は使用しないでください。この形式は信頼性が低く、ストリートビューが開かずにズームアウトされた世界地図が表示されることがよくあります。必ず map_action=pano 形式を使用してください。
例:
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=40.76545,-73.98115&heading=90&pitch=0&fov=90
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.8584,2.2945&heading=180&pitch=0&fov=90
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=46.414,10.013&heading=270&pitch=-5&fov=90
HTML ページでの実装方法:
単独のストリートビューボタンの場合:
<a href="https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=40.76545,-73.98115&heading=90&pitch=0&fov=90"
target="_blank" rel="noopener noreferrer"
style="display:inline-block; padding:12px 24px; background:#4f46e5; color:white;
border-radius:8px; text-decoration:none; font-weight:600;">
Open Street View →
</a>
JavaScript 関数の場合(例:場所が多数ある旅行計画ページ):
function openStreetView(lat, lng, name) {
window.open(
`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${lat},${lng}&heading=0&pitch=0&fov=90`,
'_blank'
);
}
コンテキスト付きのカード/プレビューの場合:
<div class="streetview-card">
<div class="sv-preview">
<div class="sv-overlay">
<span class="sv-icon">🔭</span>
<span>Interactive Street View</span>
</div>
</div>
<a href="https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat},{lng}&heading=0&pitch=0&fov=90"
target="_blank" rel="noopener noreferrer" class="sv-button">
Open in Google Maps →
</a>
<p class="sv-note">Opens full 360° interactive Street View — pan, zoom, and walk around</p>
</div>
統合された旅行計画ページでは、 以前の StreetViewPanorama セクションを、スタイル付きのボタン/リンクカードに置き換えてください。ユーザーがクリックすると、新しいタブで完全なストリートビューが開きます。Google マップから直接、完全にインタラクティブな体験を利用できます。
この方法を採用する理由:
- API キーの露出ゼロ — HTML ソースにキーが一切含まれません
- 費用ゼロ — API 呼び出しも課金もありません
- より優れた体験 — 制限付きの埋め込みではなく、ナビゲーション機能を備えた完全な Google マップのストリートビューを利用できます
- あらゆるデプロイ方式に対応(個人利用、BYOK、プラットフォームキー)
統合型のワンストップページ
複数の要素を含むリクエスト(旅行計画、場所の調査、比較など)では、収集したすべてのデータを1つのインタラクティブなダッシュボードにまとめた、統合型 HTML ページの生成を必ず提案してください。 ターミナル出力をスクロールし続けるのではなく、ユーザーがすべての情報を1か所で確認できるようにします。
統合型ページには、会話中に収集したデータをすべて含めます。たとえば、旅行計画ページには次のような情報をまとめられます。
- 運転ルートのポリラインを含むインタラクティブなルートマップ
- 目的地の天気ウィジェット
- 写真、評価、営業時間を含むホテル/場所のカード
- Google マップで完全な360°ビューを開くストリートビューリンク付きのレストランのおすすめ
- タイムライン/旅程セクション
- レンタカーと空港の情報
統合型ページのデザイン原則:
- セクションを明確に分けた、すっきりとしたモダンなダッシュボードレイアウトを使用します
- 各セクションは、テキストだけでなく、マップ、カード、アイコン、バッジなどを使って視覚的に充実させます
- スムーズなスクロールナビゲーションを含めます(アクティブなリンクを強調表示する、すりガラス風の固定ナビゲーション)
- スクロールに合わせてアニメーションを表示します(IntersectionObserver を使って各セクションを下からフェードイン)
- あらゆる画面サイズに完全対応させます。デスクトップ(>1024px)、タブレット(641~1024px)、モバイル(<=640px)、小型スマートフォン(<=380px)
- モバイルでは、カード、ボタン、旅行チップ、統計グリッドを1列に並べます
- モバイルでは、マップの高さを縮小し(280px)、ボタンを全幅にします
デフォルトテーマ:温かみのあるストーン・サンライズ
ユーザーが別のテーマを指定しない限り、すべての HTML ページでこのテーマがデフォルトで使用されます。
カラーパレット:
- 背景:
#fafaf9(温かみのあるオフホワイト) - サーフェス:カードは
#ffffff、代替サーフェスは#f5f5f4 - 境界線:
#e7e5e4(温かみのあるストーン)、#f0eeec(明るい区切り線) - テキスト:メインは
#1c1917、セカンダリは#57534e、ターシャリは#a8a29e - アクセント:
#4f46e5(インディゴ)、ライトは#eef2ff、ミッドは#c7d2fe - セマンティックカラー:緑
#059669、アンバー#d97706、赤#dc2626、青#2563eb
タイポグラフィ:
- 見出し:
Playfair Display(セリフ体、ウェイト 700~900)— エディトリアルで高級感のある雰囲気 - 本文:
Inter(サンセリフ体)、フォントスムージングを全面適用 - セクションのパターン:大文字のラベル(11px、アクセントカラー)→ セリフ体のタイトル(26px)→ 説明(14px、ターシャリカラー)
ヒーロー: linear-gradient(160deg, #eef2ff, #faf5ff, #fff7ed) — インディゴからラベンダー、ピーチへ
マップ: デフォルトでは、埋め込み iframe を使った Google Maps スタイルを使用します。Maps JS API を使用する場合(オプトイン)は、明るいカスタムスタイルを適用します。落ち着いたストーン系の色調、柔らかな青の水域 #c9d7e4、緑の公園 #d4e9d4、白い道路を使用します。
影: 基本は控えめな 0 1px 2px rgba(0,0,0,0.04)、ホバー時は 0 4px 6px
ナビゲーション: すりガラス風の固定表示(rgba(255,255,255,0.85) と backdrop-filter: blur(20px))、アクティブリンクには下線アニメーション
インタラクション: ホバー時にカードが浮き上がる(translateY(-2px))、タイムラインのドットが塗りつぶされ、光彩リングが表示される、ホバー時にステップがインデントされる、ボタンが浮き上がり影が強くなる
API キーのセキュリティと本番環境のアーキテクチャ
問題点
クライアント側の HTML/JavaScript に埋め込まれた API キーは、ブラウザーの開発者ツールからユーザーに見えてしまいます。個人利用では問題ありませんが、複数のユーザーにサービスを提供する本番アプリでは重大な問題になります。
デプロイモード
このスキルは、セキュリティ特性の異なる 3 つのデプロイモードに対応しています。
モード 1:個人利用/CLI 利用(単一ユーザー)
ユーザー自身の API キーを .env に設定し、gmaps.py でローカルに使用します。キーがマシンの外部に出ることはありません。
User's Machine
├─ .env (GOOGLE_MAPS_API_KEY=...)
├─ gmaps.py → calls Google APIs directly
└─ HTML pages → zero-key embed iframes (preferred) or key embedded (acceptable)
リスク:低 — ユーザー自身のマシンで、ユーザー自身のキーを使用します。
キーの制限:不要(または、使用する API に限定します)。
ベストプラクティス:個人利用でも、HTML ページにはキー不要の output=embed iframe を優先してください。カスタムマーカー、ポリライン、クラスタリングなどの高度な機能が必要な場合に限り、Maps JS API を使用します。
モード 2:ユーザーが自身のキーを持ち込む(マルチユーザーアプリ)
ユーザーが自身の Google API キーを設定します。請求はユーザー自身が管理します。
Your App
├─ User configures their own API key in app settings
├─ Key stored in user's profile (encrypted at rest)
├─ Used server-side for data queries
└─ Frontend key: user creates a separate domain-restricted key
リスク:低~中 — ユーザー自身のキーであり、請求もユーザー自身が負担します。 重要:共有・エクスポート可能な HTML ページを生成する際、ユーザーのキーを埋め込んでは絶対にいけません。代わりに静的エクスポートを使用してください(下記の「共有可能なエクスポートモード」を参照)。 オンボーディング:GCP Console の設定と API の有効化をユーザーに案内してください(上記の「セットアップ」セクションを参照)。
モード 3:プラットフォームキー(ユーザーがあなたに支払う)— 重大
ユーザーはあなたのプラットフォームに料金を支払います。Google API キーを用意するのはあなたです。ユーザーにキーを見せては絶対にいけません。
アーキテクチャ:2 キー+バックエンドプロキシ
┌─────────────────────────────────────────────────────┐
│ User's Browser │
│ │
│ HTML Page (served from app.yourdomain.com) │
│ ├─ Interactive Maps ← Frontend Key (domain-locked) │
│ ├─ Street View ← Frontend Key (domain-locked) │
│ └─ All data (weather, places, directions, etc.) │
│ ↑ pre-rendered from backend, NO key in browser │
│ │
└──────────────────┬────────────────────────────────────┘
│ /api/geocode, /api/directions, etc.
▼
┌──────────────────────────────────────────────────────┐
│ YOUR Backend Server │
│ │
│ Backend Key (env var, never sent to browser) │
│ ├─ Geocoding, Directions, Places, Weather, etc. │
│ ├─ Street View Static → returns image bytes │
│ └─ All data APIs proxied with your key server-side │
│ │
│ Key restricted by: Server IP address │
│ Even if leaked: won't work from other IPs │
└──────────────────┬────────────────────────────────────┘
│
▼
Google Maps Platform
フロントエンドキー(クライアント側、HTML 内):
- 有効にするもの:Maps JavaScript API のみ(インタラクティブなマップの描画用)
- 制限方法:HTTP リファラー →
https://app.yourdomain.com/* - 誰かがキーをコピーしても、あなたのドメインからしか使用できません
- データ API(ジオコーディング、場所など)は呼び出せません。このキーでは無効になっています
バックエンドキー(サーバー側、非公開):
- 有効にするもの:すべてのデータ API(ジオコーディング、ルート案内、場所、天気、花粉、太陽光など)
- 制限方法:サーバー IP アドレス
- ブラウザーに送信されることはなく、サーバーの環境変数内にのみ保存されます
- 漏えいした場合でも、あなたのサーバーの IP からしか使用できません
このモードでの HTML ページの動作:
// UNSAFE — key exposed, data fetched client-side:
const service = new google.maps.DirectionsService();
service.route({ origin: 'JFK', destination: 'The Plaza' });
// SAFE — data pre-fetched by backend, only map rendering in browser:
const routeData = /* injected by server from backend API call */;
const path = google.maps.geometry.encoding.decodePath(routeData.polyline);
new google.maps.Polyline({ path: path, map: map });
GCP Console で 2 つのキーを設定する
ステップ 1:フロントエンドキーを作成する
- GCP Console の APIs & Services > Credentials に移動します
- Create Credentials > API Key をクリックします
- キーをクリックして編集します
- Application restrictions で HTTP referrers を選択します
- ドメインを追加します:
https://app.yourdomain.com/* - API restrictions で Restrict key を選択します
- Maps JavaScript API のみを有効にします
- 保存します
ステップ 2:バックエンドキーを作成する
- Create Credentials > API Key をもう一度クリックします
- キーをクリックして編集します
- Application restrictions で IP addresses を選択します
- サーバーの IP アドレスを追加します
- API restrictions で Restrict key を選択します
- 次を有効にします:Geocoding、Routes、Places (New)、Weather、Air Quality、Pollen、Solar、Elevation、Time Zone、Address Validation、Roads、Street View Static、Geolocation、Aerial View、Route Optimization
- 保存します
ステップ 3:アプリを設定する
# Backend server environment
GOOGLE_MAPS_BACKEND_KEY=AIzaSy...xxx # Server-side only, IP-restricted
GOOGLE_MAPS_FRONTEND_KEY=AIzaSy...yyy # Injected into HTML, domain-restricted
共有可能なエクスポートモード
ユーザーが HTML ページをダウンロードまたは共有(メール、Slack など)する場合は、API キーを一切含まない静的エクスポートを生成します:
| 要素 | アプリ内(インタラクティブ) | 共有可能なエクスポート |
|---|---|---|
| 地図 | Maps JavaScript API(フロントエンドキー) | Maps Embed API <iframe>(無料、キーの不正使用リスクなし) |
| ストリートビュー | Google Maps への直接リンク(キー不要) | Google Maps への直接リンク(キー不要) |
| ルート線 | DirectionsRenderer(フロントエンドキー) | パスを重ねた静的地図画像(base64) |
| データ(天気、場所) | バックエンドで事前レンダリング | 同じ事前レンダリング済み HTML — API 呼び出し不要 |
| API キーの露出 | フロントエンドキー、ドメイン制限あり | キーなし |
埋め込み URL を生成するには(無料、無制限):
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode place --query "Marea Restaurant NYC"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode directions --origin "JFK" --destination "The Plaza Hotel NYC"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode streetview --lat 40.76545 --lng -73.98115
セキュリティの概要
| デプロイ方法 | データ API | 地図の描画 | キーの露出 | 共有可能 |
|---|---|---|---|---|
| 個人 CLI | ユーザーのキーをローカルで使用 | キー不要の埋め込み iframe(デフォルト) | なし | はい(キーなし) |
| 個人 CLI(上級者向け) | ユーザーのキーをローカルで使用 | Maps JS API(ポリライン、クラスタリングなどをオプトイン) | ユーザー自身の責任 | いいえ(キーが漏洩) |
| BYOK(ユーザーのキー) | サーバー上でユーザーのキーを使用 | ユーザーがフロントエンドキーを作成 | ユーザー自身の責任 | 静的エクスポートのみ |
| プラットフォームキー(費用はあなたが負担) | バックエンドキー(IP 制限あり) | フロントエンドキー(ドメイン制限あり) | 安全 | 静的エクスポートのみ |
レート制限と不正使用の防止(プラットフォームモード)
複数のユーザーに自分のキーを使ってサービスを提供する場合は、次も実装します:
- ユーザーごとのレート制限:ユーザー 1 人あたりの API 呼び出し数を 1 時間または 1 日単位で制限します
- 認証:認証済みの有料ユーザーのみが API 呼び出しを実行できるようにします
- 使用状況の追跡:課金に備えて、どのユーザーがどの API 呼び出しを実行したかを記録します
- 割り当てアラート:予期しない急増を検知できるよう、GCP の課金アラートを設定します
- 予算上限:GCP Console で 1 日あたりの最大支出額を設定します
エラー処理と API 設定のガイド
重要:コマンドが失敗した場合は、必ずすぐにユーザーに伝えてください。 Web 検索やその他の回避策に黙って切り替えてはいけません。ユーザーが修正方法を判断できるよう、何が壊れているのかを知らせる必要があります。
コマンドが失敗した場合は、エラーの種類を検知して、次のように応答します:
- 403 Forbidden / API not enabled:停止します。ユーザーに伝えます。Playwright を使った手順を案内します(下記参照)
- REQUEST_DENIED:停止します。ユーザーに伝えます。Playwright を使った手順を案内します(下記参照)
- 400 Bad Request:パラメーターが無効です — API ドキュメントを確認します
- 429 Rate Limited:リクエストが多すぎます — 短い待機時間を追加します
- ZERO_RESULTS:結果が見つかりません — より広い条件で検索します
- INVALID_REQUEST:必須パラメーターが不足しています
- キーが見つからない:
.envまたは環境変数にGOOGLE_MAPS_API_KEYが設定されていることを確認します - RefererNotAllowedMapError:フロントエンドキーの HTTP リファラー制限が現在のドメインと一致していません
API の有効化ガイド(Playwright による操作)
API が有効になっていない場合は、必ず最初にこの手順を案内してください。 この手順を省略したり、黙って回避したりしないでください。
ユーザーの API 呼び出しが 403、REQUEST_DENIED、または「API が有効になっていません」というエラーで失敗した場合:
-
何が起きたのかをわかりやすく伝えます:
「[API Name] がまだ Google Cloud プロジェクトで有効になっていないようです。ご安心ください。ブラウザーで有効にする手順をご案内できます。今すぐ進めてもよろしいですか?」
-
ユーザーが「はい」と答えたら、Playwright MCP を使って有効化を自動化します:
Step 1: Navigate to the specific API's enablement page: https://console.cloud.google.com/apis/library/[API_ENDPOINT] Step 2: If a project selector appears, let the user pick their project (or auto-select if there's only one) Step 3: Click the "Enable" button Step 4: Wait for the confirmation (loading spinner → "API enabled" or the button changes to "Manage") Step 5: Confirm to the user: "Done! [API Name] is now enabled. Let me retry your request." Step 6: Retry the original command automatically -
Playwright で移動するためのAPI エンドポイント URL(以下の正確なパスを使用します):
API GCP ライブラリの URL パス ジオコーディング geocoding-backend.googleapis.comRoutes routes-backend.googleapis.comPlaces(新) places-backend.googleapis.comElevation elevation-backend.googleapis.comTime Zone timezone-backend.googleapis.comAir Quality airquality.googleapis.comPollen pollen.googleapis.comSolar solar.googleapis.comWeather weather.googleapis.comAddress Validation addressvalidation.googleapis.comRoads roads.googleapis.comStreet View Static street-view-image-backend.googleapis.comMaps Static static-maps-backend.googleapis.comMaps JavaScript maps-backend.googleapis.comMaps Embed maps-embed-backend.googleapis.comGeolocation geolocation.googleapis.comAerial View aerialview.googleapis.comRoute Optimization routeoptimization.googleapis.comURL の形式:
https://console.cloud.google.com/apis/library/[path_from_table] -
ユーザーが「いいえ」と答えた場合(手動での設定を希望する場合)、直接 URL を案内します:
「わかりました。こちらが直接リンクです。「有効にする」をクリックしてください。 https://console.cloud.google.com/apis/library/[API_ENDPOINT]」
-
複数 API の一括有効化:初めて設定するユーザーに複数の API の有効化が必要な場合は、まとめて有効にすることを提案します:
「よく使われる API(Geocoding、Routes、Places、Weather、Elevation、Time Zone、Maps JavaScript)をまとめて有効にできます。すべて設定してもよろしいですか?」
その後、Playwright で各 API のページを順に開き、それぞれの「有効にする」をクリックします。
-
Playwright による操作の重要事項:
- ユーザーは、ブラウザーで Google Cloud Console にログイン済みである必要があります
- ログインしていない場合は、まず https://console.cloud.google.com でログインするよう伝えます
- 一部の API(Weather、Solar)では、プロジェクトで課金を有効にする必要がある場合があります
- 有効化後、API が使用可能になるまで約 30 秒かかる場合があります
- 「有効にする」ボタンが表示されず、「管理」と表示されている場合は、API はすでに有効です
料金に関する注意事項
ほとんどの API はリクエストごとに課金されます。主な無料枠と有料枠は以下のとおりです:
- Maps Embed API:常に無料(共有可能なエクスポートに使用)
- Maps JavaScript API:読み込み 1,000 回あたり $7
- Street View(JS):パノラマ読み込み 1,000 回あたり $7 — HTML ページでは絶対に使用せず、代わりに Google Maps の直接リンクを使用してください(無料、キー不要)
- Google Maps Platform の月額 $200 の無料クレジット
- Routes API:機能に応じてリクエスト 1,000 件あたり $5~15
- Places API:リクエスト 1,000 件あたり $17~40
- 環境 API(Air Quality、Pollen、Solar):料金は API によって異なります
- 最新の料金は Google Maps の料金を確認してください
備考
- 出力はすべて JSON です(画像のダウンロードはファイルに保存されます)
- 外部の Python 依存関係はありません。標準ライブラリのみを使用します
- スクリプトは次の場所で
.envを検索します:CWD、ホームディレクトリ、スキルディレクトリ - 画像 API(streetview、static-map)では、ファイルはローカルに保存されます
- Weather API では、別途課金の有効化が必要な場合があります
- Aerial View は米国の住所のみ対応しています
- Route Optimization には GCP プロジェクト ID が必要です
- Roads の制限速度情報には Asset Tracking ライセンスが必要です