공유 수영장 이동은 여러 소비자가 동시에 차량을 공유하는 공유 이동입니다. 즉, 해당 이동은 독립적이지 않고 동시적입니다. 작동 방식은 공항 셔틀버스의 작동 방식과 유사하지만 운전자가 경로 중에 소비자를 하차할 수도 있다는 점이 다릅니다.
공용 수영장 이동과 단일 목적지 이동의 주요 차이점은 공용 수영장 이동에서는 이동 운영자가 동시에 둘 이상의 승객을 수송할 수 있다는 점입니다.
이 튜토리얼에서는 공유 수영장 여행을 만드는 과정을 안내합니다. 또한 고객이 휴대전화에서 이동 진행 상황을 시각화할 수 있도록 해당 이동을 소비자 애플리케이션과 통합하는 방법도 보여줍니다. 이 통합은 Consumer 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;
}
공유 풀 이동을 지원하는 Vehicle
를 만들려면 CreateVehicleRequest
에 전달된 Vehicle
객체의 지원되는 이동 유형 목록에 TripType.SHARED
를 추가해야 합니다.
Vehicle vehicle = Vehicle.newBuilder()
.setVehicleState(VehicleState.OFFLINE)
.addSupportedTripTypes(TripType.SHARED)
.setMaximumCapacity(4)
.setVehicleType(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
.build();
2단계: 위치 추적 사용 설정
위치 추적은 이동 중에 차량의 위치를 추적하는 것을 의미하며 여기서 운전자 앱이 차량의 현재 위치가 포함된 Fleet Engine으로 원격 분석을 전송합니다. 위치 정보에서 지속적으로 업데이트되는 이 스트림은 이동 경로를 따라 차량의 진행 상황을 전달하는 데 사용됩니다. 위치 추적을 사용 설정하면 드라이버 앱이 기본 빈도인 5초마다 한 번씩 이 원격 분석 데이터를 전송하기 시작합니다.
Android 및 iOS에서 위치 추적을 사용 설정하는 방법은 다음과 같습니다.
Android용 Driver SDK 메서드
enableLocationTracking()
를 호출합니다.iOS용 드라이버 SDK 부울 속성
locationTrackingEnabled
을true
로 설정합니다.
예
다음 코드 예에서는 위치 추적을 사용 설정하는 방법을 보여줍니다.
Java
RidesharingVehicleReporter vehicleReporter = ...;
vehicleReporter.enableLocationTracking();
Kotlin
val vehicleReporter = ...
vehicleReporter.enableLocationTracking()
Swift
vehicleReporter.locationTrackingEnabled = true
Objective-C
_vehicleReporter.locationTrackingEnabled = YES;
3단계: 차량 상태를 온라인으로 설정
차량의 상태를 온라인으로 설정하여 (즉, 차량을 사용할 수 있도록 하기 위해) 차량을 가동하지만 위치 추적을 사용 설정하기 전에는 차량을 사용할 수 없습니다.
Android 및 iOS의 경우 다음과 같이 차량 상태를 온라인으로 설정합니다.
Android용 Driver SDK 메서드
setVehicleState(VehicleState.ONLINE)
를 호출합니다.iOS용 드라이버 SDK 메서드
vehicleReporter.update(.online)
를 호출합니다.
예
다음 코드 예는 차량 상태를 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
객체를 만들어야 합니다.
CreateTripRequest
요청 메시지와 함께CreateTrip()
메서드를 호출하여 경로를 만들 수 있습니다.
필수 속성 제공
공유 수영장 여행을 만들려면 다음 필드가 필요합니다.
parent
- 공급업체 ID가 포함된 문자열입니다. Fleet Engine을 호출하는 데 사용되는 서비스 계정이 포함된 Google Cloud 프로젝트의 프로젝트 ID와 동일해야 합니다.
trip_id
- 이 여정을 고유하게 식별하는, 만드는 문자열입니다.
trip
- 생성할
Trip
객체입니다.
다음 필드는 CreateTripRequest
에 전달된 Trip
객체에서 설정해야 합니다.
trip_type
TripType.SHARED
pickup_point
- 여행의 출발지입니다.
dropoff_point
- 경로의 하차 지점입니다. 이 필드는 경로를 만들 때 필요하지 않으며 나중에
UpdateTrip
를 호출하여 설정할 수 있습니다.
예
다음 백엔드 통합 샘플은 경로를 만들고 차량에 공유 풀로 자동으로 할당하는 방법을 보여줍니다.
// Vehicle with VEHICLE_ID ID is already created and it is assigned Trip A.
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_ID = "shared-trip-A";
static final String VEHICLE_ID = "your-vehicle-id";
static final String TRIP_A_ID = "trip-a-id";
static final String TRIP_B_ID = "trip-b-id";
TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);
String parent = "providers/" + PROJECT_ID;
LatLng tripBPickup =
LatLng.newBuilder().setLatitude(-12.12314).setLongitude(88.142123).build();
LatLng tripBDropoff =
LatLng.newBuilder().setLatitude(-14.12314).setLongitude(90.142123).build();
TerminalLocation tripBPickupTerminalLocation =
TerminalLocation.newBuilder().setPoint(tripBPickup).build();
TerminalLocation tripBDropoffTerminalLocation =
TerminalLocation.newBuilder().setPoint(tripBDropoff).build();
// TripA already exists and it's assigned to a vehicle with VEHICLE_ID ID.
Trip tripB = Trip.newBuilder()
.setTripType(TripType.SHARED)
.setVehicleId(VEHICLE_ID)
.setPickupPoint(tripBPickupTerminalLocation)
.setDropoffPoint(tripBDropoffTerminalLocation)
.addAllVehicleWaypoints(
// This is where you define the arrival order for unvisited waypoints.
// If you don’t specify an order, then the Fleet Engine adds Trip B’s
// waypoints to the end of Trip A’s.
ImmutableList.of(
// Trip B’s pickup point.
TripWaypoint.newBuilder()
.setLocation(tripBPickupTerminalLocation)
.setTripId(TRIP_B_ID)
.setWaypointType(WaypointType.PICKUP_WAYPOINT_TYPE)
.build(),
// Trip A’s drop-off point.
TripWaypoint.newBuilder()
.setLocation(tripA.getDropoffPoint())
.setTripId(TRIP_A_ID)
.setWaypointType(WaypointType.DROP_OFF_WAYPOINT_TYPE)
.build(),
// Trip B’s drop-off point.
TripWaypoint.newBuilder()
.setLocation(tripBDropoffTerminalLocation)
.setTripId(TRIP_B_ID)
.setWaypointType(WaypointType.DROP_OFF_WAYPOINT_TYPE)
.build()))
.build();
// Create Trip request
CreateTripRequest createTripRequest = CreateTripRequest.newBuilder()
.setParent(parent)
.setTripId(TRIP_B_ID)
.setTrip(tripB)
.build();
try {
// createdTrip.remainingWaypoints will contain shared-pool waypoints.
// [tripB.pickup, tripA.dropoff, tripB.dropoff]
Trip createdTrip = tripService.createTrip(createTripRequest);
} catch (StatusRuntimeException e) {
Status s = e.getStatus();
switch (s.getCode()) {
case ALREADY_EXISTS:
break;
case PERMISSION_DENIED:
break;
}
return;
}
5단계: 차량 ID 및 경유지로 이동 업데이트
Fleet Engine이 경로를 따라 차량을 추적할 수 있도록 차량 ID로 이동을 구성해야 합니다.
UpdateTripRequest
로UpdateTrip
엔드포인트를 호출하여 차량 ID로 이동을 업데이트할 수 있습니다.update_mask
필드를 사용하여 차량 ID를 업데이트한다고 지정합니다.
경로의 차량 경유지 모음 (Trip.vehicle_waypoints
)에서 방문하지 않은 경유지를 대상으로 순서를 도입해야 합니다. Fleet Engine은 이 목록을 사용하여 공유 풀에 있는 모든 이동의 이동 경유지를 자동으로 업데이트합니다.
예를 들어 공유 수영장 이동 두 개(이동 A 및 이동 B)가 있다고 가정해 보겠습니다. 이동 A가 하차 위치로 이동 중입니다. 그런 다음 이동경로 B가 동일한 차량에
추가됩니다. 이동 B에 대한 하나의 UpdateTripRequest
에서
vehicleId
를 설정하고 Trip.vehicle_waypoints
을 최적의
경유지 순서(B 수령
→ A 하차 →
B 하차)로 설정합니다.
getVehicle()
를 호출하면
B Pickup → A Drop-off → B Drop-off를 포함하는 남은 경유지(remainingWaypoints
) 목록이 반환됩니다.- 경로 A의
getTrip()
또는onTripRemainingWaypointsUpdated
콜백은 B 픽업 → A 하차를 포함하는 남은 경유지(remainingWaypoints
) 목록을 반환합니다. - 이동 B에 대한
getTrip()
또는onTripRemainingWaypointsUpdated
콜백은 B 수령 → A 하차 → B 하차를 포함하는 남은 경유지(remainingWaypoints
) 목록을 반환합니다.
예
다음 백엔드 통합 샘플은 2개의 공유 풀 이동에 대해 차량 ID 및 경유지로 이동을 업데이트하는 방법을 보여줍니다.
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_A_ID = "share-trip-A";
static final String TRIP_B_ID = "share-trip-B";
static final String VEHICLE_ID = "Vehicle";
String tripName = "providers/" + PROJECT_ID + "/trips/" + TRIP_B_ID;
// Get Trip A and Trip B objects from either the Fleet Engine or storage.
Trip tripA = …;
Trip tripB = …;
TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);
// The trip settings to update.
Trip trip = Trip.newBuilder()
.setVehicleId(VEHICLE_ID)
.addAllVehicleWaypoints(
// This is where you define the arrival order for unvisited waypoints.
// If you don’t specify an order, then the Fleet Engine adds Trip B’s
// waypoints to the end of Trip A’s.
ImmutableList.of(
// Trip B’s pickup point.
TripWaypoint.newBuilder()
.setLocation(tripB.getPickupPoint())
.setTripId(TRIP_B_ID)
.setWaypointType(WaypointType.PICKUP_WAYPOINT_TYPE)
.build(),
// Trip A’s drop-off point.
TripWaypoint.newBuilder()
.setLocation(tripA.getDropoffPoint())
.setTripId(TRIP_A_ID)
.setWaypointType(WaypointType.DROP_OFF_WAYPOINT_TYPE)
.build(),
// Trip B’s drop-off point.
TripWaypoint.newBuilder()
.setLocation(tripB.getDropoffPoint())
.setTripId(TRIP_B_ID)
.setWaypointType(WaypointType.DROP_OFF_WAYPOINT_TYPE)
.build()))
.build();
// The trip update request.
UpdateTripRequest updateTripRequest = UpdateTripRequest.newBuilder()
.setName(tripName)
.setTrip(trip)
.setUpdateMask(FieldMask.newBuilder()
.addPaths("vehicle_id")
.addPaths("vehicle_waypoints"))
.build();
// Error handling. If Fleet Engine has both a trip and vehicle with the IDs,
// and if the credentials validate, and if the given vehicle_waypoints list
// is valid, then the service updates the trip.
try {
Trip updatedTrip = tripService.updateTrip(updateTripRequest);
} catch (StatusRuntimeException e) {
Status s = e.getStatus();
switch (s.getCode()) {
case NOT_FOUND: // Either the trip or vehicle does not exist.
break;
case PERMISSION_DENIED:
break;
case INVALID_REQUEST: // vehicle_waypoints is invalid.
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에 액세스할 수 있습니다.
Android용 Consumer SDK
ConsumerController
객체를 가져옵니다. 자세한 내용은 사용자 인터페이스 요소 API 사용을 참고하세요.iOS용 Consumer SDK
GMTCMapView
객체를 가져옵니다. 자세한 내용은 사용자 인터페이스 요소 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는 경로의 활성 구간만 표시하지만 목적지를 포함하는 나머지 구간을 표시할 수도 있습니다.
다른 경로의 경유지 정보를 표시하려면 다음과 같이 이동과 관련된 모든 경유지에 액세스하면 됩니다.
Android용 Consumer SDK 메서드
TripModel.getTripInfo()
를 호출합니다. 그런 다음TripInfo.getRemainingWaypoints()
를 호출하여TripWaypoint
를 가져옵니다. 각TripWaypoint
객체에는 이동 ID, 경유지 위치, 경유지 유형이 포함되어 있습니다.iOS용 Consumer SDK 속성
GMTCTripModel.currentTrip
을 가져옵니다. 그런 다음GMTSTrip.remainingWaypoints
배열을 가져와GMTSTripWaypoint
에 액세스합니다. 각GMTSTripWaypoint
객체에는 이동 ID, 경유지 위치, 경유지 유형이 포함되어 있습니다.
8단계: Fleet Engine에서 이동 상태 관리
TripStatus
열거형 값 중 하나를 사용하여 이동 상태를 지정합니다. 이동 상태가 변경되면 (예: ENROUTE_TO_PICKUP
에서 ARRIVED_AT_PICKUP
로 변경) Fleet Engine을 통해 이동 상태를 업데이트해야 합니다. 이동 상태는 항상 NEW
값으로 시작하고 COMPLETE
또는 CANCELED
값으로 끝납니다. 자세한 내용은 trip_status
를 참고하세요.
예
다음 백엔드 통합 샘플은 Fleet Engine에서 이동 상태를 업데이트하는 방법을 보여줍니다.
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_ID = "trip-8241890";
String tripName = "providers/" + PROJECT_ID + "/trips/" + TRIP_ID;
TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);
// Trip settings to be updated.
Trip trip = Trip.newBuilder()
.setTripStatus(TripStatus.ARRIVED_AT_PICKUP)
.build();
// Trip update request
UpdateTripRequest updateTripRequest = UpdateTripRequest.newBuilder()
.setName(tripName)
.setTrip(trip)
.setUpdateMask(FieldMask.newBuilder().addPaths("trip_status"))
.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: // The given trip status is invalid.
break;
case PERMISSION_DENIED:
break;
}
return;
}