milkcocoaとgmaps.jsで、スマホ(と、まろ氏)の位置情報をリアルタイムに取得してみた

のびすけ


milkcocoaとgmaps.jsで、スマホ(と、まろ氏)の位置情報をリアルタイムに取得してみた

こんにちは。エンジニアののびすけです。
最近、同じくエンジニアのまろ氏が目立ってきて焦っています。

先日、Google Mapsのライブラリであるgmaps.jsを使った 「Web初心者でもGoogle Mapsをカスタマイズできるgmaps.jsでAPIを使い倒そう!」 とmilkcocoaを使った 「インタラクティブコンテンツを作ろう!milkcocoaで5分のチャットアプリ制作」 を書きました。

Web上の地図表現とインタラクティブな表現。
これらを使って何かをやりたいとは思ったのですが、アイディアが無いので(誰かください)今回はこの2つの技術を組み合わせて、エンジニアのまろ氏の現在地をGoogle Maps上にリアルタイムに反映してみたいと思います。

今回はこれを1時間弱程度で作りました。milkcocoaとgmaps.jsは便利っすなぁ。

作ったものの構成イメージ

構成イメージ

上のような構成になりました。スマホで5秒おきに位置情報を取得して送信します。このときの位置情報取得にはgmaps.jsを使っています。

WebSocketを使ってスマホ位置情報を送信し、同時にWebサイト側へgmaps.jsで反映させています。

WebSocketを利用するためのサービスとしてmilkcocoaを使っています。

準備したもの

すでに前述している部分もありますが、同じことをやってみる人は以下を準備すると良いと思います。

  • gmaps.jsの準備
  • milkcocoaの準備
  • スマートフォンとPC
    スマートフォンから位置情報を発信しつづけて、PC側のWebページで位置情報を取得し、地図へマッピングをします。
  • ホスティング環境の準備
    外部からアクセスする必要があるのでホスティング環境(サーバー)を用意しました。ここはすぐに使えるGithub Pagesを利用しています。

実装してみる

まずは情報送信側です。

デザイナーのりょうちんとエンジニアのまろ氏の2人にスマホでアクセスしてもらいました。2人を識別するためにボタンを用意して、位置情報を送信しつづける際に押してもらう想定です。

必須ではないのですが、2人のスマホ画面にも地図を表示させてみました。
53行目〜83行目は位置情報送信側には無くても大丈夫です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>gmapsサンプル</title>
    <style>
        @charset "utf-8";
        #map {
            height: 400px;
        }
    </style>
    <link rel="stylesheet" href="./foundation.css">
    <script src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <script src="./gmaps.js"></script>
    <script src="http://cdn.mlkcca.com/v0.2.8/milkcocoa.js"></script>
    <script>
        var dataStore = new MilkCocoa("https://{YOUR APP ID}.mlkcca.com").dataStore('chat');

        var type = '';
        function ryo(){
            type = 'ryo';
            alert("りょうちんとして位置情報を送信します。");
        }
        function maro(){
            type = 'maro';
            alert("まろしとして位置情報を送信します。");
        }

        window.onload = function(){

            setInterval(function(){
                GMaps.geolocate({
                    success: function(position) {
                        dataStore.send({
                            lat : position.coords.latitude,
                            lon : position.coords.longitude,
                            type: type
                        });
                    },
                    error: function(error) {
                        console.log('Geolocation failed: '+error.message);
                    },
                    not_supported: function() {
                        console.log('Your browser does not support geolocation');
                    },
                    always: function() {
                        console.log('done');
                    }
                });
            },5000);


            var lat = 35.710285;
            var lng = 139.77714;
            var map = new GMaps({
                div: "#map",
                lat: lat,
                lng: lng,
                zoom: 17
            });

            dataStore.on('send', function(data) {
                var lat = data.value.lat, lng = data.value.lon;

                var img = '';
                if(data.value.type == 'ryo'){
                    img = 'http://i.gyazo.com/7502afdcf0bbcc1f6d8f3d85e66616f6.png';
                }else if(data.value.type == 'maro'){
                    img = 'http://i.gyazo.com/f7b2e1dac073595c3e53a260413aec14.png';
                }

                map.setCenter(lat, lng);
                map.addMarker({
                    lat: lat,
                    lng: lng,
                    title: "LIG社員",
                    icon: img,
                    infoWindow: {
                        content: "<p>LIG社員は<br/>ココだよ!</p>"
                    }
                });
                console.log('recieve',data.value);
            });

        };
    </script>
</head>
<body>
<div id="map"></div>
<button onClick="ryo()">
    りょうちん
</button>
<button onClick="maro()">
    まろし
</button>
</body>
</html>

次に閲覧側です。こちらはmilkcocoaから情報を取得したらマッピングします。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>gmapsサンプル</title>
    <style>
        @charset "utf-8";
        #map {
            height: 400px;
        }
    </style>
    <script src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <script src="./gmaps.js"></script>
    <script src="http://cdn.mlkcca.com/v0.2.8/milkcocoa.js"></script>
    <script>
        var dataStore = new MilkCocoa("https://{YOUR APP ID}.mlkcca.com").dataStore('chat');

        window.onload = function(){

            var lat = 35.710285;
            var lng = 139.77714;
            var map = new GMaps({
                div: "#map",
                lat: lat,
                lng: lng,
                zoom: 17
            });

            dataStore.on('send', function(data) {
                var lat = data.value.lat, lng = data.value.lon;

                var img = '';
                if(data.value.type == 'ryo'){
                    img = 'http://i.gyazo.com/7502afdcf0bbcc1f6d8f3d85e66616f6.png';
                }else if(data.value.type == 'maro'){
                    img = 'http://i.gyazo.com/f7b2e1dac073595c3e53a260413aec14.png';
                }

                map.setCenter(lat, lng);
                map.addMarker({
                    lat: lat,
                    lng: lng,
                    title: "LIG社員",
                    icon: img,
                    infoWindow: {
                        content: "<p>LIG社員は<br/>ココだよ!</p>"
                    }
                });
                console.log('recieve',data.value);
            });

        };
    </script>
</head>
<body>
<div id="map"></div>
</body>
</html>

どちらもmilkcocoaのsendメソッドとsendイベントのみを利用して、情報は一切サーバーに保存していません。

実際に動かしてみた様子

655px

上のように、移動した軌跡が5秒に1回アイコンがマッピングされていきます。

実際にお昼ごはんを食べに行った時に使ってみました。

iPhoneでWebページを開いたまま「キッチンジロー」というお店に行きました。LIGから徒歩10分くらいです。

のびすけ

同時に地図への描画専用ページを見て、確認しつつ歩きました。

位置情報

上の画像でも分かるように、着実にマッピングされています。

会社ではディレクターのフジくんにWebページを見ててもらいました。

655px

「キッチンジロー」に行ったことが、フジくんから見ても分かったようですね。なかなか精度よくマッピングできています。

まとめ

いかがでしたでしょうか。

リアルタイムに地図へマッピングするのは難しい、というイメージがすこし前まではあったと思いますが、こういったライブラリやサービスがそろってきたことで、こんなに簡単に実現できるようになりました。

今回のマッピングはなぜか男性社員に協力してもらったのですが、女性社員にすれば良かったと後悔しています。

次こそは……!

次回作にご期待下さい。

 

【のびすけ、日々挑戦中】

Web制作者でもネイティブアプリが作れる!node-webkitを使ってみよう。

インタラクティブコンテンツを作ろう!milkcocoaで5分のチャットアプリ制作

Node.jsからGoogle Analytics APIにアクセスし、GA情報を表示させよう

所要時間3分!? Github PagesとHEXOで爆速ブログ構築してみよう!

PHPer必見!最強PHPerになれると噂の「新言語Hack」を試してみよう!

のびすけ
この記事を書いた人
のびすけ

バックエンドエンジニア

2014年入社

この記事を読んだ人におすすめ