Google Maps JavaScript API で地図とマーカーと情報ウインドウ

# はじめに

[APIキー](https://www.google.com/search?q=google+maps+platform+api+key+qiita)未使用のコードなので [For development purposes only](https://www.google.com/search?q=google+maps+for+development+purposes+only&tbm=isch) の表示になります。

# 単一marker

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { width: 100%; height: 100%; }
body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
// 即時関数
(() => {
  // 地図の設定と作成
  const map = new google.maps.Map(document.getElementById('map'), {
    center: { lat: 30.37486500, lng: 130.9576461 },
    zoom: 14,
  });
  // マーカーの設定と作成
  const marker = new google.maps.Marker({
    position: { lat: 30.37486500, lng: 130.9576461 },
    title: 'popup-title',
    icon: '',
    // icon: 'https://placehold.jp/cc9999/993333/32x32.png',
    // iconにurlを指定すればマーカーイメージの変更が可能
    map, // map: map, のショートハンド
  });
  // 情報ウインドウの設定と作成
  const infoWindow = new google.maps.InfoWindow({
    content: '<h3>test</h3><p>hogehoge</p>',
  });
  // 情報ウインドウのオープンをマーカーのクリックイベントに登録
  marker.addListener('click', () => {
    infoWindow.open(map, marker);
  });
  // 情報ウインドウのオープン
  infoWindow.open(map, marker);
})();
</script>
</body>
</html>
```

# 複数marker

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { width: 100%; height: 100%; }
body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
// 即時関数
(() => {
  // 地図情報
  const mapData = {
    map: undefined,
    pos: {
      lat: 30.37486500,
      lng: 130.9576461,
    },
    zoom: 14,
  };
  // マーカー情報(情報ウインドウ含む)
  const markerData = [
    {
      marker: undefined,
      pos: {
        lat: 30.37486500,
        lng: 130.9576461,
      },
      title: 'popup-title1',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: true,
      infoWindowContent: '<h3>test1</h3><p>hogehoge</p>',
    },
    {
      marker: undefined,
      pos: {
        lat: 30.39205130,
        lng: 130.9612252,
      },
      title: 'popup-title2',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: false,
      infoWindowContent: '<h3>test2</h3><p>fugafuga</p>',
    },
    {
      marker: undefined,
      pos: {
        lat: 30.40160000,
        lng: 130.9674100,
      },
      title: 'popup-title3',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: false,
      infoWindowContent: '<h3>test3</h3><p>piyopiyo</p>',
    },
  ];
  // 地図の設定と作成
  mapData.map = new google.maps.Map(document.getElementById('map'), {
    center: mapData.pos,
    zoom: mapData.zoom,
  });
  markerData.forEach((md, i) => {
    // マーカーの設定と作成
    markerData[i].marker = new google.maps.Marker({
      position: md.pos,
      title: md.title,
      icon: md.icon,
      map: mapData.map,
    });
    if (md.infoWindowContent) {
      // 情報ウインドウの設定と作成
      markerData[i].infoWindow = new google.maps.InfoWindow({
        content: md.infoWindowContent,
      });
      // 情報ウインドウのオープンをマーカーのクリックイベントに登録
      md.marker.addListener('click', () => {
        md.infoWindow.open(mapData.map, md.marker);
      });
      // 情報ウインドウのオープン
      if (md.infoWindowOpen) {
        md.infoWindow.open(mapData.map, md.marker);
      }
    }
  });
})();
</script>
</body>
</html>
```

# 地図の中心の緯度と経度と縮尺を自動調整

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { width: 100%; height: 100%; }
body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
// 即時関数
(() => {
  // 地図情報
  const mapData = {
    map: undefined,
    pos: {
      lat: 30.37486500,
      lng: 130.9576461,
    },
    zoom: 14,
    fitBounds: undefined,
    fitBoundsFlag: true,
  };
  // マーカー情報(情報ウインドウ含む)
  const markerData = [
    {
      marker: undefined,
      pos: {
        lat: 30.37486500,
        lng: 130.9576461,
      },
      title: 'popup-title1',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: true,
      infoWindowContent: '<h3>test1</h3><p>hogehoge</p>',
    },
    {
      marker: undefined,
      pos: {
        lat: 30.39205130,
        lng: 130.9612252,
      },
      title: 'popup-title2',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: false,
      infoWindowContent: '<h3>test2</h3><p>fugafuga</p>',
    },
    {
      marker: undefined,
      pos: {
        lat: 30.40160000,
        lng: 130.9674100,
      },
      title: 'popup-title3',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: false,
      infoWindowContent: '<h3>test3</h3><p>piyopiyo</p>',
    },
  ];
  // 地図の設定と作成
  mapData.map = new google.maps.Map(document.getElementById('map'), {
    center: mapData.pos,
    zoom: mapData.zoom,
  });
  // 地図の中心の緯度と経度と縮尺の設定
  mapData.fitBounds = new google.maps.LatLngBounds();
  markerData.forEach((md, i) => {
    // マーカーの設定と作成
    markerData[i].marker = new google.maps.Marker({
      position: md.pos,
      title: md.title,
      icon: md.icon,
      map: mapData.map,
    });
    if (md.infoWindowContent) {
      // 情報ウインドウの設定と作成
      markerData[i].infoWindow = new google.maps.InfoWindow({
        content: md.infoWindowContent,
      });
      // 情報ウインドウのオープンをマーカーのクリックイベントに登録
      md.marker.addListener('click', () => {
        md.infoWindow.open(mapData.map, md.marker);
      });
      // 情報ウインドウのオープン
      if (md.infoWindowOpen) {
        md.infoWindow.open(mapData.map, md.marker);
      }
      // 地図の中心の緯度と経度と縮尺の設定
      mapData.fitBounds.extend(new google.maps.LatLng(md.pos));
    }
  });
  // 地図の中心の緯度と経度と縮尺の設定
  if (mapData.fitBoundsFlag) {
    mapData.map.fitBounds(mapData.fitBounds);
  }
})();
</script>
</body>
</html>
```

# 表示される情報ウインドウは一個までだけ

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { width: 100%; height: 100%; }
body { width: 100%; height: 100%; margin: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
// 即時関数
(() => {
  // 地図情報
  const mapData = {
    map: undefined,
    pos: {
      lat: 30.37486500,
      lng: 130.9576461,
    },
    zoom: 14,
    fitBounds: undefined,
    fitBoundsFlag: true,
    infoWindowLatest: undefined,
    infoWindowAutoClose: true,
  };
  // マーカー情報(情報ウインドウ含む)
  const markerData = [
    {
      marker: undefined,
      pos: {
        lat: 30.37486500,
        lng: 130.9576461,
      },
      title: 'popup-title1',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: true,
      infoWindowContent: '<h3>test1</h3><p>hogehoge</p>',
    },
    {
      marker: undefined,
      pos: {
        lat: 30.39205130,
        lng: 130.9612252,
      },
      title: 'popup-title2',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: false,
      infoWindowContent: '<h3>test2</h3><p>fugafuga</p>',
    },
    {
      marker: undefined,
      pos: {
        lat: 30.40160000,
        lng: 130.9674100,
      },
      title: 'popup-title3',
      icon: '',
      infoWindow: undefined,
      infoWindowOpen: false,
      infoWindowContent: '<h3>test3</h3><p>piyopiyo</p>',
    },
  ];
  // 地図の設定と作成
  mapData.map = new google.maps.Map(document.getElementById('map'), {
    center: mapData.pos,
    zoom: mapData.zoom,
  });
  // 地図の中心の緯度と経度と縮尺の設定
  mapData.fitBounds = new google.maps.LatLngBounds();
  markerData.forEach((md, i) => {
    // マーカーの設定と作成
    markerData[i].marker = new google.maps.Marker({
      position: md.pos,
      title: md.title,
      icon: md.icon,
      map: mapData.map,
    });
    if (md.infoWindowContent) {
      // 情報ウインドウの設定と作成
      markerData[i].infoWindow = new google.maps.InfoWindow({
        content: md.infoWindowContent,
      });
      // 情報ウインドウのオープンをマーカーのクリックイベントに登録
      md.marker.addListener('click', () => {
        if (mapData.infoWindowLatest && mapData.infoWindowAutoClose) {
          mapData.infoWindowLatest.close();
        }
        md.infoWindow.open(mapData.map, md.marker);
        mapData.infoWindowLatest = md.infoWindow;
      });
      // 情報ウインドウのオープン
      if (md.infoWindowOpen) {
        if (mapData.infoWindowLatest && mapData.infoWindowAutoClose) {
          mapData.infoWindowLatest.close();
        }
        md.infoWindow.open(mapData.map, md.marker);
        mapData.infoWindowLatest = md.infoWindow;
      }
      // 地図の中心の緯度と経度と縮尺の設定
      mapData.fitBounds.extend(new google.maps.LatLng(md.pos));
    }
  });
  // 地図の中心の緯度と経度と縮尺の設定
  if (mapData.fitBoundsFlag) {
    mapData.map.fitBounds(mapData.fitBounds);
  }
})();
</script>
</body>
</html>
```

<!--

# DEMO

http://bl.ocks.org/feo52/raw/f19a7c21545696fa50049d310c54d938/

https://gist.github.com/feo52/f19a7c21545696fa50049d310c54d938

-->

# 参考情報

https://developers.google.com/maps/documentation/javascript/
https://developers.google.com/maps/documentation/javascript/overview
https://developers.google.com/maps/documentation/javascript/get-api-key

https://developers.google.com/maps/documentation/javascript/markers
https://developers.google.com/maps/documentation/javascript/infowindows
https://developers.google.com/maps/documentation/javascript/advanced-markers/

https://developers.google.com/maps/documentation/javascript/reference
https://developers.google.com/maps/documentation/javascript/reference/map
https://developers.google.com/maps/documentation/javascript/reference/marker
https://developers.google.com/maps/documentation/javascript/reference/info-window
https://developers.google.com/maps/documentation/javascript/reference/advanced-markers

https://developers.google.com/maps/documentation/javascript/examples/
https://developers.google.com/maps/documentation/javascript/examples/map-simple
https://developers.google.com/maps/documentation/javascript/examples/marker-simple
https://developers.google.com/maps/documentation/javascript/examples/icon-simple
https://developers.google.com/maps/documentation/javascript/examples/event-simple
https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple

## あとがき

ノンプログラマーの素人が記述をしたコードです。
狭い利用範囲と少ない利用頻度での確認ですので、
記載内容に間違いや勘違いがあるかもしれません。
上記内容を参照の際は自己責任でお願い致します。