取得路線

如要使用 Routes API 取得路線,請將 HTTP POST 要求傳送至 computeRoutes 方法 (REST),或呼叫 ComputeRoutes 方法 (gRPC)。

以下範例顯示對 computeRoutes 方法提出 REST 要求的網址:

https://routes.googleapis.com/directions/v2:computeRoutes

將您的要求選項加入 JSON 要求主體中。要求主體包含來源和目的地位置,以及您要在路徑上設定的任何選項。詳情請參閱「指定地點」和「可用的路線選項」。

回應中包含您在回應欄位遮罩中指定的欄位,方法是使用網址參數 $fields 或使用 HTTP gRPC 標頭 X-Goog-FieldMaskfield 資訊。詳情請參閱選擇要傳回的資訊

如需大眾運輸路線要求的範例,請參閱「示例:取得大眾運輸路線」。

範例:HTTP 路徑要求

以下程式碼說明如何建構 computeRoutes 要求的請求主體。在這個範例中,您會設定來源和目的地位置,並指定下列項目:

  • DRIVEtravelMode 和交通監控行車路線。

  • 採用 imperial 距離單位的 en-US 語言。

  • X-Goog-FieldMask 標頭中的回應欄位遮罩,可指定在回應中傳回下列欄位:

    • routes.duration
    • routes.distanceMeters
    • routes.polyline.encodedPolyline
curl -X POST -d '{
  "origin":{
    "location":{
      "latLng":{
        "latitude": 37.419734,
        "longitude": -122.0827784
      }
    }
  },
  "destination":{
    "location":{
      "latLng":{
        "latitude": 37.417670,
        "longitude": -122.079595
      }
    }
  },
  "travelMode": "DRIVE",
  "routingPreference": "TRAFFIC_AWARE",
  "computeAlternativeRoutes": false,
  "routeModifiers": {
    "avoidTolls": false,
    "avoidHighways": false,
    "avoidFerries": false
  },
  "languageCode": "en-US",
  "units": "IMPERIAL"
}' \
-H 'Content-Type: application/json' -H 'X-Goog-Api-Key: YOUR_API_KEY' \
-H 'X-Goog-FieldMask: routes.duration,routes.distanceMeters,routes.polyline.encodedPolyline' \
'https://routes.googleapis.com/directions/v2:computeRoutes'

範例:HTTP 路徑回應主體

上述呼叫會產生下列 JSON 回應:

{
  "routes": [
    {
      "distanceMeters": 772,
      "duration": "165s",
      "polyline": {
        "encodedPolyline": "ipkcFfichVnP@j@BLoFVwM{E?"
      }
    }
  ]
}

範例:gRPC 要求

gRPC 是由 Google 開發的高效能開放原始碼通用遠端程序呼叫 (RPC) 架構。在 gRPC 中,用戶端應用程式可以直接呼叫不同機器上伺服器應用程式中的方法,就像呼叫本機物件一樣。

以下範例顯示 gRPC 要求。

Go

package main

import (
  "context"
  "crypto/tls"
  "fmt"
  "log"
  "time"

  routespb "google.golang.org/genproto/googleapis/maps/routing/v2"
  "google.golang.org/genproto/googleapis/type/latlng"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials"
  "google.golang.org/grpc/metadata"
)

const (
  fieldMask  = "*"
  apiKey     = "INSERT_API_KEY_HERE"
  serverAddr = "routes.googleapis.com:443"
)

func main() {
  config := tls.Config{}
  conn, err := grpc.Dial(serverAddr,
      grpc.WithTransportCredentials(credentials.NewTLS(&config)))
  if err != nil {
      log.Fatalf("Failed to connect: %v", err)
  }
  defer conn.Close()
  client := routespb.NewRoutesClient(conn)
  ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
  ctx = metadata.AppendToOutgoingContext(ctx, "X-Goog-Api-Key", apiKey)
  ctx = metadata.AppendToOutgoingContext(ctx, "X-Goog-Fieldmask", fieldMask)
  defer cancel()

  // create the origin using a latitude and longitude
  origin := &routespb.Waypoint{
      LocationType: &routespb.Waypoint_Location{
          Location: &routespb.Location{
              LatLng: &latlng.LatLng{
                  Latitude:  37.417670,
                  Longitude: -122.0827784,
              },
          },
      },
  }

  // create the destination using a latitude and longitude
  destination := &routespb.Waypoint{
      LocationType: &routespb.Waypoint_Location{
          Location: &routespb.Location{
              LatLng: &latlng.LatLng{
                  Latitude:  37.417670,
                  Longitude: -122.079595,
              },
          },
      },
  }
  req := &routespb.ComputeRoutesRequest{
      Origin:                   origin,
      Destination:              destination,
      TravelMode:               routespb.RouteTravelMode_DRIVE,
      RoutingPreference:        routespb.RoutingPreference_TRAFFIC_AWARE,
      ComputeAlternativeRoutes: true,
      Units:                    routespb.Units_METRIC,
      RouteModifiers: &routespb.RouteModifiers{
          AvoidTolls:    false,
          AvoidHighways: true,
          AvoidFerries:  true,
      },
      PolylineQuality: routespb.PolylineQuality_OVERVIEW,
  }

  // execute rpc
  resp, err := client.ComputeRoutes(ctx, req)

  if err != nil {
      // "rpc error: code = InvalidArgument desc = Request contains an invalid
      // argument" may indicate that your project lacks access to Routes
      log.Fatal(err)
  }

  fmt.Printf("Response: %v", resp)

}
    

Java

package com.example;

import com.google.maps.routing.v2.*;
import com.google.type.LatLng;
import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ClientCall;
import io.grpc.ClientInterceptor;
import io.grpc.ClientInterceptors;
import io.grpc.ForwardingClientCall;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.StatusRuntimeException;
import io.grpc.netty.NettyChannelBuilder;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class RoutesClient {
   // For more detail on inserting API keys, see:
   // https://cloud.google.com/endpoints/docs/grpc/restricting-api-access-with-api-keys#java
   // For more detail on system parameters (such as FieldMask), see:
   // https://cloud.google.com/apis/docs/system-parameters
   private static final class RoutesInterceptor implements ClientInterceptor {
       private final String apiKey;
       private static final Logger logger = Logger.getLogger(RoutesInterceptor.class.getName());
       private static Metadata.Key<String> API_KEY_HEADER = Metadata.Key.of("x-goog-api-key",
               Metadata.ASCII_STRING_MARSHALLER);
       private static Metadata.Key<String> FIELD_MASK_HEADER = Metadata.Key.of("x-goog-fieldmask",
               Metadata.ASCII_STRING_MARSHALLER);

       public RoutesInterceptor(String apiKey) {
           this.apiKey = apiKey;
       }

       @Override
       public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
               CallOptions callOptions, Channel next) {
           logger.info("Intercepted " + method.getFullMethodName());
           ClientCall<ReqT, RespT> call = next.newCall(method, callOptions);
           call = new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(call) {
               @Override
               public void start(Listener<RespT> responseListener, Metadata headers) {
                   headers.put(API_KEY_HEADER, apiKey);
                   // Note that setting the field mask to * is OK for testing, but discouraged in
                   // production.
                   // For example, for ComputeRoutes, set the field mask to
                   // "routes.distanceMeters,routes.duration,routes.polyline.encodedPolyline"
                   // in order to get the route distances, durations, and encoded polylines.
                   headers.put(FIELD_MASK_HEADER, "*");
                   super.start(responseListener, headers);
               }
           };
           return call;
       }
   }

   private static final Logger logger = Logger.getLogger(RoutesClient.class.getName());
   private final RoutesGrpc.RoutesBlockingStub blockingStub;

   public RoutesClient(Channel channel) {
       blockingStub = RoutesGrpc.newBlockingStub(channel);
   }

   public static Waypoint createWaypointForLatLng(double lat, double lng) {
       return Waypoint.newBuilder()
               .setLocation(Location.newBuilder().setLatLng(LatLng.newBuilder().setLatitude(lat).setLongitude(lng)))
               .build();
   }

   public void computeRoutes() {
       ComputeRoutesRequest request = ComputeRoutesRequest.newBuilder()
               .setOrigin(createWaypointForLatLng(37.420761, -122.081356))
               .setDestination(createWaypointForLatLng(37.420999, -122.086894)).setTravelMode(RouteTravelMode.DRIVE)
               .setRoutingPreference(RoutingPreference.TRAFFIC_AWARE).setComputeAlternativeRoutes(true)
               .setRouteModifiers(
                       RouteModifiers.newBuilder().setAvoidTolls(false).setAvoidHighways(true).setAvoidFerries(true))
               .setPolylineQuality(PolylineQuality.OVERVIEW).build();
       ComputeRoutesResponse response;
       try {
           logger.info("About to send request: " + request.toString());
           response = blockingStub.withDeadlineAfter(2000, TimeUnit.MILLISECONDS).computeRoutes(request);
       } catch (StatusRuntimeException e) {
           logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
           return;
       }
       logger.info("Response: " + response.toString());
   }

   public void computeRouteMatrix() {
       ComputeRouteMatrixRequest request = ComputeRouteMatrixRequest.newBuilder()
               .addOrigins(RouteMatrixOrigin.newBuilder().setWaypoint(createWaypointForLatLng(37.420761, -122.081356))
                       .setRouteModifiers(RouteModifiers.newBuilder().setAvoidTolls(false).setAvoidHighways(true)
                               .setAvoidFerries(true)))
               .addOrigins(RouteMatrixOrigin.newBuilder().setWaypoint(createWaypointForLatLng(37.403184, -122.097371)))
               .addDestinations(RouteMatrixDestination.newBuilder()
                       .setWaypoint(createWaypointForLatLng(37.420999, -122.086894)))
               .addDestinations(RouteMatrixDestination.newBuilder()
                       .setWaypoint(createWaypointForLatLng(37.383047, -122.044651)))
               .setTravelMode(RouteTravelMode.DRIVE).setRoutingPreference(RoutingPreference.TRAFFIC_AWARE).build();
       Iterator<RouteMatrixElement> elements;
       try {
           logger.info("About to send request: " + request.toString());
           elements = blockingStub.withDeadlineAfter(2000, TimeUnit.MILLISECONDS).computeRouteMatrix(request);
       } catch (StatusRuntimeException e) {
           logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
           return;
       }

       while (elements.hasNext()) {
           logger.info("Element response: " + elements.next().toString());
       }
   }

   public static void main(String[] args) throws Exception {
       String apiKey = System.getenv("INSERT_API_KEY_HERE");

       // The standard TLS port is 443
       Channel channel = NettyChannelBuilder.forAddress("routes.googleapis.com", 443).build();
       channel = ClientInterceptors.intercept(channel, new RoutesInterceptor(apiKey));

       RoutesClient client = new RoutesClient(channel);
       client.computeRoutes();
       client.computeRouteMatrix();
   }
}

C#

如需使用 C# 的範例,請參閱 Google.Maps.Routing.V2

Node.js

const protoPath = "YOUR_PROTO_PATH";
const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");
const packageDefinition = protoLoader.loadSync(protoPath, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
});
const protoDescriptor =
  grpc.loadPackageDefinition(packageDefinition).google.maps.routing.v2;
const metadata = new grpc.Metadata();
const host = "routes.googleapis.com:443";
const apiKey = "YOUR_API_KEY";
const fieldMask = "*";
let ComputeRoutesRequest = {
  origin: {
    location: {
      lat_lng: {
        latitude: -37.816,
        longitude: 144.964,
      },
    },
  },
  destination: {
    location: {
      lat_lng: {
        latitude: -37.815,
        longitude: 144.966,
      },
    },
  },
  routing_preference: "TRAFFIC_AWARE",
  travel_mode: "DRIVE",
};
const ssl_creds = grpc.credentials.createSsl();
const call_creds = grpc.credentials.createFromMetadataGenerator(
  function (args, callback) {
    metadata.set("X-Goog-Api-Key", apiKey);
    metadata.set("X-Goog-Fieldmask", fieldMask);
    metadata.set("Content-Type", "application/json");
    callback(null, metadata);
  },
);
const credentials = grpc.credentials.combineChannelCredentials(
  ssl_creds,
  call_creds,
);
const client = new protoDescriptor.Routes(host, credentials);
client.ComputeRoutes(ComputeRoutesRequest, (error, response) => {
  if (error) {
    console.log(error);
    return;
  } else if (response) {
    console.log(response);
  }
});