מצלמה ותצוגה

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

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

דוגמאות קוד

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

מבוא

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

הגדרת גבולות

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

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

הערה: מומלץ להשתמש בשיטה הפשוטה יותר 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));