勉強したことのメモ

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

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

   2024/01/13  Google Maps API Google

GoogleMapAPIを使って現在地を取得してその場所にマーカーを設置、その後に現在地を移動すればリアルタイムもしくはボタンを押した際に、現在地マーカーを移動させたかった。つまりカーナビ的な現在地の表示をGoogleMapで再現したかった。必要そうな仕様とソースコードをメモ。

 

仕様

  • 現在地を取得してマーカー設置
  • 目的地にもマーカー設置
  • リアルタイムに現在地のマーカー場所を変えるか、ボタンを押した際にマーカーの位置を変える

 

サンプル

リアルタイム更新

https://taitan916.info/sample/gps/

手動更新

https://taitan916.info/sample/gps/index2.php

 

ソース

リアルタイム更新

<!DOCTYPE html PUBLIC "-//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 name="robots" content="noindex, nofollow" />
<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>
<script type="text/javascript" charset="utf-8">
    window.onload = function() {
        setTimeout(function(){window.scrollTo(0, 1);}, 100);
    }
</script>
<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&libraries=visualization"></script> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style>
#map_canvas {
    width: 500px;
    height: 500px;
    border: 1px solid #000;
}
</style>
</head>
<body>
    <div>
        <b>現在地情報</b><br />
        取得<div id="n"></div>
        経度<div id="x"></div>
        緯度<div id="y"></div>
    </div><br />

    <div id="map_canvas">マップ読み込み中</div>

    <img src="1.png">→現在地<br />
    <img src="2.png">→目的地(大阪城を設定)

    <script>
    $(function(){
        var count = 1;
        var currentWindow = null;
        var map;
        var marker;
        var sampleMarker;
        var geoOptions = {
            enableHighAccuracy : true, //精度を高める
            timeout : 6000, //タイムアウトは6秒
            maximumAge : 0 //キャッシュはさせない
        }

        //現在位置の取得
        if (navigator.geolocation) {
            navigator.geolocation.watchPosition( //watchPositionとすることで定期的に現在地を取得
            function (pos) {
                //取得状況
                $('#n').html((count++) + "回目");
                $('#x').html(pos.coords.latitude);
                $('#y').html(pos.coords.longitude);

                var mapData = { 'x':pos.coords.latitude, 'y':pos.coords.longitude, 'balloon':'現在位置' };
                var latlng = new google.maps.LatLng(mapData.x, mapData.y);
                if( !map ){ //初回のみマップ生成
                    var myOptions = { zoom: 10, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
                    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
                }
                if( marker ){ //現在地マーカーが設置されている場合は消去
                    marker.setMap(null);
                }
                if( !sampleMarker ){ //初回のみ目的地マーカーを設置
                    sampleMarker = { 'x':'34.687315', 'y':'135.526201', 'balloon':'大阪城' };
                    makeMarker2( sampleMarker );
                }
                makeMarker( mapData ); //現在地マーカーを設置
            },
            function (error) {
                var msg;
                switch( error.code ){
                    case 1: msg = "位置情報の利用が許可されていません"; break;
                    case 2: msg = "位置が判定できません"; break;
                    case 3: msg = "タイムアウトしました"; break;
                }
                alert(msg);
            });
        } else {
            alert("本ブラウザではGeolocationが使えません");
        }

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

            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;
            });
        }

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

            var infoWindow = new google.maps.InfoWindow();
            google.maps.event.addListener(marker2, 'click', function() {
                if (currentWindow) {
                    currentWindow.close();
                }
                infoWindow.setContent(mapData.balloon);
                infoWindow.open(map,marker2);
                currentWindow = infoWindow;
            });
        }
    });
    </script>
</body>
</html>

手動更新

<!DOCTYPE html PUBLIC "-//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 name="robots" content="noindex, nofollow" />
<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>
<script type="text/javascript" charset="utf-8">
    window.onload = function() {
        setTimeout(function(){window.scrollTo(0, 1);}, 100);
    }
</script>
<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&libraries=visualization"></script> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style>
#map_canvas {
    width: 500px;
    height: 500px;
    border: 1px solid #000;
}
</style>
</head>
<body>
    <div>
        <b>現在地情報</b><br />
        取得<div id="n"></div>
        経度<div id="x"></div>
        緯度<div id="y"></div>
    </div><br />

    <div id="map_canvas">マップ読み込み中</div><br /><br />

    <input type="button" onclick="return getNowGps();" value="位置情報を再取得" style="width:200px; height:70px;"><br />

    <img src="1.png">→現在地<br />
    <img src="2.png">→目的地(大阪城を設定)

    <script>
    var count = 1;
    var currentWindow = null;
    var map;
    var marker;
    var sampleMarker;
    var geoOptions = {
        enableHighAccuracy : true, //精度を高める
        timeout : 6000, //タイムアウトは6秒
        maximumAge : 0 //キャッシュはさせない
    }
    getNowGps(); //1回目は自動で取得

    //現在位置の取得
    function getNowGps(){
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
            function (pos) {
                //取得状況
                $('#n').html((count++) + "回目");
                $('#x').html(pos.coords.latitude);
                $('#y').html(pos.coords.longitude);

                var mapData = { 'x':pos.coords.latitude, 'y':pos.coords.longitude, 'balloon':'現在位置' };
                var latlng = new google.maps.LatLng(mapData.x, mapData.y);
                if( !map ){ //初回のみマップ生成
                    var myOptions = { zoom: 10, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
                    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
                }
                if( marker ){ //現在地マーカーが設置されている場合は消去
                    marker.setMap(null);
                }
                if( !sampleMarker ){ //初回のみ目的地マーカーを設置
                    sampleMarker = { 'x':'34.687315', 'y':'135.526201', 'balloon':'大阪城' };
                    makeMarker2( sampleMarker );
                }
                makeMarker( mapData ); //現在地マーカーを設置
            },
            function (error) {
                var msg;
                switch( error.code ){
                    case 1: msg = "位置情報の利用が許可されていません"; break;
                    case 2: msg = "位置が判定できません"; break;
                    case 3: msg = "タイムアウトしました"; break;
                }
                alert(msg);
            });
        } else {
            alert("本ブラウザではGeolocationが使えません");
        }
    }

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

        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;
        });
    }

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

        var infoWindow = new google.maps.InfoWindow();
        google.maps.event.addListener(marker2, 'click', function() {
            if (currentWindow) {
                currentWindow.close();
            }
            infoWindow.setContent(mapData.balloon);
            infoWindow.open(map,marker2);
            currentWindow = infoWindow;
        });
    }
    </script>
</body>
</html>

 

その他

手動更新に関して

リアルタイムな自動更新だとスマホの電力を食うらしい。なので手動更新バージョンを使うケースもありそう。

マーカーの移動

マーカーを現在地用とその他用に分けないと、移動させるという部分の実装が分からなかった。同じような関数が2個あるのは気になるのでなんとかしたい。

 - Google Maps API Google

  関連記事

GoogleMapAPIで住所・経度緯度入力後にマーカーを移動させる

フォーム内に住所・経度・緯度のテキストボックスを設置し、住所を入力後にボタンを押 ...

Google Maps APIで都道府県の中心地と県庁所在地にマーカーを立てる方法

Google Maps APIで都道府県の中心地もしくは県庁所在地にマーカーを立 ...

GoogleMapAPIでジオコーディングできない場合の対応方法

住所から経度緯度を取得するジオコーディングをGoogleMapAPIを用いて行お ...

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

Google Maps APIを使って現在地を取得しつつ、目的地までのルートを表 ...

GoogleMapAPIでマップ自体を移動し中心地の経度緯度を取得

GoogleMapでマップ自体をドラッグして移動した後、中心地の経度緯度を取得し ...