ZENRIN DataCom

自分が歩いてきた経路を辿ろう!Roads APIの使い方

Google Maps Roads APIは、Google Maps APIのウェブサービスAPIにあたる機能の1つで、主にルートを作成したり、移動経路を調整するためのAPIです。
ここでは、そんなGoogle Maps Roads APIの主な機能や使い方、活用法などについてわかりやすく解説します。

Google Maps Roads APIとは

Google Maps Roads APIは、移動中にGPSで取得した位置データをもとに、GPSのパンくずリストを追跡して、移動したルートを作成するためのAPIです。GPSの誤差により経路にばらつきがある場合は、取得したGPSの位置情報に基づいて走行していた道路を特定し、道路を補完する機能も提供されています。
また、GPSの位置情報から、その道路上にある区間の速度制限を取得することも可能です。

#Google Maps Roads APIを使用するためには、Google Map APIのAPIキーを取得する必要があります。

Google Maps Roads APIの実装方法

ここではRoads APIの実装方法について、サンプルをもとに解説していきます。

Google Maps Roads API は、取得した経路のGPSの情報を最大100個まで受け取ることができます。
地点を補完することが可能で、走行していた可能性が最も高い地点のデータを返します。

※参考:Snap to Roads

https://developers.google.com/maps/documentation/roads/snap?hl=ja 別ウィンドウで開く

リクエストの実行

走行した地点のスナップの取得は、以下のようにhttpsでリクエストを送信する必要があります。

https://roads.googleapis.com/v1/snapToRoads?parameters&key=YOUR_API_KEY

parametersには、緯度と経度のペアのリストを渡します。緯度と経度はコンマ「.」で区切り、座標はパイプ「|」で区切ります。

path=-35.27801,149.12958|-35.28032,149.12907|-35.28099,149.12929|
-35.28144,149.12984|-35.28194,149.13003|-35.28282,149.12956|
-35.28302,149.12881|-35.28473,149.12836
				

keyにはGoogle Maps APIのAPIキーを指定し、ブラウザのURLに入力し実行します。

実行すると、以下のように指定した緯度経度をもとに道路の形状にスナップされたデータを返します。
interpolate=trueを指定しておけば、地点間における補完が有効となり、返されるデータが道路のカーブなどに一致されます。

実行結果

{
  "snappedPoints": [
    {
      "location": {
        "latitude": -35.278004899930188,
        "longitude": 149.129531998742
      },
      "originalIndex": 0,
      "placeId": "ChIJr_xl0GdNFmsRsUtUbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2784195,
        "longitude": 149.12946589999999
      },
      "placeId": "ChIJr_xl0GdNFmsRsUtUbW7qABM"
    },
    
          省略...


    {
      "location": {
        "latitude": -35.284728747199381,
        "longitude": 149.12834860726772
      },
      "originalIndex": 7,
      "placeId": "ChIJtWxAZmpNFmsRlbUCkc6VtnA"
    }
  ]
}
				

エラーが発生した場合

リクエストのエラーが発生した場合は、APIマネージャーのライブラリより、Roads APIを有効にしていない可能性があります。
有効にする場合は、APIマネージャーのライブラリより「Google Maps Roads API」を選択し、Google Maps Roads API画面より「有効にする」をクリックしてください。

Snap to Roadsに記載されているサンプルをもとに実際にRoads APIを動かしてみます。
ここでは、シドニー箱根を中心に地図を表示させています。

記述例

var apiKey = 'YOUR_API_KEY';
   var map;
   var drawingManager;
   var placeIdArray = [];
   var polylines = [];
   var snappedCoordinates = [];

   function initialize() {
     var mapOptions = {
       zoom: 13,
       center: {lat: 35.232355, lng: 139.106937}
     };
     map = new google.maps.Map(document.getElementById('map'), mapOptions);
     map.controls[google.maps.ControlPosition.RIGHT_TOP].push(
         document.getElementById('bar'));
     var autocomplete = new google.maps.places.Autocomplete(
         document.getElementById('autoc'));
     autocomplete.bindTo('bounds', map);
     autocomplete.addListener('place_changed', function() {
       var place = autocomplete.getPlace();
       if (place.geometry.viewport) {
         map.fitBounds(place.geometry.viewport);
       } else {
         map.setCenter(place.geometry.location);
         map.setZoom(17);
       }
     });
     drawingManager = new google.maps.drawing.DrawingManager({
       drawingMode: google.maps.drawing.OverlayType.POLYLINE,
       drawingControl: true,
       drawingControlOptions: {
         position: google.maps.ControlPosition.TOP_CENTER,
         drawingModes: [
           google.maps.drawing.OverlayType.POLYLINE
         ]
       },
       polylineOptions: {
         strokeColor: '#FE2E2E',
         strokeWeight: 2
       }
     });
     drawingManager.setMap(map);
     drawingManager.addListener('polylinecomplete', function(poly) {
       var path = poly.getPath();
       polylines.push(poly);
       placeIdArray = [];
       runSnapToRoad(path);
     });
     $('#clear').click(function(ev) {
       for (var i = 0; i < polylines.length; ++i) {
         polylines[i].setMap(null);
       }
       polylines = [];
       ev.preventDefault();
       return false;
     });
   }
   function runSnapToRoad(path) {
    var pathValues = [];
    for (var i = 0; i < path.getLength(); i++) {
     pathValues.push(path.getAt(i).toUrlValue());
    }
    $.get('https://roads.googleapis.com/v1/snapToRoads', {
     interpolate: true,
     key: apiKey,
     path: pathValues.join('|')
    }, function(data) {
     processSnapToRoadResponse(data);
     drawSnappedPolyline();
     getAndDrawSpeedLimits();
    });
   }
   function processSnapToRoadResponse(data) {
    snappedCoordinates = [];
    placeIdArray = [];
    for (var i = 0; i < data.snappedPoints.length; i++) {
      var latlng = new google.maps.LatLng(
         data.snappedPoints[i].location.latitude,
         data.snappedPoints[i].location.longitude);
      snappedCoordinates.push(latlng);
      placeIdArray.push(data.snappedPoints[i].placeId);
    }
   }
   function drawSnappedPolyline() {
    var snappedPolyline = new google.maps.Polyline({
    path: snappedCoordinates,
    strokeColor: 'blue',
    strokeWeight: 3
    });
    snappedPolyline.setMap(map);
    polylines.push(snappedPolyline);
   }
   function getAndDrawSpeedLimits() {
    for (var i = 0; i <= placeIdArray.length / 100; i++) {
    var start = i * 100;
    var end = Math.min((i + 1) * 100 - 1, placeIdArray.length);
    drawSpeedLimits(start, end);
    }
   }
   function drawSpeedLimits(start, end) {
    var placeIdQuery = '';
    for (var i = start; i < end; i++) {
     placeIdQuery += '&placeId=' + placeIdArray[i];
    }
    $.get('https://roads.googleapis.com/v1/speedLimits',
      'key=' + apiKey + placeIdQuery,
      function(speedData) {
       processSpeedLimitResponse(speedData, start);
      }
    );
   }
   function processSpeedLimitResponse(speedData, start) {
    var end = start + speedData.speedLimits.length;
    for (var i = 0; i < speedData.speedLimits.length - 1; i++) {
      var speedLimit = speedData.speedLimits[i].speedLimit;
      var color = getColorForSpeed(speedLimit);
      var coords = snappedCoordinates.slice(start + i, start + i + 2);
      var snappedPolyline = new google.maps.Polyline({
        path: coords,
        strokeColor: color,
        strokeWeight: 6
      });
      snappedPolyline.setMap(map);
      polylines.push(snappedPolyline);
    }
  }
    function getColorForSpeed(speed_kph) {
    if (speed_kph <= 40) {
      return 'purple';
    }
    if (speed_kph <= 50) {
      return 'blue';
    }
    if (speed_kph <= 60) {
      return 'green';
    }
    if (speed_kph <= 80) {
      return 'yellow';
    }
    if (speed_kph <= 100) {
      return 'orange';
    }
    return 'red';
  }
 $(window).load(initialize);
			

実行例

黒赤が線を引いて作成した経路、青が作成された経路になります。
このように適当に線を引いても、道路の形状に沿ってルートを補完してくれます。
Roads APIを使用して位置などを変更したい場合は、Snap to Roadsのサンプルを参照してください。

まとめ - Roads APIの活用方法

ご説明したようにRoads APIを使用すれば、曖昧なルートを補完して経路情報を取得することができます。
たとえば、自動車や自転車などで走りたいルートに線を引いて、オリジナルのルートを作成することが可能です。
また、GPS情報を利用して、営業で使用している車が実際にどのルートを走行したか把握したい場合や、ランニングやトレッキングなどのフィットネスアプリなどに実装して、自分が走ったルートや移動距離を記録することができます。

このようにRoads APIなどのGoogle Maps APIの便利な機能を使いこなせば、さまざまなビジネスや趣味に活用することが可能ですので、ぜひ導入してみることをおすすめします。

関連の法人向けサービス