여러 목적지 경로를 만들고 표시하기

다중 목적지 이동은 소비자가 원래 요청한 목적지에 도착하기 전에 하나 이상의 정차를 할 수 있는 운전자와 일정을 예약하는 배타적인 이동입니다.

다중 목적지 이동과 단일 목적지 이동의 주요 차이점은 다중 목적지 이동에서 이동 운영자가 출발지와 하차 지점 사이에 하나 이상의 정류장을 만들 수 있다는 것입니다.

이 튜토리얼에서는 다중 목적지 이동을 만드는 과정을 안내합니다. 또한 고객이 휴대전화에서 이동 진행 상황을 시각화할 수 있도록 해당 이동을 소비자 애플리케이션과 통합하는 방법도 보여줍니다. ConsumerSDK를 사용하여 이 통합을 수행합니다.

기본 요건

이 튜토리얼을 완료하려면 다음을 완료해야 합니다.

  1. Fleet Engine 설정 자세한 내용은 Fleet Engine: 초기 설정을 참고하세요.

  2. 앱을 Driver SDK와 통합합니다. 자세한 내용은 Android용 드라이버 SDK 초기화와 iOS용 드라이버 SDK 통합 가이드를 참고하세요.

  3. 소비자 대면 앱을 소비자 SDK와 통합합니다. 자세한 내용은 Android용 Consumer SDK 시작하기와 iOS용 Consumer SDK 시작하기를 참조하세요.

  4. 승인 토큰을 설정합니다. 승인 토큰에 대한 자세한 내용은 Fleet Engine 시작하기 가이드의 승인을 위한 JSON 웹 토큰 만들기와 Fleet Engine 소비자 SDK 문서의 인증 및 승인을 참조하세요.

1단계: Fleet Engine에서 차량 만들기

차량은 Fleet의 차량을 나타내는 객체입니다. 소비자 앱에서 이벤트를 추적하려면 Fleet Engine에서 객체를 만들어야 합니다.

다음 두 가지 접근 방식 중 하나를 사용하여 차량을 만들 수 있습니다.

gRPC
CreateVehicleRequest 요청 메시지와 함께 CreateVehicle() 메서드를 호출합니다. CreateVehicle()을(를) 호출하려면 Fleet Engine 수퍼유저 권한이 있어야 합니다.
REST
https://fleetengine.googleapis.com/v1/providers.vehicles.create에 전화 걸기

주의사항

차량을 만들 때는 다음 주의사항이 적용됩니다.

  • 초기 차량 상태를 OFFLINE로 설정해야 합니다. 이렇게 하면 Fleet Engine이 이동에 맞는 차량을 찾을 수 있습니다.

  • 차량의 provider_id는 Fleet Engine을 호출하는 데 사용되는 서비스 계정이 포함된 Google Cloud 프로젝트의 프로젝트 ID와 동일해야 합니다. 여러 서비스 계정이 동일한 차량 공유 제공업체의 Fleet Engine에 액세스할 수 있지만 현재 Fleet Engine은 동일한 차량에 액세스하는 여러 Google Cloud 프로젝트의 서비스 계정을 지원하지 않습니다.

  • CreateVehicle()에서 반환된 응답에는 Vehicle 인스턴스가 포함됩니다. UpdateVehicle()를 사용하여 업데이트되지 않은 인스턴스는 7일 후에 삭제됩니다. 차량이 이미 존재하지 않는지 확인하기 위해 CreateVehicle()를 호출하기 전에 GetVehicle()를 호출해야 합니다. GetVehicle()NOT_FOUND 오류를 반환하면 CreateVehicle() 호출을 진행해야 합니다. 자세한 내용은 차량 및 차량 수명 주기를 참고하세요.

다음 제공업체 코드 샘플은 Fleet Engine에서 차량을 만드는 방법을 보여줍니다.

static final String PROJECT_ID = "my-rideshare-co-gcp-project";

VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);

String parent = "providers/" + PROJECT_ID;

Vehicle vehicle = Vehicle.newBuilder()
    .setVehicleState(VehicleState.OFFLINE)  // Initial state
    .addSupportedTripTypes(TripType.EXCLUSIVE)
    .setMaximumCapacity(4)
    .setVehicleType(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
    .build();

CreateVehicleRequest createVehicleRequest = CreateVehicleRequest.newBuilder()
    .setParent(parent)
    .setVehicleId("8241890")  // Vehicle ID assigned by solution provider.
    .setVehicle(vehicle)      // Initial state.
    .build();

// The Vehicle is created in the OFFLINE state, and no initial position is
// provided.  When the driver app calls the rideshare provider, the state can be
// set to ONLINE, and the driver app updates the vehicle location.
try {
  Vehicle createdVehicle = vehicleService.createVehicle(createVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case ALREADY_EXISTS:
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

2단계: 위치 추적 사용 설정

위치 추적은 이동 중에 차량의 위치를 추적하는 것을 의미하며 여기서 운전자 앱이 차량의 현재 위치가 포함된 Fleet Engine으로 원격 분석을 전송합니다. 위치 정보에서 지속적으로 업데이트되는 이 스트림은 이동 경로를 따라 차량의 진행 상황을 전달하는 데 사용됩니다. 위치 추적을 사용 설정하면 드라이버 앱이 기본 빈도인 5초마다 한 번씩 이 원격 분석 데이터를 전송하기 시작합니다.

Android 및 iOS에서 위치 추적을 사용 설정하는 방법은 다음과 같습니다.

다음 코드 예에서는 위치 추적을 사용 설정하는 방법을 보여줍니다.

Java

RidesharingVehicleReporter vehicleReporter = ...;

vehicleReporter.enableLocationTracking();

Kotlin

val vehicleReporter = ...

vehicleReporter.enableLocationTracking()

Swift

vehicleReporter.locationTrackingEnabled = true

Objective-C

_vehicleReporter.locationTrackingEnabled = YES;

3단계: 차량 상태를 온라인으로 설정

차량의 상태를 온라인으로 설정하여 (즉, 차량을 사용할 수 있도록 하기 위해) 차량을 가동하지만 위치 추적을 사용 설정하기 전에는 차량을 사용할 수 없습니다.

Android 및 iOS의 경우 다음과 같이 차량 상태를 온라인으로 설정합니다.

다음 코드 예는 차량 상태를 ONLINE로 설정하는 방법을 보여줍니다.

Java

vehicleReporter.setVehicleState(VehicleState.ONLINE);

Kotlin

vehicleReporter.setVehicleState(VehicleState.ONLINE)

Swift

vehicleReporter.update(.online)

Objective-C

[_vehicleReporter updateVehicleState:GMTDVehicleStateOnline];

4단계: Fleet Engine에서 이동 만들기

여러 목적지 이동을 만들려면 단일 목적지와 마찬가지로 Trip 객체를 만들어야 합니다.

이동은 출발지, 경유지, 하차 지점을 포함하는 지리 좌표 지점인 여정을 나타내는 객체입니다. 요청을 차량과 일치시킨 다음 추적할 수 있도록 각 이동 요청에 대해 하나의 Trip 객체를 만들어야 합니다.

필수 속성 제공

다중 목적지 이동을 만들려면 다음 필드가 필요합니다.

parent
공급업체 ID가 포함된 문자열입니다. Fleet Engine을 호출하는 데 사용되는 서비스 계정이 포함된 Google Cloud 프로젝트의 프로젝트 ID와 동일해야 합니다.
trip_id
이 여정을 고유하게 식별하는, 만드는 문자열입니다.
trip
`Trip` 객체를 만듭니다.

CreateTripRequest에 전달된 Trip 객체에서 다음 필드를 설정해야 합니다.

trip_type
TripType.EXCLUSIVE
pickup_point
여행의 출발지입니다.
dropoff_point
경로의 하차 지점입니다. 이 필드는 이동을 만드는 동안에는 필요하지 않으며 나중에 `UpdateTrip`을 호출하여 설정할 수 있습니다.
intermediate_destinations
운전자가 승차 및 하차 사이에 방문하는 중간 목적지 목록입니다. 하차 위치와 마찬가지로 이 필드는 이동 생성 시 필요하지 않으며 `UpdateTrip`을 호출하여 설정할 수 있습니다.

다음 백엔드 통합 샘플은 승차 지점, 하차 지점 및 중간 목적지 하나가 있는 독점 다중 목적지 이동을 만드는 방법을 보여줍니다.

static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_ID = "multi-destination-trip-A";

TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);

// Trip initial settings.
String parent = "providers/" + PROJECT_ID;

Trip trip = Trip.newBuilder()
    .setTripType(TripType.EXCLUSIVE)
    .setPickupPoint(
        TerminalLocation.newBuilder().setPoint(
            LatLng.newBuilder()
                .setLatitude(-6.195139).setLongitude(106.820826)))
    .setNumberOfPassengers(1)
    .setDropoffPoint(
        TerminalLocation.newBuilder().setPoint(
            LatLng.newBuilder()
                .setLatitude(-6.1275).setLongitude(106.6537)))
    // Add the list of intermediate destinations.
    .addAllIntermediateDestinations(
        ImmutableList.of(
            TerminalLocation.newBuilder().setPoint(
                LatLng.newBuilder()
                    .setLatitude(-6.195139).setLongitude(106.820826)).build()))
    .build();

// Create the Trip request.
CreateTripRequest createTripRequest = CreateTripRequest.newBuilder()
    .setParent(parent)
    .setTripId(TRIP_ID)  // Trip ID assigned by the Provider server.
    .setTrip(trip)       // Initial state is NEW.
    .build();

// Error handling.
try {
  Trip createdTrip =
      tripService.createTrip(createTripRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case ALREADY_EXISTS:  // Trip already exists.
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

5단계: 차량 ID 및 경유지로 이동 업데이트

Fleet Engine이 경로를 따라 차량을 추적할 수 있도록 차량 ID로 이동을 구성해야 합니다.

  • UpdateTripRequestUpdateTrip 엔드포인트를 호출하여 차량 ID로 이동을 업데이트할 수 있습니다. update_mask 필드를 사용하여 차량 ID를 업데이트한다고 지정합니다.

Notes

  • 이동을 만들 때 하차 또는 중간 목적지를 지정하지 않아도 이 시점에서 지정할 수 있습니다.

  • 진행 중인 이동에서 차량을 변경해야 하는 경우 이동 상태를 다시 새 상태로 설정하고 위에서 한 것처럼 이동을 새 차량 ID로 업데이트해야 합니다.

다음 백엔드 통합 샘플은 중간 목적지 목록을 추가하고 차량 ID를 설정하기 위해 이동을 업데이트하는 방법을 보여줍니다.

static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_ID = "multi-destination-trip-A";

String tripName = "providers/" + PROJECT_ID + "/trips/" + TRIP_ID;

TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);

// The trip settings to be updated.
Trip trip = Trip.newBuilder()
    // Add the list of intermediate destinations.
    .addAllIntermediateDestinations(
        ImmutableList.of(
            TerminalLocation.newBuilder().setPoint(
                LatLng.newBuilder()
                    .setLatitude(-6.195139).setLongitude(106.820826)).build()))
    .setVehicleId("8241890")
    .build();

// The trip update request.
UpdateTripRequest updateTripRequest = UpdateTripRequest.newBuilder()
    .setName(tripName)
    .setTrip(trip)
    .setUpdateMask(
        FieldMask.newBuilder()
            .addPaths("intermediate_destinations")
            .addPaths("vehicle_id")
            .build())
    .build();

// Error handling.
try {
  Trip updatedTrip =
      tripService.updateTrip(updateTripRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:            // The trip doesn't exist.
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

6단계: 소비자 앱에서 경로 업데이트 수신 대기

  • Android의 경우 TripModelManager에서 TripModel 객체를 가져오고 TripModelCallback 리스너를 등록하여 경로의 데이터 업데이트를 수신 대기할 수 있습니다.

  • iOS의 경우 GMTCTripService에서 GMTCTripModel 객체를 가져오고 GMTCTripModelSubscriber 구독자를 등록하여 경로의 데이터 업데이트를 수신 대기할 수 있습니다.

TripModelCallback 리스너와 GMTCTripModelSubscriber 구독자를 사용하면 앱이 자동 새로고침 간격에 따라 새로고침할 때마다 정기적인 이동 진행률 업데이트를 수신할 수 있습니다. 변경되는 값만 콜백을 트리거할 수 있습니다. 그러지 않으면 콜백이 무음으로 유지됩니다.

TripModelCallback.onTripUpdated()tripModel(_:didUpdate:updatedPropertyFields:) 메서드는 데이터 변경사항에 관계없이 항상 호출됩니다.

예시 1

다음 코드 샘플은 TripModelManager/GMTCTripService에서 TripModel를 가져와서 리스너를 설정하는 방법을 보여줍니다.

Java

// Start journey sharing after a trip has been created via Fleet Engine.
TripModelManager tripModelManager = consumerApi.getTripModelManager();

// Get a TripModel object.
TripModel tripModel = tripModelManager.getTripModel(tripName);

// Register a listener on the trip.
TripModelCallback tripCallback = new TripModelCallback() {
  ...
};
tripModel.registerTripCallback(tripCallback);

// Set the refresh interval.
TripModelOptions tripModelOptions = TripModelOptions.builder()
    .setRefreshInterval(5000) // interval in milliseconds, so 5 seconds
    .build();
tripModel.setTripModelOptions(tripModelOptions);

// The trip stops auto-refreshing when all listeners are unregistered.
tripModel.unregisterTripCallback(tripCallback);

Kotlin

// Start journey sharing after a trip has been created via Fleet Engine.
val tripModelManager = consumerApi.getTripModelManager()

// Get a TripModel object.
val tripModel = tripModelManager.getTripModel(tripName)

// Register a listener on the trip.
val tripCallback = TripModelCallback() {
  ...
}

tripModel.registerTripCallback(tripCallback)

// Set the refresh interval.
val tripModelOptions =
  TripModelOptions.builder()
    .setRefreshInterval(5000) // interval in milliseconds, so 5 seconds
    .build()

tripModel.setTripModelOptions(tripModelOptions)

// The trip stops auto-refreshing when all listeners are unregistered.
tripModel.unregisterTripCallback(tripCallback)

Swift

let tripService = GMTCServices.shared().tripService

// Create a tripModel instance for listening for updates from the trip
// specified by the trip name.
let tripModel = tripService.tripModel(forTripName: tripName)

// Register for the trip update events.
tripModel.register(self)

// Set the refresh interval (in seconds).
tripModel.options.autoRefreshTimeInterval = 5

// Unregister for the trip update events.
tripModel.unregisterSubscriber(self)

Objective-C

GMTCTripService *tripService = [GMTCServices sharedServices].tripService;

// Create a tripModel instance for listening for updates from the trip
// specified by the trip name.
GMTCTripModel *tripModel = [tripService tripModelForTripName:tripName];

// Register for the trip update events.
[tripModel registerSubscriber:self];

// Set the refresh interval (in seconds).
tripModel.options.autoRefreshTimeInterval = 5;

// Unregister for the trip update events.
[tripModel unregisterSubscriber:self];

예 2

다음 코드 샘플은 TripModelCallback 리스너와 GMTCTripModelSubscriber 구독자를 설정하는 방법을 보여줍니다.

Java

// Implements a callback for the trip model so your app can listen for trip
// updates from Fleet Engine.
TripModelCallback subscriber =
  new TripModelCallback() {

    @Override
    public void onTripStatusUpdated(TripInfo tripInfo, @TripStatus int status) {
      // ...
    }

    @Override
    public void onTripActiveRouteUpdated(TripInfo tripInfo, List<LatLng> route) {
      // ...
    }

    @Override
    public void onTripVehicleLocationUpdated(
        TripInfo tripInfo, @Nullable VehicleLocation vehicleLocation) {
      // ...
    }

    @Override
    public void onTripPickupLocationUpdated(
        TripInfo tripInfo, @Nullable TerminalLocation pickup) {
      // ...
    }

    @Override
    public void onTripPickupTimeUpdated(TripInfo tripInfo, @Nullable Long timestampMillis) {
      // ...
    }

    @Override
    public void onTripDropoffLocationUpdated(
        TripInfo tripInfo, @Nullable TerminalLocation dropoff) {
      // ...
    }

    @Override
    public void onTripDropoffTimeUpdated(TripInfo tripInfo, @Nullable Long timestampMillis) {
      // ...
    }

    @Override
    public void onTripETAToNextWaypointUpdated(
        TripInfo tripInfo, @Nullable Long timestampMillis) {
      // ...
    }

    @Override
    public void onTripActiveRouteRemainingDistanceUpdated(
        TripInfo tripInfo, @Nullable Integer distanceMeters) {
      // ...
    }

    @Override
    public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
      // ...
    }

    @Override
    public void onTripUpdated(TripInfo tripInfo) {
      // ...
    }

    @Override
    public void onTripRemainingWaypointsUpdated(
        TripInfo tripInfo, List<TripWaypoint> waypointList) {
      // ...
    }

    @Override
    public void onTripIntermediateDestinationsUpdated(
        TripInfo tripInfo, List<TerminalLocation> intermediateDestinations) {
      // ...
    }

    @Override
    public void onTripRemainingRouteDistanceUpdated(
        TripInfo tripInfo, @Nullable Integer distanceMeters) {
      // ...
    }

    @Override
    public void onTripRemainingRouteUpdated(TripInfo tripInfo, List<LatLng> route) {
      // ...
    }
  };

Kotlin

// Implements a callback for the trip model so your app can listen for trip
// updates from Fleet Engine.
val subscriber =
  object : TripModelCallback() {
    override fun onTripStatusUpdated(tripInfo: TripInfo, status: @TripStatus Int) {
      // ...
    }

    override fun onTripActiveRouteUpdated(tripInfo: TripInfo, route: List<LatLng>) {
      // ...
    }

    override fun onTripVehicleLocationUpdated(
      tripInfo: TripInfo,
      vehicleLocation: VehicleLocation?
    ) {
      // ...
    }

    override fun onTripPickupLocationUpdated(tripInfo: TripInfo, pickup: TerminalLocation?) {
      // ...
    }

    override fun onTripPickupTimeUpdated(tripInfo: TripInfo, timestampMillis: Long?) {
      // ...
    }

    override fun onTripDropoffLocationUpdated(tripInfo: TripInfo, dropoff: TerminalLocation?) {
      // ...
    }

    override fun onTripDropoffTimeUpdated(tripInfo: TripInfo, timestampMillis: Long?) {
      // ...
    }

    override fun onTripETAToNextWaypointUpdated(tripInfo: TripInfo, timestampMillis: Long?) {
      // ...
    }

    override fun onTripActiveRouteRemainingDistanceUpdated(
      tripInfo: TripInfo,
      distanceMeters: Int?
    ) {
      // ...
    }

    override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
      // ...
    }

    override fun onTripUpdated(tripInfo: TripInfo) {
      // ...
    }

    override fun onTripRemainingWaypointsUpdated(
      tripInfo: TripInfo,
      waypointList: List<TripWaypoint>
    ) {
      // ...
    }

    override fun onTripIntermediateDestinationsUpdated(
      tripInfo: TripInfo,
      intermediateDestinations: List<TerminalLocation>
    ) {
      // ...
    }

    override fun onTripRemainingRouteDistanceUpdated(tripInfo: TripInfo, distanceMeters: Int?) {
      // ...
    }

    override fun onTripRemainingRouteUpdated(tripInfo: TripInfo, route: List<LatLng>) {
      // ...
    }
  }

Swift

class TripModelSubscriber: NSObject, GMTCTripModelSubscriber {

  func tripModel(_: GMTCTripModel, didUpdate trip: GMTSTrip?, updatedPropertyFields: GMTSTripPropertyFields) {
    // Update the UI with the new `trip` data.
    updateUI(with: trip)
    ...
  }

  func tripModel(_: GMTCTripModel, didUpdate tripStatus: GMTSTripStatus) {
    // Handle trip status did change.
  }

  func tripModel(_: GMTCTripModel, didUpdateActiveRoute activeRoute: [GMTSLatLng]?) {
    // Handle trip active route did update.
  }

  func tripModel(_: GMTCTripModel, didUpdate vehicleLocation: GMTSVehicleLocation?) {
    // Handle vehicle location did update.
  }

  func tripModel(_: GMTCTripModel, didUpdatePickupLocation pickupLocation: GMTSTerminalLocation?) {
    // Handle pickup location did update.
  }

  func tripModel(_: GMTCTripModel, didUpdateDropoffLocation dropoffLocation: GMTSTerminalLocation?) {
    // Handle drop off location did update.
  }

  func tripModel(_: GMTCTripModel, didUpdatePickupETA pickupETA: TimeInterval) {
    // Handle the pickup ETA did update.
  }

  func tripModel(_: GMTCTripModel, didUpdateDropoffETA dropoffETA: TimeInterval) {
    // Handle the drop off ETA did update.
  }

  func tripModel(_: GMTCTripModel, didUpdateRemaining remainingWaypoints: [GMTSTripWaypoint]?) {
    // Handle updates to the pickup, dropoff or intermediate destinations of the trip.
  }

  func tripModel(_: GMTCTripModel, didFailUpdateTripWithError error: Error?) {
    // Handle the error.
  }

  func tripModel(_: GMTCTripModel, didUpdateIntermediateDestinations intermediateDestinations: [GMTSTerminalLocation]?) {
    // Handle the intermediate destinations being updated.
  }

  ...
}

Objective-C

@interface TripModelSubscriber : NSObject <GMTCTripModelSubscriber>
@end

@implementation TripModelSubscriber

- (void)tripModel:(GMTCTripModel *)tripModel
            didUpdateTrip:(nullable GMTSTrip *)trip
    updatedPropertyFields:(GMTSTripPropertyFields)updatedPropertyFields {
  // Update the UI with the new `trip` data.
  [self updateUIWithTrip:trip];
  ...
}

- (void)tripModel:(GMTCTripModel *)tripModel didUpdateTripStatus:(enum GMTSTripStatus)tripStatus {
  // Handle trip status did change.
}

- (void)tripModel:(GMTCTripModel *)tripModel
    didUpdateActiveRoute:(nullable NSArray<GMTSLatLng *> *)activeRoute {
  // Handle trip route did update.
}

- (void)tripModel:(GMTCTripModel *)tripModel
    didUpdateVehicleLocation:(nullable GMTSVehicleLocation *)vehicleLocation {
  // Handle vehicle location did update.
}

- (void)tripModel:(GMTCTripModel *)tripModel
    didUpdatePickupLocation:(nullable GMTSTerminalLocation *)pickupLocation {
  // Handle pickup location did update.
}

- (void)tripModel:(GMTCTripModel *)tripModel
    didUpdateDropoffLocation:(nullable GMTSTerminalLocation *)dropoffLocation {
  // Handle drop off location did update.
}

- (void)tripModel:(GMTCTripModel *)tripModel didUpdatePickupETA:(NSTimeInterval)pickupETA {
  // Handle the pickup ETA did update.
}

- (void)tripModel:(GMTCTripModel *)tripModel
    didUpdateRemainingWaypoints:(nullable NSArray<GMTSTripWaypoint *> *)remainingWaypoints {
  // Handle updates to the pickup, dropoff or intermediate destinations of the trip.
}

- (void)tripModel:(GMTCTripModel *)tripModel didUpdateDropoffETA:(NSTimeInterval)dropoffETA {
  // Handle the drop off ETA did update.
}

- (void)tripModel:(GMTCTripModel *)tripModel didFailUpdateTripWithError:(nullable NSError *)error {
  // Handle the error.
}

- (void)tripModel:(GMTCTripModel *)tripModel
    didUpdateIntermediateDestinations:
        (nullable NSArray<GMTSTerminalLocation *> *)intermediateDestinations {
  // Handle the intermediate destinations being updated.
}
…
@end

언제든지 다음과 같이 이동 정보에 액세스할 수 있습니다.

  • Android용 Consumer SDK 메서드 TripModel.getTripInfo()를 호출합니다. 이 메서드를 호출해도 데이터를 새로고침 빈도로 계속 새로고침할 수는 있지만 강제로 데이터를 새로고침하지는 않습니다.

  • iOS용 Consumer SDK 속성 GMTCTripModel.currentTrip을 가져옵니다.

7단계: 소비자 앱에 여정 표시

다음과 같이 차량 및 배송 사용자 인터페이스 요소 API에 액세스할 수 있습니다.

다음 코드 예는 여정 공유 사용자 인터페이스를 시작하는 방법을 보여줍니다.

Java

JourneySharingSession session = JourneySharingSession.createInstance(tripModel);
consumerController.showSession(session);

Kotlin

val session = JourneySharingSession.createInstance(tripModel)
consumerController.showSession(session)

Swift

let journeySharingSession = GMTCJourneySharingSession(tripModel: tripModel)
mapView.show(journeySharingSession)

Objective-C

GMTCJourneySharingSession *journeySharingSession =
    [[GMTCJourneySharingSession alloc] initWithTripModel:tripModel];
[self.mapView showMapViewSession:journeySharingSession];

기본적으로 소비자 SDK는 경로의 활성 구간만 표시하지만 중간 목적지와 하차 지점이 포함된 나머지 구간을 표시할 수 있습니다.

다른 경로의 경유지 정보를 표시하려면 다음과 같이 이동과 관련된 모든 경유지에 액세스하면 됩니다.

8단계: Fleet Engine에서 이동 상태 관리

TripStatus 열거형 값 중 하나를 사용하여 이동 상태를 지정합니다. 이동 상태가 변경되면 (예: ENROUTE_TO_PICKUP에서 ARRIVED_AT_PICKUP로 변경) Fleet Engine을 통해 이동 상태를 업데이트해야 합니다. 이동 상태는 항상 NEW 값으로 시작하고 COMPLETE 또는 CANCELED 값으로 끝납니다. 자세한 내용은 trip_status를 참고하세요.

목적지가 여러 개인 경로의 경우 단일 목적지 이동에서처럼 이동 상태를 업데이트하는 것 외에도 중간 목적지에 도달할 때마다 intermediateDestinationIndex를 업데이트하고 업데이트 요청에 intermediateDestinationsVersion를 제공해야 합니다. TripStatus 열거형에서 다음 상태를 사용해야 합니다.

  • ENROUTE_TO_PICKUP
  • ARRIVED_AT_PICKUP
  • ENROUTE_TO_INTERMEDIATE_DESTINATION
  • ARRIVED_AT_INTERMEDIATE_DESTINATION
  • ENROUTE_TO_DROPOFF
  • COMPLETE

다음 백엔드 통합 샘플은 승차 지점을 지나 첫 번째 중간 목적지로 이동하는 다중 목적지 이동을 만드는 방법을 보여줍니다.

static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_ID = "multi-destination-trip-A";

String tripName = "providers/" + PROJECT_ID + "/trips/" + TRIP_ID;

// Get the trip object from either the Fleet Engine or storage.
Trip trip = …;

TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);

// The trip settings to be updated.
Trip trip = Trip.newBuilder()
    // Trip status cannot return to a previous state once it has passed.
    .setTripStatus(TripStatus.ENROUTE_TO_INTERMEDIATE_DESTINATION)

    // Enroute to the first intermediate destination.
    .setIntermediateDestinationIndex(0)

    // You must provide an intermediate_destinations_version to ensure that you
    // have the same intermediate destinations list as the Fleet Engine.
    .setIntermediateDestinationsVersion(
         trip.getIntermediateDestinationsVersion())
    .build();

// The trip update request.
UpdateTripRequest updateTripRequest = UpdateTripRequest.newBuilder()
    .setName(tripName)
    .setTrip(trip)
    .setUpdateMask(
        FieldMask.newBuilder()
            .addPaths("trip_status")
            .addPaths("intermediate_destination_index")
            // intermediate_destinations_version must not be in the update mask.
            .build())
    .build();

// Error handling.
try {
  Trip updatedTrip =
      tripService.updateTrip(updateTripRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:            // The trip doesn't exist.
      break;
    case FAILED_PRECONDITION:  // Either the trip status is invalid, or the
                               // intermediate_destinations_version doesn't
                               // match the Fleet Engine’s.
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}