Googleマップを現在地からの経路検索で開くリンクを作成する

<h1>「Googleマップを現在地からの経路検索で開くリンク」ってなんだ</h1>
と思われることもありそうなので少し具体的に説明をば。

ウェブサイトを作っているとよくGoogleマップの埋め込みとその傍らにGoogleマップを直接開くリンクテキストなどを置いておくことがあります。

このとき特定の住所を開くだけではなく、現在地からその住所への経路検索をした状態で開きたい！という要望がありました。

経路検索をした状態というのは↓こんな感じです。
<a href="https://www.google.co.jp/maps/dir/%E5%AE%AE%E5%9F%8E%E7%9C%8C/%E6%9D%B1%E4%BA%AC/@36.9697748,139.1340859,8z/data=!3m1!4b1!4m13!4m12!1m5!1m1!1s0x5f8892ddfbe0dc71:0xce6fb9385107a4ad!2m2!1d140.8721!2d38.2688373!1m5!1m1!1s0x60188b857628235d:0xcdd8aef709a2b520!2m2!1d139.7319925!2d35.7090259" target="_blank" rel="nofollow">宮城から東京への経路</a>

この「宮城から」のところを「現在地から」で開きたい。というわけです。

調べたところGoogleマップの公式ではそういったサービスを提供していないようでしたので、Geolocation APIを使って経路検索した状態のURLを作ることにしました。
<h1>ということで、Geolocation APIの使い方を見てみる</h1>
みんなだいすき（かはわからないけど）MDNさんの<a href="https://developer.mozilla.org/ja/docs/WebAPI/Using_geolocation" target="_blank" rel="nofollow">Geolocation の利用</a>によると、Geolocation API は<code>navigator.geolocation</code>を通じて提供され、ユーザーの現在位置を取得するには<code>getCurrentPosition()</code>メソッドを呼び出すそうです。

<span style="color: #ff6600;">※Chromeはバージョン50からhttpでの現在地の取得を禁止しているので、大多数のブラウザに対応するにはhttps化する必要があります。</span>
<pre class="lang:default decode:true" title="getCurrentPositionの構文">navigator.geolocation.getCurrentPosition(success, error, options)</pre>

<hr />

`getCurrentPosition()`の第１引数は、現在位置の取得に成功したときのコールバック関数を、第２引数は失敗したときのコールバック関数を実行います。

つまり、現在位置の取得に成功した結果を受け取りたい場合には、第１引数に関数を指定してやればその関数の引数として結果が受け取れます。

```
navigator.geolocation.getCurrentPosition(function(position) {
	console.log(position);
});
```
<span style="color: #ff6600;">位置情報は`position.coords.latitude`に緯度、`coords.latitude`に経度が格納されています。</span>

<hr />

実際に使う際には、即時関数などの中でブラウザがGeolocation APIに対応しているかどうかの判定を加えて使います。

```
(function(){
	if( 'geolocation' in navigator == false) return;

	navigator.geolocation.getCurrentPosition(function(position) {
		console.log(position);
	});
}());
```

<hr />

エラー時やオプションを設定する場合にはこのようなコードになります。

```
(function(){
	if( 'geolocation' in navigator == false) return;

	navigator.geolocation.getCurrentPosition(function(position) {
		console.log(position);

	}, function(error) {
		// ブラウザがGeolocation APIに対応しているが、使えない場合とかエラーが起きたときの処理

	}, {
		timeout: 10000,	// 取得タイムアウトまでの時間（ミリ秒）
		maximumAge: 10000,	// 位置情報の有効期限（ミリ秒）
		enableHighAccuracy: true	// より精度の高い位置情報を取得するか（true／false）
	});
}());
```

<h2>ちなみに</h2>
`getCurrentPosition()`の他にも現在位置を取得するメソッドとして`watchPosition()`がありますが、こちらは現在位置が更新されるたびにコールバック関数を実行してくれるものなので、よりリアルタイムな位置情報が必要なときにはこちらを使います。

引数の設定が`getCurrentPosition()`と同じなのは覚えやすくていいですね。
<h1>現在位置の取得方法がわかったので、経路検索のURLを作って設定する</h1>
現在位置が取得できたら後は簡単です。
jQueryとか使ってa要素の<code>href</code>を経路検索のURLに書き換えます。

経路検索のURLは<span class="crayon-s">「<strong>https://www.google.co.jp/maps/dir/{緯度}</strong></span><strong><span class="crayon-s">,{経度}</span><span class="crayon-s">/{目的地}</span></strong><span class="crayon-s"><strong>/</strong>」と</span>なっているため、<span style="font-family: monospace;">{緯度}{経度}をGeolocation APIで取得した情報を指定し、{目的地}のところは予め設定した住所をURLエンコードして指定します。</span>
<pre class="lang:default decode:true" title="HTMLサンプル">&lt;a href="https://goo.gl/maps/gsdrZYZLwvD2" target="_blank" class="btn-googlemap"&gt;大きな地図で見る&lt;/a&gt;</pre>

```
$(function() {
	// Geolocation APIに対応していなかったら処理を止める
	if ( 'geolocation' in navigator == false ) return;

	var address = '北海道稚内市';
	var btn = $('.btn-googlemap');

	// リンクを書き換える
	var setLink = function(lat, lng) {
		// Google mapの経路検索のURLを作る
		var link = 'https://www.google.co.jp/maps/dir/' + lat + ',' + lng + '/' + encodeURIComponent(address) + '/';

		btn.attr('href', link);
	};

	navigator.geolocation.getCurrentPosition(function(position) {
		var coords = position.coords;
		setLink(coords.latitude, coords.longitude);
	});
});
```
今回は<code>href</code>に予めGoogle mapで住所のリンクを設定しておき、Geolocation APIが使えない場合にはその住所が開くようにしました。

しかし、使える場合でもクリックされたタイミングで現在位置を取得していないこともありえるため、取得できていなかったら簡単なローディングアニメーションを表示しておき、取得できたタイミングで`location.href`や`window.open`を使って開くようにするとユーザーには親切かなと思います。
<h1>できたもの</h1>
（このブログがhttps化してないので）<a href="https://codepen.io/Y-Kogawa/pen/BzbZRz" target="_blank" rel="nofollow">CODEPENでサンプル</a>用意してみました。スマホで見た方が位置情報が正確なので楽しいです。
<h1>おわり</h1>
ということで「Googleマップを現在地からの経路検索で開くリンクを作成する」でした。

Chromeのバージョン50以上からhttpsじゃないと使えない仕様なのは盲点になりそうなので注意が必要ですね。

ではでは ( ͡° ͜ʖ ͡° )ﾉｼ