勉強したことのメモ

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

  関連記事

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

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

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

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

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

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

Google Maps APIでマーカーが全て表示されるように自動ズームする方法

Google Maps APIでマーカーを複数設置した場合にズームの値や、マーカ ...

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

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