Criar e mostrar viagens com vários destinos

São viagens exclusivas em que um consumidor agenda com um motorista que pode fazer uma ou mais paradas antes de chegar ao destino solicitado originalmente.

A principal diferença entre uma viagem com vários destinos e uma de destino único é que, em uma viagem desse tipo, o operador pode fazer uma ou mais paradas entre os pontos de origem e de destino.

Neste tutorial, explicamos o processo de criação de uma viagem com vários destinos. Ele também mostra como você pode integrar essa viagem ao seu aplicativo para consumidores, de modo que os clientes possam visualizar o andamento da viagem pelo smartphone. Essa integração é feita usando o ConsumerSDK.

Pré-requisitos

Para concluir este tutorial, faça o seguinte:

  1. Configure o motor da frota. Para mais informações, consulte Fleet Engine: configuração inicial.

  2. Integrar seu app ao SDK do Driver. Para ver mais informações, consulte Como inicializar o SDK do driver para Android e o Guia de integração do SDK do driver para iOS.

  3. Integre seu app voltado ao consumidor com o SDK do consumidor. Para mais informações, consulte Introdução ao SDK do consumidor para Android e Introdução ao SDK do consumidor para iOS.

  4. Configurar tokens de autorização. Para mais informações sobre tokens de autorização, consulte Como criar um JSON Web Token para autorização, no guia "Introdução ao Fleet Engine", e Autenticação e autorização, na documentação do SDK do consumidor para o Fleet Engine.

Etapa 1. Criar um veículo no Fleet Engine

Os veículos são objetos que representam os veículos da sua frota. É necessário criá-los no Fleet Engine para rastreá-los no app do consumidor.

Você pode criar um veículo usando uma destas duas abordagens:

gRPC
Chame o método CreateVehicle() com a mensagem de solicitação CreateVehicleRequest. Você precisa ter privilégios de superusuário do Fleet Engine para chamar CreateVehicle().
REST
Ligue para https://fleetengine.googleapis.com/v1/providers.vehicles.create.

Advertências

As ressalvas a seguir se aplicam quando você cria um veículo.

  • Defina o estado inicial do veículo como OFFLINE. Isso garante que o Fleet Engine possa detectar seu veículo para fazer a correspondência da viagem.

  • O provider_id do veículo precisa ser igual ao ID do projeto do Google Cloud que contém as contas de serviço usadas para chamar o Fleet Engine. Várias contas de serviço podem acessar o Fleet Engine para o mesmo provedor de compartilhamento de navegação, mas o Fleet Engine atualmente não oferece suporte a contas de serviço de diferentes projetos do Google Cloud que acessam os mesmos veículos.

  • A resposta retornada de CreateVehicle() contém a instância Vehicle. A instância será excluída após sete dias se não tiver sido atualizada usando UpdateVehicle(). Chame GetVehicle() antes de chamar CreateVehicle() apenas para confirmar que o veículo ainda não existe. Se GetVehicle() retornar um erro NOT_FOUND, continue chamando CreateVehicle(). Para mais informações, consulte Veículos e o ciclo de vida deles.

Exemplo

O exemplo de código de provedor a seguir demonstra como criar um veículo no 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;
}

Etapa 2: Ativar rastreamento de localização

O rastreamento de localização se refere ao local do veículo durante a viagem, em que o app do motorista envia telemetria para o Fleet Engine, que contém a localização atual do veículo. Esse fluxo de informações de posição constantemente atualizado é usado para transmitir o progresso do veículo ao longo do trajeto da viagem. Quando você ativa o rastreamento de localização, o app do driver começa a enviar essa telemetria a uma frequência padrão de uma vez a cada cinco segundos.

Ative o acompanhamento de local para Android e iOS da seguinte maneira:

Exemplo

O exemplo de código a seguir demonstra como ativar o monitoramento de localização.

Java

RidesharingVehicleReporter vehicleReporter = ...;

vehicleReporter.enableLocationTracking();

Kotlin

val vehicleReporter = ...

vehicleReporter.enableLocationTracking()

Swift

vehicleReporter.locationTrackingEnabled = true

Objective-C

_vehicleReporter.locationTrackingEnabled = YES;

Etapa 3. Definir o estado do veículo como on-line

Para colocar um veículo em serviço (ou seja, disponibilizá-lo para uso), defina o estado dele como on-line, mas não faça isso antes de ativar o rastreamento de localização.

Defina o estado do veículo como on-line para Android e iOS da seguinte maneira:

Exemplo

O exemplo de código abaixo demonstra como definir o estado do veículo como ONLINE.

Java

vehicleReporter.setVehicleState(VehicleState.ONLINE);

Kotlin

vehicleReporter.setVehicleState(VehicleState.ONLINE)

Swift

vehicleReporter.update(.online)

Objective-C

[_vehicleReporter updateVehicleState:GMTDVehicleStateOnline];

Etapa 4. Criar uma viagem no Fleet Engine

Para criar uma viagem com vários destinos, crie um objeto Trip exatamente como você faria para um destino único.

Uma viagem é um objeto que representa uma jornada, que é uma coleção de pontos de coordenadas geográficas, incluindo origem, waypoints e pontos de desembarque. Você precisa criar um objeto Trip para cada solicitação de viagem, para que ela possa ser associada a um veículo e depois rastreada.

Forneça os atributos obrigatórios

Os campos a seguir são obrigatórios para criar uma viagem com vários destinos.

parent
Uma string que inclui o ID do provedor. Precisa ser o mesmo ID do projeto do Google Cloud que contém as contas de serviço usadas para chamar o Fleet Engine
trip_id
Uma string que você cria e que identifica exclusivamente essa viagem.
trip
Objeto "Trip" a ser criado.

É preciso definir os seguintes campos no objeto Trip transmitido para CreateTripRequest:

trip_type
TripType.EXCLUSIVE
pickup_point
O ponto de origem da viagem.
dropoff_point
O ponto de desembarque da viagem. Esse campo não é obrigatório na criação da viagem e pode ser definido depois, chamando "UpdateTrip".
intermediate_destinations
A lista de destinos intermediários que o motorista visitará entre o embarque e o desembarque. Assim como o desembarque, esse campo não é obrigatório na criação da viagem e pode ser definido chamando "UpdateTrip".

Exemplo

O exemplo de integração de back-end a seguir demonstra como criar uma viagem exclusiva com vários destinos que tenha um ponto de embarque, um ponto de desembarque e um destino intermediário.

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

Etapa 5. Atualize a viagem com o ID do veículo e waypoints.

Você precisa configurar a viagem com um ID de veículo para que o Fleet Engine possa rastrear o veículo ao longo do trajeto.

  • É possível atualizar a viagem com o ID do veículo chamando o endpoint UpdateTrip com um UpdateTripRequest. Use o campo update_mask para especificar que você está atualizando o ID do veículo.

Observações

  • Se você não especificar uma desembarque ou destinos intermediários ao criar a viagem, poderá fazer isso nesse momento.

  • Se você precisar trocar de veículo em uma viagem em andamento, defina o estado dela como novo e, em seguida, atualize a viagem (como fez acima) com o novo ID do veículo.

Exemplo

O exemplo de integração de back-end a seguir demonstra como atualizar uma viagem para adicionar uma lista de destinos intermediários e definir um ID de veículo.

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

Etapa 6. Detectar atualizações de viagens no app para consumidores

  • No Android, você pode detectar atualizações de dados de uma viagem acessando um objeto TripModel do TripModelManager e registrando um listener TripModelCallback.

  • No iOS, você pode detectar atualizações de dados de uma viagem acessando um objeto GMTCTripModel do GMTCTripService e registrando um assinante GMTCTripModelSubscriber.

Um listener TripModelCallback e um assinante GMTCTripModelSubscriber permitem que o app receba atualizações periódicas do andamento da viagem em cada atualização com base no intervalo da atualização automática. Somente os valores que mudam podem acionar o callback. Caso contrário, o callback permanecerá silencioso.

Os métodos TripModelCallback.onTripUpdated() e tripModel(_:didUpdate:updatedPropertyFields:) são sempre chamados, independentemente de qualquer mudança de dados.

Exemplo 1

O exemplo de código abaixo demonstra como conseguir um TripModel de TripModelManager/GMTCTripService e definir um listener.

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];

Exemplo 2

O exemplo de código a seguir demonstra como configurar um listener TripModelCallback e um assinante 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

Você pode acessar informações sobre a viagem a qualquer momento da seguinte maneira:

  • Chame o método TripModel.getTripInfo() do SDK do consumidor para Android. Chamar esse método não força uma atualização de dados, embora os dados ainda continuem a ser atualizados na frequência de atualização.

  • Faça o download da propriedade GMTCTripModel.currentTrip do SDK do consumidor para iOS.

Etapa 7. Mostre a jornada no app para o consumidor

Acesse as APIs do elemento da interface do usuário Rides e Deliveries da seguinte maneira:

Exemplo

O exemplo de código a seguir demonstra como iniciar a jornada da interface do usuário.

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];

Por padrão, o SDK do consumidor mostra apenas o trecho ativo no trajeto, mas você tem a opção de mostrar o trecho restante, que inclui os destinos intermediários e o desembarque.

Se você quiser mostrar informações sobre waypoints de outras viagens, pode acessar todos os waypoints relevantes para uma viagem da seguinte maneira:

Etapa 8. Gerenciar o estado da viagem no Fleet Engine

Especifique o estado de uma viagem usando um dos valores de enumeração TripStatus. Quando o estado de uma viagem muda (por exemplo, de ENROUTE_TO_PICKUP para ARRIVED_AT_PICKUP), você precisa atualizar o estado da viagem usando o Fleet Engine. O estado da viagem sempre começa com o valor NEW e termina com COMPLETE ou CANCELED. Para mais informações, consulte trip_status.

Em uma viagem com vários destinos, além de atualizar o estado da viagem como você faria em uma única viagem, também é necessário atualizar o intermediateDestinationIndex e fornecer o intermediateDestinationsVersion na solicitação de atualização sempre que você chegar a um destino intermediário. Você precisa usar os seguintes status da enumeração TripStatus.

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

Exemplo

O exemplo de integração de back-end a seguir demonstra como criar uma viagem com vários destinos que passou pelo ponto de embarque e agora está a caminho do primeiro destino intermediário.

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