デルタ システム ソリューションズ 株式会社

【住所⇔緯度・経度】位置情報の相互変換(1/3)

技術情報 JavaScript Google Maps 作り方
更新日:2016/12/14
この記事は、2019年4月10日に一部内容を見直し再編集しました。

皆さん、住所から緯度・経度、緯度・経度から住所を知りたいことってありますよね?

え?今までそんな状況になったことがない?
まぁ、普段あまり意識しませんが、地図と連携したサービスを考えた時には必要になってくる技術です。
皆さんもよくお使いのGoogleマップ。
それがまさに、緯度・経度から住所、住所から緯度・経度を変換する技術の結晶なんですよね。

今回はGoogle Maps APIを使用して、住所変換遊びをしてみましょ!

住所から緯度・経度を取得

住所から緯度・経度を取得する技術を『ジオコーディング』と言います。

Googleマップは住所だけでなく、ランドマーク名での検索も可能です。
下の【サンプル1】にて、ためしに「大坂城」で「緯度・経度取得」ボタンを押してみてください。

【サンプル1】
 住所→緯度・経度



★結果★
昔の表記の「大坂城」で検索しましたが、現代表記の「大阪城」でも同じ結果が取得できます。
「大坂城」「大阪城」の両方のランドマーク名が、同じ場所に登録されているようです。
尚、同じキーワードで複数の緯度・経度が登録されている場合は、複数件の結果が返ってきます。

【編集注】
ちなみに、2016年12月時点の検索結果はこうでした。
2019年4月には検索結果も変化しました。

では、結果がわかりやすいように地図で表示してみましょう。
緯度・経度がわかれば、Googleマップに表示することも簡単です。

【サンプル2】
 住所→緯度・経度→Googleマップ表示



自宅の住所や観光地名等、いろいろな住所で試してみてください!
サンプル1、サンプル2のソースはこちらです。
ソースを見ていただくと、意外とシンプルに実装できるということがわかります。

【サンプル1ソース】
 住所→緯度・経度
<div>
  <input type="text" id="addressInput" value="大坂城" style="width: 250px">
  <input type="button" value="緯度・経度取得" onclick="getIdoKeido();">
  <br /><br />
  ★結果★<br />
  <textarea id="idokeidoOutput" rows="3" cols="26"></textarea>
</div>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=xxxxxxxxxx"></script>
<!--「key=xxxxxxxxxx」にはGoogleで取得したAPIキーを記述します -->

<script type="text/javascript">
function getIdoKeido() {

  //入力した住所を取得します。
  var addressInput = document.getElementById('addressInput').value;

  //Google Maps APIのジオコーダを使います。
  var geocoder = new google.maps.Geocoder();
  
  //ジオコーダのgeocodeを実行します。
  //第1引数のリクエストパラメータにaddressプロパティを設定します。
  //第2引数はコールバック関数です。取得結果を処理します。
  geocoder.geocode(
    {
      address: addressInput
    },
    function(results, status) {
      
      var idokeido = "";
      
      if (status == google.maps.GeocoderStatus.OK) {
      //取得が成功した場合
        
        //結果をループして取得します。
        for (var i in results) {
          if (results[i].geometry) {
          
            //緯度を取得します。
            var ido = results[i].geometry.location.lat();
            //経度を取得します。
            var keido = results[i].geometry.location.lng();
            
            idokeido += "■緯度:" + ido + "\n 経度:" + keido + "\n";
          }
        }
      } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
        alert("住所が見つかりませんでした。");
      } else if (status == google.maps.GeocoderStatus.ERROR) {
        alert("サーバ接続に失敗しました。");
      } else if (status == google.maps.GeocoderStatus.INVALID_REQUEST) {
        alert("リクエストが無効でした。");
      } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
        alert("リクエストの制限回数を超えました。");
      } else if (status == google.maps.GeocoderStatus.REQUEST_DENIED) {
        alert("サービスが使えない状態でした。");
      } else if (status == google.maps.GeocoderStatus.UNKNOWN_ERROR) {
        alert("原因不明のエラーが発生しました。");
      }
      
      //緯度・経度の結果表示をします。
      document.getElementById('idokeidoOutput').value = idokeido;
    });
}
</script>

【サンプル2ソース】
 住所→緯度・経度→Googleマップ表示
<div>
  <input type="text" id="addressInput2" value="大坂城" style="width: 250px">
  <input type="button" value="緯度・経度取得" onclick="getIdoKeidoMap();">
  <br /><br />
  <div id="mapArea" style="width:250px; height:600px; border: 1px solid"></div>
</div>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=xxxxxxxxxx"></script>
<!--「key=xxxxxxxxxx」にはGoogleで取得したAPIキーを記述します -->

<script type="text/javascript">
//地図の初期表示
new google.maps.Map(document.getElementById("mapArea"), {
  zoom: 5,
  center: new google.maps.LatLng(36,138),
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

function getIdoKeidoMap() {

  var addressInput = document.getElementById('addressInput2').value;
  var geocoder = new google.maps.Geocoder();

  geocoder.geocode({
    address: addressInput
  }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {

      //Mapクラスのインスタンスを生成します。
      var map = new google.maps.Map(
        document.getElementById("mapArea"),
        {
          mapTypeId: google.maps.MapTypeId.ROADMAP
        }
      );
      
      //表示範囲クラスのインスタンスを生成します。
      var bounds = new google.maps.LatLngBounds();
      
      for (var i in results) {
        if (results[i].geometry) {

          //緯度・経度情報を取得します。
          var latlng = results[i].geometry.location;

          //住所を取得します。
          var address = results[i].formatted_address;

          //取得した緯度・経度で表示範囲を拡張します。
          bounds.extend(latlng);

          //地図上に緯度・経度、住所の情報を表示します。
          new google.maps.InfoWindow(
            {
              content: "(緯度, 経度) = " + latlng.toString() +
                       "<br />" + address
            }
          ).open(
            map,
            new google.maps.Marker(
              {
                position: latlng,
                map: map
              }
            )
          );
        }
      }

      //表示範囲に移動します。
      map.fitBounds(bounds);
      //地図のズームを設定します。
      map.setZoom(15);

    } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
      alert("住所が見つかりませんでした。");
    } else if (status == google.maps.GeocoderStatus.ERROR) {
      alert("サーバ接続に失敗しました。");
    } else if (status == google.maps.GeocoderStatus.INVALID_REQUEST) {
      alert("リクエストが無効でした。");
    } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
      alert("リクエストの制限回数を超えました。");
    } else if (status == google.maps.GeocoderStatus.REQUEST_DENIED) {
      alert("サービスが使えない状態でした。");
    } else if (status == google.maps.GeocoderStatus.UNKNOWN_ERROR) {
      alert("原因不明のエラーが発生しました。");
    }
  });
}
</script>

1

あなたへのおすすめ記事