경로 계획 예시

HTTP 요청 및 응답에서 ComputeCustomRoutes 메서드를 사용할 수 있습니다. 또는 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 응답의 경로 토큰은 Navigation SDK에 연결하여 탐색 세션을 시작합니다. Routes Preferred API에서 반환한 경로를 따릅니다. 경로 토큰은 만료되지 않지만 동적 도로 상태로 인해 지정된 토큰으로 생성된 경로가 원래 경로와 다를 수 있습니다. Google은 토큰 생성 후 몇 분 내에 경로 토큰을 사용하는 것이 좋습니다.

경로 토큰에 대한 자세한 내용은 Android용 Navigation SDK를 참조하세요. 및 iOS용 Navigation SDK 문서를 참조하세요.

Java 및 Go 예

다음 예는 Java를 사용하여 ComputeCustomRoutes 메서드를 호출하는 방법을 보여줍니다. Go로 이동합니다 자세한 내용은 Java 및 GitHub 이동 저장소를 참조하세요

자바

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 필드가 있으면 경로에 유료 도로가 있다는 것을 의미합니다.

routeObjectiveinclude_tolls를 지정하지만 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"
  }
}