Ví dụ về việc lên kế hoạch cho tuyến đường

Bạn có thể sử dụng phương thức ComputeCustomRoutes trong một yêu cầu và phản hồi HTTP hoặc với bất kỳ ngôn ngữ nào hỗ trợ gRPC, bao gồm cả Java và Go.

Ví dụ về HTTP

Ví dụ sau đây minh hoạ một yêu cầu và phản hồi curl mẫu.

Yêu cầu:

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'

Phản hồi:

{
  "routes": [
    {
      "route": {
        "distanceMeters": 987,
        "duration": "247s",
        "travelAdvisory": {
          "tollInfo": {}
        }
      },
      "token": "CocCCnYKCNOX2XMIWqf2EihazE0WzZ87txlU4F74nQiWxZpgRgOzf3TMHUm1sVpY4APnvf_BWoEYGibs64nuCxYcsQEXqQjaChCLGOkBHNseoyoAmAG1CxbkG58hEhJ4FiIBKkIJbwqHAz2qAhZfSgivvZI-AACAP3gBEAQaigEKhwEKLAohChYIAxISCgcQARiAwtcvEgcQAhiAhK9fEQAAAAAAAPA_EareoBH6vShAEg4IABADEAYYAkIEGgIIBRoGCgQIAhACIj8KNjIwMjAtMDYtMTB8MTI6NTY6MzcuODg3OTEzLTA3fDEwLjk5LjE5OS4xNnwtMTA3Mjc4OTI3MhCHwajvnhs"
    }
  ]
}

Mã thông báo tuyến đường trong phản hồi ComputeCustomRoutes phải được truyền đến SDK điều hướng để bắt đầu một phiên điều hướng. Phiên này cố gắng đi theo tuyến do API ưu tiên tuyến đường trả về. Mã thông báo tuyến đường không hết hạn, nhưng do tình trạng đường sá biến động, nên các tuyến đường được tạo bằng một mã thông báo nhất định có thể khác với tuyến đường ban đầu. Bạn nên sử dụng mã thông báo tuyến trong vòng vài phút sau khi tạo mã thông báo.

Để biết thêm thông tin về mã thông báo tuyến đường, hãy xem tài liệu về SDK điều hướng cho Android và SDK điều hướng cho iOS:

Ví dụ về Java và Go

Các ví dụ sau đây minh hoạ cách gọi phương thức ComputeCustomRoutes bằng Java hoặc Go. Hãy xem kho lưu trữ JavaGo GitHub tương ứng để biết hướng dẫn tạo.

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)
}

  

Ví dụ về cách tính phí cầu đường

Ví dụ sau đây sử dụng phương thức computeCustomRoutes để trả về thông tin thu phí trên một tuyến đường có giá ước tính khi phí cầu đường được sử dụng.

Tính năng này được bật với mặt nạ trường (field mask) routes.travelAdvisory.tollInfo được chỉ định trong yêu cầu. Phí cầu đường được chỉ định trong trường route_modifiers. Mức phí cầu đường được trả về dựa trên giá mà thẻ và vé được chỉ định sử dụng. Nếu bạn chỉ định nhiều lượt, thì giá thấp nhất sẽ được trả về.

Yêu cầu:

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'

Phản hồi:

{
  "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
          }
        ]
      }
    }
  ]
}

Ví dụ sau đây sử dụng phương thức computeCustomRoutes để trả về thông tin phí cầu đường trên một tuyến đường mà không cần ước tính giá.

Tính năng này cũng được bật với mặt nạ trường routes.travelAdvisory.tollInfo được chỉ định trong yêu cầu. Đây là hành vi dự kiến của API nếu không thể ước tính phí cầu đường tại thời điểm yêu cầu. Nhìn chung, việc trường tollInfo xuất hiện trong phản hồi cho biết có tuyến đường thu phí.

Nếu bạn chỉ định include_tolls trong routeObjective nhưng Google không có thông tin về giá cầu đường cho tuyến đường, thì phản hồi sẽ chứa routeObjective FALLBACK_RATECARD_WITHOUT_TOLL_PRICE_DATA dự phòng.

Yêu cầu:

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'

Phản hồi:

{
  "routes": [
    {
      "route": {
        "legs": [
          {
            "travelAdvisory": {
              "tollInfo": {}
            }
          }
        ],
        "distanceMeters": 101,
        "duration": "10s",
        "travelAdvisory": {
          "tollInfo": {}
        }
      }
    }
  ],
  "fallbackInfo": {
    "routeObjective": "FALLBACK_RATECARD_WITHOUT_TOLL_PRICE_DATA"
  }
}