JavaScript
Googleマップに複数のピンを一括表示、全てが表示される縮尺にする
Googleマップに複数の住所を一括でプロット、かつ全てが表示される縮尺にする方法をご紹介します。事前に全ての住所が分かっている場合はコードの中でそれら住所を指定すればよいですが、そうもいかない場合もあります。
例としてやること
$shops_arr
という変数に、東京駅、新宿駅、横浜駅の住所である以下の3つの住所が文字列で配列で格納されているとします。
どういうケースであってもよいですが、ユースケースの例として、WordPressのカスタムフィールドに入力された住所をプロットするというのが考えられます。配列に格納するまでの流れは、カスタムフィールドをプラグインなしで追加する方法とカスタムフィールドの値を参照する方法(プラグインなし)の記事を続けて見てください。
$shops_arr
に入っている住所をGoogleマップに表示します。
必要な準備
Google Cloud Platform(GCP)
この記事をここまで読んでいる方はすでに有効にされている方が多いかとは思いますが、まずGoogle Cloud Platformを始める必要があります。リンク先は私が書いた記事ですので、よろしければご参照ください。
Maps JavaScript APIの有効化
Maps JavaScript APIは、Googleマップをカスタマイズするのに必要なAPIです。GCPで「Maps JavaScript API」で検索すると出てくるので、そこで有効化できます。
Geocoding APIの有効化
Maps JavaScript APIは、住所と緯度経度情報の変換をするのに用いるAPIです。GCPで「Geocoding API」で検索すると出てくるので、そこで有効化できます。
コード(PHP+JavaScript)
<div id="map" style="width: 1000px; height: 500px;"></div> <!--widthとheightの値は自由-->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=【ここにAPIキー】&callback=initMap"></script> <!--googleのAPIを有効にする-->
<?php
$shops_arr_json = json_encode($shops_arr); //jsonにしてJSに渡す
?>
<script>
'use strict';
function initMap() {
const addresses = <?php echo $shops_arr_json; ?>; // jsonにした配列を受け取り
var bounds = new google.maps.LatLngBounds();
var latlng = []; //緯度経度の値をセット
var lat = []; //緯度の値をセット
var lng = []; //経度の値をセット
let maxLat = -90;
let maxLng = -180;
let minLat = 90;
let minLng = 180;
var marker = []; //マーカーの位置情報をセット
let myLatLng; //地図の中心点をセット用
let geocoder;
geocoder = new google.maps.Geocoder(); // ジオコードリクエストを送信するGeocoderの作成
const map = new google.maps.Map(document.getElementById('map'));//地図を作成する
geo(aftergeo);
function geo(callback){
let cRef = addresses.length;
for (let i = 0; i < addresses.length; i++) {
(function (i) {
geocoder.geocode({'address': addresses[i]amp;},
function(results, status) { // 結果
if (status === google.maps.GeocoderStatus.OK) { // ステータスがOKの場合
lat[i] = results[0].geometry.location.lat();//緯度を取得
lng[i] = results[0].geometry.location.lng();//経度を取得
if( maxLat < lat[i] ){ maxLat = lat[i] }
if( maxLng < lng[i] ){ maxLng = lng[i] }
if( minLat > lat[i] ){ minLat = lat[i] }
if( minLng > lng[i] ){ minLng = lng[i] }
latlng[i]=results[0].geometry.location;// マーカーを立てる位置をセット
marker[i] = new google.maps.Marker({
position: results[0].geometry.location, // マーカーを立てる位置を指定
map: map // マーカーを立てる地図を指定
});
} else { // 失敗した場合
}//if文の終了
if (--cRef <= 0) {
callback();//全て取得できたらaftergeo実行
}
var sw = new google.maps.LatLng(maxLat, minLng);
var ne = new google.maps.LatLng(minLat, maxLng);
var bounds = new google.maps.LatLngBounds(sw, ne);
map.fitBounds(bounds); //複数マーカーをマップに表示させる
}//function(results, status)の終了
);//geocoder.geocodeの終了
}) (i);
}//for文の終了
}//function geo終了
function aftergeo(){
let opt = {
maxZoom: 15 // 地図の最大ズームを指定
};
map.setOptions(opt);//オプションをmapにセット
}//function aftergeo終了
};//function initMap終了
</script>
これで、このように表示されます。
解説
以下がポイントだと思います。
- PHPからJavaScriptに住所情報の配列をjson形式で渡す
- 住所情報から緯度経度に変換
- 緯度経度、それぞれ最大値と最小値を求める
- 上記の最大値、最小値をもとに、Googleが用意している関数
fitBounds
で複数の緯度経度すべてがマップ内に表示されるようにしている(50~53行目)
まとめ
地図を見てわかったことをまとめます。わかってはいたけど、東京駅と新宿の距離に比べて、横浜遠いですね・・
で、私の住む武蔵野市から横浜も遠いなと思ってるんですが、地図で見たら東京駅からと距離的に変わらないじゃないですか!なのに新宿か東京回って行かなきゃいけないんですけど。どなたか、どうにかできる方、どうにかしてください。