勉強したことのメモ

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

  関連記事

GoogleMapAPIでクリックした座標にマーカーを設置する方法

GoogleMapAPIでクリックした位置にマーカーを設置し、座標の経度緯度をテ ...

androidでgeolocationを使うとtimeoutになる

Geolocation APIを用いて現在地をGoogleMapに表示させるとい ...

Google Maps APIで半径●メートル範囲を円で表示する方法

Google Maps APIでマーカーを立てて、そこから範囲●mもしくは●km ...

スマホでページ内リンクからGoogleMapアプリを開く

スマホでWebページにあるリンクをクリックした際にGoogleMapアプリを表示 ...

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

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