שיטות מומלצות לשימוש במפות בתלת-ממד

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

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

שיקולי ביצועים

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

טעינת המפה

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

  • טעינת API: כדי לטעון את Maps JavaScript API בטעינת הדף הראשונית, צריך להשתמש בטעינה דינמית אסינכרונית של מפות תלת-ממדיות.
  • ספריות: טוענים ספריות באופן פרוגרמטי לפי הצורך, למשל google.maps.importLibrary("maps3d"). לחלופין, אם אתם משתמשים ברכיבי אינטרנט כמו <gmp-map-3d> ישירות בדף ה-HTML עם טעינה ישירה של סקריפט, הספריות ייטענו אוטומטית בזמן המתאים.
  • ניהול רכיבי מפת הבסיס: אפשר להשתמש ב-mapId מותאם אישית כדי לסנן נקודות עניין במפת הבסיס (במצב HYBRID) ולשלוט בצפיפות שלהן, במיוחד אם לאפליקציה יש קבוצה משלה של רכיבים מותאמים אישית כמו סמנים או קווים. כך נמנע עומס ויזואלי וחפיפה פוטנציאלית. אפשר גם להשבית תכונות של משבצות וקטוריות של מפת בסיס, כמו נקודות עניין, קווים של כבישים, שמות של כבישים ושמות של רחובות (במצב SATELLITE).
  • אירועים: כדי לבנות את הלוגיקה הבאה, כמו טעינת סמנים או הנפשת המצלמה, צריך להאזין לאירועים gmp-steadystate או gmp-error.
רצף טעינת המפה
רקע של בד הציור > משבצות מצומצמות > רשת טופוגרפית > רשת פני השטח (לדוגמה: בניינים) > נקודות עניין ותוויות של כבישים, רכיבים מותאמים אישית שנפרסים במקביל (סמנים, מודלים תלת-ממדיים וכו')
  • אינטראקציית משתמש: צריך להמתין לאירוע gmp-steadystate לפני שמבצעים שינויים בתוכן של המפה. אם משתמש מתחיל ליצור אינטראקציה (הזזה, שינוי מרחק התצוגה) עם המפה לפני האירוע הראשוני gmp-steadystate, האירוע יופעל רק אחרי שהמשתמש יפסיק ליצור אינטראקציה. כדי להימנע מהצגה או מעדכון של תוכן שכבת-על (כמו סמנים או מצולעים) בזמן שהמשתמש מזיז את המפה או משנה את רמת הזום, צריך להאזין לאירועים gmp-centerchange,‏ gmp-headingchange,‏ gmp-rangechange,‏ gmp-rollchange ו-gmp-tiltchange.

  • משתמשים ב-requestAnimationFrame() (rAF) לעדכונים רציפים ומפרידים באופן מוחלט בין חישובים אינטנסיביים לבין קריאות לציור.

    • שימוש ב-rAF: מסנכרן עדכונים עם קצב הפריימים של הדפדפן כדי ליצור אנימציה חלקה של 60FPS ולצמצם את צריכת החשמל.
    • לא כדאי לבצע עבודות שדורשות הרבה משאבים: אל תבצעו משימות כבדות שלא קשורות לציור במהלך העדכון הסופי.
    • לוגיקה נפרדת: מבצעים את כל הלוגיקה האינטנסיבית לפני קריאות עדכון מינימליות של רכיבי אינטרנט בתוך לולאת rAF.
  • הגדרות ראשוניות של הסצנה: <gmp-map-3d> הגדרות המצלמה, כמו הטיה, ישפיעו על מהירות הטעינה. ככל שמבצעים זום או הטיה של הסצנה, כך יוצגו פוליגונים מפורטים יותר שצריך לטעון. רמת הפירוט תלויה גם במיקום (לדוגמה: עיר עם הרבה בניינים לעומת אזור כפרי עם מאפיינים טבעיים בלבד).

    • עדיפות לתצוגות עם פחות זום (גובה רב), תצוגות נמוכות או תצוגות ללא הטיה.
    • מוסיפים bounds (sample) למפה כדי שהמשתמשים יתמקדו באזור מסוים וקטעי המפה ייטענו במלואם.
  • הנפשה של טעינה מראש: למרות ש-<gmp-map-3d> נטען מהר מאוד, יכול להיות שיעבור זמן עד שהוא יוצג ברזולוציה מלאה למשתמשים עם מכשירים ברמת כניסה (GPU נמוך) או עם רוחב פס נמוך (4G איטי). במקרה כזה, אפשר ליצור טעינה מראש עם תמונה, אנימציה או טקסט, בזמן שהסצנה התלת-ממדית נטענת ברקע. אפשר לראות למטה את האירוע המרכזי שבו צריך להשתמש:

דוגמה לטעינה מראש
דוגמה לטרום-טעינה
// create the map in the background and wait for gmp-steadystate event
async function initMap() {
    await google.maps.importLibrary("maps3d");
    const map = document.querySelector('gmp-map-3d');
    const div = document.querySelector('div'); // preloader "
    map.addEventListener('gmp-steadystate', ({isSteady}) => {
        if (isSteady) {
            div.style.display = 'none';
        }
    });
}
initMap();
  • מפה דו-ממדית:
    • אפשר להציג למשתמשים האלה מפה דו-ממדית חלופית (לוויין) שכוללת את הנתונים הגיאוגרפיים שלכם, כמו סמנים.
דוגמה למפת לוויין
  • לחלופין, אפשר להציג למשתמשים מפה סטטית דו-ממדית משלימה במצב לוויין כדי שיוכלו לראות את המקום בזמן הטעינה.

ביצועים וניהול של רכיבים חזותיים

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

סמנים

דוגמה לטעינת סמן
תרחיש לדוגמה: 150-300ms לטעינת 300 סמנים עם 41 גליפים שונים של סמני SVG (במחשב נייד מודרני: macOS M3 Pro, ‏ Chrome)
  • הבחירה האופטימלית להתאמה אישית:
    • PinElement: לשינויים בסיסיים בסמן (צבע, קנה מידה, גבול, גליף טקסט), משתמשים באלמנט <gmp-pin> או במחלקה PinElement. זו השיטה הכי יעילה להתאמה אישית.
    • שימוש מתון בסמני HTMLImageElement או SVGElement: אפשר להשתמש בהם להתאמה אישית נוספת, כמו הוספת שקיפות או הוספת תמונה כמו סמל ל-SVGElement (נדרש קידוד base64). הם יעברו רסטריזציה בזמן הטעינה, ויהיו כרוכים בתקורת ביצועים. צריך לעטוף את HTMLImageElement ו-SVGElement ברכיב <template> לפני שמקצים אותם למשבצת ברירת המחדל של Marker3DElement.
    • בשלב הזה אי אפשר להוסיף HTML או CSS פשוטים.
  • ניהול התנהגות ההתנגשות: כדאי להשתמש במאפיין collisionBehavior של הסמן. אם יש סמנים קריטיים שחייבים להיות גלויים תמיד, צריך להגדיר את ההתנהגות בהתאם. לסמנים פחות חשובים, כדאי לאפשר להם להיעלם כדי לשמור על חוויית מפה נקייה יותר, במיוחד ברמות זום גבוהות.
  • רק נקודות עניין קריטיות: צריך להשתמש ב-drawsWhenOccluded (או להגדיר את המאפיין באופן פרוגרמטי) רק לסמנים שחייבים להיות גלויים דרך בניינים או פני שטח (למשל, יעד הצלה, קו שירות קבור או הדמות של משתמש).
  • בדיקת הסתרה: מכיוון שהמפה היא תלת-ממדית, יכול להיות שבניינים או פני השטח יסתירו את הסמנים. כדי לוודא שנקודות עניין חשובות יישארו גלויות, כדאי לבדוק זוויות מצלמה שונות וגבהים שונים של סמנים, או להטמיע לוגיקה להתאמת הנראות והגובה כשהן מוסתרות.
  • שימוש בגובה: במפות תלת-ממד, הסמנים צריכים להשתמש במיקום עם ערך גובה. לסמנים שמשויכים לפני שטח או למבנים, צריך להשתמש ב-altitudeMode: 'RELATIVE_TO_GROUND',‏ 'RELATIVE_TO_MESH' או בהגדרות דומות כדי לוודא שהסמן מעוגן בצורה נכונה כשהמפה מוטה או מסובבת.

פוליגונים וקווי פוליגון

דוגמה לטעינת פוליגון
תרחיש לדוגמה: טעינה של 1,000 מצולעים אורכת 100-150 אלפיות השנייה (מחשב נייד מודרני: macOS M3 Pro,‏ Chrome)
  • פשט גיאומטריה: לפני הרינדור, מפעילים אלגוריתם פישוט על נתוני הנתיב. כך מצמצמים את מספר הקודקודים תוך שמירה על הצורה הכללית, ומשפרים באופן משמעותי את מהירות הרינדור, במיוחד כשמדובר בגבולות או בנתיבים מורכבים.
  • הפחתה לפי רמת הזום: במערכי נתונים גדולים מאוד, כדאי לטעון גיאומטריה עם רמת פירוט גבוהה רק כשהמשתמש מבצע זום לאזור. ברמת זום נמוכה, צריך רק גרסה פשוטה מאוד של הקו הפוליגוני או הפוליגון.
  • חישוב מראש של פוליגונים תלת-ממדיים: אם הפוליגונים תלת-ממדיים (extruded: true), נתוני הנתיב מגדירים נפח תלת-ממדי (רשת). העיבוד של מצולעים מורכבים עם הרבה קודקודים דורש הרבה משאבי מחשוב. חשוב לוודא שנתוני המקור של הפוליגונים פשוטים ככל האפשר.
  • בדיקת הביצועים של קו פוליגוני ופוליגון: כשמוסיפים קווים פוליגוניים או פוליגונים רבים או מורכבים, במיוחד כשמבצעים אקסטרוזיה לתלת-ממד, חשוב לוודא שהם לא גורמים לירידה בקצב הפריימים. אם צריך, מגבילים את מספר הקודקודים או משתמשים באלגוריתמים של פישוט.
  • כשמעדכנים צורה, משנים את כל המערך של הנתיב בפעולה אחת, במקום להשתמש בלולאה ולשנות רכיבים בודדים. פעולת הקצאה אחת (למשל, polyline.path = newPathArray;) יעילה הרבה יותר מכמה עדכונים איטרטיביים.
  • הימנעו משימוש בקווי פוליגון תלת-ממדיים (במידת האפשר): קווי פוליגון יכולים להשתמש בערך גובה כדי להיות ממוקמים במרחב תלת-ממדי, אבל יצירת קו פוליגון תלת-ממדי (למשל, אם מגדירים לו רוחב קו וטווח גובה גדול) עלולה להיות עתירת משאבים מבחינה גרפית. כדי לשפר את הביצועים, כדאי להשתמש בקווי פוליגון דו-ממדיים על הקרקע (RELATIVE_TO_GROUND) או ברוחב קו מינימלי.
  • מומלץ להשתמש ב-drawsOccludedSegments רק לרכיבי ניתוב קריטיים. לצורות רקע או צורות הקשריות, מאפשרים להן להיות מוסתרות באופן טבעי על ידי הגיאומטריה התלת-ממדית של המפה. הצגה של גיאומטריה מוסתרת לא קריטית מוסיפה מורכבות מיותרת לעיבוד.

מודלים תלת-ממדיים

העיבוד של מודל תלת-ממד מסוג ‎ .glb והאינטראקטיביות שלו, כמו אירוע gmp-click, מהירים מאוד ב-<gmp-map-3d>.

דוגמה לטעינת מודל תלת-ממדי
תרחיש לדוגמה: לוקח בערך 2 שניות להציג 1,000 מקרים של מודל תלת-ממדי קל (200KB) שנע לאורך נתיב. (מחשב נייד מודרני: macOS M3 Pro, ‏ Chrome)
  • צמצום גודל הקובץ באמצעות דחיסה: כדי להבטיח טעינה מהירה, במיוחד ברשתות סלולריות, חשוב לשמור על קבצים מורכבים של מודלים מסוג ‎ .glb בגודל של פחות מ-5MB (רצוי פחות). השיטה העיקרית להשגת המטרה הזו היא להחיל דחיסת Draco על נתוני הרשת בקובצי ה-‎.glb, מה שיכול להקטין באופן משמעותי את גודל הקובץ (לעתים קרובות ביותר מ-50%) עם אובדן מינימלי של איכות חזותית.
  • מיקום מרכז המודל: מוודאים שתוכנת המודלים התלת-ממדיים מייצאת את המודל עם המיקום שלו (נקודה 0, 0, 0) במרכז הבסיס של המודל. כך קל יותר למקם ולסובב את המודל במפה, ולוודא שהוא מעוגן בצורה נכונה לקואורדינטות Lat ו-Lng.
  • ניהול CORS: אם קובצי המודל מתארחים בדומיין או ב-CDN שונים מאלה של אפליקציית האינטרנט, צריך להגדיר את שרת האירוח כך שיכלול את הכותרות הנדרשות של שיתוף משאבים בין מקורות (CORS) (לדוגמה, Access-Control-Allow-Origin: *‎). אחרת, המפה לא תוכל לטעון את המודל.