勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

Google Maps APIで現在地取得と目的地までのルートを表示させる方法

   2024/01/13  Google Maps API Google

Google Maps APIを使って現在地を取得しつつ、目的地までのルートを表示させたかった。他にもマーカーをデフォルトではなく任意の画像アイコンを使ったり、目的地&現在地以外にもマーカー立てたりと色々カスタムしたかった。以下に対応方法をメモ。

 

仕様

  • 基本的には現在地を取得して目的地までのルート線を引いたマップ
  • 目的地や現在地のマーカーはこちらで用意した画像を使う
  • ルート線の色や太さを変えたい
  • 目的地、現在地以外にもマーカーを立てる場合もあり
  • 現在地が取得できない場合は目的地とその他マーカーのみ立てる

 

サンプル

https://taitan916.info/sample/maproot/

目的地は通天閣で飛行機のマーカー、現在地はハートのマーカー、その他として大阪城をマグカップのマーカーで設置している。

 

ソース

<!DOCTYPE html "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta id="viewport" name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
<title>GoogleMapAPIで現在地の取得と目的地までのルート表示</title>
<style type="text/css">
#map_canvas {
    height: 100%;
    width: 100%;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=true"></script> 
<script>
var currentWindow = null;
destinationList = {    //目的地の配列
    'title' : '通天閣', 
    'lat' : '34.652499', 
    'long' : '135.506306'
}
rendererOptions = {
    draggable: true,    //ドラッグ操作の有効/無効
    preserveViewport: true,    //ズームの有無
    suppressMarkers: true,    //デフォルトのマーカーを非表示
    polylineOptions: {    //ルートの色と太さはここで変える
        strokeColor:"#f00",    //色
        strokeWeight:3    //太さ
    }
};
var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var directionsService = new google.maps.DirectionsService();
var map;


//現在地の取得
function getGps(){
    var tmp = new Array();
    if( navigator.geolocation ){
        navigator.geolocation.getCurrentPosition(
            function( pos ){ //位置取得成功
                tmp['long'] = pos.coords.longitude; //経度
                tmp['lat'] = pos.coords.latitude; //緯度
                initialize( tmp );
            },
            function( error ){ //失敗
                switch( error.code ){
                    case 1: tmp['msg'] = "位置情報の利用が許可されていません"; break;
                    case 2: tmp['msg'] = "デバイスの位置が判定できません"; break;
                    case 3: tmp['msg'] = "タイムアウトしました"; break;
                }
                initialize( tmp );
            }
        );
    } else { //使用不可のブラウザ
        tmp['msg'] = 'このブラウザでは位置取得が出来ません。';
        initialize( tmp );
    }
}


//MAPの生成
function initialize( data ) {
    if( data.msg ){    //現在地が取得できない場合は目的地を中心に設定
        alert( data.msg );    //エラー内容をアラート表示
        var center = new google.maps.LatLng(destinationList.lat, destinationList.long);
    } else { //現在地を取得できれば現在地を中心に設定
        gps = data;
        var center = new google.maps.LatLng(data.lat, data.long);
    }
    var zoom = 12;
    var mapTypeId = google.maps.MapTypeId.ROADMAP

    var opts = {
        center: center,
        zoom: zoom,
        mapTypeId: mapTypeId
    };
    map = new google.maps.Map(document.getElementById("map_canvas"),opts);
    directionsDisplay.setMap(map);
    google.maps.event.addListener(directionsDisplay,'directions_changed', function(){});

    var mapData = {    //目的地のマーカーを作成
        'x':destinationList.lat, 
        'y':destinationList.long,
        'icon':'./img/1.png',
        'balloon':'目的地バルーン内<br><span style="color:#f00;">HTML使用可能</span>'
    };
    makeMarker(mapData);

    var mapData = {    //その他のマーカーを作成
        'x':'34.687315', 
        'y':'135.526201',
        'icon':'./img/2.png',
        'balloon':'大阪城バルーン内<br><span style="color:#f00;">HTML使用可能</span>'
    };
    makeMarker(mapData);

    if( data.msg ){    //現在地を取得できない場合はルート検索不要なのでここで終了
        return false;
    }

    var mapData = {    //現在地のマーカーを作成
        'x':gps.lat, 
        'y':gps.long,
        'icon':'./img/3.png',
        'balloon':'現在地バルーン内<br><span style="color:#f00;">HTML使用可能</span>'
    };
    makeMarker(mapData);

    calcRoute();
}


//ルート設定
function calcRoute() {
    var request = {
        origin: gps.lat+','+gps.long,    //現在地(必須)。経度緯度かテキスト入力。
        destination: destinationList.lat+','+destinationList.long,    //目的地(必須)。経度緯度かテキスト入力。
        travelMode: google.maps.DirectionsTravelMode.DRIVING,    //交通手段(必須)。これだと道路網を使用した標準の運転ルート。
//        travelMode: google.maps.DirectionsTravelMode.WALKING,    //交通手段(必須)。これだと歩行者専用道路と歩道(使用できる場合)を使用した徒歩ルート。
//        travelMode: google.maps.DirectionsTravelMode.BICYLING,    //交通手段(必須)。これだと自転車パスと優先道路を使用する自転車ルート。
        optimizeWaypoints: true,    //最適化して、最短ルートを取得するように指定
        avoidHighways: false,    //高速道路を使うかどうか。trueだと高速道路を可能な限りルートの計算から除外
        avoidTolls: false    //有料道路を使うかどうか。trueだと有料道路を可能な限りルートの計算から除外
    };

    directionsService.route(request, function(response,status){
        if (status == google.maps.DirectionsStatus.OK){
            directionsDisplay.setDirections(response);
        }
    });
}


//マーカー作成
function makeMarker( mapData ){
    var marker = new google.maps.Marker({
        position : new google.maps.LatLng(mapData.x,mapData.y), 
        map: map, 
        icon: mapData.icon
    });

    var infoWindow = new google.maps.InfoWindow();
    google.maps.event.addListener(marker, 'click', function() {
        if (currentWindow) {
            currentWindow.close();
        }
        infoWindow.setContent(mapData.balloon);
        infoWindow.open(map,marker);
        currentWindow = infoWindow;
    });
}
</script>
</head>
<body onload="getGps()">
    <div id="map_canvas">マップ読み込み中……<div>
</body>
</html>

 

その他

非同期通信

非同期通信が絡むみたいで処理されていく順番や、スコープがどうなるのかがちょっとよく分からなかった。

リアルタイム更新

出来るのか分からないけどカーナビみたいにリアルタイムで現在地を変更しつつ、ルート線も変更できるような形に作り変えたい。方法調べる。

使用制限

GoogleMapAPIの使用制限として、地図の読み込みは1日あたり最大25000回までとのこと。個人利用や、店舗紹介ぐらいなら大丈夫そうだけど、マップがメインのサービスの場合はひっかかりそうなので覚えておく。

 

公式リファレンス

https://developers.google.com/maps/documentation/javascript/directions?hl=ja

 

参考サイト

http://www.google-mapi.com/googlemaps/route-two_points.html

 - Google Maps API Google

  関連記事

Google Maps APIで住所から経度緯度を取得する方法

やりたかった事はformに住所を入れてsubmitする際に、javascript ...

Google Maps APIでヒートマップを表示する方法

Google Maps APIで花粉状況や雨量を可視化しやすいようなヒートマップ ...

Google Maps APIとPHPを組み合わせて複数マーカーとウィンドウを連携させる方法

やりたかった事は以下の通り。 mysqlから経度緯度、マーカー名、マーカーIDを ...

Google Maps APIでリアルタイムに現在地のマーカーを更新する方法

GoogleMapAPIを使って現在地を取得してその場所にマーカーを設置、その後 ...

Google map APIでマーカー(アイコン)を好きな画像に変える

Googleマップでユーザーにマーカー画像をアップロードさせて、それをマップ表示 ...