מצלמה ותצוגה

בחירת פלטפורמה: Android iOS JavaScript

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

דוגמאות קוד

במאגר ApiDemos ב-GitHub יש דוגמה שמציגה את התכונות של המצלמה:

מבוא

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

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

‫Maps SDK ל-Android מאפשר לשנות את נקודת המבט של המשתמש במפה על ידי שינוי המצלמה של המפה.

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

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

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

מיקום המצלמה

תצוגת המפה מוגדרת כמצלמה שמכוונת כלפי מטה אל מישור שטוח. המיקום של המצלמה (ולכן גם של רינדור המפה) מוגדר על ידי המאפיינים הבאים: target (מיקום לפי קו רוחב/קו אורך),‏ bearing,‏ tilt ו-zoom.

תרשים של מאפייני המצלמה

יעד (מיקום)

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

קו הרוחב יכול להיות בין ‎-85 ל-85 מעלות, כולל. ערכים שגבוהים או נמוכים מהטווח הזה יוצמדו לערך הקרוב ביותר בטווח. לדוגמה, אם תציינו קו רוחב של 100, הערך יוגדר כ-85. קו האורך נע בין ‎-180 ל-180 מעלות, כולל. ערכים שגבוהים מהטווח הזה או נמוכים ממנו יעברו המרה כך שייכללו בטווח (‎-180, 180). לדוגמה, הערכים 480, ‏ 840 ו-1200 יעוגלו ל-120 מעלות.

כיוון

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

זווית של 0 מעלות מציינת שהחלק העליון של המפה מצביע על הצפון האמיתי. ערך הכיוון 90 מציין שהחלק העליון של המפה מצביע מזרחה (90 מעלות במצפן). ערך של 180 מציין שחלקו העליון של המפה מצביע דרומה.

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

הטיה (זווית צפייה)

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

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

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

בתמונות שלמטה, זווית הצפייה היא 45 מעלות. שימו לב שהמצלמה זזה לאורך חצי קשת בין נקודה ישרה מעל הראש (0 מעלות) לבין הקרקע (90 מעלות), למיקום 3. המצלמה עדיין מכוונת לנקודת המרכז של המפה, אבל האזור שמיוצג על ידי הקו במיקום 4 גלוי עכשיו.

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

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

שינוי מרחק התצוגה

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

הגדלת רמת הזום ב-1 מכפילה את רוחב העולם במסך. לכן, ברמת זום N, הרוחב של העולם הוא בערך ‎256 * 2N dp. לדוגמה, ברמת זום 2, הרוחב של העולם כולו הוא בערך 1,024dp.

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

  • ‫1: World
  • ‫5: מסת יבשה/יבשת
  • ‫10: עיר
  • ‫15: רחובות
  • ‫20: בניינים
התמונות הבאות מראות את המראה החזותי של רמות זום שונות:
צילום מסך של מפה ברמת זום 5
מפה ברמת זום 5.
צילום מסך של מפה ברמת זום של 15
מפה ברמת זום 15.
צילום מסך של מפה ברמת זום 20
מפה ברמת זום 20.

הזזת המצלמה

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

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

כדי לשנות את המיקום של המצלמה, צריך לציין לאן רוצים להזיז את המצלמה באמצעות CameraUpdate. ‫Maps API מאפשר ליצור סוגים רבים ושונים של CameraUpdate באמצעות CameraUpdateFactory. אלה האפשרויות הזמינות:

שינוי רמת הזום והגדרת זום מינימלי ומקסימלי

CameraUpdateFactory.zoomIn() ו-CameraUpdateFactory.zoomOut() נותנים לכם CameraUpdate שמשנה את רמת הזום ב-1.0, תוך שמירה על כל שאר המאפיינים ללא שינוי.

CameraUpdateFactory.zoomTo(float) נותן לכם CameraUpdate שמשנה את רמת הזום לערך שצוין, בלי לשנות את כל שאר המאפיינים.

CameraUpdateFactory.zoomBy(float) ו-CameraUpdateFactory.zoomBy(float, Point) נותנים את הערך CameraUpdate שמגדיל (או מקטין, אם הערך שלילי) את רמת הזום בערך שצוין. האפשרות השנייה מקבעת את הנקודה שצוינה במסך כך שהיא תישאר באותו מיקום (קו רוחב/קו אורך), ולכן יכול להיות שהיא תשנה את המיקום של המצלמה כדי להשיג את זה.

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

Kotlin

private lateinit var map: GoogleMap

    map.setMinZoomPreference(6.0f)
    map.setMaxZoomPreference(14.0f)

      

Java

private GoogleMap map;
    map.setMinZoomPreference(6.0f);
    map.setMaxZoomPreference(14.0f);

      

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

שינוי המיקום של המצלמה

יש שתי שיטות נוחות לשינויים נפוצים במיקום. ‫CameraUpdateFactory.newLatLng(LatLng) נותן לכם CameraUpdate שמשנה את קו הרוחב וקו האורך של המצלמה, תוך שמירה על כל שאר המאפיינים. ‫CameraUpdateFactory.newLatLngZoom(LatLng, float) נותן לכם CameraUpdate שמשנה את קו הרוחב, קו האורך והזום של המצלמה, תוך שמירה על כל שאר המאפיינים.

כדי לשנות את מיקום המצלמה בצורה הכי גמישה, משתמשים ב-CameraUpdateFactory.newCameraPosition(CameraPosition). הפקודה הזו יוצרת CameraUpdate שמזיז את המצלמה למיקום שצוין. אפשר לקבל CameraPosition ישירות באמצעות new CameraPosition() או באמצעות CameraPosition.Builder באמצעות new CameraPosition.Builder().

הזזה אופקית (גלילה)

CameraUpdateFactory.scrollBy(float, float) נותן לכם CameraUpdate שמשנה את קו הרוחב וקו האורך של המצלמה כך שהמפה תזוז במספר הפיקסלים שצוין. ערך חיובי של x גורם למצלמה לנוע ימינה, כך שהמפה נראית כאילו היא זזה שמאלה. ערך חיובי של y גורם למצלמה לנוע למטה, כך שנראה שהמפה נעה למעלה. לעומת זאת, ערכי x שליליים גורמים למצלמה לנוע שמאלה, כך שנראה שהמפה זזה ימינה, וערכי y שליליים גורמים למצלמה לנוע למעלה. הגלילה היא יחסית לאוריינטציה הנוכחית של המצלמה. לדוגמה, אם הכיוון של המצלמה הוא 90 מעלות, אז מזרח הוא 'למעלה'.

הגדרת גבולות

הגדרת גבולות המפה

לפעמים כדאי להזיז את המצלמה כך שאזור העניין כולו יהיה גלוי ברמת הזום הגדולה ביותר האפשרית. לדוגמה, אם אתם מציגים את כל תחנות הדלק ברדיוס של 8 ק"מ ממיקום המשתמש, יכול להיות שתרצו להזיז את המצלמה כך שכולן יוצגו על המסך. כדי לעשות את זה, קודם צריך לחשב את LatLngBounds שרוצים שיוצג במסך. אחר כך אפשר להשתמש ב-CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding) כדי לקבל CameraUpdate שמשנה את מיקום המצלמה כך ש-LatLngBounds הנתון יתאים כולו למפה, תוך התחשבות בשוליים (בפיקסלים) שצוינו. הערך המוחזר CameraUpdate מבטיח שהמרווח (בפיקסלים) בין הגבולות שצוינו לקצה המפה יהיה לפחות כמו הריווח שצוין. שימו לב שגם הטיית המפה וגם הכיוון שלה יהיו 0.

Kotlin

val australiaBounds = LatLngBounds(
    LatLng((-44.0), 113.0),  // SW bounds
    LatLng((-10.0), 154.0) // NE bounds
)
map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))

      

Java

LatLngBounds australiaBounds = new LatLngBounds(
    new LatLng(-44, 113), // SW bounds
    new LatLng(-10, 154)  // NE bounds
);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));

      

מרכוז המפה באזור מסוים

במקרים מסוימים, יכול להיות שתרצו למרכז את המצלמה בתוך גבולות מסוימים במקום לכלול את הגבולות הקיצוניים. לדוגמה, כדי למרכז את המצלמה על מדינה מסוימת תוך שמירה על זום קבוע. במקרה כזה, אפשר להשתמש בשיטה דומה, ליצור LatLngBounds ולהשתמש ב-CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom) עם LatLngBounds.getCenter() method. השיטה getCenter()‎ תחזיר את המרכז הגיאוגרפי של LatLngBounds.

Kotlin

val australiaBounds = LatLngBounds(
    LatLng((-44.0), 113.0),  // SW bounds
    LatLng((-10.0), 154.0) // NE bounds
)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))

      

Java

LatLngBounds australiaBounds = new LatLngBounds(
    new LatLng(-44, 113), // SW bounds
    new LatLng(-10, 154)  // NE bounds
);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));

      

עומס יתר של השיטה, newLatLngBounds(boundary, width, height, padding), מאפשר לציין רוחב וגובה בפיקסלים למלבן, במטרה שהם יתאימו לממדים של המפה. המיקום של המלבן נקבע כך שהמרכז שלו יהיה זהה למרכז של אזור התצוגה במפה (כך שאם המידות שצוינו זהות למידות של אזור התצוגה במפה, המלבן יחפוף לאזור התצוגה במפה). הערך שמוחזר CameraUpdate יזיז את המצלמה כך שהערכים שצוינו LatLngBounds ימוקמו במרכז המסך בתוך המלבן שצוין, ברמת הזום הגבוהה ביותר האפשרית, תוך התחשבות בשוליים הנדרשים.

הערה: כדאי להשתמש בשיטה הפשוטה יותר newLatLngBounds(boundary, padding) כדי ליצור CameraUpdate רק אם מתכוונים להשתמש בו כדי להזיז את המצלמה אחרי שהמפה עברה פריסה. במהלך הפריסה, ה-API מחשב את גבולות התצוגה של המפה שנדרשים כדי להקרין בצורה נכונה את התיבה התוחמת. לעומת זאת, אפשר להשתמש ב-CameraUpdate שמוחזר על ידי השיטה המורכבת יותר CameraUpdate בכל שלב, גם לפני שהמפה עברה פריסה, כי ה-API מחשב את גבולות התצוגה מהארגומנטים שמעבירים.newLatLngBounds(boundary, width, height, padding)

הגבלת ההזזה של המשתמש לאזור מסוים

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

Kotlin

// Create a LatLngBounds that includes the city of Adelaide in Australia.
val adelaideBounds = LatLngBounds(
    LatLng(-35.0, 138.58),  // SW bounds
    LatLng(-34.9, 138.61) // NE bounds
)

// Constrain the camera target to the Adelaide bounds.
map.setLatLngBoundsForCameraTarget(adelaideBounds)

      

Java

// Create a LatLngBounds that includes the city of Adelaide in Australia.
LatLngBounds adelaideBounds = new LatLngBounds(
    new LatLng(-35.0, 138.58), // SW bounds
    new LatLng(-34.9, 138.61)  // NE bounds
);

// Constrain the camera target to the Adelaide bounds.
map.setLatLngBoundsForCameraTarget(adelaideBounds);

      

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

תרשים שמציג LatLngBounds של מצלמה שגדול יותר מאזור התצוגה.

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

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

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

תרשים שמציג LatLngBounds של מצלמה שקטן יותר מאזור התצוגה.

עדכון השידור מהמצלמה

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

כדי לשפר את חוויית המשתמש, במיוחד כשמדובר בתנועות קצרות, אפשר להוסיף אנימציה לשינוי. כדי לעשות את זה במקום להתקשר GoogleMap.moveCamera להתקשר GoogleMap.animateCamera. המפה תעבור בצורה חלקה למאפיינים החדשים. הצורה המפורטת ביותר של השיטה הזו, GoogleMap.animateCamera(cameraUpdate, duration, callback), כוללת שלושה ארגומנטים:

cameraUpdate
CameraUpdate שמתארת לאן להזיז את המצלמה.
callback
אובייקט שמטמיע את GoogleMap.CancellableCallback. הממשק הכללי הזה לטיפול במשימות מגדיר שתי שיטות: `onCancel()` ו-`onFinished()`. לגבי אנימציה, השיטות נקראות בנסיבות הבאות:
onFinish()
מופעל אם האנימציה מסתיימת ללא הפרעה.
onCancel()

מופעל אם האנימציה מופסקת על ידי קריאה ל-stopAnimation() או הפעלה של תנועת מצלמה חדשה.

הבעיה הזו יכולה לקרות גם אם מתקשרים אל GoogleMap.stopAnimation().

duration
משך הזמן הרצוי של האנימציה, באלפיות השנייה, בתור int.

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

Kotlin

val sydney = LatLng(-33.88, 151.21)
val mountainView = LatLng(37.4, -122.1)

// Move the camera instantly to Sydney with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f))

// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomIn())

// Zoom out to zoom level 10, animating with a duration of 2 seconds.
map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null)

// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
val cameraPosition = CameraPosition.Builder()
    .target(mountainView) // Sets the center of the map to Mountain View
    .zoom(17f)            // Sets the zoom
    .bearing(90f)         // Sets the orientation of the camera to east
    .tilt(30f)            // Sets the tilt of the camera to 30 degrees
    .build()              // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))

      

Java

LatLng sydney = new LatLng(-33.88,151.21);
LatLng mountainView = new LatLng(37.4, -122.1);

// Move the camera instantly to Sydney with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15));

// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomIn());

// Zoom out to zoom level 10, animating with a duration of 2 seconds.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
CameraPosition cameraPosition = new CameraPosition.Builder()
    .target(mountainView )      // Sets the center of the map to Mountain View
    .zoom(17)                   // Sets the zoom
    .bearing(90)                // Sets the orientation of the camera to east
    .tilt(30)                   // Sets the tilt of the camera to 30 degrees
    .build();                   // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));