מצלמה ותצוגה

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

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

דוגמאות קוד

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

מבוא

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

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

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

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

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

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

מיקום המצלמה

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

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

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

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

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

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

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

אם הערך של 0 הוא 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 מגדילה את רוחב העולם במסך פי 2. לכן, ברמת הזום N, רוחב העולם הוא בערך 256 * 2N dp. לדוגמה, ברמת זום 2, רוחב העולם כולו הוא כ-1,024dp.

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

  • 1: עולם
  • 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 מעלות, והמזרח הוא 'למעלה'.

הגדרת גבולות

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

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

      

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

תרשים שבו מוצגת טווחי LatLng של מצלמה גדולים יותר מחלון התצוגה.

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

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

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

תרשים שבו מוצגת טווחי LatLng של מצלמה קטנים יותר מחלון התצוגה.

עדכון תצוגת המצלמה

כדי להוסיף למפה 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));