מסלול הגעה

מפתחים באזור הכלכלי האירופי (EEA)

אפשר לקבל מסלול באמצעות Compute Routes API על ידי שליחת בקשת HTTP POST לשיטה computeRoutes (REST) או על ידי קריאה לשיטה ComputeRoutes (gRPC).

בדוגמה הבאה מוצגת כתובת ה-URL של בקשת REST לשיטת computeRoutes:

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

אפשרויות הבקשה צריכות להיכלל בגוף הבקשה בפורמט JSON. גוף הבקשה מכיל את מיקומי המקור והיעד ואת האפשרויות שרוצים להגדיר במסלול. מידע נוסף זמין במאמרים ציון מיקומים ואפשרויות מסלול זמינות.

התשובה מכילה את השדות שציינתם במסכת השדות של התשובה באמצעות הפרמטר של כתובת ה-URL‏ $fields או field, או מידע באמצעות כותרת ה-HTTP gRPC‏ X-Goog-FieldMask. פרטים נוספים זמינים במאמר בנושא בחירת המידע שיוחזר.

דוגמה לבקשה למסלול לתחבורה ציבורית מופיעה במאמר דוגמה: קבלת מסלול לתחבורה ציבורית.

דוגמה: בקשת מסלול HTTP

בדוגמה הבאה מוצג איך ליצור גוף בקשה עבור בקשת computeRoutes. בדוגמה הזו, הגדרתם את מיקומי המקור והיעד וציינתם גם:

  • travelMode של DRIVE ומסלול נסיעה שמתעדכן לפי מצב התנועה.

  • שפה של en-US עם יחידות מרחק של metric. ההעדפות האלה חלות רק על הערכים המותאמים לשפה המקומית, כשמבקשים אותם. הערך distanceMeters תמיד מופיע במדד.

  • מסכת שדות של תגובה בכותרת 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": "METRIC"
}' \
-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 הוא מסגרת RPC אוניברסלית בקוד פתוח עם ביצועים גבוהים, שפותחה על ידי Google. ב-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);
  }
});