スマホの GPS で位置情報を取得して Google Map と Mapbox に表示する方法


[初回公開] 2008年05月28日

スマホに搭載されている GPS で位置情報となる緯度経度は HTML と JavaScript を利用することでウェブサイト上でも簡単に取得することができ、取得した緯度経度の値を無料で利用できる Google Map と Mapbox といった地図サービスと連携して現在地の地図を表示する方法を紹介する。

スマホの GPS で位置情報を取得して Google Map と Mapbox に表示する方法




1.スマホの GPS センサとは


スマホの GPS センサとは、人工衛星からの電波を利用して地球上での位置を測定するための機器で、カーナビなどでも利用されている。
測定した位置情報は緯度経度として数値化して表される。



位置情報の取得に人工衛星を利用することから回りの建物の状況によっては 10m 前後の誤差を生じることがあり、曇りや雨の日など天候状態によっても左右される。
また、電波が届かない屋内では正確に位置を取得することができないものの、スマホにおいては携帯電話の通話や通信で利用する基地局や Wi-Fi の電波を利用してある程度の位置を取得することが可能である。

2.GPS を利用した機能やサービス


GPS で取得した位置情報を利用した機能やサービスとしては、カーナビに代表されるように地図と連携した現在地を示したり目的地までのルートを案内するものが多い。
最近では位置情報を利用したスマホアプリや、カメラで撮影した写真の一枚一枚に位置情報を埋め込む機能もある。

サービスとしてはリアルタイムに現在位置が取得できることから、その近辺の天気予報や最寄の店舗案内など情報提供サービスとして利用されることも増えてきている。

3.スマホの GPS を使って地図サービスと連携する


スマホやタブレットに搭載されている GPS を利用して位置情報を取得できるのはアプリを構築しなくても HTML と JavaScript を利用したウェブサイトでも簡単に行うことができる。



ウェブサイトで位置情報を取得し、そこで得た緯度経度を Google Map と Mapbox といった地図サービスと連携して現在地の地図を表示するサンプルが下記となる。

3-1.スマホの GPS を HTML に表示する


スマホで GPS を利用して位置情報を取得し、その結果をウェブサイト上に表示するスクリプトは次の通りである。
下記は HTML の body タグ内のみを抜粋しており、位置情報の取得には JavaScript の navigator.geolocation を利用する。

<body>
<p id="lng"></p>
<p id="lat"></p>

<script>
// 現在位置を取得
navigator.geolocation
.getCurrentPosition( success, error, options );

var options = {
enableHighAccuracy: true,
timeout: 1000,
maximumAge: 0
};

// 位置取得の成功時
function success( position ) {
var crd = position.coords;
defLng = crd.longitude;
defLat = crd.latitude;
document.getElementById("lat").textContent = "緯度 : " + defLng;
document.getElementById("lng").textContent = "経度 : " + defLat;
};
</script>
</body>


enableHighAccuracy は GPS の精度を高めるため true にしている。
また、maximumAge はキャッシュの利用を示しており、0 にすることで常に最新の情報を取得するようになる。

上記を記載したテキストファイルを拡張子 .html として保存し、サーバに設置してスマホのブラウザでアクセスすると下図のように位置情報の取得許可を問うポップアップが表示される。

位置情報取得の確認ポップアップが表示


ポップアップ内の「許可」をタップすると下図のように緯度経度が数値として表示されるのが確認できる。

スマホのブラウザに緯度経度が表示される様子


3-2.Google Map に取得した位置情報を渡す


スマホの GPS で取得した位置情報を地図サービスの Google Map に組み込み、現在地が地図の中心に表示されるとともにデフォルトデザインのマーカーが立つようにするサンプルコードが下記となる。

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key={API キー}&
sensor=false"></script>
<script type="text/javascript">
function load() {
var latlng = new google.maps.LatLng( defLat, defLng );
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map( document.getElementById( "map" ), myOptions );

var iconFlag_1 = new google.maps.Marker({
position: new google.maps.LatLng( defLat, defLng ),
map: map
});
}
</script>

<div id="map" style="width:480px; height:520px"></div>




まず、Google Map をウェブサイト上で利用するためには Google Map の API キーが必要になるため、1 行目で指定している。
読み込んだ Google Map は map と命名した ID を利用しているため、同じく id = map と設定した div タグに描画される。

Google Map の読み込み時に地図の中心を取得した緯度経度の値を指定しているとともに、マーカーの位置指定でも取得した緯度経度の値を指定してブラウザで確認したものが下図となる。

スマホの GPS で取得した位置情報を Google Map に組み込んだ様子


3-3.Mapbox に取得した位置情報を渡す


スマホの GPS で取得した位置情報を地図サービスの Mapbox に組み込み、現在地が地図の中心に表示されるとともにデフォルトデザインのマーカーが立つようにするサンプルコードが下記となる。

<div id="map"></div>
<script src="https://api.mapbox.com/mapbox-gl-js/v1.6.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.6.1/mapbox-gl.css" rel="stylesheet" />
<script>
mapboxgl.accessToken = '{Mapbox のトークンキー}';

var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
center: [defLng, defLat],
zoom: 16
});

map.on('load', function() {
map.setLayoutProperty('country-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('road-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('state-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('settlement-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('settlement-subdivision-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('airport-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('poi-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('water-point-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('water-line-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('natural-point-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('natural-line-label', 'text-field', ['get', 'name_ja']);
map.setLayoutProperty('waterway-label', 'text-field', ['get', 'name_ja']);
map.addControl(new mapboxgl.NavigationControl(), 'bottom-right');
});

const marker1 = new mapboxgl.Marker()
.setLngLat( [defLng, defLat] )
.addTo( map );
</script>


まず、Mapbox をウェブサイト上で利用するためには Mapbox の API キーが必要になるため、変数 mapboxgl.accessToken に格納している。
読み込んだ Mapbox は map と命名した ID を利用しているため、同じく id = map と設定した div タグに描画される。

Mapbox の読み込み時に地図の中心を取得した緯度経度の値で指定しているとともに、マーカーの位置指定でも取得した緯度経度の値を指定してブラウザで確認したものが下図となる。

スマホの GPS で取得した位置情報を Mapbox に組み込んだ様子


尚、Mapbox を JavaScript で読み込む際に map.setLayoutProperty() に country-label や poi-label を指定しているが、これは地図上に表示される国名や地名、商業施設名などを日本語表記にするために必要な設定である。

4.スマホの GPS を地図情報サービスと連携する利用例


スマホの GPS を地図情報サービスと連携する利用例としては、現在地から近い店舗をマーカー付きで表示したり、ルート案内をさせることができる。



昨今では災害時に最寄の避難所を表示したり、断水時の給水提供場所などを地図サービスと連携して自治体のサービスとして提供されることも増えてきている。

5.ガラケでの GPS の利用例


スマホは JavaScritpt が利用できるので簡単に GPS を利用した位置情報を取得することができるが、ガラケ(フィーチャーフォン)においては JavaScript が使えない機種があるため、キャリア側で a タグにオプションを付けることで位置情報が取得できるようになっている。

位置情報の取得方法は DoCoMo、Softbank、au のそれぞれで取得方法が異なっており、その中で Docomo での緯度経度の出し方が下記となる。
尚、位置情報取得に関する詳しい仕様は公式サイトに公開されている。

スマホの GPS で取得した位置情報を Mapbox に組み込んだ様子

-> NTT Docomo GPS 利用マニュアル

Docomo で位置情報を取得する場合は、HTML に下記のように a タグに lcs オプションを記述する。

[a タグの記述例]
<a href="{遷移先の URL}" lcs>

[form タグの記述例]
<form method="get" action="{遷移先の URL}" lcs>


次に遷移先のページで緯度と経度の値が渡されるので、をのデータを利用して Google Map や Mapbox など地図サービスと連携して利用する。

上記の a タグ、form タグともに GET メソッドでページ遷移しているため、PHP であれば $_GET['lat']、$_GET['lon'] で値が取得できる。
ただし、渡される緯度と経度のデータは世界測地系のフォーマットとなっており「+34.40.88.556」「+135.10.58.102」のように「dms(±dd.mm.ss.sss)」の形式となっているので地図サービスで利用するためには 10 進数に変換する必要がある。

dd は 10 進法で度で示し、mm は 60 進法で分を、ss は 60 進法で秒を示しており、最後の sss は ss の小数点以下の数値となっている。
これを 10 進数の形に変換するためには 60 進数の部分を 10 進数に変換、それらを合計することで算出できる。
尚、mm であるのに対して ss は秒なので、mm と ss の間では通常の時刻の考え方と同じく 60 倍の単位の相違があることに注意が必要である。
これらを元に算出する計算式が下記となる。

$lat = preg_split("/\+/" , $lat); //値の+取る
$lon = preg_split("/\+/" , $lon); //値の+取る

// 緯度をピリオドごとに切り分け配列に入れる
$lat = preg_split("/\./" , $lat);
// 経度をピリオドごとに切り分け配列に入れる
$lon = preg_split("/\./" , $lon);

$lat = $lat[0] + ( ($lat[1]/60) + (( $lat[2] + ($lat[3]/1000)) / 3600 ) );
$lon = $lat[0] + ( ($lon[1]/60) + (( $lon[2] + ($lon[3]/1000)) / 3600 ) );


このソースで変換された値は「34.69126555556」「135.18280611111」となり、Google Map や Mapbox など地図サービスで利用できるようになる。

ガラケで取得した位置情報を 10 進数に変換して地図サービスと連携したものが下図となる。

ガラケの GPS で取得した位置情報を Google Map に組み込んだ様子


ガラケは JavaScript が利用できないことを想定して、1 ページ目は地図の表示だけさせ、2 ページ目で位置情報を利用した地図表示を行う 2 段階構えが必要なため、上図にある「現在地」をクリックすると位置情報を送信するか確認するポップアップが表示される。

ガラケの位置情報送信の確認画面




ウェブサイトに送信する位置情報は 3 種類あり、最新の情報を送る場合は「現在地確認」をクリックすると機種内の GPS が作動して位置情報を取得する。
スマホと異なり、位置情報を取得するのに若干の時間を要す。

ガラケの位置情報取得の状況


位置情報が取得できれば、ウェブサイトの 2 ページに緯度経度が渡され、現在いる場所の地図が表示される。

ガラケで現在地の地図を表示


ガラケの機種にもよるが、性能が格段に上がっている現在のスマホに比べるとやや GPS の精度が低く、ガラケの GPS 設定で感度を下げていると現在地から 50m から 300m の誤差がでることがある。

関連記事