【Gemini CLI活用】GoogleMapにクマ出現率表示アプリ作成中|クマ共生ハッカソン進捗②
石川県オープンデータ利活用企画のクマ共生ハッカソンにチャレンジしています。
初回参加レポートはこちら。
日々の試行錯誤の状況を報告します。
前回のおさらいと今回やったこと
前回までやったことは以下を参照。
Gemini CLIを使って試行錯誤しながらWebアプリを作っています。
前回はGoogle Map上の固定座標のクマ出現確率を表示しただけだったので、今回はGoogleMap APIを使ってユーザーがクリックした位置のクマ出現確率を表示できるように改修しました。
結論から言えば、こんな感じにクリックしたところのクマ出現確率が表示されるようになりました。

具体的な作業は以下のとおりです。
GoogleMap APIを使って指定座標のクマ出現率を表示する仕様に変更する
GoogleMAP APIキーを外出しする仕様に変更する
以下ではそれぞれについて紹介します。
①GoogleMap APIを使って指定座標のクマ出現率を表示する仕様に変更する
まずは最初にGeminiCLIで作ったアプリを動かしてみます。
GoogleMap APIキーを頂いたので(※ふぁらお加藤さんありがとうございます)それを設定して起動するだけです。
きっとGemini CLIがいい感じのアプリを作ってくれていると信じて、そのまま起動します。
Webアプリを起動すると地図が出ました。

ここで任意の場所をクリックするとクマ出現確率が表示されるはずなのですが、

何も出ませんでした。
何も出ないよ。助けて。とGemini CLIに聞いてもいいのですが、コードがぐちゃぐちゃになりそうだったので、エラー解析してみました。
ブラウザの開発者ツールを開いてConsoleを確認すると、404エラーが出ていました。

バックエンドの処理(localhost:3001/api/vi/・・・・)を呼び出しに行ったけど見つからなかったよ。というエラーになります。
確かにバックエンドは3000ポートで起動しているので見つからないですね。

コードを見るとindex.jsでポート番号指定していました。これを3001に変更します。
const express = require('express');
const app = express();
const port = 3001;
app.get('/api/v1/bears/probability', (req, res) => {
const { latitude, longitude, date } = req.query;
// 入力値のバリデーション(今回は省略)
// クマの出現確率を計算するロジック(ダミー)
const probability = Math.floor(Math.random() * 101);
res.json({ probability });
});
バックエンドが3001ポートで起動しました。

これで行けるか!?再度地図をクリックしてみます。
でました!!

左上に小さく表示されています。

②GoogleMAP APIキーを外出しする仕様に変更する
基本的な仕組みはできたので、汎用性を高めるためにGoogleMap APIキーは外出しして管理する仕様に変更します。
せっかくなのでGeminiCLI使って修正してみました。
修正前はApp.jsに直接APIキーを記入する仕様になっています。
const App = () => {
const { isLoaded } = useJsApiLoader({
id: 'google-map-script',
googleMapsApiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxx" // ここにAPIキーを入力してください
});
const [marker, setMarker] = useState(null);
const [probability, setProbability] = useState(null);
const onMapClick = useCallback((event) => {
const lat = event.latLng.lat();Gamini CLIを使っての初めての仕様修正。既存の仕様が壊れないかドキドキです。
以下のように指示しました。
Google MAP APIキーは.envファイルで指定する仕様にして。
APIキーはgithubにコミットしたくないので開発者がcloseしてから設定する仕様にして。.envファイルの作成
.gitignoreファイルの作成
はちゃんとやってくれました。

ただ、GoogleMAPを表示する処理が既存と変わってしまいました。
なぜかhtmlにタグが追加されています。

こういうときなんて言ったらいいかよくわかりませんが、意図を伝えてみます。
いい感じになおしてくれました。

htmlの修正も元に戻してくれるという素晴らしい対応力!

さっそく起動してみます。ちゃんと起動しました。
と思ったのですが、再びバックエンドの404エラーが!!!!

どうやらフロントエンドからバックエンドを呼び出すときにポートを指定しないと、フロントエンドと同じポート番号を使うようです。
せっかく環境変数ファイルを追加したので、ここでバックエンドのポート番号も管理する仕様にしてもらいます。
以下のように指示しました。
axios.get(`${baseUrl}/api/v1/bears/probability`, {
params: {
latitude: lat,
longitude: lng,
date: today
}
})
ポート番号を指定したい いい感じに直してくれたっぽいです。

.envファイルにバックエンドのポート番号を指定して、もう一度アプリを起動してみます。
CROSエラーになりました。。。。なかなか完成しない。

エラー全文をGeminiCLIに投げてみます。
(index):1 Access to XMLHttpRequest at 'http://localhost:3001/api/v1/bears/probability?latitude=36.67774035058112&longitude=136.699931640625&date=2025-08-11' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.バックエンドにCROSミドルウエアを追加するといいみたいです。パッケージのインストールとコードの修正をやってくれました。

調べたらヘッダーの追加でもよかったみたいですね。
三度目の正直!今度こそ表示できました!

こんな感じでGeminiCLIと対話しながら少しずつアプリを改修していきたいです。
Gemini CLIは修正前に修正するかどうか聞いてくれるので「そうじゃないのでは!?」と思ったら提案を削除するのがおすすめです。
その判断をするために修正後のイメージはちゃんと自分で理解しておかないとダメですね。プログラミングの勉強頑張ります!
まとめ
今回はGoogleMap APIを使ってユーザーがクリックした位置のクマ出現確率を表示できるように改修しました。
環境変数に設定値を外だしする改修や、GeminiCLIと対話しながらエラーを解消するといった経験もできて、AIコーディング開発っぽくなったかなと思います(自己満足
これで基本的な流れはできたはず。
この後どうしていくかはチームメンバーと相談します。
最後までお読みいただきありがとうございました。
