3.9万件のバイク駐車場にストリートビューを埋め込んだ実装ガイド
はじめに
バイクポータルサイト「MotoHub」を個人開発しています。
MotoHubにはバイク専用の駐車場マップ機能があり、全国約39,000件のバイク駐車場を掲載しています。駐車場の詳細ページにGoogleストリートビューを埋め込んで入口の外観を確認できるようにしました。
環境
Laravel 12 / PHP 8.3 / Blade
Google Street View Static API
├── APIキーは Maps 専用キー(YouTube用とは分離)
└── API制限: Street View Static API のみ有効
Cloudflare CDN
なぜストリートビューか
バイク駐車場を利用するユーザーの最大の不安は**「入口がどこか分からない」**。特にコインパーキングは建物の陰にあったり、看板が小さかったりします。
ストリートビューで事前に外観を確認できれば:
- 初めての場所でも迷わない
- 「バイクが実際に入れるか」の雰囲気がわかる
- ユーザーの滞在時間が伸びる → SEO効果
実装方法
Street View Static API
インタラクティブ(マウスで動かせる)なストリートビューはMaps JavaScript APIが必要で、実装が複雑です。
今回はStreet View Static APIを使いました。静止画像を返すシンプルなAPIで、<img> タグだけで埋め込めます。
https://maps.googleapis.com/maps/api/streetview
?size=640x400
&location={lat},{lng}
&heading=0
&pitch=0
&fov=90
&key={API_KEY}
| パラメータ | 説明 | 値 |
|---|---|---|
| size | 画像サイズ | 640x400(無料プランの上限) |
| location | 緯度・経度 | DBのlat/lngカラム |
| heading | カメラの方角 | 0(北向き、デフォルト) |
| pitch | カメラの上下角度 | 0(水平) |
| fov | 視野角 | 90(デフォルト) |
Bladeテンプレート
{{-- parking/show.blade.php --}}
@if($parking->lat && $parking->lng)
<div class="mt-6">
<h3 class="text-sm font-semibold text-gray-600 mb-2">
📷 ストリートビューで入口を確認
</h3>
<img
src="https://maps.googleapis.com/maps/api/streetview?size=640x400&location={{ $parking->lat }},{{ $parking->lng }}&key={{ config('services.google_maps.key') }}"
alt="{{ $parking->name }}のストリートビュー"
class="w-full rounded-lg"
loading="lazy"
/>
</div>
@endif
ポイント:
-
loading="lazy"で遅延読み込み(ページの初期表示速度に影響しない) -
lat/lngがnullの駐車場では非表示(@ifで囲む) -
alt属性に駐車場名を入れる(SEO・アクセシビリティ)
APIキーの管理
YouTube用とMaps用で分ける
最初はYouTube Data API と同じキーを使おうとしましたが、リファラー制限の設定が競合しました。
- YouTube Data API → HTTPリファラー制限あり(
motohub.jp/*) - Street View Static API → サーバーサイドから呼ぶのでリファラーが付かない
結果、Street View Static APIがリファラー制限で弾かれて表示されない。
解決策:APIキーを2つに分ける
# .env
YOUTUBE_API_KEY=AIza...xxx # YouTube Data API v3 のみ、リファラー制限あり
GOOGLE_MAPS_API_KEY=AIza...yyy # Street View Static API のみ、制限なし(API制限でSV Staticのみ)
// config/services.php
'google_maps' => [
'key' => env('GOOGLE_MAPS_API_KEY'),
],
| キー | 用途 | アプリケーション制限 | API制限 |
|---|---|---|---|
| YOUTUBE_API_KEY | YouTube動画表示 | HTTPリファラー | YouTube Data API v3 |
| GOOGLE_MAPS_API_KEY | ストリートビュー | なし | Street View Static API |
静止画 vs インタラクティブ
Street View Static APIは静止画像なので、マウスで動かしたりドラッグで視点を変えることはできません。
| 方式 | API | 操作 | コスト | 実装難易度 |
|---|---|---|---|---|
| 静止画 | Street View Static API | 見るだけ | 安い | 低(imgタグのみ) |
| インタラクティブ | Maps JavaScript API | マウスで操作可能 | 高い | 中 |
MotoHubでは「入口の外観が確認できれば十分」と判断し、静止画を採用しました。詳しく見たいユーザーは「Google Mapsで開く」リンクから確認できます。
ストリートビューが存在しない場所の対応
Street View Static APIは、指定した座標にストリートビュー画像がない場合、灰色の「Sorry, we have no imagery here」画像を返します。HTTPステータスは200のまま。
対策案
// ストリートビューのメタデータAPIで事前チェック
$metaUrl = "https://maps.googleapis.com/maps/api/streetview/metadata"
. "?location={$lat},{$lng}&key={$apiKey}";
$response = Http::get($metaUrl);
$data = $response->json();
if ($data['status'] === 'OK') {
// ストリートビューあり → 表示
} else {
// ストリートビューなし → セクション非表示
}
ただし、39,000件すべてで事前チェックするとAPIコストが増えるので、MotoHubではメタデータAPIは使わず、そのまま表示しています。灰色の画像が表示されるケースは少数で、ユーザーの理解で対応可能と判断しました。
SEOへの効果
駐車場詳細ページにストリートビューを追加したことで:
- コンテンツの充実 → ページの情報量が増える
- 滞在時間の増加 → ユーザーが画像を確認する時間
- 差別化 → 競合の駐車場サイトにストリートビューはない
さらに同時に追加した他のコンテンツとの相乗効果:
駐車場詳細ページのコンテンツ一覧:
├── 基本情報(料金・台数・営業時間)
├── Google Map 埋め込み
├── 📷 ストリートビュー ← 今回追加
├── 💰 料金シミュレーター ← 同時追加
├── ❓ FAQ + JSON-LD ← 同時追加
├── 🏍 エリアの在庫バイク ← 同時追加
├── 📍 周辺の駐車場
└── 🏪 周辺のバイクショップ
39,000ページすべてにこれだけのコンテンツがあるので、Googleの評価向上が期待できます。
料金
Street View Static APIの料金は1,000リクエストあたり$7(2026年4月時点)。
MotoHubの場合:
- DAU 420人 × 平均数ページ閲覧 = 1日数百〜1,000リクエスト程度
- Googleの無料枠($200/月)で十分収まる
- Cloudflare CDNで画像がキャッシュされれば、さらにリクエスト数は減る
まとめ
| やったこと | 効果 |
|---|---|
| Street View Static API で静止画埋め込み | imgタグだけで実装完了 |
| APIキーを用途別に分離 | リファラー制限の競合を回避 |
| lazy loading | 初期表示速度に影響なし |
| lat/lng nullチェック | データがない駐車場では非表示 |
実装時間は30分程度。 39,000ページに一括でストリートビューが付くので、コスパの高い施策です。
参考
🏍 MotoHub: https://motohub.jp
X: https://x.com/motohub_jp
GitHub: https://github.com/ausssxi/MotoHub
