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

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

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

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

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

טעינת המפה

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

  • טעינת 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();
  • מפה דו-ממדית:
    • אפשר להציג למשתמשים האלה מפה דו-ממדית חלופית (לוויין) שכוללת את הנתונים הגיאוגרפיים שלכם, כמו סמנים.
דוגמה למפת לוויין
  • לחלופין, אפשר להציג למשתמשים מפה סטטית דו-ממדית משלימה במצב SATELLITE כדי שיוכלו לראות את המקום בזמן הטעינה.

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

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

סמנים

דוגמה לטעינת סמן
תרחיש לדוגמה: 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) במרכז הבסיס של המודל. כך קל יותר למקם ולסובב את המודל במפה, ולוודא שהוא מעוגן בצורה נכונה לקואורדינטות של קו הרוחב וקו האורך.
  • ניהול CORS: אם קובצי המודל שלכם מאוחסנים בדומיין או ב-CDN שונים מאלה של אפליקציית האינטרנט שלכם, אתם צריכים להגדיר את שרת האירוח כך שיכלול את הכותרות הנדרשות של שיתוף משאבים בין מקורות (CORS) (לדוגמה, ‫Access-Control-Allow-Origin: *). אחרת, המפה לא יכולה לטעון את המודל.