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

تتيح لك مكتبة JavaScript Fleet Tracking Library عرض مواقع المركبات في أساطيلها في الوقت الفعلي تقريبًا. تستخدم المكتبة Deliveries API للسماح بعرض صور لمركبات التسليم وكذلك المهام. وكما هي الحال في مكتبة تتبّع شحن JavaScript، فهي تتضمّن مكوّن خريطة JavaScript بديلاً للكيان google.maps.Map العادي ومكوّنات البيانات لربطها مع Fleet Engine.

المكوّنات

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

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

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

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

موفِّرو المواقع الجغرافية

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

مقدّم الموقع الجغرافي لمركبة التسليم

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

مقدّم موقع أسطول التسليم

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

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

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

مركبات توصيل الطلبات

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

علامات الموقع الجغرافي للمهمة

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

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

بدء استخدام مكتبة JavaScript Fleet Tracking Library

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

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

لتتبُّع مركبات التسليم من خلال موفِّر الموقع الجغرافي لمركبة التسليم، يمكنك إنشاء رمز 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 Fleet Tracking Library رمزًا مميزًا من خلال أداة استرجاع الرموز المميّزة للمصادقة في حال استيفاء أيّ من المتطلّبات التالية:

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

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

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

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 Fleet Tracking Library مسبقًا موفر مواقع جغرافية لواجهة برمجة التطبيقات Fleet Engine Deliveries API. استخدم معرّف مشروعك ومرجعًا لمصنع الرموز المميزة لإنشاء مثيل له.

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 باستخدام موفِّر الموقع الجغرافي. وتشمل معلومات التعريف الوقت المقدر للوصول والمسافة المتبقية قبل موعد الركوب أو التسليم التالي للمركبة. تؤدي التغييرات في المعلومات الوصفية إلى تشغيل حدث تحديث. يوضح المثال التالي كيفية الاستماع إلى أحداث التغيير هذه.

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 باستخدام موفّر الموقع الجغرافي. وتتضمن المعلومات الوصفية خصائص المركبة، مثل حالة التنقل والمسافة المتبقية والسمات المخصّصة. يمكنك الاطّلاع على المستندات المرجعية لمزيد من التفاصيل. يؤدي التغيير إلى المعلومات الوصفية إلى تشغيل حدث update. يوضح المثال التالي كيفية الاستماع إلى أحداث التغيير هذه.

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 بدون الحاجة إلى إجراء أي تغييرات على الرمز. يتم حفظ أنماط الخريطة كمعرّفات خرائط في مشروعك على السحابة الإلكترونية. لتطبيق نمط على خريطة تتبُّع عدد العناصر في 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 Fleet Tracking Library، يمكنك تخصيص شكل ومظهر العلامات التي تمت إضافتها إلى الخريطة. يمكنك القيام بذلك عن طريق تحديد تخصيصات العلامات، التي تطبقها مكتبة Fleet Tracking Library قبل إضافة علامات إلى الخريطة ومع كل تحديث للعلامة.

أبسط طريقة تخصيص هي تحديد كائن 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، يمكنك أيضًا تخصيص مظهر وطابع مسار المركبة المتَّبع على الخريطة. تنشئ المكتبة كائن google.maps.Polyline لكل زوج من الإحداثيات في المسار النشط أو المتبقي للمركبة. يمكنك تصميم عناصر 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 نشط باستخدام دالة تخصيص. اتّبِع هذا النمط لتخصيص تصميم أي عنصر 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 Journey Share، والتي تتضمّن ميزة "تتبُّع الأسطول":

  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>

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