Google Maps APIを使ってカスタマイズした地図を埋め込む

Google Mapは、ご存知の通り便利な地図サイトです。

お店の位置をお伝えする目的で設置することがときどきあります。
APIを使わない埋め込みも可能ですが、凝ったことをしたい場合はAPIが必要になります。

設置機会がありましたので、Google Maps API(Google Maps Platform API)について調べてきました。
2025年3月から使用時の料金体系が変わったそうで、そのあたりも調べてきました。

地図を埋め込む(初級)

地図を埋め込むのはかんたんです。
住所、施設名で検索すると、該当箇所に赤いピン(マーカー)が立ちます。
Google Map を開いて、共有→地図を埋め込む→HTMLをコピー、だけです。

埋め込みHTMLは以下のようになっています。

コード

<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d13102.882072271374!2d135.53174343828186!3d34.81297261147066!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x6000fcb25f71d869%3A0x65fccb40c464e1e4!2zRVhQTyc3MOODkeODk-ODquOCquODsw!5e0!3m2!1sja!2sjp!4v1742463964803!5m2!1sja!2sjp" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>

WordPressだとかんたんに埋め込み完了。

カスタマイズした地図を埋め込む

カスタマイズした地図を埋め込む場合は、Google APIを利用する必要があります。
API利用にはAPIキーが必要になります。Google Cloud内で取得します。

そのために、GoogleアカウントGoogle Cloudの利用登録が必要になります。

Google Cloud

Google CloudはGoogleが提供するサービスを利用するためのプラットフォームです。
2025年3月時点では、300ドル分(90日)の無制限に利用できる枠がもらえます。
その後は、利用したサービスに応じて、無料枠が設定されていて、超えた分は請求されます(クレジットカードの登録が必要)。

このあと使うことになる、Maps JavaScript APIは10000回/月間まで無料です(2025年4月の情報で、詳細はDynamic Mapsの料金を参照)。

Google Cloud コンソールをクリックし、ナビゲーションメニュー(左上の三本線)から [Google Maps Platform] >[APIとサービス] に移動します。機能が多いのでわりと迷子になりがちです。

Google Maps Platform内には、マップ関連のいろいろなAPIが表示されます。
利用するAPIをEnableにします(表示上は、Disableになっていると利用可能状態)。

KeysリンクからAPIキーを取得します。
APIキーを他人に利用される場合がありますので、利用できるウェブサイトを指定して、ドメインなどで利用制限をかけるのが一般的です。

機能は、Guidesリンクを押すと、紹介されています。地図以外にも、ストリートビュー、3Dなどあります。

Maps JavaScript API…複数のマーカーをセット、カスタムスタイル、情報ウィンドウの表示、イベントなどに使えます。高度にカスタマイズできますので、これがメイン
Geocoding API…住所と地理座標を変換します。
Maps Static API…シンプルな地図を設置します。Maps JavaScript APIの機能簡易版

Maps JavaScript API

カスタマイズした地図を作りたいときに使います。
図形を書いたたり、色を塗ったり、距離を測ったりできるそうですが、ふつうは使う機会もないかなと思います。

また、ライブラリがいくつかあります。必要なライブラリだけ読み込んで使います。
参考)概要  |  Maps JavaScript API  |  Google for Developers

一般的にはこの2つの利用が多いのではないかと思います。

スタイルと色のカスタマイズは、最近の推奨はGoogle Cloud内で行う方法です。
コード側にJSONをつっこんで動作させる例を見かけますが、動作しないことがあります(後述の、mapIDやAdvancedMarkerElementが原因で)。

まずは、地図にマーカーを複数追加する方法を見ていきます。複数店舗ある場合に使えます。
その他、マウスイベント、情報ウィンドウも使えるサンプルコードを書いてみます。

Maps JavaScript APIを使う場合の流れは、APIキーの取得 → HTMLを書く → JavaScriptを書く

APIキーの取得

APIキーは [Google Maps Platform] >[鍵と認証情報] で取得します。
APIキーの制限もここで行います。他サイトで無断で使われないように、使用できるドメインなどを設定し制限します。

カスタマイズ地図を作る

今回のサンプルコードでは、マーカーを3ヶ所に追加して、マーカーの色を赤からオレンジに変えます。
マーカーホバー時に情報ウィンドウが開き、マーカークリック時にズームするようにしています。

HTMLサンプル

<!--スタイルは任意-->
<style>
  #map {height: 100%;}
  h2 {color: #4160ce; margin-top: 0;}
  address {color: #999; font-size: small; margin-bottom: 5px;}
  div {margin-bottom: 5px;}
</style>

<h3>My Google Maps Demo</h3>
<!--The div element for the map -->
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initGeo" async></script>

3行目…地図の設置場所の高さ指定は必須
12行目…Maps JavaScript APIを読込完了後に、callbackで任意の関数を呼び出します。YOUR_API_KEYは各自のキーを入れます

JavaScriptサンプル

let center;
const array = [
  {title:'大阪・関西万博', content:'<h2>2025年大阪・関西万博</h2><address>大阪府大阪市此花区夢洲中1丁目</address><div>会期:2025年4月13日-10月13日</div><a href="https://www.expo2025.or.jp/">website</a>', lat:34.64959500000001, lng: 135.38357394970728},
  {title:'大阪万博', content:'<h2>日本万国博覧会</h2><address>大阪府吹田市千里万博公園</address><div>会期:1970年3月15日-9月13日</div><a href="https://www.expo70-park.jp/">website</a>', lat:34.809860588935784, lng:135.53195480750057},
  {title:'花博', content:'<h2>国際花と緑の博覧会</h2><address>大阪府大阪市鶴見区緑地公園2−163</address><div>会期:1990年4月1日-9月30日</div><a href="http://www.tsurumi-ryokuchi.jp/">website</a>', lat:34.71198776213642, lng:135.57605370935343}
];

async function initGeo() {
  let geocoder;

  //ライブラリを読み込む
  const { Geocoder } = await google.maps.importLibrary("geocoding")

  //addressの住所を座標に変換
  geocoder = new Geocoder();
  geocoder.geocode({
    address: '大阪市',
  }, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      center = results[0].geometry.location;
    }
    initMap();
  });
}

async function initMap() {
  let map;
  let marker=[];
  let infoWindow=[];

  //geocodingを使わずに座標を指定する場合は、以下の通り
  //center = {lat: 34.809860588935784, lng: 135.53195480750057};

  //ライブラリを読み込む
  const { Map } = await google.maps.importLibrary("maps");

  //PinElementも使わない場合はこちら↓
  //const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
  //PinElementも使う場合はこちら↓
  const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");

  //マップを表示する
  map = new Map(document.getElementById("map"), {
    zoom: 12,
    center: center,
    mapId: "DEMO_MAP_ID",
  });

  //マーカーを表示する
  for(let i = 0; i < array.length; i++) {

    //マーカーの色を変更する
    const pinBackground = new PinElement({
      background: "#FBBC04",
    });

    //マーカーを表示する
    marker[i] = new AdvancedMarkerElement({
      map: map,
      position: {lat: array[i].lat, lng: array[i].lng},
      title: array[i].title,
      content: pinBackground.element, //マーカーの色を変更する
    });

    //マーカークリック時にズームする
    marker[i].addListener('gmp-click', function(){
      map.setZoom(15);
      map.setCenter(marker[i].position);
    });

    //マーカーホバー時に情報ウィンドウを表示する
    infoWindow[i] = new google.maps.InfoWindow({
      content: array[i].content,
      ariaLabel: array[i].title,
    });
    marker[i].content.addEventListener('mouseenter', function(){
      //mouseout時にウィンドウを非表示にすると挙動が怪しかったので、こういう仕様にしている
      for(let i = 0; i < array.length; i++) {
        infoWindow[i].close(); 
      }
      infoWindow[i].open(map, marker[i]);
    });
  }
}

2-6行目…情報ウィンドウで表示
8-24行目…Geocoding APIを使うサンプルコードです。Maps JavaScript APIとは別の無料枠を消費します。あらかじめ自分で座標取得できる場合はそうしておくほうが、費用にならなくてよいです
39行目…PinElementはマーカーの色を変える機能
43-47行目…マップ表示。zoom、centerは必須。mapIDはAdvancedMarkerElement利用時に必須
58-63行目…マーカー表示。positionで座標を指示します。3ヶ所あるので配列を使います
72-82行目…情報ウィンドウ表示
76行目Google Maps AdvancedMarker hover listener function not working - Stack Overflow 参照

参考)APIのマニュアル関係
Google Maps JavaScript API v3 Reference  |  Google for Developers
Advanced Markers  |  Maps JavaScript API  |  Google for Developers
Info Window  |  Maps JavaScript API  |  Google for Developers

AdvancedMarkerElement

2024年2月にgoogle.maps.Markerのサポート終了し、google.maps.marker.AdvancedMarkerElementに変更になりました(現状、従来版も動作しますが、非推奨です)。
古いコードを参考にしている場合は注意が必要です。
参考)高度なマーカーに移行する  |  Maps JavaScript API  |  Google for Developers

それに伴って、mapIdの指定が必須になりました。
mapId: "DEMO_MAP_ID", (=コードサンプルで使用できるマップID )で動作しますが、本番時は自前で用意するのが一般的です。

マップIDの作成は、ナビゲーションメニューから [Google Maps Platform] >[マップ管理] で行います。

地図の色を変える

地図の外観のカスタマイズは、Google Cloud内で行うそうです。
AdvancedMarkerElementで必須になったマップIDに、用意した地図のスタイルを紐づけて、サイトに反映させます。
参考)地図をカスタマイズする  |  Maps JavaScript API  |  Google for Developers

ナビゲーションメニューから [Google Maps Platform] >[地図のスタイル] に移動します。
カスタマイズで、ラベルを消したり、色の調整を行います。設定箇所が多いので大変
(同様に、JSON形式で出力してくれるスタイリングウィザードもあります、使いやすい方で調整)。

マップ管理で、スタイルを変更します。「自分のスタイル」が表示されていれば、選択することで、マップIDに紐づけできます。コード内のmapId: "作成したマップID", で呼び出します。

その他機能を付けたい

その他機能を付けたい場合はコードサンプルを参考にするとよさそうです。
参考)Code Samples  |  Maps JavaScript API  |  Google for Developers

おわりに

マニュアルは新旧の仕様が入り混じっていて、結構わかりにくいです。
サンプルコードの結果は、以下の通りです。

コーディングの補足情報

・「map: map,」という箇所は「map,」という風に省略可能。

・Dynamic Library Import を使用する
Maps JavaScript APIは必要な時点で必要なライブラリだけをリクエストして読み込みます。
下記ページを読むと、ライブラリごとのプロパティがわかります。
参考)Library interfaces  |  Maps JavaScript API  |  Google for Developers

・課金関連、マップの初期作成時のトラブルシューティング

・更新によって影響が出た場合、一時的な回避策としてバージョンを指定できる。

v=でバージョンが指定できる

<script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&v=weekly"></script>

執筆者

えいじ@naeco.jp この記事を書いた人

メーカー系情報システム部門出身の個人事業主。
自作するのが好きですぐに試したくなる、凝り性なWebエンジニア。
カラーミーショップ、モールなどのECについて記事にしています。

ご相談・お問い合わせはこちら