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

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

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

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

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

טעינת המפה

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

  • טעינת API: משתמשים בטעינה דינמית אסינכרונית של מפות תלת-ממדיות כדי לטעון את Maps JavaScript API בטעינת הדף הראשונית.
  • ספריות: טוענים ספריות באופן פרוגרמטי במקומות שבהם הן נדרשות, כמו google.maps.importLibrary("maps3d"). לחלופין, אם אתם משתמשים ברכיבי אינטרנט כמו <gmp-map-3d> ישירות בדף ה-HTML עם טעינת סקריפט ישירה, הספריות ייטענו באופן אוטומטי בזמן המתאים.
  • ניהול התכונות של מפת הבסיס: אפשר להשתמש במזהה מפה מותאם אישית כדי לסנן נקודות עניין במפת הבסיס (מצב 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> הגדרות המצלמה, כמו הטיה, ישפיעו על מהירות הטעינה. ככל שמגדילים את התצוגה או מטים את הסצנה, כך מוצגים יותר פוליגונים מפורטים וצריך לטעון אותם. רמת הפירוט תלויה גם במיקום (למשל: עיר עם הרבה בניינים לעומת אזור כפרי עם מאפיינים טבעיים בלבד).

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

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

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

סמנים

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

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

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

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

העיבוד והאינטראקטיביות של מודל תלת-ממדי בפורמט ‎ .glb, כמו אירוע מסוג קליק של gmp, מהירים מאוד ב-<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: *‎). אחרת, המפה לא תוכל לטעון את המודל.