副業・個人開発として「メモリーズ」というアプリを作っています。写真のGPSデータとGoogle Places APIを組み合わせて、行ったお店や場所を自動で記録するアプリです。
この記事では、Google Places APIを実際に使ってみてわかったこと、特に「費用の落とし穴」と「費用を抑える設計」について書きます。
対象読者Google Places APIを個人開発で使おうとしているエンジニア、特に費用面が心配な人に向けて書きます。
- 作っているアプリのコンセプト
- Google Places APIで何ができるか
- 料金体系が2025年に変わった話(重要)
- 費用の落とし穴:全写真を自動スキャンしようとしたら…
- 費用を抑える設計:GPSデータだけを使う
- 実際の実装コード
- まとめ:API設計は費用を先に考える
作っているアプリのコンセプト
「メモリーズ」は、写真を撮るだけで行ったお店や場所が自動で記録されるアプリです。
「あのカフェどこだっけ?」「先月行ったレストランの名前が思い出せない」という体験から着想しました。食べログやGoogleマップは検索ツールですが、「自分が行った場所の記録」に特化したアプリがないと感じていました。
? メモリーズのコンセプト
写真を撮る(スマートフォンのカメラ)
↓ GPS情報が写真に埋め込まれる(EXIF)
アプリが自動でGPSを読み取る
↓ Google Places APIで「ここ何の店?」を確認
店名・カテゴリ・住所が自動で記録される
↓
「あのカフェどこだっけ?」→ すぐ見つかる
Google Places APIで何ができるか
Google Places APIを使うと以下の情報を取得できます。
| 取得できる情報 | 詳細 | 費用感 |
|---|---|---|
| 店名・住所・カテゴリ | 店舗名、住所、レストラン/カフェ等の分類 | 安い(Essentials) |
| 場所の検索(Nearby Search) | 座標の近くにある場所を探す | やや高い(Pro) |
| 評価・レビュー | 星評価、ユーザーレビュー | 高い(Enterprise+Atmosphere) |
| 写真 | 店舗・料理の写真 | 高い(Place Photos) |
? POINT
Places APIは「どの情報を取得するか」で費用が変わります。取得するフィールドをEssentials(名前・住所・カテゴリ)に絞れば安く、レビューや写真などのAtmosphere系を取ると一気に高くなります。FieldMaskで取得フィールドを絞ることが費用管理の基本です。
料金体系が2025年に変わった話(重要)
注意点があります。Google Maps Platformの料金体系は2025年3月に大きく変わりました。古い記事を参考にすると料金感がズレるので、ここを押さえておきます。
変更点は主に3つです。
① 全アカウント共通の月$200無料クレジットが廃止された。代わりにSKU(機能)ごとに無料枠が設定される方式になりました。
② SKUごとに無料枠がある。個人開発にとってはこれが朗報です。例えばNearby Searchは月5,000件まで無料、店名や住所などのPlace Details Essentialsは月10,000件まで無料です。
③ Essentials / Pro / Enterprise の3階層になった。取得する情報の種類で階層が分かれ、料金も段階的に変わります。
| SKU(2026年時点) | 無料枠/月 | 超過後(〜10万件) |
|---|---|---|
| Nearby Search(Pro) | 5,000件 | $32 / 1,000件 |
| Place Details Essentials | 10,000件 | $5 / 1,000件 |
| Geocoding | 10,000件 | $5 / 1,000件 |
| Place Photos(Enterprise) | 1,000件 | $7 / 1,000件 |
⚠️ 料金は変わる前提で
APIの料金は改定されることがあります。実装前に必ずGoogle公式の料金ページ(developers.google.com/maps/billing-and-pricing/pricing)で最新の数字を確認してください。この記事の数字も2026年時点のものです。費用の落とし穴:全写真を自動スキャンしようとしたら…
最初のコンセプトは「カメラロールの全写真を自動スキャンして、全部記録する」でした。でもAPI費用を計算したら現実を思い知りました。
# API費用の計算(Nearby Search Pro = $32 / 1,000件で試算) # 無料枠(月5,000件)を超えた分が課金対象 # カメラロール10,000枚を一気にスキャンした場合 # 無料 5,000件 + 課金 5,000件 5,000件 × $0.032 = $160(約24,000円)を1回で消費 # ユーザーが月1,000枚撮る場合(無料枠内に収まらない) # 無料 5,000件 → 月1,000枚なら無料枠内 … に見えるが # 「全写真スキャン」だと過去分も毎回走るので一気に超える # ユーザーが1,000人いて全員が無料枠を超えたら 1,000人 × 数千円 = 数百万円/月 ?
個人開発でこの規模のAPI費用は絶対に払えません。「全自動で全部スキャン」というコンセプトは費用との戦いでした。
⚠️ 個人開発でAPIを使うときの鉄則
機能を設計する前に、まずAPI費用のシミュレーションをすること。「無料枠は何件か」「ユーザーが月○回使ったら超過分はいくらか」を必ず計算してから実装に入る。費用を抑える設計:GPSデータだけを使う
解決策は「画像データを送らず、GPS座標だけをAPIに投げる」設計にすることでした。
✅ 費用を抑えた設計
アプリ起動時
↓ カメラロールの「新着写真」のGPS座標だけを取得
(画像データは送らない → 通信量ゼロ)
↓ GPS座標をPlaces APIに送る
(Nearby Search → 取得フィールドはEssentialsのみ)
↓ 店・スポットが見つかった写真だけ記録
↓ 詳細を見たいときだけ追加情報を取得
(遅延読み込み)
| 処理 | タイミング | 費用 |
|---|---|---|
| GPS取得(EXIF読み取り) | 全写真・起動時 | 無料 |
| Nearby Search(Essentialsフィールド) | 新着のGPS付き写真のみ | 無料枠内に収めやすい |
| レビュー・写真取得 | ユーザーが詳細を開いたときだけ | 最小限 |
この設計に変えたことで、API呼び出し回数を大幅に減らし、多くのユーザーが無料枠内に収まるレベルまで費用を抑えられました。
実際の実装コード
写真のGPS情報を取得する
import * as MediaLibrary from 'expo-media-library';
// カメラロールから最新の写真を取得
const getRecentPhotosWithGPS = async () => {
const { assets } = await MediaLibrary.getAssetsAsync({
mediaType: 'photo',
sortBy: MediaLibrary.SortBy.creationTime,
first: 50, // 最新50枚だけ取得(無料枠を意識)
});
// GPS情報がある写真だけをフィルタ
const photosWithGPS = assets.filter(
asset => asset.location !== null
);
return photosWithGPS;
};
GPS座標からお店を検索する(Places API New)
const PLACES_API_KEY = 'YOUR_API_KEY';
// Places API (New) の Nearby Search はPOSTで呼ぶ
// FieldMask で取得フィールドを絞ることが費用管理の要
const searchNearbyPlaces = async (latitude, longitude) => {
const response = await fetch(
'https://places.googleapis.com/v1/places:searchNearby',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Goog-Api-Key': PLACES_API_KEY,
// 取得フィールドをEssentialsだけに絞る → 費用を抑える
'X-Goog-FieldMask':
'places.displayName,places.formattedAddress,places.types',
},
body: JSON.stringify({
locationRestriction: {
circle: {
center: { latitude, longitude },
radius: 50.0, // 50m以内に絞る
},
},
maxResultCount: 1, // 一番近い1件だけ
}),
}
);
const data = await response.json();
return data.places?.[0]; // 一番近い場所を返す
};
? POINT
Places API (New) ではX-Goog-FieldMaskヘッダーで取得フィールドを指定します。ここをdisplayName・formattedAddress・typesなどEssentialsだけに絞ると、Atmosphere系(レビュー・写真)の高い課金を避けられます。radius=50で範囲を絞れば、関係ない場所が引っかかるのも防げます。
⚠️ 旧APIとの違い
以前のmaps.googleapis.com/maps/api/place/nearbysearch/json(GETで呼ぶ旧API)はLegacy扱いになっています。新規実装はplaces.googleapis.com/v1/places:searchNearby(POST + FieldMask)の新APIを使うのが推奨です。古い記事のコードをそのままコピーすると動かないことがあるので注意。
- 料金体系は2025年に刷新。$200共通クレジット廃止、SKUごとの無料枠方式に
- Nearby Searchは月5,000件、Place Details Essentialsは月10,000件まで無料
- 「全写真を自動スキャン」は費用が爆発する。設計前に無料枠と超過費用を計算する
- 「画像を送らずGPS座標だけ」+「FieldMaskでEssentialsに絞る」で費用を最小化
- 新規実装はPlaces API (New)(places.googleapis.com + FieldMask)を使う
個人開発は費用との戦いです。「技術的にできる」と「費用的に持続可能」は別の話。設計前にAPI費用と無料枠を必ず計算する習慣が個人開発を長続きさせるコツだと思っています。


コメント