אפשר להשתמש ב-method ComputeCustomRoutes
בבקשה ובתשובה של HTTP
או בכל שפה שתומכת ב-gRPC, כולל Java ו-Go.
דוגמאות ל-HTTP
הדוגמה הבאה ממחישה דוגמה של בקשת curl ותגובה.
בקשה:
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",
"routeObjective": {
"rateCard":{
"costPerMinute":{
"value":1.1
},
"costPerKm":{
"value":2.2
}
}
}
}' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: <YOUR_API_KEY>' \
-H 'X-Goog-FieldMask: routes.route.distanceMeters,routes.route.duration,routes.token,routes.route.travelAdvisory.tollInfo' \
'https://routespreferred.googleapis.com/v1alpha:computeCustomRoutes'
תשובה:
{
"routes": [
{
"route": {
"distanceMeters": 987,
"duration": "247s",
"travelAdvisory": {
"tollInfo": {}
}
},
"token": "CocCCnYKCNOX2XMIWqf2EihazE0WzZ87txlU4F74nQiWxZpgRgOzf3TMHUm1sVpY4APnvf_BWoEYGibs64nuCxYcsQEXqQjaChCLGOkBHNseoyoAmAG1CxbkG58hEhJ4FiIBKkIJbwqHAz2qAhZfSgivvZI-AACAP3gBEAQaigEKhwEKLAohChYIAxISCgcQARiAwtcvEgcQAhiAhK9fEQAAAAAAAPA_EareoBH6vShAEg4IABADEAYYAkIEGgIIBRoGCgQIAhACIj8KNjIwMjAtMDYtMTB8MTI6NTY6MzcuODg3OTEzLTA3fDEwLjk5LjE5OS4xNnwtMTA3Mjc4OTI3MhCHwajvnhs"
}
]
}
יש להעביר את אסימון הנתיב בתגובה ComputeCustomRoutes
ל-SDK לניווט כדי להתחיל סשן ניווט, שמנסה
לעקוב אחר המסלול שהוחזר על-ידי Routes Preferred API.
התוקף של אסימוני הניתוב לא פג, אבל בגלל תנאי הדרך הדינמיים, הנתיבים שנוצרו
עם אסימון נתון, עשויים להיות שונים מהמסלול המקורי. אנחנו מאוד ממליצים
מומלץ להשתמש באסימון הנתיב בתוך כמה דקות ממועד יצירת האסימון.
למידע נוסף על אסימוני מסלול, ראו את ה-SDK לניווט ב-Android ותיעוד של Navigation SDK ל-iOS:
דוגמאות ל-Java ו-Go
הדוגמאות הבאות מראות איך לקרוא ל-method ComputeCustomRoutes
באמצעות Java
או 'עבור'. אפשר לעיין בפונקציות המתאימות
Java ו
קחו GitHub
הוראות ל-build.
Java
package com.example; import com.google.maps.routes.v1.ComputeCustomRoutesRequest; import com.google.maps.routes.v1.ComputeCustomRoutesResponse; import com.google.maps.routes.v1.Location; import com.google.maps.routes.v1.PolylineQuality; import com.google.maps.routes.v1.RouteModifiers; import com.google.maps.routes.v1.RouteObjective; import com.google.maps.routes.v1.RouteObjective.RateCard; import com.google.maps.routes.v1.RouteObjective.RateCard.MonetaryCost; import com.google.maps.routes.v1.RouteTravelMode; import com.google.maps.routes.v1.RoutingPreference; import com.google.maps.routes.v1.Units; import com.google.maps.routes.v1.Waypoint; import com.google.maps.routes.v1alpha.RoutesAlphaGrpc; 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.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; public class RoutesPreferredCustomRoutesClient { // 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 RoutesPreferredInterceptor implements ClientInterceptor { private final String apiKey; private static final Logger logger = Logger.getLogger(RoutesPreferredInterceptor.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 RoutesPreferredInterceptor(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 ComputeCustomRoutes, set the field mask to // "routes.route.duration,routes.route.distanceMeters,routes.route.polyline" // 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(RoutesPreferredCustomRoutesClient.class.getName()); private final RoutesAlphaGrpc.RoutesAlphaBlockingStub blockingStub; public RoutesPreferredCustomRoutesClient(Channel channel) { blockingStub = RoutesAlphaGrpc.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 computeCustomRoutes() { ComputeCustomRoutesRequest request = ComputeCustomRoutesRequest.newBuilder() .setOrigin(createWaypointForLatLng(37.420761, -122.081356)) .setDestination(createWaypointForLatLng(37.420999, -122.086894)) .setRouteObjective( RouteObjective.newBuilder() .setRateCard( RateCard.newBuilder() .setCostPerMinute(MonetaryCost.newBuilder().setValue(1.1)))) .setTravelMode(RouteTravelMode.DRIVE) .setRoutingPreference(RoutingPreference.TRAFFIC_AWARE) .setUnits(Units.METRIC) .setLanguageCode("en-us") .setRouteModifiers( RouteModifiers.newBuilder() .setAvoidTolls(false) .setAvoidHighways(true) .setAvoidFerries(true)) .setPolylineQuality(PolylineQuality.OVERVIEW) .build(); ComputeCustomRoutesResponse response; try { logger.info("About to send request: " + request.toString()); response = blockingStub.withDeadlineAfter(2000, TimeUnit.MILLISECONDS).computeCustomRoutes(request); } catch (StatusRuntimeException e) { logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); return; } logger.info("Response: " + response.toString()); } public static void main(String[] args) throws Exception { String apiKey = System.getenv("GOOGLE_MAPS_API_KEY"); // The standard TLS port is 443 Channel channel = NettyChannelBuilder.forAddress("routespreferred.googleapis.com", 443).build(); channel = ClientInterceptors.intercept(channel, new RoutesPreferredInterceptor(apiKey)); RoutesPreferredCustomRoutesClient client = new RoutesPreferredCustomRoutesClient(channel); client.computeCustomRoutes(); } }
Go
package main import ( "context" "crypto/tls" "log" "os" "time" "github.com/golang/protobuf/proto" v1 "google.golang.org/genproto/googleapis/maps/routes/v1" v1alpha "google.golang.org/genproto/googleapis/maps/routes/v1alpha" "google.golang.org/genproto/googleapis/type/latlng" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" ) const ( serverAddr = "routespreferred.googleapis.com:443" // 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. fieldMask = "*" ) func createWaypoint(lat float64, lng float64) *v1.Waypoint { return &v1.Waypoint{LocationType: &v1.Waypoint_Location{ Location: &v1.Location{ LatLng: &latlng.LatLng{Latitude: lat, Longitude: lng}, }, }} } func callComputeCustomRoutes(client v1alpha.RoutesAlphaClient, ctx *context.Context) { request := v1.ComputeCustomRoutesRequest{ Origin: createWaypoint(37.420761, -122.081356), Destination: createWaypoint(37.420999, -122.086894), RouteObjective: &v1.RouteObjective{ Objective: &v1.RouteObjective_RateCard_{ RateCard: &v1.RouteObjective_RateCard{ CostPerMinute: &v1.RouteObjective_RateCard_MonetaryCost{Value: 1.1}, }, }, }, TravelMode: v1.RouteTravelMode_DRIVE, RoutingPreference: v1.RoutingPreference_TRAFFIC_AWARE, Units: v1.Units_METRIC, LanguageCode: "en-us", RouteModifiers: &v1.RouteModifiers{ AvoidTolls: false, AvoidHighways: true, AvoidFerries: true, }, PolylineQuality: v1.PolylineQuality_OVERVIEW, } marshaler := proto.TextMarshaler{} log.Printf("Sending request: \n%s", marshaler.Text(&request)) result, err := client.ComputeCustomRoutes(*ctx, &request) if err != nil { log.Fatalf("Failed to call ComputeCustomRoutes: %v", err) } log.Printf("Result: %s", marshaler.Text(result)) } 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 := v1alpha.NewRoutesAlphaClient(conn) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) ctx = metadata.AppendToOutgoingContext(ctx, "X-Goog-Api-Key", os.Getenv("GOOGLE_MAPS_API_KEY")) ctx = metadata.AppendToOutgoingContext(ctx, "X-Goog-Fieldmask", fieldMask) defer cancel() callComputeCustomRoutes(client, &ctx) }
דוגמאות לחישוב של אגרות
בדוגמה הבאה נעשה שימוש בשיטה computeCustomRoutes
כדי להציג את פרטי החיובים בכביש עם מחיר משוער כשמשתמשים בכרטיס נסיעה בכביש אגרה.
התכונה הזו מופעלת באמצעות מסכת השדה routes.travelAdvisory.tollInfo
שצוינה בבקשה. מינוי לכביש אגרה מצוין בroute_modifiers
השדה הזה. מחיר האגרה שמוחזר מבוסס על התמחור של הכרטיס שצוין. אם צוינו יותר מכרטיס אחד, המערכת תחזיר את המחיר הזול ביותר.
בקשה:
curl -X POST -d '{
"origin":{
"location":{
"latLng":{
"latitude":47.7020056,
"longitude":-122.3479236
}
}
},
"destination":{
"location":{
"latLng":{
"latitude":47.6192234,
"longitude": -122.1676792
}
}
},
"travelMode":"DRIVE",
"routingPreference": "TRAFFIC_AWARE_OPTIMAL",
"routeModifiers":{
"vehicleInfo":{
"emissionType": "GASOLINE"
},
"tollPasses": [
"US_MA_EZPASSMA",
"US_WA_GOOD_TO_GO"
]
},
"routeObjective":{
"rateCard":{
"costPerMinute":{
"value":2
},
"costPerKm":{
"value": 1
},
"includeTolls": true
}
}
}'\
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: <YOUR_API_KEY>' \
-H 'X-Goog-FieldMask: routes.route.duration,routes.route.distanceMeters,routes.route.travelAdvisory.tollInfo,routes.route.legs.travelAdvisory.tollInfo,fallbackInfo' \
'https://routespreferred.googleapis.com/v1alpha:computeCustomRoutes'
תשובה:
{
"routes": [
{
"route": {
"legs": [
{
"travelAdvisory": {
"tollInfo": {
"estimatedPrice": [
{
"currencyCode": "USD",
"units": "2",
"nanos": 700000000
}
]
}
}
}
],
"distanceMeters": 22496,
"duration": "1391s",
"travelAdvisory": {
"tollInfo": {
"estimatedPrice": [
{
"currencyCode": "USD",
"units": "2",
"nanos": 700000000
}
]
}
}
]
}
הדוגמה הבאה משתמשת
computeCustomRoutes
שיטה להחזרת מידע על כבישי אגרה על מסלול ללא הערכת מחיר.
התכונה הזו מופעלת גם באמצעות routes.travelAdvisory.tollInfo
מסכת שדות שצוינה בבקשה. זו ההתנהגות הצפויה
של ה-API אם לא ניתן להעריך את מחירי האגרה בזמן הבקשה.
באופן כללי, נוכחות השדה tollInfo
בתשובה מצביעה
שיש כביש אגרה.
אם מציינים את הערך include_tolls
ב-routeObjective
אבל ל-Google אין מידע על מחירי כבישי אגרה למסלול, התשובה תכלול את הערך החלופי routeObjective
FALLBACK_RATECARD_WITHOUT_TOLL_PRICE_DATA.
בקשה:
curl -X POST -d '{
"origin":{
"location":{
"latLng":{
"latitude":39.56227274,
"longitude":15.12008516
}
}
},
"destination":{
"location":{
"latLng":{
"latitude":39.56205718,
"longitude": 15.12250773
}
}
},
"travelMode":"DRIVE",
"routingPreference": "TRAFFIC_AWARE",
"routeObjective":{
"rateCard":{
"costPerMinute":{
"value":1
},
"costPerKm":{
"value": 1
},
"includeTolls": true
}
}
}' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: <YOUR_API_KEY>' \
-H 'X-Goog-FieldMask: routes.route.duration,routes.route.distanceMeters,routes.route.travelAdvisory.tollInfo,routes.route.legs.travelAdvisory.tollInfo.estimatedPrice,fallbackInfo' \
'https://routespreferred.googleapis.com/v1alpha:computeCustomRoutes'
תשובה:
{
"routes": [
{
"route": {
"legs": [
{
"travelAdvisory": {
"tollInfo": {}
}
}
],
"distanceMeters": 101,
"duration": "10s",
"travelAdvisory": {
"tollInfo": {}
}
}
}
],
"fallbackInfo": {
"routeObjective": "FALLBACK_RATECARD_WITHOUT_TOLL_PRICE_DATA"
}
}