您已全部設定完成!

若要開始開發,請參閱我們的開發人員文件

啟用 Google Maps Roads API

為協助您開始,我們將先引導您使用「Google 開發人員控制台」來執行一些動作:

  1. 建立或選擇專案
  2. 啟用 Google Maps Roads API
  3. 建立適當的金鑰
繼續

Snap to Roads



Google Maps Roads API 能夠在任一路線上取得最多 100 個沿途 GPS 點,然後傳回相似的資料集,並將點沿著車輛最有可能行駛的道路貼齊。

此外,您也可以要求針對點進行內插計算,並取得符合道路幾何圖形之平滑路徑結果。

要求

針對貼齊道路的要求必須使用下列格式,透過 HTTPS 傳送:

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

參數用法

必要參數

  • path — 路徑必須被貼齊。 path 參數接受緯度/經度組合的清單。 緯度與經度值應該以逗點分隔。 座標應該以直立線字元 "|" 分隔。 例如: path=60.170880,24.942795|60.170879,24.942796|60.170877,24.942796

    注意:貼齊演算法在地點相距不太遠的情況下運作最佳。 如果您發現有奇怪的貼齊行為,請嘗試建立點更加緊密的路徑。 為確保能獲得最佳的「貼齊道路」品質,您應該盡可能提供連續兩點相距 300m 內的路徑。

這同時能協助處理連續點之間因 GPS 訊號遺失或雜訊而造成的隔離長跳躍問題。

  • key — 您應用程式的 API 金鑰。 您的應用程式必須透過將 API 金鑰包括在每個要求中,以在每次將要求傳送至 Google Maps Roads API 時識別自己。

瞭解如何取得金鑰

選擇性參數

  • interpolate:是否要對路徑進行內插計算,以包括形成完整道路幾何圖形的所有點。 如果是 true,也會傳回額外的內插計算點,並取得符合道路幾何圖形之路徑的結果,就算是經過轉角或通過隧道也一樣。

與原始路徑相比,內插計算的路徑很有可能包含更多的點。 預設為 false

回應

對於每個有效的要求,Google Maps Roads API 將會以要求 URL 內指定的格式傳回回應。 下列元素可能會出現在 Snap to Roads 回應中。

  • snappedPoints:已貼齊點的陣列。 每個點都是由下列欄位所組成:

    • location — 包含 latitudelongitude 值。
    • originalIndex:指出原始要求中對應值的整數。 要求中的每個值都應該對應到回應中的一個貼齊值。 然而,如果您已設定 interpolate=true,則回應可能會比要求包含更多座標。 內插計算的值將不會有 originalIndex。 這些值都是從 0 編製索引,因此 originalIndex4 的點將會是第五個傳遞至 path 參數之緯度/經度的貼齊值。
    • placeId:地點的唯一識別碼。 由 Google Maps Roads API 傳回的所有地點 ID 都會與道路區段對應。 [地點 ID] 可與其他 Google API 搭配使用,包括 Google Places APIGoogle Maps JavaScript API。 例如,如果您需要為 Google Maps Roads API 傳回的貼齊點取得道路名稱,您可以將 placeId 傳遞至 Google Places APIGoogle Maps Geocoding API。 在 Google Maps Roads API 中,您可以在速度限制要求中傳遞 placeId,以判斷該道路區段的沿途速度限制。

範例要求

下列要求將會把指定點貼齊至道路幾何圖形。 這個特定的資料組合跟隨著一條環形道路,透過設定 interpolate=true,便能確保傳回的幾何圖形會符合道路的弧度。

如果 interpolate=false,貼齊的路徑仍然會跟隨道路,但折線結果將不會那麼圓滑。

要求

https://roads.googleapis.com/v1/snapToRoads?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&interpolate=true&key=YOUR_API_KEY

回應

{
  "snappedPoints": [
    {
      "location": {
        "latitude": -35.2784167,
        "longitude": 149.1294692
      },
      "originalIndex": 0,
      "placeId": "ChIJoR7CemhNFmsRQB9QbW7qABM"
    },
    {
      "location": {
        "latitude": -35.280321693840129,
        "longitude": 149.12908274880189
      },
      "originalIndex": 1,
      "placeId": "ChIJiy6YT2hNFmsRkHZAbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2803415,
        "longitude": 149.1290788
      },
      "placeId": "ChIJiy6YT2hNFmsRkHZAbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2803415,
        "longitude": 149.1290788
      },
      "placeId": "ChIJI2FUTGhNFmsRcHpAbW7qABM"
    },
    {
      "location": {
        "latitude": -35.280451499999991,
        "longitude": 149.1290784
      },
      "placeId": "ChIJI2FUTGhNFmsRcHpAbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2805167,
        "longitude": 149.1290879
      },
      "placeId": "ChIJI2FUTGhNFmsRcHpAbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2805901,
        "longitude": 149.1291104
      },
      "placeId": "ChIJI2FUTGhNFmsRcHpAbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2805901,
        "longitude": 149.1291104
      },
      "placeId": "ChIJW9R7smlNFmsRMH1AbW7qABM"
    },
    {
      "location": {
        "latitude": -35.280734599999995,
        "longitude": 149.1291517
      },
      "placeId": "ChIJW9R7smlNFmsRMH1AbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2807852,
        "longitude": 149.1291716
      },
      "placeId": "ChIJW9R7smlNFmsRMH1AbW7qABM"
    },
    {
      "location": {
        "latitude": -35.2808499,
        "longitude": 149.1292099
      },
      "placeId": "ChIJW9R7smlNFmsRMH1AbW7qABM"
    },
    {
      "location": {
        "latitude": -35.280923099999995,
        "longitude": 149.129278
      },
      "placeId": "ChIJW9R7smlNFmsRMH1AbW7qABM"
    },
    {
      "location": {
        "latitude": -35.280960897210818,
        "longitude": 149.1293250692261
      },
      "originalIndex": 2,
      "placeId": "ChIJW9R7smlNFmsRMH1AbW7qABM"
    },
    ... results truncated ...
    {
      "location": {
        "latitude": -35.284728724835304,
        "longitude": 149.12835061713685
      },
      "originalIndex": 7,
      "placeId": "ChIJW5JAZmpNFmsRegG0-Jc80sM"
    }
  ]
}

示範

  1. 取得 API 金鑰
  2. 製作下列程式碼的副本,然後以您自己的金鑰取代 API 金鑰。 如果沒有 API 金鑰,該示範將無法運作。
  3. 在瀏覽器中載入示範。
    您應該可以看到一個置中於澳洲雪梨的地圖。
  4. 在地圖四處點擊,以建立車輛路線。 請注意,如果您的點相隔太遠,將可能無法正確貼齊。
  5. 按兩下以將路線貼齊至道路上,並在折線上以色彩區分速度限制:
    • 紫色 <= 40 km/h
    • 藍色 = 40-50 km/h
    • 綠色 = 50-60 km/h
    • 黃色 = 70-80 km/h
    • 橘色 = 90-100 km/h
    • 紅色 = >100 km/h

注意:貼齊演算法在地點相距較近的情況下運作最佳。 如果您發現有奇怪的貼齊行為,請嘗試建立點更加緊密的路徑。 例如,在城市中,各點必須在相互的幾個街區內,以提升「貼齊道路」品質。

全螢幕檢視此範例。

JavaScript
var apiKey = 'YOUR_API_KEY';

var map;
var drawingManager;
var placeIdArray = [];
var polylines = [];
var snappedCoordinates = [];

function initialize() {
  var mapOptions = {
    zoom: 17,
    center: {lat: -33.8667, lng: 151.1955}
  };
  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  // Adds a Places search box. Searching for a place will center the map on that
  // location.
  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);
    }
  });

  // Enables the polyline drawing control. Click on the map to start drawing a
  // polyline. Each click will add a new vertice. Double-click to stop drawing.
  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: '#696969',
      strokeWeight: 2
    }
  });
  drawingManager.setMap(map);

  // Snap-to-road when the polyline is completed.
  drawingManager.addListener('polylinecomplete', function(poly) {
    var path = poly.getPath();
    polylines.push(poly);
    placeIdArray = [];
    runSnapToRoad(path);
  });

  // Clear button. Click to remove all polylines.
  $('#clear').click(function(ev) {
    for (var i = 0; i < polylines.length; ++i) {
      polylines[i].setMap(null);
    }
    polylines = [];
    ev.preventDefault();
    return false;
  });
}

// Snap a user-created polyline to roads and draw the snapped path
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();
  });
}

// Store snapped polyline returned by the snap-to-road service.
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);
  }
}

// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
  var snappedPolyline = new google.maps.Polyline({
    path: snappedCoordinates,
    strokeColor: 'black',
    strokeWeight: 3
  });

  snappedPolyline.setMap(map);
  polylines.push(snappedPolyline);
}

// Gets speed limits (for 100 segments at a time) and draws a polyline
// color-coded by speed limit. Must be called after processing snap-to-road
// response.
function getAndDrawSpeedLimits() {
  for (var i = 0; i <= placeIdArray.length / 100; i++) {
    // Ensure that no query exceeds the max 100 placeID limit.
    var start = i * 100;
    var end = Math.min((i + 1) * 100 - 1, placeIdArray.length);

    drawSpeedLimits(start, end);
  }
}

// Gets speed limits for a 100-segment path and draws a polyline color-coded by
// speed limit. Must be called after processing snap-to-road response.
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);
        }
    );
}

// Draw a polyline segment (up to 100 road segments) color-coded by speed limit.
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);

    // Take two points for a single-segment polyline.
    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);
JavaScript + HTML
<!DOCTYPE html> <html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Roads API 示範</title>
    <style>
      html, body, #map {
        height: 100%;
        margin: 0px;
        padding: 0px
      }

      #panel {
        position: absolute;
        top: 5px;
        left: 50%;
        margin-left: -180px;
        z-index: 5;
        background-color: #fff;
        padding: 5px;
        border: 1px solid #999;
      }

      #bar {
        width: 240px;
        background-color: rgba(255, 255, 255, 0.75);
        margin: 8px;
        padding: 4px;
        border-radius: 4px;
      }

      #autoc {
        width: 100%;
        box-sizing: border-box;
      }
    </style>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?libraries=drawing,places"></script>
    <script>
var apiKey = 'YOUR_API_KEY';

var map;
var drawingManager;
var placeIdArray = [];
var polylines = [];
var snappedCoordinates = [];

function initialize() {
  var mapOptions = {
    zoom: 17,
    center: {lat: -33.8667, lng: 151.1955}
  };
  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  // Adds a Places search box. Searching for a place will center the map on that
  // location.
  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);
    }
  });

  // Enables the polyline drawing control. Click on the map to start drawing a
  // polyline. Each click will add a new vertice. Double-click to stop drawing.
  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: '#696969',
      strokeWeight: 2
    }
  });
  drawingManager.setMap(map);

  // Snap-to-road when the polyline is completed.
  drawingManager.addListener('polylinecomplete', function(poly) {
    var path = poly.getPath();
    polylines.push(poly);
    placeIdArray = [];
    runSnapToRoad(path);
  });

  // Clear button. Click to remove all polylines.
  $('#clear').click(function(ev) {
    for (var i = 0; i < polylines.length; ++i) {
      polylines[i].setMap(null);
    }
    polylines = [];
    ev.preventDefault();
    return false;
  });
}

// Snap a user-created polyline to roads and draw the snapped path
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();
  });
}

// Store snapped polyline returned by the snap-to-road service.
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);
  }
}

// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
  var snappedPolyline = new google.maps.Polyline({
    path: snappedCoordinates,
    strokeColor: 'black',
    strokeWeight: 3
  });

  snappedPolyline.setMap(map);
  polylines.push(snappedPolyline);
}

// Gets speed limits (for 100 segments at a time) and draws a polyline
// color-coded by speed limit. Must be called after processing snap-to-road
// response.
function getAndDrawSpeedLimits() {
  for (var i = 0; i <= placeIdArray.length / 100; i++) {
    // Ensure that no query exceeds the max 100 placeID limit.
    var start = i * 100;
    var end = Math.min((i + 1) * 100 - 1, placeIdArray.length);

    drawSpeedLimits(start, end);
  }
}

// Gets speed limits for a 100-segment path and draws a polyline color-coded by
// speed limit. Must be called after processing snap-to-road response.
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);
        }
    );
}

// Draw a polyline segment (up to 100 road segments) color-coded by speed limit.
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);

    // Take two points for a single-segment polyline.
    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);

    </script>
  </head>

  <body>
    <div id="map"></div>
    <div id="bar">
      <p class="auto"><input type="text" id="autoc"/></p>
      <p><a id="clear" href="#">按一下此處</a>來清除地圖。</p>
    </div>
  </body>
</html>

傳送您對下列選項的寶貴意見...

這個網頁
Google Maps Roads API
Google Maps Roads API
需要協助嗎?請前往我們的支援網頁