إنشاء رحلات مشتركة مشتركة

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

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

يوضّح هذا القسم تفاصيل الطلب اللازمة لإنشاء رحلة في 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 لا رقم تعريف المركبة المخصّصة للرحلة

مثال: إنشاء رحلة مشتركة

يوضّح نموذج دمج الخلفية التالي كيفية إنشاء رحلة وتعيينها لمركبة كرحلة مشتركة.

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

تعديل رحلات مشاركة المركبة

يجب ربط أي رحلة يتم إنشاؤها في Fleet Engine بمركبة لكي تتمكّن Fleet Engine من احتساب الوقت المقدَّر للوصول إلى الوجهة وتتبُّع الرحلة. يمكنك إجراء ذلك أثناء إنشاء الرحلة أو لاحقًا عند تعديلها.

بالنسبة إلى رحلات مشاركة المركبة، يجب تحديد ترتيب لنقاط المرور غير التي لم تتم زيارتها في مجموعة نقاط مرور المركبة الخاصة بالرحلة (Trip.vehicle_waypoints). تستخدم Fleet Engine هذه القائمة لتعديل نقاط مرور الرحلة تلقائيًا لجميع الرحلات في مجموعة مشاركة المركبة.

على سبيل المثال، لنفترض أنّ لديك رحلتَين مشتركتَين، الرحلة أ والرحلة ب:

  • الرحلة A في طريقها إلى موقع التوصيل.
  • بعد ذلك، تتم إضافة الرحلة B إلى المركبة نفسها.

في UpdateTripRequest واحد للرحلة B، يمكنك ضبط vehicleId، بالإضافة إلى ضبط Trip.vehicle_waypoints على ترتيب نقاط التوقف الأمثل: نقطة الاستلام → نقطة التسليم → نقطة التسليم.

  • عند الاتصال بـ getVehicle()، يتم عرض remainingWaypoints التي تتضمّن:
    ب استلام → أ تسليم → ب تسليم.
  • يجب أن تعرض دالة رد الاتصال getTrip() أو onTripRemainingWaypointsUpdated الخاصة بالرحلة A الرمز remainingWaypoints الذي يتضمّن:
    B الاستلام ← A التسليم.
  • يجب أن تعرض الدالة getTrip() أو الدالة onTripRemainingWaypointsUpdated التي يتم استدعاؤها من أجل الرحلة B الرمز remainingWaypoints الذي يتضمّن:
    نقطة الاستلام → نقطة التوصيل → نقطة التوصيل.

مثال

يوضّح نموذج دمج الخلفية التالي كيفية تعديل رحلة باستخدام معرّف المركبة ونقاط الطريق لرحلتَين مشتركتَين.

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

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