אפשר להטות ולסובב את המפות ב-SDK של מפות ל-Android באמצעות תנועות פשוטות, וכך המשתמשים יכולים להתאים את המפה לכיוון שמתאים להם. בכל רמת זום, אפשר להזיז את המפה או לשנות את נקודת המבט שלה עם זמן אחזור קצר מאוד, בזכות שטח האחסון הקטן יותר של המשבצות של המפה המבוססת על וקטורים.
דוגמאות קוד
המאגר ApiDemos ב-GitHub כולל דוגמה שממחישה את תכונות המצלמה:
- CameraDemoActivity – Kotlin: שינוי מיקום המצלמה
- CameraDemoActivity – Java: שינוי מיקום המצלמה
מבוא
בדומה למפות 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 הוא המיקום הנוכחי במפה. המפה שנוצרה מוצגת מתחת.
בתמונות הבאות, זווית הצפייה היא 45 מעלות. שימו לב שהמצלמה נעה למחצית קשת בין מיקום ישר מעל הראש (0 מעלות) לבין מיקום על הקרקע (90 מעלות), למיקום 3. המצלמה עדיין מכוונת לנקודת המרכז של המפה, אבל האזור שמיוצג על ידי הקו במיקום 4 גלוי עכשיו.
המפה בצילום המסך הזה עדיין ממוקמת באותה נקודה כמו במפה המקורית, אבל תכונות נוספות הופיעו בחלק העליון של המפה. ככל שהזווית גדלה מעבר ל-45 מעלות, האובייקטים שבין המצלמה לבין מיקום המפה נראים גדולים יותר באופן יחסי, ואילו האובייקטים שמעבר למיקום המפה נראים קטנים יותר באופן יחסי, וכך נוצר אפקט תלת-ממדי.
שינוי מרחק התצוגה
רמת הזום של המצלמה קובעת את קנה המידה של המפה. ברמות זום גדולות יותר אפשר לראות יותר פרטים במסך, וברמות זום קטנות יותר אפשר לראות יותר מהעולם במסך. ברמת הזום 0, קנה המידה של המפה הוא כזה שהרוחב של העולם כולו הוא כ-256dp (פיקסלים שאינם תלויים בדחיסות).
הגדלת רמת הזום ב-1 מגדילה את רוחב העולם במסך פי 2. לכן, ברמת הזום N, הרוחב של העולם הוא בערך 256 * 2Ndp. לדוגמה, ברמת זום 2, העולם כולו הוא בערך 1,024dp רוחב.
רמת הזום לא חייבת להיות מספר שלם. טווח רמות הזום המותרות במפה תלוי בכמה גורמים, כולל היעד, סוג המפה וגודל המסך. כל מספר מחוץ לטווח יומיר לערך החוקי הקרוב ביותר, שיכול להיות רמת הזום המינימלית או רמת הזום המקסימלית. ברשימה הבאה מפורטת רמת הפירוט המשוערת שאפשר לראות בכל רמת זום:
- 1: עולם
- 5: יבשת
- 10: עיר
- 15: רחובות
- 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);
התרשים הבא מדגים תרחיש שבו יעד המצלמה מוגבל לאזור שהוא מעט גדול יותר מאזור התצוגה. המשתמש יכול לגלול ולזוז, בתנאי שהמטרה של המצלמה נשארת בתוך האזור המוגדר. הצלב מייצג את יעד המצלמה:
המפה תמיד ממלאת את אזור התצוגה, גם אם כתוצאה מכך מוצגים באזור התצוגה אזורים מחוץ לגבולות שהוגדרו. לדוגמה, אם ממקמים את יעד המצלמה בפינה של האזור המוגדר, האזור שמעבר לפינה גלוי באזור התצוגה, אבל המשתמשים לא יכולים לגלול לאזור הזה. התרשים הבא מדגים את התרחיש הזה. הצלב מייצג את היעד של המצלמה:
בתרשים הבא, לטווח המצלמה יש גבולות מוגבלים מאוד, ולכן למשתמש יש מעט מאוד אפשרויות לגלול במפה או לשנות את זווית התצוגה שלה. הצלב מייצג את יעד המצלמה:
עדכון תצוגת המצלמה
כדי להוסיף 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));