私が業務中にGoogleMapsAPIでハマった話についての備忘録です。
GoogleMapsAPIについて
GoogleMapsAPIとは、Googleマップを表示する際に独自にカスタマイズして使用できるようにするAPIです。
GoogleマップをカスタマイズするためのAPIは大きく分けて「モバイルAPI」「ウェブAPI」「ウェブサービスAPI」の3つのようです。
今回使用したのはウェブAPIの「JavaScript API」
本題
シナリオテスト中に「検索結果が1件の時にリクエストが再度送られている」という不具合が発生しました。
以下が実際のコードの省略版になります。
this.map = new this.google.maps.Map(target, {
~~~ 省略 ~~~
});
//検索ボタンクリック
onClickSearchButton() {
this.isClick = true;
//APIリクエスト呼び出し
this.search();
//マーカー作成
this.createMarker();
//マーカーがすべて見えるようにマップを描画
this.setAllMarkersVisibleBounds();
},
//APIリクエスト
search() {
console.log('検索中(click_button)');
this.google.maps.event.addListener(this.map, 'zoom_changed', () => {
//検索ボタンでの検索時は、zoom_changedイベントでの検索は行わない
if (this.isClick) {
this.isClick = false;
return;
}
console.log('検索中(zoom_changed)');
});
},
//マーカー作成
createMarker() {
console.log('マーカー作成');
},
//マーカーをすべて描画
setAllMarkersVisibleBounds() {
console.log('マーカーをすべて描画');
this.map.fitBounds();
}
このコードで検索ボタンクリックの検索処理を実行すると以下の出力結果になります。
検索中(click_button)
マーカー作成
マーカーをすべて描画
検索中(zoom_changed)
検索ボタンでの検索時はzoom_changed
イベントでは何も行わないようにしているはずなのに
zoom_changed
イベントの検索が走ってしまっています。
その原因はthis.map.fitbounds()
にありました。
fitboundsとは
下の画像のようにマーカーが見切れてるのを右の画像のように描画範囲にマーカーを表示し
てくれるメソッドです。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓
しかし、検索結果が1件だった場合にfitboundsを使用すると以下のように
ズームレベルを最大にしてしまうようなのです。
これだけならまだよかったのですが何やら挙動がおかしい。
極限までズームしようとして失敗。
しょうがないからズームレベルを最大(レベル22)に設定。
という変な挙動をしてるらしい。
コード修正
以下が修正したコードです。
this.map = new this.google.maps.Map(target, {
~~~ 省略 ~~~
});
//検索ボタンクリック
onClickSearchButton() {
//初回ズームフラグ・・・修正1
this.isInitialZoom = true;
this.isClick = true;
//APIリクエスト呼び出し
this.search();
//マーカー作成
this.createMarker();
//マーカーがすべて見えるようにマップを描画
this.setAllMarkersVisibleBounds();
},
//APIリクエスト
search() {
console.log('検索中(click_button)');
//マップの描画完了時・・・修正2
this.google.maps.event.addListener(this.map, 'tilesloaded', () => {
this.isInitialZoom = false;
});
this.google.maps.event.addListener(this.map, 'zoom_changed', () => {
//検索ボタンでの検索時は、zoom_changedイベントでの検索は行わない
if (this.isClick) {
this.isClick = false;
return;
}
//修正3
if (!this.isInitialZoom) {
console.log('検索中(zoom_changed)');
}
});
},
//マーカー作成
createMarker() {
console.log('マーカー作成');
},
//マーカーをすべて描画
setAllMarkersVisibleBounds() {
console.log('マーカーをすべて描画');
this.map.fitBounds();
}
1.初回ズームフラグを立てる
2.tilesloadedイベント時(マップの描画完了時)に初回ズームフラグをfalseに変更
3.zoom_changedイベント時の検索は初回ズームフラグがfalseの時のみ実行されるように修正
これでバグともおさらばです。
まとめ
今回の不具合について、どこで調べても「初回ズームフラグを噛ませればいけるよ」
みたいなことしか書いてなかったがうまくいきませんでした。
zoom_changedイベントが終わったタイミングにちょうどかみ合ったのがtilesloadedイベントだったため、これを使ってみたら見事にうまくいったという話でした。
以上、ありがとうございました。