מעקב אחרי משלוחים באמצעות ספריית המעקב אחר משלוחים ב-JavaScript

ספריית JavaScript Shipment Tracking Library מאפשרת להציג באופן חזותי את המיקום של כלי הרכב ושל המיקומים שמעניינים אתכם במעקב ב-Flet Engine. הספרייה מכילה רכיב מפה של JavaScript שמהווה תחליף לישות google.maps.Map רגילה ורכיבי נתונים לצורך התחברות אל Fleet Engine. באמצעות JavaScript Shipment Tracking Library (ספריית המעקב אחר משלוחים של JavaScript), תוכלו לספק חוויית מעקב מותאמת אישית ומונפשת למעקב אחר המשלוח מאפליקציית האינטרנט.

רכיבים

ספריית JavaScript Shipment Tracking Library מספקת רכיבים להצגה חזותית של הרכב והמסלול שלו בזמן ההתקדמות ליעד, וגם פידים של נתונים גולמיים לגבי זמן ההגעה המשוער של הנהג או המרחק שנותר לנסיעה.

תצוגת מפה של מעקב המשלוח

הרכיב של תצוגת המפה ממחיש באופן חזותי את המיקום של כלי הרכב והיעדים. אם המסלול של הרכב ידוע, האנימציה של הרכב מופיעה ברכיב תצוגת המפה כשהוא נע במסלול החזוי.

ספק המיקום למשלוח

ספק של מיקומי משלוחים מוסיף פרטי מיקום של אובייקטים במעקב אל מפת המעקב אחרי משלוחים, לצורך מעקב אחרי המשלוח הראשון והאחרון.

אפשר להשתמש בספק של מיקום המשלוח כדי לעקוב אחר:

  • מקום האיסוף או המשלוח של המשלוח.
  • המיקום והמסלול של כלי המשלוח.

אובייקטים של מיקום במעקב

ספק המיקום עוקב אחרי המיקום של אובייקטים כמו כלי רכב ויעדים.

מיקום היעד

מיקום היעד הוא המיקום שבו התהליך מסתיים. זהו המיקום המתוכנן של המשימות, למעקב אחר המשלוח.

מיקום הרכב

מיקום הרכב הוא המיקום של כלי הרכב במעקב. אפשר גם להציג מסלול לרכב.

שולף אסימון אימות

כדי לשלוט בגישה לנתוני המיקום שמאוחסנים ב-Feet Engine, צריך להטמיע בשרת שלכם שירות הנפקה של JSON Web Token (JWT) עבור Fleet Engine. לאחר מכן מטמיעים כלי אחזור של אסימון אימות כחלק מאפליקציית האינטרנט, באמצעות JavaScript Journey Sharing Library כדי לאמת את הגישה לנתוני המיקום.

אפשרויות עיצוב

סגנונות של סמנים וקווים פוליגוניים קובעים את המראה והתחושה של אובייקטים של מיקום במעקב במפה. אפשר להשתמש באפשרויות סגנון בהתאמה אישית כדי לשנות את סגנון ברירת המחדל כך שיתאים לסגנון של אפליקציית האינטרנט שלכם.

שליטה בחשיפה של מיקומים במעקב

בקטע הזה מתוארים אמצעי הבקרה של הרשאות הגישה לאובייקטים שנמצאים במעקב במפה. הכללים הבאים חלים על שתי קטגוריות של אובייקטים:

  • סמן מיקום
  • נתוני המשימה

הצגת סמן המיקום

כל סמני המיקום של המוצא והיעד מוצגים תמיד במפה. לדוגמה, מיקום המשלוח תמיד מוצג במפה, ללא קשר למצב המשלוח.

הרשאות גישה לנתוני המשימה

בקטע הזה מתוארים כללי ברירת המחדל של הרשאות גישה שחלים על נתוני המשימות, כמו מיקום הרכב והמסלול שנותר. אפשר להתאים אישית הרבה משימות, אבל לא את כולן:

  • משימות לא זמינות - לא ניתן להתאים אישית את החשיפה של משימות אלה.
  • משימות פעילות ברכב – אפשר להתאים אישית משימות כאלה.
  • משימות לא פעילות שקשורות לרכב – לא ניתן להתאים אישית את הרשאות הגישה למשימות האלה.

משימות לא זמינות

אם יש לפחות משימה אחת של חוסר זמינות (למשל, אם הנהג יוצא להפסקה או אם הרכב מתמלא) במסלול של המשימה שעוקבים אחריה, הרכב לא גלוי. זמן ההגעה המשוער וזמן ההשלמה המשוער של המשימה עדיין זמינים.

משימות שקשורות לכלי רכב פעילים

האובייקט TaskTrackingInfo מספק מספר רכיבי נתונים שאפשר להציג בספרייה למעקב אחר משלוחים. כברירת מחדל, השדות האלה מופיעים כשהמשימה מוקצית לרכב וכשהרכב נמצא במרחק 5 עצירות מהמשימה. הרשאות הגישה מסתיימות כשהמשימה מסתיימת או מבוטלת. הנה השדות הבאים:

  • קווים פוליגוניים של מסלול
  • זמן הגעה משוער
  • זמן השלמת המשימה המשוער
  • מרחק הנסיעה שנותר למשימה
  • מספר התחנות שנותרו
  • מיקום הרכב

כשיוצרים או מעדכנים את המשימה ב-Fleet Engine, אפשר להתאים אישית את הרשאות הגישה לכל משימה בנפרד.TaskTrackingViewConfig כך נוצרים כללים למקרים שבהם רכיבי נתונים נפרדים זמינים, על סמך הקריטריונים הבאים (אפשרות החשיפה בהמשך):

  • מספר התחנות שנותרו
  • משך הזמן עד לזמן ההגעה המשוער
  • מרחק הנסיעה שנותר
  • הצגת הלחצן תמיד
  • אף פעם לא גלוי

חשוב לזכור שאפשר לשייך כל רכיב נתונים רק לאפשרות חשיפה אחת. לא ניתן לשלב קריטריונים באמצעות OR או AND.

הנה דוגמה להתאמה אישית. הכללים להתאמה אישית זו הם:

  • הצגת קווים פוליגוניים במסלול אם הרכב נמצא במרחק של 3 עצירות ביניים.
  • הצג את זמן ההגעה המשוער אם מרחק הנסיעה הנותר קצר מ-5,000 מטר.
  • אל תציג אף פעם את מספר התחנות הנותר.
  • כל שדה אחר שומר על הנראות המוגדרת כברירת מחדל כשהרכב נמצא במרחק של 5 עצירות ביניים מהמשימה.
"taskTrackingViewConfig": {
  "routePolylinePointsVisibility": {
    "remainingStopCountThreshold": 3
  },
  "estimatedArrivalTimeVisibility": {
    "remainingDrivingDistanceMetersThreshold": 5000
  },
  "remainingStopCountVisibility": {
    "never": true
  }
}

תוכלו גם להתאים אישית את הגדרת ברירת המחדל של הרשאות הגישה לפרויקט באמצעות פנייה לצוות התמיכה.

קווים פוליגוניים במסלולים וכללי הרשאות גישה למיקום הרכב:

כשיש קווים פוליגוניים במסלול, גם מיקום הרכב צריך להיות גלוי, אחרת אפשר לציין את מיקום הרכב בסופם של קווים פוליגוניים. כלומר, בקווים פוליגוניים במסלול לא יכולה להיות אפשרות הרשאות גישה פחות מגבילה.

צריך לפעול לפי הכללים האלה כדי לספק שילוב תקין של קווים פוליגוניים במסלול / הרשאות גישה למיקום הרכב:

  • כאשר קווים פוליגוניים במסלול ומיקום הרכב כוללים את אותו סוג של אפשרות חשיפה זהה:

    • אם אפשרות החשיפה נשארת במספר התחנות, משך הזמן עד זמן ההגעה המשוער או מרחק הנסיעה שנותר, בקווים פוליגוניים במסלול צריך לציין ערך שקטן או שווה לערך שהוגדר לאפשרות החשיפה של מיקום הרכב. לדוגמה:
    "taskTrackingViewConfig": {
      "routePolylinePointsVisibility": {
        "remainingStopCountThreshold": 3
      },
      "vehicleLocationVisibility": {
        "remainingStopCountThreshold": 5
      },
    }
    
    • אם בקווים פוליגוניים במסלול יש אפשרות לראות תמיד את החשיפה, מיקום הרכב צריך לאפשר גישה גלויה תמיד.
    • אם למיקום הרכב יש אפשרות לא גלויה אף פעם, קווים פוליגוניים במסלול חייבים לספק גם אפשרות לא גלויה אף פעם.
  • אם לקווים פוליגוניים במסלול ולמיקום הרכב יש סוגים שונים של הרשאות גישה, מיקום הרכב גלוי רק כששתי האפשרויות של הרשאות הגישה מתקיימים.

    לדוגמה:

    "taskTrackingViewConfig": {
      "routePolylinePointsVisibility": {
        "remainingStopCountThreshold": 3
      },
      "vehicleLocationVisibility": {
        "remainingDrivingDistanceMetersThreshold": 3000
      },
    }
    

    בדוגמה הזו, המיקום של הרכב מופיע רק אם מספר העצירות שנותרו הוא לפחות 3 וגם מרחק הנסיעה הנותר של 3,000 מטר לפחות.

תחילת העבודה עם ספריית שיתוף הפעולה של JavaScript

לפני שאתם משתמשים ב-JavaScript Journey Share Library, ודאו שאתם מכירים את Fleet Engine ושאתם משיגים מפתח API.

כדי לעקוב אחרי מסירה, קודם כול צריך ליצור הצהרה על זכויות יוצרים במזהה לצורכי מעקב.

יצירת הצהרה על זכויות יוצרים במזהה לצורכי מעקב

כדי לעקוב אחרי משלוח באמצעות הספק של מיקום המשלוח, צריך ליצור אסימון אינטרנט מסוג JSON (JWT) עם הצהרה של מזהה לצורכי מעקב.

כדי ליצור את המטען הייעודי (payload) של JWT, מוסיפים הצהרה נוספת בקטע ההרשאות עם המפתח trackingid. מגדירים את הערך כמזהה לצורכי מעקב אחר המשלוח.

בדוגמה הבאה אפשר לראות איך ליצור אסימון למעקב לפי מזהה לצורכי מעקב:

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

יצירת מאחזר אסימון אימות

תוכלו ליצור מאחזר אסימון אימות כדי לאחזר אסימון שנוצר עם ההצהרות המתאימות בשרתים שלכם, באמצעות אישור של חשבון השירות לפרויקט. חשוב להנפיק אסימונים רק בשרתים, ואף פעם לא לשתף את האישורים עם לקוחות. אחרת, תוכלו לסכן את האבטחה של המערכת שלכם.

המאחזר צריך להחזיר מבנה נתונים שכולל שני שדות שעוטפים ב-Promise:

  • מחרוזת 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 אחרי שה-API נטען. המאפיין defer מאפשר לדפדפן להמשיך לעבד את שאר הדף בזמן שה-API נטען.

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

מעקב אחר משלוח

בקטע הזה נסביר איך להשתמש בספריית המעקב אחר משלוחים ב-JavaScript על מנת לעקוב אחר איסוף או מסירה של משלוח. לפני שמריצים את הקוד, חשוב לטעון את הספרייה מפונקציית הקריאה החוזרת שצוינה בתג הסקריפט.

הפיכת ספק של מיקום משלוחים

ה-JavaScript Shipment Tracking Library מגדיר מראש ספק מיקום ל-Fleet Engine Deliveries API. כדי ליצור את האסימון, משתמשים במזהה הפרויקט ובהפניה ליצרן האסימונים.

JavaScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineShipmentLocationProvider({
          projectId: 'your-project-id',
          authTokenFetcher: authTokenFetcher, // the token fetcher defined in the previous step

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

TypeScript

locationProvider =
    new google.maps.journeySharing
        .FleetEngineShipmentLocationProvider({
          projectId: 'your-project-id',
          authTokenFetcher: authTokenFetcher, // the token fetcher defined in the previous step

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

הפעלה של תצוגת המפה

לאחר הטעינה של ספריית ה-Journey Share, הפעילו את תצוגת המפה והוסיפו אותה לדף ה-HTML. הדף צריך להכיל רכיב <div> שמכיל את תצוגת המפה. בדוגמה הבאה, האלמנט <div> נקרא map_canvas.

כדי להימנע מתנאי מרוץ, צריך להגדיר את המזהה לצורכי מעקב של ספק המיקום בקריאה החוזרת (callback) שמופעלת אחרי שהמפה מאתחלת.

JavaScript

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

// If you did not specify a tracking ID in the location
// provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.trackingId = 'your-tracking-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({lat: 37.2, lng: -121.9});
mapView.map.setZoom(14);

TypeScript

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

// If you did not specify a tracking ID in the location
// provider constructor, you may do so here.
// Location tracking will start as soon as this is set.
locationProvider.trackingId = 'your-tracking-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({lat: 37.2, lng: -121.9});
mapView.map.setZoom(14);

מזהה לצורכי מעקב

המזהה לצורכי מעקב שסופק לספק המיקום עשוי להתאים לכמה משימות. לדוגמה, איסוף ומשימת מסירה של אותה חבילה, או כמה ניסיונות מסירה כושלים. נבחרה משימה אחת שתופיע במפת המעקב אחר משלוחים. המשימה שתוצג נקבעת כך:

  1. אם יש רק משימה אחת פתוחה לאיסוף, היא מוצגת. אם יש כמה משימות פתוחות לאיסוף, נוצרת שגיאה.
  2. אם יש רק משימה פתוחה אחת של מסירה, היא מוצגת. אם יש כמה משימות מסירה פתוחות, נוצרת שגיאה.
  3. אם יש משימות מסירה סגורות:
    • אם יש בדיוק משימת מסירה אחת שנסגרה, היא מוצגת.
    • אם יש כמה משימות מסירה סגורות, תוצג המשימה עם שעת היעד האחרונה.
    • אם יש כמה משימות מסירה סגורות, ולכל אחת מהן אין מועד סיום, נוצרת שגיאה.
  4. אם יש משימות לאיסוף סגורות:
    • אם יש רק משימה אחת מסוג איסוף שנסגרה, היא מוצגת.
    • אם יש כמה משימות איסוף סגורות, מוצגת המשימה עם שעת היעד האחרונה.
    • אם יש כמה משימות איסוף סגורות, ולכל אחת מהן אין מועד סיום, נוצרת שגיאה.
  5. אם לא, לא תוצג משימה.

האזנה לאירועי שינוי

אפשר לאחזר מטא מידע של משימה מאובייקט פרטי המעקב אחר המשימות באמצעות ספק המיקום. המטא-מידע כולל את זמן ההגעה המשוער, מספר העצירות שנותרו והמרחק שנותר לפני האיסוף או המסירה. שינויים במטא-מידע מפעילים אירוע עדכון. הדוגמה הבאה ממחישה איך להאזין לאירועי השינוי האלה.

JavaScript

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

TypeScript

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

טיפול בשגיאות

שגיאות שמקורם בשליחת פרטי משלוח באופן אסינכרוני גורמות לאירועי שגיאה. הדוגמה הבאה ממחישה איך להאזין לאירועים האלה כדי לטפל בשגיאות.

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

הערה: כדי לטפל בשגיאות לא צפויות, חשוב לתחום את הקריאות לספרייה בבלוקים try...catch.

הפסקת מעקב

כדי למנוע מספק המיקום לעקוב אחרי המשלוח, צריך להסיר את המזהה לצורכי מעקב מספק המיקום.

JavaScript

locationProvider.trackingId = '';

TypeScript

locationProvider.trackingId = '';

הסרת ספק המיקום מתצוגת המפה

הדוגמה הבאה מראה איך להסיר ספק מיקום מתצוגת המפה.

JavaScript

mapView.removeLocationProvider(locationProvider);

TypeScript

mapView.removeLocationProvider(locationProvider);

התאמה אישית של המראה והתחושה של המפה הבסיסית

כדי להתאים אישית את המראה והתחושה של רכיב המפות, תוכלו לעצב את המפה באמצעות כלים מבוססי-ענן או על ידי הגדרת אפשרויות ישירות בקוד.

שימוש בעיצוב מפות מבוסס-ענן

סגנון מפות מבוסס-ענן מאפשר ליצור ולערוך סגנונות מפה לכל אחת מהאפליקציות שמשתמשות במפות Google דרך מסוף Google Cloud, בלי שתצטרכו לבצע שינויים בקוד. סגנונות המפה נשמרים כמזהי מפות בפרויקט 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'
  }
  // Any other styling options.
});

TypeScript

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

שימוש בעיצוב מפה מבוסס-קוד

דרך נוספת להתאמה אישית של עיצוב המפה היא להגדיר את 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 Shipment Tracking Library, תוכלו להתאים אישית את המראה והסגנון של הסמנים שנוספו למפה. כדי לעשות זאת, אתם יכולים לציין התאמות אישיות של סמנים, שאותן ספריית מעקב המשלוחים מחילה לפני הוספת הסמנים למפה ובכל עדכון של הסמנים.

הדרך הפשוטה ביותר להתאים אישית היא לציין אובייקט MarkerOptions שיוחל על כל הסמנים מאותו סוג. השינויים שצוינו באובייקט חלים אחרי יצירת כל סמן, ומחליפים את כל אפשרויות ברירת המחדל.

אפשרות מתקדמת יותר היא לציין פונקציית התאמה אישית. פונקציות התאמה אישית מאפשרות לעצב את הסמנים על סמך נתונים, וגם להוסיף אינטראקטיביות לסמנים, כמו טיפול בקליקים. באופן ספציפי, המעקב אחרי משלוחים מעביר נתונים לפונקציית ההתאמה האישית לגבי סוג האובייקט שהסמן מייצג: רכב או יעד. כך ניתן לשנות את עיצוב הסמנים בהתאם למצב הנוכחי של רכיב הסמן עצמו. לדוגמה, מספר העצירות המתוכננות שנותרו עד ליעד. אפשר אפילו להתנגד לנתונים ממקורות מחוץ ל-Feet Engine ולעצב את הסמן על סמך המידע הזה.

הספרייה 'מעקב אחר משלוחים' מספקת את הפרמטרים הבאים להתאמה אישית ב-FleetEngineShipmentLocationProviderOptions:

שינוי הסגנון של הסמנים באמצעות MarkerOptions

הדוגמה הבאה ממחישה איך להגדיר את הסגנון של סמן של רכב עם אובייקט MarkerOptions. השתמש בדפוס זה כדי להתאים אישית את הסגנון של כל סמן באמצעות אחת מההתאמות האישיות של הסמנים שפורטו למעלה.

JavaScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

TypeScript

deliveryVehicleMarkerCustomization = {
  cursor: 'grab'
};

שינוי הסגנון של הסמנים באמצעות פונקציות של התאמה אישית

הדוגמה הבאה מציגה איך להגדיר את הסגנון של הסמן של הרכב. השתמש בתבנית זו כדי להתאים אישית את הסגנון של סמן באמצעות כל אחד מהפרמטרים להתאמה אישית של סמנים הרשומים למעלה.

JavaScript

deliveryVehicleMarkerCustomization =
  (params) => {
    var stopsLeft = params.taskTrackingInfo.remainingStopCount;
    params.marker.setLabel(`${stopsLeft}`);
  };

TypeScript

deliveryVehicleMarkerCustomization =
  (params: ShipmentMarkerCustomizationFunctionParams) => {
    const stopsLeft = params.taskTrackingInfo.remainingStopCount;
    params.marker.setLabel(`${stopsLeft}`);
  };

הוספת טיפול בקליקים לסמנים

הדוגמה הבאה מראה איך להוסיף טיפול בקליקים לסמן של רכב. עקוב אחר הדפוס הזה כדי להוסיף טיפול בקליקים לכל סמן באמצעות אחד מהפרמטרים להתאמה אישית של סמנים הרשומים למעלה.

JavaScript

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

TypeScript

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

שימוש בהתאמות אישיות של קווים פוליגוניים

בספריית המעקב אחרי משלוחים אפשר גם להתאים אישית את העיצוב והסגנון של מסלול המשלוח במפה. הספרייה יוצרת אובייקט google.maps.Polyline לכל זוג קואורדינטות בנתיב הפעיל או הנותר של המשלוח. ניתן לעצב את האובייקטים Polyline על ידי ציון התאמות אישיות של קו פוליגוני. הספרייה מחילה את ההתאמות האישיות האלה בשני מצבים: לפני הוספת האובייקטים למפה, וכשהנתונים שבהם נעשה שימוש באובייקטים השתנו.

בדומה להתאמה אישית של סמנים, אפשר לציין קבוצה של PolylineOptions שתחול על כל האובייקטים התואמים מסוג Polyline כאשר הם נוצרים או מעודכנים.

באופן דומה, אפשר לציין פונקציית התאמה אישית. פונקציות של התאמה אישית מאפשרות לעצב את האובייקטים באופן אינדיבידואלי על סמך נתונים שנשלחים על ידי Fleet Engine. הפונקציה יכולה לשנות את הסגנון של כל אובייקט בהתאם למצב הנוכחי של המשלוח. לדוגמה, צבע האובייקט Polyline בגוון עמוק יותר, או הפיכתו לעבה יותר כשהרכב נע לאט יותר. אפשר אפילו להצטרף נגד ממקורות מחוץ ל-Feet Engine ולעצב את האובייקט Polyline על סמך המידע הזה.

אפשר לציין את ההתאמות האישיות באמצעות הפרמטרים שצוינו ב-FleetEngineShipmentLocationProviderOptions. ניתן לך להגדיר התאמות למצבים שונים של נתיב הנסיעה – שכבר נסעת, נסעה או לא נסעת עדיין. הפרמטרים הם:

שינוי העיצוב של 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.taskTrackingInfo.remainingDrivingDistanceMeters;
    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: ShipmentPolylineCustomizationFunctionParams) => {
    const distance = params.taskTrackingInfo.remainingDrivingDistanceMeters;
    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});

locationProvider.addListener('update', e => {
  const stopsCount =
      e.taskTrackingInfo.remainingStopCount;
  infoWindow.setContent(
      `Your vehicle is ${stopsCount} stops away.`);

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

locationProvider.addListener('update', (e: google.maps.journeySharing.FleetEngineShipmentLocationProviderUpdateEvent) => {
  const stopsCount =
      e.taskTrackingInfo.remainingStopCount;
  infoWindow.setContent(
      `Your vehicle is ${stopsCount} stops away.`);

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

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

locationProvider.addListener('update', (e: google.maps.journeySharing.FleetEngineShipmentLocationProviderUpdateEvent) => {
  const stopsCount =
      e.taskTrackingInfo.remainingStopCount;
  infoWindow.setContent(
      `Your vehicle is ${stopsCount} stops away.`);

  // 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 כדי להחליף מפה קיימת שכוללת סמנים או התאמות אישיות אחרות, בלי לאבד את ההתאמות האישיות.

לדוגמה, נניח שיש לכם דף אינטרנט עם ישות 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. מוסיפים את ספריית המיקומים לטוען ה-API.

בדוגמה הבאה אפשר לראות את השינויים שצריך לבצע:

<!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.
  locationProvider = new google.maps.journeySharing.FleetEngineShipmentLocationProvider({
    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
  });

  locationProvider.trackingId = TRACKING_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.
    -->
    <script defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=journeySharing">
    </script>
  </body>
</html>

אם יש לכם חבילה שבמעקב עם המזהה שצוין ליד אולורו, היא תוצג עכשיו במפה.