You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过GRPC调用谷歌Routing API?是否可无需GRPC使用该API?

谷歌Routing API集成:gRPC调用指南与无gRPC替代方案

1. 如何用gRPC调用谷歌Routing API?

结合你提供的官方示例代码,实现步骤如下:

前置准备

  • 项目需引入必要依赖:gRPC核心库(grpc-netty、grpc-protobuf)、谷歌Maps Routing V2客户端SDK(即com.google.maps.routing.v2.*相关类,由官方proto文件生成)。
  • 拥有有效的谷歌Cloud API密钥,且已开启Routes API权限。

代码解析与运行

  1. API密钥注入:示例通过RoutesInterceptor拦截gRPC请求,将API密钥放入x-goog-api-key请求头。你需要把代码里的INSERT_API_KEY_HERE替换为实际密钥,或通过环境变量传入。

    注意:生产环境不要用*作为x-goog-fieldmask的值,应明确指定所需返回字段,比如routes.distanceMeters,routes.duration,routes.polyline.encodedPolyline,减少不必要的数据传输。

  2. 创建gRPC通道:通过NettyChannelBuilder连接谷歌Routing API的gRPC端点routes.googleapis.com:443(标准TLS端口)。
  3. 构建请求对象:比如computeRoutes方法中,用Builder模式配置起点、终点、出行模式(DRIVE/WALK等)、路由偏好(TRAFFIC_AWARE/TRAFFIC_AWARE_OPTIMAL等)、路由修改器(是否避开高速/收费站等)等参数。
  4. 发起gRPC调用:使用阻塞式Stub(RoutesBlockingStub)调用API,设置超时时间(示例中为2000毫秒),处理返回响应或异常。

你提供的完整示例代码:

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 API_KEY_HEADER = Metadata.Key.of("x-goog-api-key",
               Metadata.ASCII_STRING_MARSHALLER);
       private static Metadata.Key FIELD_MASK_HEADER = Metadata.Key.of("x-goog-fieldmask",
               Metadata.ASCII_STRING_MARSHALLER);

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

       @Override
       public  ClientCall interceptCall(MethodDescriptor method,
               CallOptions callOptions, Channel next) {
           logger.info("Intercepted " + method.getFullMethodName());
           ClientCall call = next.newCall(method, callOptions);
           call = new ForwardingClientCall.SimpleForwardingClientCall(call) {
               @Override
               public void start(Listener 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 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();
   }
}

2. 无需依赖gRPC使用Routing API的方式

当然存在,谷歌Routing API提供RESTful接口,可直接通过HTTP请求调用,完全不需要gRPC相关依赖:

核心步骤

  1. 确定REST端点:比如ComputeRoutes对应POST端点为https://routes.googleapis.com/directions/v2:computeRoutes,ComputeRouteMatrix对应https://routes.googleapis.com/directions/v2:computeRouteMatrix。
  2. 设置请求头:
    • x-goog-api-key:你的谷歌Cloud API密钥
    • x-goog-fieldmask:指定所需返回字段(和gRPC要求一致,生产环境避免用*)
    • Content-Type: application/json
  3. 构造JSON请求体:结构与gRPC请求对象一一对应,比如ComputeRoutes的请求体示例:
{
  "origin": {
    "location": {
      "latLng": {
        "latitude": 37.420761,
        "longitude": -122.081356
      }
    }
  },
  "destination": {
    "location": {
      "latLng": {
        "latitude": 37.420999,
        "longitude": -122.086894
      }
    }
  },
  "travelMode": "DRIVE",
  "routingPreference": "TRAFFIC_AWARE",
  "computeAlternativeRoutes": true,
  "routeModifiers": {
    "avoidTolls": false,
    "avoidHighways": true,
    "avoidFerries": true
  },
  "polylineQuality": "OVERVIEW"
}
  1. 发送请求:用任意HTTP客户端(比如Java的HttpClient、OkHttp,或curl命令)发送POST请求,处理JSON格式的响应即可。

内容的提问来源于stack exchange,提问作者Chichi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:17:33