מצלמה ותצוגה

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

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

דוגמאות קוד

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

מבוא

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

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

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

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

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

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

מיקום המצלמה

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

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

טירגוט (מיקום)

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

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

כיוון (כיוון)

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

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

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

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

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

הזזת המצלמה

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

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

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

גבולות

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

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

      

עומס יתר ב-method 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() '. באנימציה, ה-methods נקראות בנסיבות הבאות:
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));