Google Maps JavaScript API では、ユーザーの操作に応じたイベント処理が柔軟に行えます。クリックやズーム、マーカー操作などに反応する地図アプリを構築できます。
ユーザーの操作に対して反応する具体的な操作内容
・ユーザーが地図をクリック → マーカーが表示される
・地図をドラッグ → 表示位置が変わる
・マーカーをクリック → 情報ウィンドウが開く
・ズーム操作 → 地図の縮尺が変わる
地図のクリックイベント取得
ユーザーが地図上をクリックした際に、その地点の緯度・経度を取得するには map.addListener("click", ...) を使います。
では何故、クリックイベントが必要なのでしょうか?
◾️地図表示範囲に応じたデータの再読み込み(バウンディングボックス)
サーバーに「この範囲のデータちょうだい」とリクエスト処理が可能。
◾️ズームレベルに応じた情報の出し分け
ズームが浅い時 → 市町村のラベルだけ・ズームが深い時 → ピンで詳細な情報
◾️画面内の中心が移動したら、その地点のバス停情報(データは作る必要あり)などを取得
APIで天気など取得・GeoNamesで地名や標高などを取得・GSI(地理院地図)API
map.addListener("click", function(event) {
const lat = event.latLng.lat();
const lng = event.latLng.lng();
console.log("クリックされた座標:", lat, lng);
});
複数マーカーに対応する場合はループ処理+クロージャに注意が必要です。
こんな書き方では考慮不足となります。
<script>
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 35.68002723791246, lng: 139.72039046547408 },
zoom: 12,
});
const locations = [
{ lat: 35.6895, lng: 139.6917, title: "新宿" },
{ lat: 35.6812, lng: 139.7671, title: "東京駅" },
{ lat: 35.6586, lng: 139.7454, title: "東京タワー" },
];
const infoWindow = new google.maps.InfoWindow();
for (var i = 0; i < locations.length; i++) {
const marker = new google.maps.Marker({
position: { lat: locations[i].lat, lng: locations[i].lng },
map: map,
title: locations[i].title,
});
// iがループ後の値(3)になってしまう
marker.addListener("click", function () {
infoWindow.setContent(locations[i].title); // ← i=3 なので undefined
infoWindow.open(map, marker);
});
}
}
</script>
正しくは
for (let i = 0; i < locations.length; i++) {
const marker = new google.maps.Marker({
position: { lat: locations[i].lat, lng: locations[i].lng },
map: map,
title: locations[i].title,
});
marker.addListener("click", function () {
infoWindow.setContent(locations[i].title); //iのスコープが各ループ内で保持される
infoWindow.open(map, marker);
});
}
地図の移動・ズームイベント
地図のズームレベル変更や移動(パン)を検知するには、以下のイベントを使います。
map.addListener("zoom_changed", function () {
console.log("ズームレベル:", map.getZoom());
});
map.addListener("dragend", function () {
const center = map.getCenter();
console.log("地図の中心が移動しました:", center.toUrlValue(6));
});
idle イベントを使えば「移動 or ズーム完了時」にまとめて処理することも可能です。
idle イベントの補足事項。
上記のイベント(zoom_changedやcenter_changed)では、操作中何度も発火します(無駄な処理が増える)
しかし、idle は 「落ち着いた後に1回だけ」なので、API通信や描画などのトリガーに最適な関数と思われます。
ユーザーインターフェース(UI)/マウス操作イベントとき
| click | click・地図がクリックされた |
| dblclick | ダブルクリック時 |
| mousedown / mouseup | マウス押下/リリース |
| mousemove | マウスが移動したとき |
| mouseout / mouseover | ホバー切替時 |
| rightclick | 右クリック時 |
| drag / dragstart / dragend | ドラッグ中・開始・終了時 |
| tilesloaded | 地図タイルが読み込まれたとき |
| idle | 地図の表示が完全に静止したとき |
プロパティ変更イベント
| center_changed | 中心位置が変わったとき |
| zoom_changed | ズームレベルが変わったとき |
| bounds_changed | 表示範囲(緯度経度)が変わったとき |
| projection_changed | 地図投影方法が変わったとき |
| maptypeid_changed | 地図タイプ(地図/航空写真など)が変わったとき |
| heading_changed(ベクター地図) | 地図の回転角が変わったとき |
| tilt_changed | チルト角度が変わったとき |
| fullscreen_changed | フルスクリーン切替時 |
経度緯度のリアルタイムトラッキング
ユーザーの現在位置を取得し、地図上に表示・追従するには HTML5 の Geolocation API を使います。
HTTPS環境でのみ動作します。PC・スマホともに位置情報の許可が必要です。

以下に Geolocation API を使用したあなたのアクセスしている地域を表示します。ブラウザから位置情報取得の許可を求めるポップアップが表示されますので、動作をご確認ください。
https://buspochi.jp/eolocation.html
