Google Maps(グーグルマップ)上に現在位置を表示する方法

今回は、グーグルマップ上に、現在位置を表示させる方法です。

グーグルマップを使いますが、現在位置情報の取得にはGoogle Maps APIを利用するわけではありません。

なお、Google Maps関連の記事についてはこちらにまとめてありますので、ご覧ください。

Google Maps(グーグルマップ)上に現在位置を表示する方法

サンプル

「現在位置」ボタンを押してみてください。


タイムスタンプ
緯度
経度
位置(正確さ)
高度
高度(正確さ)
方角
速度
エラーコード
エラーメッセージ

HTMLコード

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
   <title>Sample Map</title>
   <script defer
       src="https://maps.googleapis.com/maps/api/js?key=(APIキー)&callback=initMap" >
   </script>
   <style type="text/css">
      #map_canvas {
         width: 100%;
         height:50%;
      }
      html,
      body {
         height: 100%;
         margin: 0;
         padding: 0;
      }
   </style>
   <script type="text/javascript">
      var map;
      var marker;
      var circle;

      function initMap() {
         var myLatlng = new google.maps.LatLng(35.683755,139.745625);
         var mapOptions = {
           zoom: 14,
           center: myLatlng
         }
         map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
      }

      function success(pos) {
         var crd = pos.coords;
         var timeStamp = pos.timestamp;

         document.getElementById('tdTime').innerHTML = timeStamp;

         var currentPos = new google.maps.LatLng( crd.latitude, crd.longitude);
 
         if ( marker != undefined )  marker.setMap(null);
         if ( circle != undefined )  circle.setMap(null);

         /* 現在位置にマーカーを設定 */
         marker =  new google.maps.Marker({ position: currentPos ,map: map});

         /* 位置の誤差領域 */
         circle = new google.maps.Circle({
            strokeColor: "#3333FF",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#3333FF",
            fillOpacity: 0.35,
            map: map,
            draggable: false,
            center: currentPos,
            radius: crd.accuracy   /* 位置の誤差(m)を半径とする */
         });
         map.setCenter(currentPos);
         map.setZoom(14);
         setInfo(crd);
      }
      function error(err) {
         document.getElementById('tdErrCd').innerHTML = err.code;
         document.getElementById('tdErrMg').innerHTML = err.message;
      }
      function setInfo(crd) {
         document.getElementById('tdLat').innerHTML = crd.latitude;
         document.getElementById('tdLng').innerHTML = crd.longitude;
         document.getElementById('tdAcrPos').innerHTML = crd.accuracy + 'm';
         document.getElementById('tdAlt').innerHTML = crd.altitude;
         document.getElementById('tdAcrAlt').innerHTML = crd.altitudeAccuracy;
         document.getElementById('tdHdg').innerHTML = crd.heading;
         document.getElementById('tdSpd').innerHTML = crd.speed;
      }
      function clearInfo() {
         document.getElementById('tdTime').innerHTML = '';
         document.getElementById('tdLat').innerHTML = '';
         document.getElementById('tdLng').innerHTML = '';
         document.getElementById('tdAcrPos').innerHTML = '';
         document.getElementById('tdAlt').innerHTML = '';
         document.getElementById('tdAcrAlt').innerHTML = '';
         document.getElementById('tdHdg').innerHTML = '';
         document.getElementById('tdSpd').innerHTML = '';
         document.getElementById('tdErrCd').innerHTML ='';
         document.getElementById('tdErrMg').innerHTML = '';
      }
      function getPosition() {
         clearInfo();
         var options = {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
         };
         navigator.geolocation.getCurrentPosition(success, error, options);
      }
   </script>
</head>
<body>
   <div id="map_canvas"></div>
   <br /><input type="button" value="現在位置" onclick="getPosition();" />
   <p>
   <table style="width:100%">
      <tr><th style="width=50%">タイムスタンプ</th><td id="tdTime"></td></tr>
      <tr><th>緯度</th><td id="tdLat"></td></tr>
      <tr><th>経度</th><td id="tdLng"></td></tr>
      <tr><th>位置(正確さ)</th><td id="tdAcrPos"></td></tr>
      <tr><th>高度</th><td id="tdAlt"></td></tr>
      <tr><th>高度(正確さ)</th><td id="tdAcrAlt"></td></tr>
      <tr><th>方角</th><td id="tdHdg"></td></tr>
      <tr><th>速度</th><td id="tdSpd"></td></tr>
      <tr><th>エラーコード</th><td id="tdErrCd"></td></tr>
      <tr><th>エラーメッセージ</th><td id="tdErrMg"></td></tr>
   </table>
   </p>
</body>
</html>

デモ

Web API「Geolocation」を利用し、現在位置を取得する

Geolocation

現在位置情報などの情報は「Geolocation」を利用することになります。

「Geolocation」には3つのメソッドを利用できますが、「getCurrentPosition()」を利用します。

現在位置取得

名前からもわかる通り、「getCurrentPosition()」を利用すると、現在位置情報を取得することができます。

サンプルでは「現在位置」ボタンを押すと、「getCurrentPosition()」メソッドを呼び出すようにしてあります。

      function getPosition() {
         clearInfo();
         var options = {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
         };
         navigator.geolocation.getCurrentPosition(success, error, options);
      }

パラメータ(引数)

success現在位置の取得に成功した場合に呼ばれるコールバック関数を指定してください。
コールバック関数には引数としてGeolocationPosition オブジェクトが渡されます
error現在位置の取得に失敗した場合に呼ばれるコールバック関数。省略可能。
コールバック関数には引数としてGeolocationPositionError オブジェクトが渡されます
options現在位置を実行する際のオプションになります。省略可能。
PositionOptions型の値を渡すことになります。
getCurrentPosition()の引数

options

第3パラメータの「options」はPositionOptions型になります。

PositionOptions型は以下のような構造体です。以下の値をパラメータとして指定することができます。

enableHighAccuracy高精度の結果を求めることを表す Boolean 型
true:高精度の位置情報取得
false:高精度ではない位置取得
デフォルトでは「false」
falseだと電力消費が抑えられたり結果の応答が速かったりするそうです
timeoutタイムアウト時間(ミリ秒)
デフォルトでは「Infinity」で無制限になります。
maximumAge位置情報の有効期限 (ミリ秒)
有効期限内の場合は、キャッシュから位置情報を返すことになります。
デフォルトは「0」なので、毎回最新位置情報を取得することになります。

位置情報取得成功

getCurrentPosition()で最新位置情報の取得に成功した場合には、第1引数で設定したコールバック関数が呼び出されます。

      function success(pos) {
         var crd = pos.coords;
         var timeStamp = pos.timestamp;

         document.getElementById('tdTime').innerHTML = timeStamp;

         var currentPos = new google.maps.LatLng( crd.latitude, crd.longitude);
 
         if ( marker != undefined )  marker.setMap(null);
         if ( circle != undefined )  circle.setMap(null);

         /* 現在位置にマーカーを設定 */
         marker =  new google.maps.Marker({ position: currentPos ,map: map});

         /* 位置の誤差領域 */
         circle = new google.maps.Circle({
            strokeColor: "#3333FF",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#3333FF",
            fillOpacity: 0.35,
            map: map,
            draggable: false,
            center: currentPos,
            radius: crd.accuracy   /* 位置の誤差(m)を半径とする */
         });
         map.setCenter(currentPos);
         map.setZoom(14);
         setInfo(crd);
      }

位置情報の取得に成功すると「getCurrentPosition()」の第一引数で指定した関数が呼び出されます。

第一引数の関数には「GeolocationPosition」のオブジェクトが引数としてわたされて呼び出されます。

GeolocationPositionは二つの情報を持つ構造体です。

coords現在位置を示す GeolocationCoordinates オブジェクト
timestamp位置情報が取得された時間を表す DOMTimeStamp オブジェクト
ミリ秒単位の絶対値または相対値のようです。

具体的な位置情報はGeolocationCoordinatesオブジェクトの「coords」が保持しています。

GeolocationCoordinatesオブジェクトは以下のような取得された位置情報を保持している構造体です。

latitude緯度で度数で表されるdouble型
負数は南緯になります。
longitude経度で度数で表されるdouble型
負数は西経になります。
altitude高度、double型
accuracy取得される位置情報の性格さ、誤差になります。
単位はメートル(m)。
取得される緯度/経度は誤差があり、その誤差の範囲がこの「accuracy」です。
取得された緯度/経度でaccurayの範囲内でずれがあります、という意味です。
よってこのサンプルでは、accuracyの範囲で円を描画しています。
きっとご自身の位置はきっと円の内に必ずあると思います。
altitudeAccuracy取得される高度の性格さ、誤差になります。
単位はメートル(m)。
これも「accuracy」と同じで、現在地の高度の誤差になります。
heading現在向いている方角。
0~360、北から時計回りに、北からの角度。
0:北、東:90、南:180、西:270
speed プロパティの値が 0の場合、常にNaN
speed移動速度、メートル毎秒で表します。m/sec
double 型で返します。
nullになることがあります。

このサンプルでは、これらの値をすべてテーブルカラムに設定するようにしています。

どのような値が取得されるか、確認するのもよいかと思います。

位置情報取得失敗

位置情報の取得に失敗した場合は、getCurrentPosition()の第2引数で定義した関数が呼び出されることになります。

      function error(err) {
         document.getElementById('tdErrCd').innerHTML = err.code;
         document.getElementById('tdErrMg').innerHTML = err.message;
      }

第二引数の関数には「GeolocationPositionError」のオブジェクトが引数としてわたされて呼び出されます。

GeolocationPositionErrorオブジェクトは以下の二つの情報を保持している構造体です。

codeエラーコードになります。
エラーコードは、以下の「code」を参照してください。
messageエラーメッセージになります。

code

定数説明
1PERMISSION_DENIEDこのページにはアクセス許可がないため、位置情報の取得に失敗。
2POSITION_UNAVAILABLE少なくともひとつの位置情報ソースが内部的なエラーを返したため、位置情報の取得に失敗。
3TIMEOUT指定された制限時間内に位置情報を取得することができなかった。

実際どのような場合、エラーになるか?

うまく、位置情報をとれる場合もあるし、とれないこともあります。いままで取れなかった要因がいくつかあったので書いておきます。

  • ブラウザで位置情報をブロック
  • スマホでGPSをオフ
  • サイトがhttpsじゃなくて「http」であった。

などがあります。

また、現在位置の精度は、当然、パソコンであった場合には、かなり、ざっくりです。

一方スマホはGPSから位置情報が取得できるからだと思いますが、かなり正確な情報を取得でき、かつ、「accuracy」も小さくなります。

このサンプルページをパソコンとスマホで実行してみて比べてみるのもよいかもしれません。

ご参考

関連ページ