maesblog

Google Maps JS APIを使って「住所から緯度経度を取得し地図を検索する」機能を実装する方法

このブログでもちょいちょい紹介している写真公開用ブログの方で掲載した写真の場所を示す地図を表示させる機能をGoogle Maps JavaScript API V3を使って実装しました。その辺の実装方法をまとめようと思ていますが、その前にその機能の基礎となるキーワードからの地図検索機能の実装方法をまとめておきます。Google Maps JavaScript APIを使うと凄く簡単に実装することができます。

サンプル

以下サンプルになります。キーワード入力フォームに[住所]、[建物名]、[緯度経度(緯度と軽度の間はカンマ区切り)]などを入力して、「地図検索」ボタンを押すと、フォームの下のスペースに地図が表示されるようになっています。

地図検索機能サンプル

Google Maps APIの概要

そもそもGoogle Maps APIとは?

まず最初にGoogle Maps APIについて簡単に説明しておきます。場所を調べる時にGoogle Maps(Googleマップ)を利用される方も多いと思いますが、このGoogle Mapsの機能を自分のWebサイトやアプリなどに追加したい時に利用するツールとなります。Google Mapsの多くの機能を実装するにはいろんな情報にアクセスする必要があります。そうした情報を簡単に扱えるようにGoogleが用意してくれたツールがGoogle Maps APIということになります。

今回利用したGoogle Maps JavaScript APIは、そのGoogle Maps APIの中のひとつの機能となり、JavaScriptを使ってGoogle Mapsの機能を簡単に扱えるようにしたツールとなっています。現在の正式なバージョンは「3」となります。

ドキュメント類、参考サイト、本

Google Maps APIは日本語のドキュメントもしっかり用意されていてかなり充実しています。なので、公式ドキュメントだけでも十分と言えば十分ですが、併せて参考になりそうなWebサイトと本を紹介します。

デベロッパー向け Google マップ資料
Googleの公式ドキュメントです。全部目を通したわけではないですが、ほぼ全て日本語版となっています。ページも見やすく、内容もかなり充実しています。
Google Maps API入門 (全19回) – プログラミングならドットインストール
おなじみドットインストールのGoogle Mpas APIのレッスンページ。動画で実演してくれるのがありがたいですね。時間のある方はぜひ。
Geekなぺーじ:Google Maps JavaScript APIプログラミング
こちらのサイトもかなり詳しい説明が書いてあります。ポイントごとに記事が書かれているので、やりたいことがピンポイントで確認できます。そういう意味ではかなり重宝するのではないでしょうか。
Google API Expertが解説する Google Maps APIプログラミングガイド
本で持っておきたいという方にはこちらオススメの本です。何と言ってもこの本はGoogleが認定したGoogle Maps API担当のExpert4名が実践を交えて解説してくれています。内容もかなり充実しています。

Google Maps JavaScript APIを使う上での注意点

Google Maps JavaScript APIを営利目的で利用する場合、地図の読み込み制限があり、1日あたり最大25,000回まで許可されます。営利目的のウェブサイトで毎日継続的に使用制限を超過している場合は、Google Maps API for Businessライセンスを購入などする必要があります。詳細は以下でご確認可能です。

なお、非営利団体は、使用制限の対象にはなりません。またGoogle Earth Outreach Grantに申し込み適格な非営利団体と認められれば、無償でGoogle Maps API for Businessライセンスが供与されるということです。

実装方法

では、さっそく実装方法について説明していきます。手順ごとに3つに分けて説明します。

地図を表示させる – Hello World

Googleのドキュメントにもあるように、以下のソースコードで地図を表示させることが可能です。

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

    <style type="text/css">
      html { height: 100% }
      body { height: 100%; margin: 0; padding: 0 }
      #map_canvas { height: 100% }
    </style>

    <!-- Google Maps APIを読み込む -->
    <script type="text/javascript"
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&sensor=SET_TO_TRUE_OR_FALSE">
    </script>

    <!-- initialize()関数を定義 -->
    <script type="text/javascript">
      function initialize() {
        // 地図を表示する際のオプションを設定
        var mapOptions = {
          center: new google.maps.LatLng(-34.397, 150.644),
          zoom: 8,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        // Mapオブジェクトに地図表示要素情報とオプション情報を渡し、インスタンス生成
        var map = new google.maps.Map(document.getElementById("map_canvas"),
            mapOptions);
      }
    </script>
  </head>

  <!-- ページが読み込まれたらinitialize()関数を実行 -->
  <body onload="initialize()">
    <!-- 地図を表示させる要素。widthとheightを必ず指定する。 -->
    <div id="map_canvas" style="width:100%; height:100%"></div>
  </body>
</html>

まず大事なポイントとしては、Google Maps APIをページに読み込んでおくということです。以下をheadタグ内に記述します。その際にAPIキーを取得してAPIのURLに埋め込みんでおきます。sensorパラメータも必須項目となり、ユーザーの位置情報を取得するのにセンサー(GPSなど)を使用するかどうかtrue、falseで設定します。

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&sensor=SET_TO_TRUE_OR_FALSE"></script>

地図を表示させる処理はinitialize()関数に定義して、ページが読み込まれた後に実行するようになっています。initialize()関数の中では、google.maps.Map()コンストラクタに地図を表示させる要素情報(第一引数)と地図表示に関するオプション情報(第二引数)を渡して、地図を表示させるインスタンスを生成しています。ここで注意が必要なことは、第一引数に指定する地図を表示させる要素は必ずdocument.getElementById()メソッドで指定するということです。

var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

地図表示に関するオプションに関しては以下のようなオブジェクトリテラルで定義します。

var mapOptions = {
  // 地図の中心点となる位置情報(緯度, 経度)
  center: new google.maps.LatLng(-34.397, 150.644),
  // 地図nズームレベル 数字が大きい程ズームイン
  zoom: 8, 
  // 地図のタイプ ROADMAP、HYBRIDなど
  mapTypeId: google.maps.MapTypeId.ROADMAP
};

以上でWebサイトやアプリなどで地図を表示することができるようになりますが、ここでひとつやっかいなことがあります。表示させたい場所を指定するには、その場所の緯度と経度の情報が必要であるということです。おそらく自分の知りたい場所の緯度と経度をちゃんと把握している人なんていないでしょう。

そこで、「住所」を地理的位置に変換する「ジオコーディング」処理が必要となってきます。キーワードから地図検索する機能を実装するにも、この処理が必要となってきます。この「ジオコーディング」については、Google Maps APIでちゃんとサポートされています。この「ジオコーディング」の実装については次の項目で説明しますが、「ジオコーディング」を実装すると以下のような住所を緯度経度に変換する機能なんかも作ることができます。

住所を緯度経度に変換する機能

住所から緯度・経度情報を取得する – ジオコーディング

ジオコーディングは住所から緯度・経度情報を取得することを言い、Google Maps APIでもサポートされています。詳細はGoogleのドキュメントを見るのが一番だと思います。

今回のサンプルでは、ジオコーディングの処理用に以下のようなcodeAddress()関数を定義しました。引数に「住所」情報を指定することで、緯度・経度情報に変換して、地図に反映する仕組みになっています。

function codeAddress(address) {
  // google.maps.Geocoder()コンストラクタのインスタンスを生成
  var geocoder = new google.maps.Geocoder();

  // 地図表示に関するオプション
  var mapOptions = {
    zoom: 18,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    // マウスホイールによるズーム操作を無効
    scrollwheel: false
  };

  // 地図を表示させるインスタンスを生成
  var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

  // geocoder.geocode()メソッドを実行 
  geocoder.geocode( { 'address': address}, function(results, status) {
    // ジオコーディングが成功した場合
    if (status == google.maps.GeocoderStatus.OK) {
      // google.maps.Map()コンストラクタに定義されているsetCenter()メソッドで
      // 変換した緯度・経度情報を地図の中心に表示
      map.setCenter(results[0].geometry.location);

      // 地図上に目印となるマーカーを設定います。
      // google.maps.Marker()コンストラクタにマーカーを設置するMapオブジェクトと
      // 変換した緯度・経度情報を渡してインスタンスを生成
      // →マーカー詳細
      var marker = new google.maps.Marker({
        map: map,
        position: results[0].geometry.location
      });
    // ジオコーディングが成功しなかった場合
    } else {
      console.log('Geocode was not successful for the following reason: ' + status);
    } 
  });
}

ここでポイントとなるのが、google.maps.Geocoder()オブジェクトのgeocode()メソッドです。geocode()メソッドはジオコーディングサービスへのリクエストを開始します。サンプルではnewでgoogle.maps.Geocoder()のインスタンスを生成してgeocoder.geocode()として実行しています。

引数には、GeocodeRequestオブジェクトリテラル(第一引数)と、ジオコーダの結果が取得されたときに実行するコールバックメソッド(第二引数)を指定します。第二引数に指定するコールバックには、結果(results)と状態(status)を受け取る2つのパラメータを指定します。

処理の流れとしては、以下のようになっています。

  1. まず位置情報を指定せずに上記のinitialize()関数と同じ処理を実行します。
  2. 次に取得した住所をジオコーディングサービスを使って、緯度経度情報に変換し、その結果を受け取ってコールバック関数に渡します。
  3. コールバック関数では、変換した緯度経度情報を地図に反映させ、さらにマーカーを設置します。

なお、ジオコーディングサービスを利用する上での注意点として、Google Geocoding APIには使用制限があります。1日あたりの位置情報リクエストが2,500回に制限されています(Google Maps API for Business利用者は、1日あたり100,000件までリクエスト実行可能)。また、Google Geocoding APIはGoogleマップ上の結果表示と組み合わせる場合にのみ使用でき、地図に表示せずにジオコーディングの結果だけを利用することは禁止されています。詳細は以下でご確認可能です。

検索フォームを実装する

最後に検索フォームの実装です。サンプルのフォームは以下のようになっています。

<form>
  <input type="text" value="東京スカイツリー" id="address">
  <input type="button" value="地図検索" id="button">
</form>

JavaScript部分は以下の通りです。

<script>
// ボタンに指定したid要素を取得
var button = document.getElementById("button");

// ボタンが押された時の処理
button.onclick = function() {
  // フォームに入力された住所情報を取得
  var address = document.getElementById("address").value;
  // 取得した住所を引数に指定してcodeAddress()関数を実行
  codeAddress(address);
}
</script>

まとめると

まとめるとサンプルのソースコードは以下のようになります。意外と忘れがちなのが、地図を表示させる要素のwidthとheightの指定です。ちゃんと処理は書けているはずなのに、要素の幅と高さの指定がないために地図が表示されなくてハマることがあるので注意です。

HTML

<form>
  <input type="text" value="東京スカイツリー" id="address">
  <input type="button" value="地図検索" id="button">
</form>

<!-- 地図を表示させる要素 -->
<div id="map-canvas"></div>

CSS

/* 地図を表示させる要素の幅、高さなどを指定 */
#map-canvas {
  width: 100%;
  height: 200px;
  background-color: #e7e7e7;
}

JavaScript

var getMap = (function() {
  function codeAddress(address) {
    // google.maps.Geocoder()コンストラクタのインスタンスを生成
    var geocoder = new google.maps.Geocoder();

    // 地図表示に関するオプション
    var mapOptions = {
      zoom: 18,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      // マウスホイールによるズーム操作を無効
      scrollwheel: false
    };

    // 地図を表示させるインスタンスを生成
    var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

    // geocoder.geocode()メソッドを実行 
    geocoder.geocode( { 'address': address}, function(results, status) {
      // ジオコーディングが成功した場合
      if (status == google.maps.GeocoderStatus.OK) {
        // google.maps.Map()コンストラクタに定義されているsetCenter()メソッドで
        // 変換した緯度・経度情報を地図の中心に表示
        map.setCenter(results[0].geometry.location);

        // 地図上に目印となるマーカーを設定います。
        // google.maps.Marker()コンストラクタにマーカーを設置するMapオブジェクトと
        // 変換した緯度・経度情報を渡してインスタンスを生成
        // →マーカー詳細
        var marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
        });
      // ジオコーディングが成功しなかった場合
      } else {
        console.log('Geocode was not successful for the following reason: ' + status);
      } 
    });
  }

  return {
    getAddress: function() {    
      // ボタンに指定したid要素を取得
      var button = document.getElementById("button");

      // ボタンが押された時の処理
      button.onclick = function() {
        // フォームに入力された住所情報を取得
        var address = document.getElementById("address").value;
        // 取得した住所を引数に指定してcodeAddress()関数を実行
        codeAddress(address);
      }    
    }
  };
})();

getMap.getAddress();

以上、Google Maps JavaScript APIを使って「キーワードから緯度経度を取得し地図を検索する」機能を実装する方法となります。今回の機能は今後Google Maps APIを使っていく上での基礎となります。ドキュメントが膨大であることからもわかるように、Google Maps APIはかなりの機能を持っています。いろんな機能を盛り込んで、面白いサービス作りたいですね。

関連記事

コメント

  • 必須

コメント