إنشاء رحلات إلى وجهات متعددة

يوضّح هذا المستند كيفية إنشاء رحلة متعددة الوجهات وضبط الحقل المناسب وتخصيصها لمركبة لتنفيذها. يفترض هذا الدليل أنّك قد أعددت "محرك الأسطول"، وأنّك أنشأت مركبات، وأنّ لديك تطبيقًا يعمل للسائقين، وتطبيقًا اختياريًا للمستهلكين. من المفترض أيضًا أن تكون على دراية بسيناريوهات الرحلات المختلفة المتاحة للرحلات عند الطلب. اطّلِع على الأدلة ذات الصلة التالية لتحديد ما يلي:

أساسيات إنشاء الرحلات

يصف هذا القسم تفاصيل الطلب اللازمة لإنشاء رحلة في Fleet Engine. يمكنك إصدار طلب إنشاء باستخدام gRPC وREST.

  • طريقة CreateTrip(): gRPC أو REST
  • رسالة CreateTripRequest: gRPC فقط

حقول الرحلة

استخدِم الحقول التالية لإنشاء رحلة في Fleet Engine. يمكنك استخدام ملفّات مختلفة للأنواع المختلفة من الرحلات: الرحلات التي تتضمن وجهة واحدة أو وجهات متعددة، والرحلات المتتالية، أو الرحلات المشتركة. يمكنك إدخال الحقول الاختيارية عند إنشاء الرحلة، أو يمكنك ضبطها لاحقًا عند تعديل الرحلة.

حقول الرحلة
الاسم مطلوب؟ الوصف
parent نعم سلسلة تتضمّن رقم تعريف المشروع يجب أن يكون هذا المعرّف هو المعرّف نفسه المستخدَم في عملية دمج Fleet Engine بالكامل، مع أدوار حساب الخدمة نفسها.
trip_id نعم سلسلة تنشئها لتحديد هذه الرحلة بشكل فريد تفرض معرّفات الرحلات بعض القيود، كما هو موضّح في المرجع.
trip_type نعم اضبط TripType على القيم التالية لنوع الرحلة التي تنشئها:
  • وجهة واحدة: اضبط القيمة على SHARED أو EXCLUSIVE.
  • الوجهات المتعددة: اضبط القيمة على EXCLUSIVE.
  • تسلسل: اضبط القيمة على EXCLUSIVE.
  • الجمع المشترَك: اضبطه على SHARED.
pickup_point نعم نقطة انطلاق الرحلة
الوجهات المتوسطة نعم

الرحلات التي تتضمّن وجهات متعددة فقط: قائمة الوجهات الوسيطة التي يزورها السائق بين نقطة المغادرة ونقطة الوصول. كما هو الحال مع dropoff_point، يمكن أيضًا ضبط هذا الحقل في وقت لاحق من خلال استدعاء UpdateTrip، ولكن الرحلات التي تتضمّن وجهات متعددة تحتوي بحكم التعريف على وجهات وسيطة.

vehicle_waypoints نعم

الرحلات المشتركة فقط: يتيح هذا الحقل تداخل نقاط التوقف من رحلات متعددة. يحتوي هذا الملف على جميع نقاط التوقف المتبقية للمركبة المحدّدة، بالإضافة إلى نقاط التوقف لتحميل الركاب وإيقافهم في هذه الرحلة. يمكنك ضبط هذا الحقل من خلال الاتصال برقم CreateTrip أو UpdateTrip. يمكنك أيضًا تعديل نقاط الطريق للمركبة من خلال حقل waypoints من خلال الاتصال برقم UpdateVehicle. لا تعرض الخدمة هذه المعلومات في المكالمات على GetTrip بسبب أسباب تتعلّق بالخصوصية.

number_of_passengers لا عدد الركاب في الرحلة
dropoff_point لا وجهة الرحلة.
vehicle_id لا معرّف المركبة المحدّد للرحلة

مثال: إنشاء رحلة متعددة الوجهات

يوضّح القسم التالي كيفية إنشاء رحلة حصرية متعددة الوجهات تتضمّن نقطة استلام ونقطة تسليم ووجهة وسيطة واحدة.

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

تعديل رحلة متعددة الوجهات

يجب ضبط الرحلة باستخدام رقم تعريف المركبة حتى يتمكّن محرّك الأسطول من تتبُّع المركبة على طول مسارها. لمعرفة تفاصيل عن تعديل رحلة، يُرجى الاطّلاع على مقالة تعديل الرحلات وإدارتها.

إذا لم تحدّد وجهة تسليم أو وجهات وسيطة عند إنشاء الرحلة، يمكنك إجراء ذلك في أي وقت في هذه المرحلة.

مثال على تعديل رحلة

يوضّح القسم التالي كيفية تعديل رحلة لإضافة قائمة بنقاط التوقف المتوسّطة وضبط معرّف المركبة.

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

إدارة حالة الرحلة للرحلات التي تتضمّن وجهات متعددة

يمكنك تحديد حالة الرحلة باستخدام إحدى قيم التعداد TripStatus. عند تغيُّر حالة رحلة، مثلاً من ENROUTE_TO_PICKUP إلى ARRIVED_AT_PICKUP، عليك تعديل حالة الرحلة في Fleet Engine. تبدأ حالة الرحلة دائمًا بقيمة NEW وتنتهي بقيمة إما COMPLETE أو CANCELED.

بالنسبة إلى الرحلة التي تتضمّن عدّة وجهات، بالإضافة إلى تعديل حالة الرحلة كما هو الحال في رحلة ذات وجهة واحدة، يجب أيضًا تعديل ما يلي في كل مرة تصل فيها مركبتك إلى وجهة وسيطة:

  • 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 Fleet Engine's.
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}

الخطوات التالية