تتبُّع أسطولك باستخدام مكتبة JavaScript FleetTracking

تتيح لك مكتبة تتبع أساطيل JavaScript عرض مواقع المركبات في أساطيلها في الوقت الفعلي تقريبًا. تستخدم المكتبة واجهة برمجة تطبيقات التسليم للسماح بعرض مؤثرات عرض مركبات التسليم بالإضافة إلى المهام. ومثل مكتبة تتبّع الشحنات في JavaScript، فهي تحتوي على مكوِّن خريطة JavaScript بديل بديل لكيان google.maps.Map العادي ومكوّنات البيانات التي يتم ربطها بـ Fleet Engine.

المكوّنات

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

عرض الخريطة الخاصة بتتبع الأسطول

يتصور عنصر عرض خريطة تتبع الأسطول موقع المركبات والمهام. إذا كان مسار المركبة معروفًا، فإن عنصر عرض الخريطة يحرّك هذه المركبة أثناء تحرّكها على طول مسارها المتنبأ به.

مثال على عرض الخريطة الخاصة بتتبُّع الأسطول

مقدمو خدمة المواقع الجغرافية

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

مزوِّد خدمة توصيل المركبات

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

مزوِّد خدمة توصيل الطلبات

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

التحكم في مستوى رؤية المواقع التي يتم تتبعها

يصف هذا القسم قواعد مستوى الرؤية لكائنات المواقع التي يتم تتبعها على الخريطة لموفِّر الموقع Fleet Engine المحدد مسبقًا. ويمكن لموفّري المواقع الجغرافية المخصّصين أو المشتقين تغيير قواعد مستوى الظهور.

مركبات توصيل

تكون مركبة التسليم مرئية فور إنشائها في Fleet Engine، وتكون مرئية في جميع أنحاء مسارها بغض النظر عن مهامها.

علامات موقع المهمة

تظهر محطات المركبات المخطط لها على الخريطة كعلامات لتوقف المركبات. يتم عرض علامات المهام المكتملة بأسلوب مختلف عن المحطات المخططة للمركبة.

يتم عرض موقع نتائج المهمة مع علامات نتائج المهمة. يتم عرض المهام ذات النتيجة الناجحة مع علامات المهام الناجحة، بينما يتم عرض جميع المهام الأخرى بعلامات مهام غير ناجحة.

بدء استخدام مكتبة JavaScript Fleet Tracking Library (مكتبة تتبُّع مجموعة JavaScript)

قبل استخدام مكتبة JavaScript Fleet Tracking Library (مكتبة تتبُّع مجموعة JavaScript)، عليك التأكّد من أنّك على عِلم بـ Fleet Engine ومن الحصول على مفتاح واجهة برمجة التطبيقات (API). ثم أنشئ معرّف مهمة ومطالبة بمعرّف المركبة التسليم.

إنشاء معرّف مهمة والمطالبة بمعرّف مركبة التسليم

لتتبُّع مركبات التسليم باستخدام موفّر الموقع الجغرافي لمركبة التسليم، عليك إنشاء رمز JSON المميّز للويب (JWT) مع معرّف مهمة ومطالبة بمعرّف مركبة التسليم.

لإنشاء حمولة بيانات JWT، عليك إضافة مطالبة أخرى في قسم التفويض باستخدام المفتاحَين taskid وdeliveryvehicleid وضبط قيمة كل مفتاح على *. ويجب إنشاء الرمز المميّز باستخدام دور المستخدم المميز لخدمة Fleet Engine Cloud IAM. تجدر الإشارة إلى أنّ هذا الإجراء يمنح إمكانية وصول واسع النطاق لإنشاء كيانات Fleet Engine وقراءتها وتعديلها، ويجب عدم مشاركتها إلّا مع المستخدمين الموثوق بهم.

يوضح المثال التالي كيفية إنشاء رمز مميز للتتبع حسب المركبة والمهمة:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "private_key_id_of_consumer_service_account"
}
.
{
  "iss": "superuser@yourgcpproject.iam.gserviceaccount.com",
  "sub": "superuser@yourgcpproject.iam.gserviceaccount.com",
  "aud": "https://fleetengine.googleapis.com/",
  "iat": 1511900000,
  "exp": 1511903600,
  "scope": "https://www.googleapis.com/auth/xapi",
  "authorization": {
     "taskid": "*",
     "deliveryvehicleid": "*",
   }
}

إنشاء أداة استرجاع الرمز المميّز للمصادقة

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

يجب أن يعرض الجلب بنية بيانات بحقلَين، ملفوفًا بوعد:

  • سلسلة token.
  • رقم expiresInSeconds تنتهي صلاحية الرمز المميز في هذه المدة الزمنية بعد الجلب.

وتطلب مكتبة تتبُّع مجموعة JavaScript رمزًا مميزًا عبر استرجاع الرمز المميّز للمصادقة عندما يكون أيٌّ ممّا يلي صحيحًا:

  • لا يتضمن رمزًا مميزًا، على سبيل المثال عندما لا يستدعي الجلب عند تحميل صفحة جديدة، أو عندما لا يستدعي الجلب رمزًا مميزًا.
  • انتهت صلاحية الرمز المميّز الذي تم استرجاعه سابقًا.
  • ويكون الرمز المميّز الذي تم استرجاعه سابقًا في غضون دقيقة واحدة من انتهاء صلاحيته.

بخلاف ذلك، تستخدم المكتبة الرمز المميّز الذي تم إصداره مسبقًا، ولا يزال صالحًا، ولا تستدعي الجلب.

يوضّح المثال التالي كيفية إنشاء أداة استرجاع الرمز المميّز للمصادقة:

JavaScript

function authTokenFetcher(options) {
  // options is a record containing two keys called 
  // serviceType and context. The developer should
  // generate the correct SERVER_TOKEN_URL and request
  // based on the values of these fields.
  const response = await fetch(SERVER_TOKEN_URL);
  if (!response.ok) {
    throw new Error(response.statusText);
  }
  const data = await response.json();
  return {
    token: data.Token,
    expiresInSeconds: data.ExpiresInSeconds
  };
}

TypeScript

function authTokenFetcher(options: {
  serviceType: google.maps.journeySharing.FleetEngineServiceType,
  context: google.maps.journeySharing.AuthTokenContext,
}): Promise<google.maps.journeySharing.AuthToken> {
  // The developer should generate the correct
  // SERVER_TOKEN_URL based on options.
  const response = await fetch(SERVER_TOKEN_URL);
  if (!response.ok) {
    throw new Error(response.statusText);
  }
  const data = await response.json();
  return {
    token: data.token,
    expiresInSeconds: data.expiration_timestamp_ms - Date.now(),
  };
}

عند تنفيذ نقطة النهاية من جهة الخادم لاستخراج الرموز المميزة، ضع ما يلي في الاعتبار:

  • يجب أن تعرض نقطة النهاية وقت انتهاء صلاحية الرمز المميّز. وفي المثال أعلاه، يتم تحديده على أنّه data.ExpiresInSeconds.
  • يجب أن يمرر جالب رمز المصادقة وقت انتهاء الصلاحية (بالثواني، من وقت الجلب) إلى المكتبة، كما هو موضح في المثال.
  • يعتمد SERVER_TOKEN_URL على تنفيذ الخلفية، وفي ما يلي عناوين URL لنموذج خلفية التطبيق:
    • https://SERVER_URL/token/delivery_driver/DELIVERY_VEHICLE_ID
    • https://SERVER_URL/token/delivery_consumer/TRACKING_ID
    • https://SERVER_URL/token/fleet_reader

تحميل خريطة من HTML

يوضح المثال التالي كيفية تحميل مكتبة مشاركة رحلة JavaScript من عنوان URL محدّد. تنفذ المعلمة callback الدالة initMap بعد تحميل واجهة برمجة التطبيقات. السمة defer تتيح للمتصفح الاستمرار في عرض بقية صفحتك أثناء تحميل واجهة برمجة التطبيقات.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing" defer></script>

متابعة مركبة توصيل

يوضّح هذا القسم كيفية استخدام مكتبة JavaScript Fleet Tracking Library (مكتبة تتبُّع أسطول JavaScript) لمتابعة مركبة تسليم. تأكّد من تحميل المكتبة من دالة الاستدعاء المحدّدة في علامة النص البرمجي قبل تشغيل الرمز.

إنشاء مثيل لمزوّد خدمة الموقع الجغرافي لمركبة توصيل

تحدّد مكتبة JavaScript Fleet Tracking Library مسبقًا موفّر الموقع الجغرافي لواجهة برمجة تطبيقات Fleet Engine Deliveries. استخدم معرف المشروع ومرجعًا إلى مصنع الرموز المميزة لإنشاء مثيل له.

JavaScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, you may specify 
          // deliveryVehicleId to immediately start
          // tracking.
          deliveryVehicleId: 'your-delivery-id',
});

TypeScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, you may specify
          // deliveryVehicleId to immediately start
          // tracking.
          deliveryVehicleId: 'your-delivery-id',
});

إعداد عرض الخريطة

بعد تحميل مكتبة مشاركة رحلة JavaScript، قم بتهيئة عرض الخريطة وإضافته إلى صفحة HTML. يجب أن تحتوي صفحتك على عنصر <div> يحتوي على عرض الخريطة. تتم تسمية العنصر <div> باسم map_canvas في المثال أدناه.

JavaScript

const mapView = new 
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'), 
  locationProviders: [locationProvider],
  // Styling customizations; see below.
  vehicleMarkerSetup: vehicleMarkerSetup,
  anticipatedRoutePolylineSetup:
      anticipatedRoutePolylineSetup,
  // Any undefined styling options will use defaults.
});

// If you did not specify a delivery vehicle ID in the 
// location provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.deliveryVehicleId 
                        = 'your-delivery-vehicle-id';

// Give the map an initial viewport to allow it to 
// initialize; otherwise the 'ready' event above may 
// not fire. The user also has access to the mapView
// object to customize as they wish.
mapView.map.setCenter('Times Square, New York, NY');
mapView.map.setZoom(14);

TypeScript

const mapView = new 
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  // Styling customizations; see below.
  vehicleMarkerSetup: vehicleMarkerSetup,
  anticipatedRoutePolylineSetup:
      anticipatedRoutePolylineSetup,
  // Any undefined styling options will use defaults.
});

// If you did not specify a delivery vehicle ID in the 
// location provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.deliveryVehicleId 
                        = 'your-delivery-vehicle-id';

// Give the map an initial viewport to allow it to 
// initialize; otherwise the 'ready' event above may 
// not fire. The user also has access to the mapView 
// object to customize as they wish.
mapView.map.setCenter('Times Square, New York, NY');
mapView.map.setZoom(14);

الاستماع إلى أحداث تغيير الأحداث

يمكنك استرداد معلومات وصفية حول مهمة من الكائن deliveryVehicle باستخدام موفر الموقع. تتضمن المعلومات الوصفية الوقت المقدر للوصول والمسافة المتبقية قبل موعد الاستلام أو النزول التالي للمركبة. تؤدي التغييرات التي تطرأ على المعلومات الوصفية إلى تشغيل حدث update. يوضح المثال التالي كيفية الاستماع إلى أحداث التغيير هذه.

JavaScript

locationProvider.addListener('update', e => {
  // e.deliveryVehicle contains data that may be        
  // useful to the rest of the UI.  
  if (e.deliveryVehicle) {
    console.log(e.deliveryVehicle.remainingDuration);
  }
});

TypeScript

locationProvider.addListener('update',
    (e: google.maps.journeySharing.FleetEngineDeliveryVehicleLocationProviderUpdateEvent) => {
  // e.deliveryVehicle contains data that may be
  // useful to the rest of the UI.
  if (e.deliveryVehicle) {
    console.log(e.deliveryVehicle.remainingDuration);
  }
});

الاستماع إلى الأخطاء

تؤدي الأخطاء التي تنشأ بشكل غير متزامن عن طلب معلومات مركبة التسليم إلى ظهور أحداث الخطأ. يوضح المثال التالي كيفية الاستماع إلى هذه الأحداث من أجل معالجة الأخطاء.

JavaScript

locationProvider.addListener('error', e => {
  // e.error is the error that triggered the event.
  console.error(e.error);
});

TypeScript

locationProvider.addListener('error', (e: google.maps.ErrorEvent) => {
  // e.error is the error that triggered the event.
  console.error(e.error);
});

إيقاف التتبُّع

لمنع مقدّم الموقع الجغرافي من تتبُّع مركبة التسليم، عليك إزالة رقم تعريف مركبة التسليم من مقدّم الموقع الجغرافي.

JavaScript

locationProvider.deliveryVehicleId = '';

TypeScript

locationProvider.deliveryVehicleId = '';

إزالة مقدم الموقع من عرض الخريطة

يوضح المثال التالي كيفية إزالة مزوِّد خدمة موقع من عرض الخريطة.

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

الاطّلاع على أسطول توصيل

يوضح هذا القسم كيفية استخدام مكتبة "مشاركة رحلة JavaScript" لعرض مجموعة تسليم. تأكّد من تحميل المكتبة من دالة الاستدعاء المحدّدة في علامة النص البرمجي قبل تشغيل الرمز.

إنشاء مثيل لمزوِّد موقع أسطول تسليم

تحدّد مكتبة JavaScript Fleet Tracking Library مسبقًا موفّر الموقع الجغرافي الذي يجلب عدة مركبات من FleetEngine Deliveries API. استخدِم رقم تعريف مشروعك بالإضافة إلى مرجع إلى أداة استرجاع الرموز المميّزة لإنشاء مثيل له.

JavaScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

TypeScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

تحدد deliveryVehicleFilter استعلامًا يُستخدم لتصفية المركبات المعروضة على الخريطة. يتم تمرير هذا الفلتر مباشرةً إلى Fleet Engine. راجِع ListDeliveryVehiclesRequest.filter للاطّلاع على التنسيقات المتوافقة.

تفرض ميزة "locationRestriction" قيودًا على المساحة التي يمكن عرض المركبات فيها على الخريطة. كما أنها تتحكم في ما إذا كان تتبع الموقع الجغرافي نشطًا أم لا. لن يبدأ تتبع الموقع حتى يتم تعيين ذلك.

بمجرد إنشاء موفِّر الموقع، قم بتهيئة عرض الخريطة.

تعيين تقييد الموقع باستخدام إطار عرض الخريطة

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

JavaScript

google.maps.event.addListenerOnce(
  mapView.map, 'bounds_changed', () => {
    const bounds = mapView.map.getBounds();
    if (bounds) {
      // If you did not specify a location restriction in the
      // location provider constructor, you may do so here.
      // Location tracking will start as soon as this is set.
      locationProvider.locationRestriction = bounds;
    }
  });

TypeScript

google.maps.event.addListenerOnce(
  mapView.map, 'bounds_changed', () => {
    const bounds = mapView.map.getBounds();
    if (bounds) {
      // If you did not specify a location restriction in the
      // location provider constructor, you may do so here.
      // Location tracking will start as soon as this is set.
      locationProvider.locationRestriction = bounds;
    }
  });

الاستماع إلى أحداث تغيير الأحداث

يمكنك استرداد معلومات وصفية حول مجموعة الأجهزة من كائن deliveryVehicles باستخدام موفر الموقع. وتشمل المعلومات الوصفية خصائص المركبات مثل حالة التنقّل والمسافة المتبقية والسمات المخصّصة. يمكنك الاطّلاع على المستندات المرجعية لمزيد من التفاصيل. غيِّر البيانات الوصفية إلى عامل تشغيل حدث تحديث. يوضح المثال التالي كيفية الاستماع إلى أحداث التغيير هذه.

JavaScript

locationProvider.addListener('update', e => {
  // e.deliveryVehicles contains data that may be
  // useful to the rest of the UI.
  if (e.deliveryVehicles) {
    for (vehicle of e.deliveryVehicles) {
      console.log(vehicle.remainingDistanceMeters);
    }
  }
});

TypeScript

locationProvider.addListener('update',
    (e: google.maps.journeySharing.FleetEngineDeliveryFleetLocationProviderUpdateEvent) => {
  // e.deliveryVehicles contains data that may be
  // useful to the rest of the UI.
  if (e.deliveryVehicles) {
    for (vehicle of e.deliveryVehicles) {
      console.log(vehicle.remainingDistanceMeters);
    }
  }
});

الاستماع إلى الأخطاء

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

إيقاف التتبُّع

لإيقاف مزود الموقع من تتبع أسطول التوصيل، قم بتعيين حدود مزود الموقع على قيمة فارغة.

JavaScript

locationProvider.locationRestriction = null;

TypeScript

locationProvider.locationRestriction = null;

إزالة مقدم الموقع من عرض الخريطة

يوضح المثال التالي كيفية إزالة مزوِّد خدمة موقع من عرض الخريطة.

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

تتبَّع سيارة توصيل واطّلِع على أسطول توصيل الطلبات

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

JavaScript

deliveryFleetLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

deliveryVehicleLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher
        });

const mapView = new
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [
    deliveryFleetLocationProvider,
    deliveryVehicleLocationProvider,
  ],
  // Any other options
});

TypeScript

deliveryFleetLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryFleetLocationProvider({
          projectId,
          authTokenFetcher,

          // Optionally, specify location bounds to
          // limit which delivery vehicles are
          // retrieved and immediately start tracking.
          locationRestriction: {
            north: 37.3,
            east: -121.8,
            south: 37.1,
            west: -122,
          },
          // Optionally, specify a filter to limit
          // which delivery vehicles are retrieved.
          deliveryVehicleFilter:
            'attributes.foo = "bar" AND attributes.baz = "qux"',
        });

deliveryVehicleLocationProvider =
    new google.maps.journeySharing
        .FleetEngineDeliveryVehicleLocationProvider({
          projectId,
          authTokenFetcher
        });

const mapView = new
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [
    deliveryFleetLocationProvider,
    deliveryVehicleLocationProvider,
  ],
  // Any other options
});

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

JavaScript

// Specify the customization function either separately, or as a field in
// the options for the delivery fleet location provider constructor.
deliveryFleetLocationProvider.deliveryVehicleMarkerCustomization =
  (params) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // params.vehicle.name follows the format
        // "providers/{provider}/deliveryVehicles/{vehicleId}".
        // Only the vehicleId portion is used for the delivery vehicle
        // location provider.
        deliveryVehicleLocationProvider.deliveryVehicleId =
            params.vehicle.name.split('/').pop();
      });
    }
  };

TypeScript

// Specify the customization function either separately, or as a field in
// the options for the delivery fleet location provider constructor.
deliveryFleetLocationProvider.deliveryVehicleMarkerCustomization =
  (params: google.maps.journeySharing.DeliveryVehicleMarkerCustomizationFunctionParams) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // params.vehicle.name follows the format
        // "providers/{provider}/deliveryVehicles/{vehicleId}".
        // Only the vehicleId portion is used for the delivery vehicle
        // location provider.
        deliveryVehicleLocationProvider.deliveryVehicleId =
            params.vehicle.name.split('/').pop();
      });
    }
  };

يمكنك إخفاء العلامة عن مقدّم خدمة الموقع الجغرافي لمركبة التسليم لمنع عرض علامتان للمركبة نفسها:

JavaScript

// Specify the customization function either separately, or as a field in 
// the options for the delivery vehicle location provider constructor.
deliveryVehicleLocationProvider.deliveryVehicleMarkerCustomization =
  (params) => {
    if (params.isNew) {
      params.marker.setVisible(false);
    }
  };

TypeScript

// Specify the customization function either separately, or as a field in
// the options for the delivery vehicle location provider constructor.
deliveryVehicleLocationProvider.deliveryVehicleMarkerCustomization =
  (params: deliveryVehicleMarkerCustomizationFunctionParams) => {
    if (params.isNew) {
      params.marker.setVisible(false);
    }
  };

تخصيص شكل ومظهر الخريطة الأساسية

لتخصيص شكل ومظهر عنصر الخرائط، يمكنك إضافة نمط إلى الخريطة باستخدام أدوات مستندة إلى السحابة الإلكترونية أو من خلال ضبط الخيارات مباشرةً في الرمز.

استخدام تصميم الخرائط المستند إلى السحابة الإلكترونية

يتيح لك تصميم الخرائط المستند إلى السحابة الإلكترونية إنشاء أنماط الخرائط وتعديلها لأيّ من تطبيقاتك التي تستخدم "خرائط Google" من وحدة التحكّم في Google Cloud بدون الحاجة إلى إجراء أي تغييرات على الرموز البرمجية. يتم حفظ أنماط الخرائط كمعرّفات خرائط في مشروعك على Google Cloud. لتطبيق نمط على خريطة تتبُّع مجموعة JavaScript، حدِّد mapId عند إنشاء JourneySharingMapView. لا يمكن تغيير الحقل mapId أو إضافته بعد إنشاء مثيل JourneySharingMapView. يوضح المثال التالي كيفية تفعيل نمط خريطة تم إنشاؤه مسبقًا باستخدام معرّف الخريطة.

JavaScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    mapId: 'YOUR_MAP_ID'
  }
});

TypeScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    mapId: 'YOUR_MAP_ID'
  }
});

استخدام تصميم الخريطة المستند إلى الرمز

هناك طريقة أخرى لتخصيص تصميم الخريطة، وهي ضبط mapOptions عند إنشاء JourneySharingMapView.

JavaScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    styles: [
      {
        "featureType": "road.arterial",
        "elementType": "geometry",
        "stylers": [
          { "color": "#CCFFFF" }
        ]
      }
    ]
  }
});

TypeScript

const mapView = new google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  mapOptions: {
    styles: [
      {
        "featureType": "road.arterial",
        "elementType": "geometry",
        "stylers": [
          { "color": "#CCFFFF" }
        ]
      }
    ]
  }
});

استخدام عمليات تخصيص العلامات

باستخدام مكتبة تتبع مجموعة JavaScript، يمكنك تخصيص شكل ومظهر العلامات التي تمت إضافتها إلى الخريطة. يمكنك إجراء ذلك عن طريق تحديد تخصيصات العلامات، التي تطبقها مكتبة تتبع الأسطول بعد ذلك قبل إضافة علامات إلى الخريطة ومع كل تحديث للعلامة.

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

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

بالإضافة إلى ذلك، يمكنك استخدام وظائف التخصيص لتصفية مستوى رؤية العلامة. للقيام بذلك، يجب استدعاء setVisible(false) على محدّد الموقع.

وفي المقابل، لأسباب تتعلّق بالأداء، ننصحك بالفلترة باستخدام الفلترة الأصلية في مزوِّد خدمة الموقع الجغرافي، مثل FleetEngineDeliveryFleetLocationProvider.deliveryVehicleFilter. ومع ذلك، عندما تحتاج إلى وظيفة تصفية إضافية، يمكنك تطبيق التصفية باستخدام دالة التخصيص.

توفّر مكتبة "تتبُّع مجموعة الأجهزة" مَعلمات التخصيص التالية:

تغيير تصميم العلامات باستخدام MarkerOptions

يعرض المثال التالي كيفية ضبط تصميم علامة مركبة باستخدام عنصر MarkerOptions. اتبع هذا النمط لتخصيص تصميم أي علامة باستخدام أي من معلمات تخصيص العلامة المدرجة أعلاه.

JavaScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

TypeScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

تغيير تصميم العلامات باستخدام وظائف التخصيص

يعرض المثال التالي كيفية ضبط تصميم علامة المركبة. اتبع هذا النمط لتخصيص تصميم أي علامة باستخدام أي من معلمات تخصيص العلامة المدرجة أعلاه.

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    params.marker.setLabel(`${stopsLeft}`);
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: DeliveryVehicleMarkerCustomizationFunctionParams) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    params.marker.setLabel(`${stopsLeft}`);
  };

إضافة معالجة النقر إلى العلامات

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

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // Perform desired action.
      });
    }
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: DeliveryVehicleMarkerCustomizationFunctionParams) => {
    if (params.isNew) {
      params.marker.addListener('click', () => {
        // Perform desired action.
      });
    }
  };

فلترة العلامات المرئية

يعرض المثال التالي كيفية فلترة علامات المركبات الظاهرة. اتبع هذا النمط لتصفية أي علامات باستخدام أي من معلمات تخصيص العلامة المذكورة أعلاه.

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    if (stopsLeft > 10) {
      params.marker.setVisible(false);
    }
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: DeliveryVehicleMarkerCustomizationFunctionParams) => {
    var stopsLeft = params.vehicle.remainingVehicleJourneySegments.length;
    if (stopsLeft > 10) {
      params.marker.setVisible(false);
    }
  };

استخدام عمليات تخصيص الخطوط المتعددة عند متابعة مركبة توصيل

باستخدام مكتبة JavaScript Fleet Tracking Library (مكتبة تتبُّع أسطول JavaScript)، يمكنك أيضًا تخصيص مظهر ومظهر مسار السيارة الذي تتّبعه على الخريطة. تنشئ المكتبة كائنًا google.maps.Polyline لكل زوج من الإحداثيات في المسار النشط أو المتبقي للمركبة path. يمكنك تصميم عناصر Polyline من خلال تحديد عمليات تخصيص الخطوط المتعددة. تطبق المكتبة بعد ذلك هذه التخصيصات في حالتين: قبل إضافة الكائنات إلى الخريطة، وعندما تتغير البيانات المستخدمة للكائنات.

على غرار تخصيص العلامة، يمكنك تحديد مجموعة من PolylineOptions ليتم تطبيقها على جميع كائنات Polyline المطابقة عند إنشائها أو تعديلها.

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

يمكنك تحديد عمليات التخصيص باستخدام المَعلمات المقدَّمة في FleetEngineDeliveryVehicleLocationProviderOptions. ويمكنك ضبط عمليات تخصيص لحالات المسار المختلفة في رحلة المركبة، سواء أثناء السفر أو السفر النشط أو الذي لم تسافر بعد. وتكون المعلمات على النحو التالي:

تغيير تصميم عناصر Polyline باستخدام PolylineOptions

يوضّح المثال التالي كيفية ضبط تصميم عنصر Polyline باستخدام السمة PolylineOptions. اتّبِع هذا النمط لتخصيص تصميم أي عنصر Polyline باستخدام أي من عمليات تخصيص الخطوط المتعددة المذكورة سابقًا.

JavaScript

activePolylineCustomization = {
  strokeWidth: 5,
  strokeColor: 'black',
};

TypeScript

activePolylineCustomization = {
  strokeWidth: 5,
  strokeColor: 'black',
};

تغيير تصميم عناصر Polyline باستخدام وظائف التخصيص

يوضّح المثال التالي كيفية ضبط تصميم عنصر متعدد الخطوط نشط باستخدام دالة تخصيص. اتّبِع هذا النمط لتخصيص تصميم أي عنصر Polyline باستخدام أي من معلَمات تخصيص الخطوط المتعددة المذكورة سابقًا.

JavaScript

// Color the Polyline objects in green if the vehicle is nearby.
activePolylineCustomization =
  (params) => {
    const distance = params.deliveryVehicle.remainingDistanceMeters;
    if (distance < 1000) {

      // params.polylines contains an ordered list of Polyline objects for
      // the path.
      for (const polylineObject of params.polylines) {
        polylineObject.setOptions({strokeColor: 'green'});
      }
    }
  };

TypeScript

// Color the Polyline objects in green if the vehicle is nearby.
activePolylineCustomization =
  (params: DeliveryVehiclePolylineCustomizationFunctionParams) => {
    const distance = params.deliveryVehicle.remainingDistanceMeters;
    if (distance < 1000) {

      // params.polylines contains an ordered list of Polyline objects for
      // the path.
      for (const polylineObject of params.polylines) {
        polylineObject.setOptions({strokeColor: 'green'});
      }
    }
  };

التحكّم في إذن الوصول إلى عناصر Polyline

بشكل تلقائي، تكون جميع عناصر Polyline مرئية. لجعل عنصر Polyline غير مرئي، اضبط خاصية visible الخاصة به:

JavaScript

remainingPolylineCustomization = {visible: false};

TypeScript

remainingPolylineCustomization = {visible: false};

عرض InfoWindow لمركبة أو علامة موقع جغرافي

يمكنك استخدام InfoWindow لعرض معلومات إضافية عن مركبة أو علامة موقع جغرافي.

يوضح المثال التالي كيفية إنشاء InfoWindow وإرفاقه بعلامة مركبة.

JavaScript

// 1. Create an info window.
const infoWindow = new google.maps.InfoWindow(
    {disableAutoPan: true});

// (Assumes a delivery vehicle location provider.)
locationProvider.addListener('update', e => {
  if (e.deliveryVehicle) {
    const distance = 
           e.deliveryVehicle.remainingDistanceMeters;
    infoWindow.setContent(
        `Your vehicle is ${distance}m away from the next task.`);

    // 2. Attach the info window to a vehicle marker.   
    // This property can return multiple markers.
    const marker = mapView.vehicleMarkers[0];
    infoWindow.open(mapView.map, marker);
  }
});

// 3. Close the info window.
infoWindow.close();

TypeScript

// 1. Create an info window.
const infoWindow = new google.maps.InfoWindow(
    {disableAutoPan: true});

// (Assumes a delivery vehicle location provider.)
locationProvider.addListener('update', (e: google.maps.journeySharing.FleetEngineDeliveryVehicleLocationProviderUpdateEvent) => {
  if (e.deliveryVehicle) {
    const distance = 
           e.deliveryVehicle.remainingDistanceMeters;
    infoWindow.setContent(
        `Your vehicle is ${distance}m away from the next task.`);

    // 2. Attach the info window to a vehicle marker.   
    // This property can return multiple markers.
    const marker = mapView.vehicleMarkers[0];
    infoWindow.open(mapView.map, marker);
  }
});

// 3. Close the info window.
infoWindow.close();

إيقاف الاحتواء التلقائي

يمكنك إيقاف ملاءمة إطار العرض تلقائيًا للمركبة والمسار المتوقع للخريطة من خلال إيقاف "الإعداد التلقائي". يوضح المثال التالي كيفية إيقاف الضبط التلقائي عند ضبط عرض الخريطة لمشاركة الرحلة.

JavaScript

const mapView = new
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  automaticViewportMode:
      google.maps.journeySharing
          .AutomaticViewportMode.NONE,
  ...
});

TypeScript

const mapView = new
    google.maps.journeySharing.JourneySharingMapView({
  element: document.getElementById('map_canvas'),
  locationProviders: [locationProvider],
  automaticViewportMode:
      google.maps.journeySharing
          .AutomaticViewportMode.NONE,
  ...
});

استبدال خريطة حالية

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

على سبيل المثال، لنفترض أنّ لديك صفحة ويب بها كيان google.maps.Map عادي تظهر عليه علامة:

<!DOCTYPE html>
<html>
  <head>
    <style>
       /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
       }
    </style>
  </head>
  <body>
    <h3>My Google Maps Demo</h3>
    <!--The div element for the map -->
    <div id="map"></div>
    <script>
// Initialize and add the map
function initMap() {
  // The location of Uluru
  var uluru = {lat: -25.344, lng: 131.036};
  // The map, initially centered at Mountain View, CA.
  var map = new google.maps.Map(document.getElementById('map'));
  map.setOptions({center: {lat: 37.424069, lng: -122.0916944}, zoom: 14});

  // The marker, now positioned at Uluru
  var marker = new google.maps.Marker({position: uluru, map: map});
}
    </script>
    <!-- Load the API from the specified URL.
       * The async attribute allows the browser to render the page while the API loads.
       * The key parameter will contain your own API key (which is not needed for this tutorial).
       * The callback parameter executes the initMap() function.
    -->
    <script defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
  </body>
</html>

لإضافة مكتبة "مشاركة رحلة JavaScript" التي تتضمّن "تتبُّع الأسطول":

  1. أضِف رمزًا إلى المصنع.
  2. إعداد موفِّر الموقع الجغرافي في دالة initMap().
  3. تهيئة عرض الخريطة في دالة initMap(). يحتوي العرض على الخريطة.
  4. انقل التخصيص إلى دالة رد الاتصال لإعداد عرض الخريطة.
  5. أضف مكتبة المواقع إلى برنامج تحميل واجهة برمجة التطبيقات.

يوضح المثال التالي التغييرات التي سيتم إجراؤها:

<!DOCTYPE html>
<html>
  <head>
    <style>
       /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
       }
    </style>
  </head>
  <body>
    <h3>My Google Maps Demo</h3>
    <!--The div element for the map -->
    <div id="map"></div>
    <script>
let locationProvider;

// (1) Authentication Token Fetcher
function authTokenFetcher(options) {
  // options is a record containing two keys called 
  // serviceType and context. The developer should
  // generate the correct SERVER_TOKEN_URL and request
  // based on the values of these fields.
  const response = await fetch(SERVER_TOKEN_URL);
      if (!response.ok) {
        throw new Error(response.statusText);
      }
      const data = await response.json();
      return {
        token: data.Token,
        expiresInSeconds: data.ExpiresInSeconds
      };
}

// Initialize and add the map
function initMap() {
  // (2) Initialize location provider. Use FleetEngineDeliveryVehicleLocationProvider
  // as appropriate.
  locationProvider = new google.maps.journeySharing.FleetEngineDeliveryVehicleLocationProvider({
    YOUR_PROVIDER_ID,
    authTokenFetcher,
  });

  // (3) Initialize map view (which contains the map).
  const mapView = new google.maps.journeySharing.JourneySharingMapView({
    element: document.getElementById('map'),
    locationProviders: [locationProvider],
    // any styling options
  });

mapView.addListener('ready', () => {
  locationProvider.deliveryVehicleId = DELIVERY_VEHICLE_ID;

    // (4) Add customizations like before.

    // The location of Uluru
    var uluru = {lat: -25.344, lng: 131.036};
    // The map, initially centered at Mountain View, CA.
    var map = mapView.map;
    map.setOptions({center: {lat: 37.424069, lng: -122.0916944}, zoom: 14});
    // The marker, now positioned at Uluru
    var marker = new google.maps.Marker({position: uluru, map: map});
  };
}
    </script>
    <!-- Load the API from the specified URL
      * The async attribute allows the browser to render the page while the API loads
      * The key parameter will contain your own API key (which is not needed for this tutorial)
      * The callback parameter executes the initMap() function
      *
      * (5) Add the journey sharing library to the API loader, which includes Fleet Tracking functionality.
    -->
    <script defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing">
    </script>
  </body>
</html>

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