勉強したことのメモ

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

  関連記事

androidでgeolocationを使うとtimeoutになる

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

Advanced Custom FieldsでGoogleMapの使用する方法

Advanced Custom FieldsでGoogleMapを使用したかった ...

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

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

Google Maps APIでメインカラーを変更する方法

GoogleMapAPIを用いたMAPでカラー変更をしたかった。カラーコードの指 ...

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

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