מצלמה ותצוגה

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

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

דוגמאות קוד

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

מבוא

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

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

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

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

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

Zoom

רמת הזום של המצלמה קובעת את קנה המידה של המפה. ברמות זום גדולות יותר, אפשר לראות יותר פרטים במסך, וברמות זום קטנות יותר, אפשר לראות יותר מהעולם במסך. ברמת זום 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 שמוחזר על ידי השיטה המורכבת יותר newLatLngBounds(boundary, width, height, padding) בכל שלב, גם לפני שהמפה עברה פריסה, כי ה-API מחשב את גבולות התצוגה מהארגומנטים שמעבירים.

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

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

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