ユーザー操作とイベント処理の取得

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)/マウス操作イベントとき

clickclick・地図がクリックされた
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