【Laravel】GoogleMapsAPIで住所から緯度経度を取得する方法
はじめに
この記事のゴール
Laravelのプロジェクト内で、住所から緯度経度を取得します
この記事の続きです。
【Laravel】GoogleMapsAPIを使って現在地を表示させる方法
【完成の図】
ゴールまでの道のり
- ジオコーディングのAPIを有効にする
- フォームの記述
- jsファイルの作成
この記事の対象者
- 初めてGoogleMapsAPIを使う方
- Laravel初学者
環境
- macOS Catalina 10.15.5
- PHP 7.3.17
- Laravel Framework 6.18.41
実践
1. ジオコーディングのAPIを有効にする
GoogleAPIsのこのプロジェクトのダッシュボードへ移動します。
「APIとサービスの有効化」をクリックします。
左下の「マップ」をクリック
「Geocoding API」をクリック
「有効にする」をクリック(自分の場合は、もう既に有効にしてしまっているので「APIが有効です」と表示されています)
これで、ジオコーディングのAPIを有効にすることができました。
2. フォームの記述
次に、住所から緯度経度を取得する際に必要なフォームを作成していきます。
まず、前回( 【Laravel】GoogleMapsAPIを使って現在地を表示させる方法)までで、resources/views/welcome.blade.phpは
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
省略
</head>
<body>
<div id="map" style="height:500px">
</div>
{!! Form::open(['route' => 'result.currentLocation','method' => 'get']) !!}
{{--隠しフォームでlivescontrollerに位置情報を渡す--}}
{{--lat用--}}
{!! Form::hidden('lat','lat',['class'=>'lat_input']) !!}
{{--lng用--}}
{!! Form::hidden('lng','lng',['class'=>'lng_input']) !!}
{{--setlocation.jsを読み込んで、位置情報取得するまで押せないようにdisabledを付与し、非アクティブにする。--}}
{{--その後、disableはfalseになるようにsetlocation.js内に記述した--}}
{!! Form::submit("周辺を表示", ['class' => "btn btn-success btn-block",'disabled']) !!}
{!! Form::close() !!}
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script src="{{ asset('/js/setLocation.js') }}"></script>
<script src="{{ asset('/js/result.js') }}"></script>
<script src="https://maps.googleapis.com/maps/api/js?language=ja®ion=JP&key=AIzaSyDkveHRqHWUqMU4CS_isfGbuBrzzoo6v4o&callback=initMap" async defer>
</script>
</body>
</html>
このようになっていると思います。
この章では、
- 住所を入力するinputタグ
- 住所を緯度経度へ変換するボタンタグ
- 住所から変換された緯度経度を表示するinputタグ
- JSファイルの読み込み設定
この、3つのタグを作成 + jsファイルを読み込むための記述をしていきます。
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
省略
</head>
<body>
<div id="map" style="height:500px">
</div>
{!! Form::open(['route' => 'result.currentLocation','method' => 'get']) !!}
{{--隠しフォームでlivescontrollerに位置情報を渡す--}}
{{--lat用--}}
{!! Form::hidden('lat','lat',['class'=>'lat_input']) !!}
{{--lng用--}}
{!! Form::hidden('lng','lng',['class'=>'lng_input']) !!}
{{--setlocation.jsを読み込んで、位置情報取得するまで押せないようにdisabledを付与し、非アクティブにする。--}}
{{--その後、disableはfalseになるようにsetlocation.js内に記述した--}}
{!! Form::submit("周辺を表示", ['class' => "btn btn-success btn-block",'disabled']) !!}
{!! Form::close() !!}
//ここから下を追加
<input type="text" id="addressInput">
<button id="searchGeo">緯度経度変換</button>
<div>
緯度:<input type="text" id="lat">
経度:<input type="text" id="lng">
</div>
//ここから上を追加
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script src="{{ asset('/js/setLocation.js') }}"></script>
<script src="{{ asset('/js/result.js') }}"></script>
<script src="{{ asset('/js/getLatLng.js') }}"></script> //これを追加
<script src="https://maps.googleapis.com/maps/api/js?language=ja®ion=JP&key=AIzaSyDkveHRqHWUqMU4CS_isfGbuBrzzoo6v4o&callback=initMap" async defer>
</script>
</body>
</html>
-
<input type="text" id="addressInput">
ここに住所を入力します。typeはtextを指定。idは、後からJSファイルで使いやすいように、addressInputを指定しています。 -
<button id="searchGeo">緯度経度変換</button>
住所から緯度経度を取得するとき用のボタンを作成します。idはsearchGeoを指定して、ボタンの表示は「緯度経度変換」とします。 -
緯度:<input type="text" id="lat">(経度:<input type="text" id="lng">)
住所から取得された緯度経度をここに表示させます。typeはtextでidはlat(lng)を指定しています。
ここで一旦ブラウザを見てみましょう。
このようにフォームが作成されていると思います。
3. jsファイルの作成
最後にwelcome.blade.phpで読み込み設定をしたgetLatLng.js
を作成していきます。
public/js 内にgetLatLng.jsを作成し、以下のように記述します。
function getLatLng() {
// 入力した住所を取得します。
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) {
console.log(results, status)
var latlng = "";
if (status == google.maps.GeocoderStatus.OK) {
// 取得が成功した場合
// 結果をループして取得します。
for (var i in results) {
if (results[i].geometry) {
// 緯度を取得します。
var lat = results[i].geometry.location.lat();
// 経度を取得します。
var lng = results[i].geometry.location.lng();
// val()メソッドを使ってvalue値を設定できる
// idがlat(またはlng)のvalue値に、変数lat(またはlng)を設定する
$('#lat').val(lat);
$('#lng').val(lng);
// そもそも、ループを回して、検索結果にあっているものをiに入れていっているため
// 精度の低いものもでてきてしまう。その必要はないから、一回でbreak
break;
}
}
} 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("原因不明のエラーが発生しました。");
}
});
}
$('#searchGeo').on('click', getLatLng);
ポイントは3つです。
1 var addressInput = document.getElementById('addressInput').value;
これを記述することで、welcome.blade.php内のidがaddressInputの、value属性を変数addressInputに格納しています。
2 var geocoder = new google.maps.Geocoder();
この記述でGeocoderをインスタンス化しています。
3 geocoder.geocode()とすることで、geocoderを実行します。第一引数には、addressプロパティを設定し、入力した住所を格納しているaddressInputを指定します。第二引数には、コールバック関数を設定しています。住所の取得結果を用いて取得成功の場合は、緯度(経度)を取得し、idがlat(lng)のvalue属性に格納しています。また、住所の取得結果に失敗した場合は、ステータスに応じてその結果を表示させるようにelseifで記述しています。
さて、ここまで来ると完成です。
ブラウザで確認してみましょう。
住所を入力し、緯度経度変換ボタンを押せば、緯度経度が表示されてます。
以上が
「GoogleMapsAPIで住所から緯度経度を取得する方法」でした。
おわりに
以上で、地図3部作のすべてが終了しました。
見ていただきありがとうございました。
Discussion