GoogleMapを使った道案内
(WebPageとAndroidアプリを同時作成)

cordova対応のandroid開発環境・仮想マシンを使ってWebページをAndroidアプリ化する。

Android開発環境・仮想マシンでcordovaを使ったAndroidアプリの作成例を紹介します。

ここに通常のWeb版が置いてあります。

このWeb版をそのままAndroidアプリ化できます。

cordovaはAndroidアプリケーションをJavaをほとんど使わず、HTML,CSS,JavaScriptで 開発できるようにするツールです。基本的にはローカルに持つHTMLファイルを 表示するブラウザアプリと成っていて、WebページがそのままAndroidアプリとして 動作するようにしたものです。

ブラウザの高機能化とHTML5による共通規格化がアプリのあり方を大きく変えてきていることを 感じることが出来ます。ブラウザベースのアプリケーションは今後の主流のひとつとなると 思われます。

HTMLによるWebページ作成は一般的なWebサーバー用のページの作り方と全く変わりません。 CGI等サーバー依存の機能を使わず、HTML,CSS,JavaScriptだけでページを作成すれば、それをそのまま Androidアプリとして作成することが可能となります。

ソースコードの取扱いについて

例題ソースコードはご自由にご利用ください。パブリックドメインとし改変自由です。

最初の方にある設定部分で「ゴールの位置」、「現在位置が取れない時のデフォルトの位置」、 「デフォルトのstart位置の説明」を書換え、titleを変更すれば簡単に再利用できると思います。

道案内に使用するツール

ツール 利用している機能
GoogleMap API V3 Googleのサイトを呼び出して、ルート検索し地図とルートを表示する。
HTML5
geolocation API
HTML5対応のブラウザを通して現在位置情報を取得する。
Dynamic Icons 動的にURLで指定したアイコンを生成して返す。

道案内のソースコード

短いので全体を書いておきます。

<!DOCTYPE html > 
<html> 
<head> 
  <title>Trail4You 道案内・例題ページ</title> 
  <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
  <!--
     
     このページのソースは会社への道案内等に ご自由にご利用下さい。
     出来れば、一番下のTrail4Youへのリンクを残して頂けると有り難いです。
     
  -->

  <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script> 
  <script type="text/javascript">

    //---- 設定 ---------
    // 「ゴールの位置」と「現在位置が取れない時のデフォルトの位置」を定義してください。
    var goal_latlng          = new google.maps.LatLng(35.54219641731306,139.44565147161484);  // 目的地 = 町田駅
    var default_start_latlng = new google.maps.LatLng(35.53548441173569,139.47316020727158);  // デフォルトStart=成瀬駅
    var default_message      = '成瀬駅からのルートを表示します。';                            // デフォルトのstart位置の説明
    //---- 設定終了 ---------
    
    function getLocation(callback) {
      if (navigator.geolocation) {
        function default_location(message)
        {
          window.alert(message + default_message);
          callback(default_start_latlng);
        }
        
        navigator.geolocation.getCurrentPosition(
          function (position) 
          {
            callback(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
          },

          function (error) 
          {
            var message = "Error";
            switch (error.code) 
            {
              case error.POSITION_UNAVAILABLE:
                message = "位置情報の取得ができませんでした。";
                break;
              case error.PERMISSION_DENIED:
                message = "位置情報取得の使用許可がされませんでした。";
                break;
              case error.PERMISSION_DENIED_TIMEOUT:
                message = "位置情報取得中にタイムアウトしました。";
                break;
            }
            default_location(message);
          },

          {
            timeout : 2000,
            maximumAge : 0,
            enableHighAccuracy: true
          }
        );
      }
      else 
      {
        default_location("Geolocationがサポートされていません。");
      }
    }

    google.maps.event.addDomListener(window, 'load', 
      function() 
      {
        var mapOptions = { zoom: 16, center: null, mapTypeId: google.maps.MapTypeId.ROADMAP, scaleControl: true };
        var mapObj = new google.maps.Map(document.getElementById('gmap'), mapOptions); 

        directionsRenderer = new google.maps.DirectionsRenderer(); // ルートを表示するマップを設定
        directionsRenderer.setMap(mapObj); 

        function showMap(currentLatLng) 
        {
          var request = { 
            origin: currentLatLng,      // 開始地点
            destination: goal_latlng,   // 終了地点
            travelMode: google.maps.DirectionsTravelMode.WALKING // ルーティングの種類=徒歩
          }; 

          var directionsService  = new google.maps.DirectionsService();
          directionsService.route(request,
            function(result, status) 
            { 
              if (status == google.maps.DirectionsStatus.OK) {
                directionsRenderer.suppressMarkers = true;
                directionsRenderer.setDirections(result); 

                var icon_text;
                if (currentLatLng == default_start_latlng)
                {
                  icon_text = "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=bbT|Start|FFFFFF|22C022"
                }
                else
                {
                  icon_text = "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=bbT|Now|FFFFFF|22C022"
                }
                var marker = new google.maps.Marker({
                  position: currentLatLng, 
                  map: mapObj,
                  icon: icon_text
                });

                var marker = new google.maps.Marker({
                  position: goal_latlng, 
                  map: mapObj,
                  icon: "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=bbT|Goal|FFFFFF|22C022"
                });

              } 
            }
          ); 
        }

        getLocation(showMap);

      }
    );

  function ReloadPage(){
    window.location.reload();
  }    
  </script> 
</head> 
<body> 
    <div id="gmap" style="width: 99%; height: 400px;  border: 1px solid Gray;"> 
    </div> 
    <h2 onClick="ReloadPage()">ルート更新</h2>
    <hr>
    
    
    
    <!-- 出来ればこの下の行は残して下さい。ご協力を宜しくお願いします。 -->
    <h5>この道案内は<a href="https://www.trail4you.com/Bazaar/">Trail4You</a>の
    <a href="https://www.trail4you.com/map1.html">「Trail4You 道案内・例題ページ」</a>を利用しています</h5>
    <!-- ここまで -->
    
</body> 
</html> 

道案内のソースコード解説

このプログラムは以下の順序で実行されます。

  • google.maps.event.addDomListenerの呼び出しから始まり、
  • 地図を用意したところで、位置情報を取出し(getLocation)、
  • 位置情報を元にルート探索と探索結果を表示(showMap)する。

それぞれがコールバックという仕組みで繋がれて実行されます。


最初の部分はお決まりのヘッダ指定です。 再利用する場合 title部分を書き換えて下さい。 文字コードはUTF8を使用しています。

| <!DOCTYPE html > 
| <html> 
| <head> 
|   <title>Trail4You 道案内・例題ページ</title> 
|   <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
|   <!--
|      
|      このページのソースは会社への道案内等に ご自由にご利用下さい。
|      出来れば、一番下のTrail4Youへのリンクを残して頂けると有り難いです。
|      
|   -->
|

GoogleMapのコードを読み込みます。

|   <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>

ここからがJavaScriptでの処理部分となります。

|   <script type="text/javascript">
|

再利用する場合にはこの位置情報と説明を書き換えて下さい。

Googleマップで右クリック「この場所について」を選択すると緯度経度が取得できます。

|     //---- 設定 ---------
|     // 「ゴールの位置」と「現在位置が取れない時のデフォルトの位置」を定義してください。
|     var goal_latlng          = new google.maps.LatLng(35.54219641731306,139.44565147161484);  // 目的地 = 町田駅
|     var default_start_latlng = new google.maps.LatLng(35.53548441173569,139.47316020727158);  // デフォルトStart=成瀬駅
|     var default_message      = '成瀬駅からのルートを表示します。';                            // デフォルトのstart位置の説明
|     //---- 設定終了 ---------
|

gotLocation 関数はコールバック関数を受け取り、位置情報が取得できたらコールバック関数を呼び出します。

navigator.geolocation が有るか調べることでgeolocation対応のブラウザであるかが 判定できます。

|     function getLocation(callback) {
|       if (navigator.geolocation) {

default_location関数は位置情報が取得できなかったときに呼び出され 渡されたメッセージにデフォルト位置の説明を追加して表示した後で デフォルトの位置を返す関数です。

getLocation関数の中で定義されている事に注意して下さい。 ここで定義されているのでgetLocationが受け取ったcallback関数を 使う事が出来ます。

|         function default_location(message)
|         {
|           window.alert(message + default_message);
|           callback(default_start_latlng);
|         }
|

実際に位置情報を取得するAPI(getCurrentPosition)を呼び出します。 引数として以下のものを渡しています。

  • 成功した時に呼び出される関数
  • 失敗したときに呼び出される関数
  • オプションパラメータ
|         navigator.geolocation.getCurrentPosition(

最初の引数の成功したときに呼び出される関数です。 無名関数として直接定義しています。

成功したときにはpositionに渡されるオブジェクトから緯度経度を使ってLatLngを作って コールバックしています。

|           function (position) 
|           {
|             callback(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
|           },
|

二つめの引数の失敗したときに呼び出される関数です。 無名関数として直接定義しています。

エラーの内容を解析して表示するメッセージを設定し デフォルト位置を返す関数(default_location)を呼び出します。

|           function (error) 
|           {
|             var message = "Error";
|             switch (error.code) 
|             {
|               case error.POSITION_UNAVAILABLE:
|                 message = "位置情報の取得ができませんでした。";
|                 break;
|               case error.PERMISSION_DENIED:
|                 message = "位置情報取得の使用許可がされませんでした。";
|                 break;
|               case error.PERMISSION_DENIED_TIMEOUT:
|                 message = "位置情報取得中にタイムアウトしました。";
|                 break;
|             }
|             default_location(message);
|           },
|

三つめの引数のオプションパラメータです。

2秒のタイムアウト、毎回位置情報を取り直す、GPSデータを利用する、を指定しています。

|           {
|             timeout : 2000,
|             maximumAge : 0,
|             enableHighAccuracy: true
|           }
|         );
|       }

geolocation機能の無いブラウザの場合にはデフォルト値を返すようにしています。

|       else 
|       {
|         default_location("Geolocationがサポートされていません。");
|       }
|     }
|

ここからGoogleMapの表示部分です。 コードがloadされた後に実行されます。

|     google.maps.event.addDomListener(window, 'load', 
|       function() 
|       {

mapオブジェクトを作成します。

|         var mapOptions = { zoom: 16, center: null, mapTypeId: google.maps.MapTypeId.ROADMAP, scaleControl: true };
|         var mapObj = new google.maps.Map(document.getElementById('gmap'), mapOptions); 
|

ルート案内表示用のオブジェクトを作成します。

|         directionsRenderer = new google.maps.DirectionsRenderer(); // ルートを表示するマップを設定
|         directionsRenderer.setMap(mapObj); 
|

位置情報を読込んだ後に呼び出される関数をここで定義しています。 この位置で定義しているので直前で定義しているマップやルート用オブジェクトを 関数内で使用することが出来ます。

実際に呼び出されるのはgetLocationの中からであることに注意して下さい。

|         function showMap(currentLatLng) 
|         {
|           var request = { 
|             origin: currentLatLng,      // 開始地点
|             destination: goal_latlng,   // 終了地点
|             travelMode: google.maps.DirectionsTravelMode.WALKING // ルーティングの種類=徒歩
|           }; 
|

ルート探索を実行します。 引数に探索が終了した場合に呼び出される関数を渡しています。

|           var directionsService  = new google.maps.DirectionsService();
|           directionsService.route(request,

探索が終了した場合に呼び出される関数です。

|             function(result, status) 
|             { 
|               if (status == google.maps.DirectionsStatus.OK) {

探索が成功した場合に標準のマーカーを表示しない設定をして ルートを表示させています。

|                 directionsRenderer.suppressMarkers = true;
|                 directionsRenderer.setDirections(result); 
|

条件により開始点のアイコンを切り替えて表示させています。

https://chart.googleapis.com/chart にパラメータを渡すことで様々なアイコンを 生成することが可能です。ここではシンプルな文字列アイコンを生成しています。

詳細は「道案内に使用するツール」に有るリンク先を参照して下さい。

直接アイコン用の画像イメージを指定して表示させることも可能です。

|                 var icon_text;
|                 if (currentLatLng == default_start_latlng)
|                 {
|                   icon_text = "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=bbT|Start|FFFFFF|22C022"
|                 }
|                 else
|                 {
|                   icon_text = "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=bbT|Now|FFFFFF|22C022"
|                 }
|                 var marker = new google.maps.Marker({
|                   position: currentLatLng, 
|                   map: mapObj,
|                   icon: icon_text
|                 });
|

ゴール地点のアイコンを表示させています。

|                 var marker = new google.maps.Marker({
|                   position: goal_latlng, 
|                   map: mapObj,
|                   icon: "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=bbT|Goal|FFFFFF|22C022"
|                 });
|                 
|               } 
|             }
|           ); 
|         }
|

位置情報取出しを呼び出し、完了したときにshowMap関数が呼び出されるようにしています。

|         getLocation(showMap);
|         
|       }
|     );
|

リロード用の関数です。

電池を消耗させ無い為と、ゆっくりと地図を操作したりできるようにする為に、 自動的なリロードはしない設計としています。

|   function ReloadPage(){
|     window.location.reload();
|   }    
|   </script> 
| </head> 
| <body>

id="gmap"のdivに地図が表示されます。

|     <div id="gmap" style="width: 99%; height: 400px;  border: 1px solid Gray;"> 
|     </div>

リロード用のボタン代わりにh2を使っています。

|     <h2 onClick="ReloadPage()">ルート更新</h2>
|     <hr>

Androidアプリ化の方法

  • Trail4YouのAndroid開発環境・仮想マシンを立ち上げEclipseで Android applicationプロジェクトを生成します。
  • 簡単なcordova用の設定を行ないます。
  • assets/www/index.html をここで解説したソースに置き換えます。
  • プロジェクトを選択して実行させます。 これで、AVD上でアプリケーションとして実行されます。
  • 必要に応じてapkファイルとして生成してアプリとして配布します。

以上でAndroid用アプリが簡単に作成できます。