אפשר להטות ולסובב את המפות ב-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 * 2N dp. לדוגמה, ברמת זום 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));