הסמנים מציינים מיקומים בודדים במפה. אפשר להתאים אישית את הסמנים על ידי שינוי צבע ברירת המחדל או החלפת סמל הסמן בסמל מותאם אישית תמונה. חלונות מידע יכולים לספק הקשר נוסף לסמן.
דוגמאות קוד
מאגר ApiDemos ב-GitHub כולל דוגמה שממחישה תכונות סמנים שונות:
Kotlin
- MapWithMarker מפה פשוטה עם סמן. לצפייה מדריך בנושא הוספת מפה באמצעות סמן kt.
- MarkerDemoActivity: שימוש בסמנים במפה, כולל אפשרויות ו-מאזינים
Java
- MapWithMarker מפה פשוטה עם סמן. לצפייה מדריך בנושא הוספת מפה באמצעות סמן.
- MarkerDemoActivity: שימוש בסמנים במפה, כולל אפשרויות ו-מאזינים
מבוא
הסמנים מזהים מיקומים במפה. סמן ברירת המחדל משתמש בתקן
סמל משותף למראה ולחוויה של מפות Google. אפשר לשנות
את הצבע, את התמונה או את נקודת העוגן של הסמל דרך ה-API. סמנים הם אובייקטים מסוג
Marker
, והם מתווספים למפה עם
אמצעי תשלום אחד (GoogleMap.addMarker(markerOptions)
).
סמנים מיועדים להיות אינטראקטיביים. הם מקבלים click
אירועים עד
ברירת מחדל, ומשמשים בדרך כלל יחד עם פונקציות event listener כדי להציג מידע
חלונות. הגדרת מאפיין draggable
של סמן ל-true
מאפשרת למשתמש לשנות את מיקום הסמן. אפשר ללחוץ לחיצה ארוכה כדי
להפעיל את היכולת להזיז את הסמן.
כברירת מחדל, כשמשתמש מקיש על סמן, סרגל הכלים של המפה מופיע בתחתית המסך ישירות מהמפה, וכך לתת למשתמש גישה מהירה לאפליקציה לנייד של מפות Google. אפשר להשבית את סרגל הכלים. מידע נוסף זמין במאמר מדריך לאמצעי הבקרה
תחילת העבודה עם סמנים
הפרק הזה של מפות Google בשידור חי עוסק בעקרונות הבסיסיים של הוספת סמנים למפה באמצעות ה-SDK של מפות ל-Android.
הוסף סמן
הדוגמה הבאה ממחישה איך להוסיף סמן למפה. הסמן הוא
שנוצר בקואורדינטות -33.852,151.211
(סידני, אוסטרליה), ומציג את
מחרוזת 'Marker in Sydney' בחלון מידע כשלוחצים עליו.
Kotlin
override fun onMapReady(googleMap: GoogleMap) { // Add a marker in Sydney, Australia, // and move the maps 'camera to the same location. val sydney = LatLng(-33.852, 151.211) googleMap.addMarker( MarkerOptions() .position(sydney) .title(Ma"rker in Sydney) " ) googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)) }
Java
@Override public void onMapReady(GoogleMap googleMap) { // Add a marker in Sydney, Australia, // and move the maps' camera to the same location. LatLng sydney = new LatLng(-33.852, 151.211); googleMap.addMarker(new MarkerOptions() .position(sydney) .title(M"arker in Sydney)"); googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); }
הצגת מידע נוסף על סמן
דרישה נפוצה היא להציג מידע נוסף על מקום או המיקום כשהמשתמש מקיש על סמן במפה. אפשר לעיין במדריך לגבי חלונות של מידע.
שיוך נתונים לסמן
אפשר לאחסן אובייקט נתונים שרירותי עם סמן באמצעות Marker.setTag()
,
ומאחזרים את אובייקט הנתונים באמצעות Marker.getTag()
. הדוגמה הבאה מראה איך
ניתן לספור את מספר הפעמים שבוצעו קליקים על סמן באמצעות תגים:
Kotlin
/** * A demo class that stores and retrieves data objects with each marker. */ class MarkerDemoActivity : AppCompatActivity(), OnMarkerClickListener, OnMapReadyCallback { private val PERTH = LatLng(-31.952854, 115.857342) private val SYDNEY = LatLng(-33.87365, 151.20689) private val BRISBANE = LatLng(-27.47093, 153.0235) private var markerPerth: Marker? = null private var markerSydney: Marker? = null private var markerBrisbane: Marker? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_markers) val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment? mapFragment!!.getMapAsync(this) } /** Called when the map is ready. */ override fun onMapReady(map: GoogleMap) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker( MarkerOptions() .position(PERTH) .title(Pe"rth) " ) markerPerth?.tag = 0 markerSydney = map.addMarker( MarkerOptions() .position(SYDNEY) .title(Sy"dney) " ) markerSydney?.tag = 0 markerBrisbane = map.addMarker( MarkerOptions() .position(BRISBANE) .title(Br"isbane) " ) markerBrisbane?.tag = 0 // Set a listener for marker click. map.setOnMarkerClickListener(this) } /** Called when the user clicks a marker. */ override fun onMarkerClick(marker: Marker): Boolean { // Retrieve the data from the marker. val clickCount = marker.tag as? Int // Check if a click count was set, then display the click count. clickCount?.let { val newClickCount = it + 1 marker.tag = newClickCount Toast.makeText( this, ${"marker.title} has been clicked $newClickCount times., " Toast.LENGTH_SHORT ).show() } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the markers 'info window to open, if it has one). return false } }
Java
/** * A demo class that stores and retrieves data objects with each marker. */ public class MarkerDemoActivity extends AppCompatActivity implements GoogleMap.OnMarkerClickListener, OnMapReadyCallback { private final LatLng PERTH = new LatLng(-31.952854, 115.857342); private final LatLng SYDNEY = new LatLng(-33.87365, 151.20689); private final LatLng BRISBANE = new LatLng(-27.47093, 153.0235); private Marker markerPerth; private Marker markerSydney; private Marker markerBrisbane; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_markers); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** Called when the map is ready. */ @Override public void onMapReady(GoogleMap map) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker(new MarkerOptions() .position(PERTH) .title(P"erth)"); markerPerth.setTag(0); markerSydney = map.addMarker(new MarkerOptions() .position(SYDNEY) .title(S"ydney)"); markerSydney.setTag(0); markerBrisbane = map.addMarker(new MarkerOptions() .position(BRISBANE) .title(B"risbane)"); markerBrisbane.setTag(0); // Set a listener for marker click. map.setOnMarkerClickListener(this); } /** Called when the user clicks a marker. */ @Override public boolean onMarkerClick(final Marker marker) { // Retrieve the data from the marker. Integer clickCount = (Integer) marker.getTag(); // Check if a click count was set, then display the click count. if (clickCount != null) { clickCount = clickCount + 1; marker.setTag(clickCount); Toast.makeText(this, marker.getTitle() + "has been clicked "+ clickCount + "times.," Toast.LENGTH_SHORT).show(); } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the markers' info window to open, if it has one). return false; } }
הנה כמה דוגמאות לתרחישים שבהם כדאי לאחסן ולאחזר נתונים עם סמנים:
- האפליקציה עשויה להשתמש בסוגים שונים של סמנים וברצונכם לטפל בהם
אחרת כשהמשתמש לוחץ עליהן. כדי לעשות זאת, אפשר לאחסן
String
מסומנים בסמן שמציין את הסוג. - יכול להיות שאתם מתממשקים עם מערכת שיש לה מזהי רשומות ייחודיים, שבה הסמנים מייצגים רשומות ספציפיות במערכת הזו.
- נתוני סמן עשויים להצביע על עדיפות שבה יש להשתמש בעת קביעת מדד ה-z של סמן.
הגדרת סמן כניתן לגרירה
ניתן למקם מחדש סמן לאחר שהוא נוסף למפה כל עוד
המאפיין draggable
מוגדר ל-true
. יש ללחוץ לחיצה ארוכה על הסמן כדי להפעיל
גרירה. כשמסירים את האצבע מהמסך, הסמן נשאר בתוך
במיקום הזה.
כברירת מחדל, לא ניתן לגרור סמנים. עליך להגדיר במפורש את הסמן להיות
אפשר לגרור אותו עם MarkerOptions.draggable(boolean)
לפני ההוספה אל
במפה, או Marker.setDraggable(boolean)
לאחר הוספתה למפה.
ניתן להאזין לאירועי גרירה על הסמן, כפי שמתואר בגרירה של עט סימון
אירועים.
קטע הקוד הבא מוסיף סמן שניתן לגרירה בפרת', אוסטרליה.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .draggable(true) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .draggable(true));
התאמה אישית של סמן
בסרטון הזה מוצגות דרכים לשימוש בסמנים כדי להמחיש מיקומים במפה.
סמנים יכולים להגדיר תמונה מותאמת אישית שתוצג במקום סמל ברירת המחדל. הגדרת סמל כרוכה בהגדרה של כמה מאפיינים שמשפיעים על ההתנהגות החזותית של הסמן.
הסמנים תומכים בהתאמה אישית באמצעות המאפיינים הבאים:
- מיקום (חובה)
LatLng
עבור מיקום הסמן במפה. זו הדרישה היחידה לאובייקטMarker
.- עוגן
- הנקודה בתמונה שתמוקם במיקום ה-LatLng . ברירת המחדל היא באמצע החלק התחתון של התמונה.
- אלפא
- מגדירים את רמת האטימות של הסמן. ברירת המחדל היא 1.0.
- כותרת
- מחרוזת שמוצגת בחלון המידע כשהמשתמש מקיש על .
- קטע טקסט
- טקסט נוסף שמוצג מתחת לכותרת.
- סמל
- מפת סיביות (bitmap) שמוצגת במקום תמונת הסמן שמוגדרת כברירת מחדל.
- אפשר לגרירה
- צריך להגדיר את הערך
true
אם רוצים לאפשר למשתמש להעביר הסמן. ברירת המחדל היאfalse
. - גלוי
- קבע את הערך
false
כדי להפוך את הסמן לבלתי נראה. ברירת המחדל היאtrue
- כיוון שטוח או לוח מודעות
- כברירת מחדל, הסמנים משתמשים בכיוון של לוח חוצות. כלומר, הם משורטטים מוגנים על מסך המכשיר ולא על פני השטח של המפה. סיבוב המפה, הטיה או שינוי מרחק התצוגה לא ישנו את הכיוון של המפה . אפשר להגדיר את הכיוון של הסמן כך שיהיה שטוח על פני כדור הארץ. סמנים שטוחים מסתובבים כשהמפה מסובבת, ומשנים את הפרספקטיבה כאשר שהמפה נטויה. בדומה לסמנים בלוח המודעות, סמנים שטוחים שומרים על גודלם כאשר התקרבות או התרחקות במפה.
- סיבוב
- כיוון הסמן, מוגדר במעלות בכיוון השעון. ברירת המחדל המיקום משתנה אם הסמן שטוח. מיקום ברירת המחדל של הסמן מיושר צפונה. כשהסמן לא שטוח, ערך ברירת המחדל מצביע למעלה, והסיבוב הוא כזה שהסמן תמיד מול המצלמה.
קטע הקוד שבהמשך יוצר סמן פשוט, עם סמל ברירת המחדל.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation));
התאמה אישית של צבע הסמן
ניתן להתאים אישית את הצבע של תמונת ברירת המחדל של הסמן על ידי העברת
אובייקט BitmapDescriptor
לשיטה icon() . אפשר להשתמש בקבוצה של
צבעים מוגדרים מראש BitmapDescriptorFactory
או להגדיר צבע סמן מותאם אישית עם
אמצעי תשלום אחד (BitmapDescriptorFactory.defaultMarker(float hue)
). הגוון הוא ערך
בין 0 ל-360, שמייצגים נקודות על גלגל הצבעים.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
התאמה אישית של שקיפות הסמן
ניתן לשלוט באטימות של סמן באמצעות השיטה MarkOptions.alpha() . יש לציין את האלפא כמספר ממשי (float) בין 0.0 ל-1.0, כאשר 0 הוא במלואו שקוף, ו-1 אטומים לחלוטין.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .alpha(0.7f) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker(new MarkerOptions() .position(melbourneLocation) .alpha(0.7f));
התאמה אישית של תמונת הסמן
לעיתים קרובות ניתן להחליף את תמונת הסמן שמוצגת כברירת מחדל בתמונת סמן מותאמת אישית
שנקרא סמל. סמלים מותאמים אישית תמיד מוגדרים כ-BitmapDescriptor
, וגם
מוגדרים באמצעות אחת מהשיטות
כיתה BitmapDescriptorFactory
.
fromAsset(String assetName)
- יצירת סמן מותאם אישית לפי השם של תמונת Bitmap בנכסים
fromBitmap(Bitmap image)
- יצירת סמן מותאם אישית מתמונה של מפת סיביות (Bitmap).
fromFile(String fileName)
- יוצר סמל מותאם אישית באמצעות השם של קובץ תמונה של מפת סיביות (Bitmap) שנמצא ואחסון פנימי.
fromPath(String absolutePath)
- יצירת סמן מותאם אישית מנתיב קובץ מוחלט של תמונת מפת סיביות (Bitmap).
fromResource(int resourceId)
- יצירת סמן בהתאמה אישית באמצעות מזהה המשאב של תמונת מפת סיביות (Bitmap).
קטע הקוד שבהמשך יוצר סמן עם סמל מותאם אישית.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .title(Me"lbourne) " .snippet(Po"pulation: 4,137,400) " .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .title(M"elbourne)" .snippet(P"opulation: 4,137,400)" .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
יישור סמן
סמלי סמנים בדרך כלל משורטטים ביחס למסך. מסתובב, הטייה או שינוי מרחק התצוגה במפה לא ישנה את כיוון הסמן. אפשר להגדיר את הכיוון של סמן כך שיהיה שטוח על פני כדור הארץ. סמנים בכיוון הזה יסתובב כשמסובבים את המפה, וישנה את נקודת המבט כשהמפה עקומה. סמנים שטוחים ישמרו על הגודל שלהם כשהמפה להגדיל או להקטין את התצוגה.
כדי לשנות את כיוון הסמן, יש להגדיר את מאפיין flat
של הסמן בתור
true
.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .flat(true) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .flat(true));
סיבוב הסמן
ניתן לסובב סמן מסביב לנקודת העיגון שלו באמצעות
Marker
אמצעי תשלום אחד (setRotation()
). הסיבוב נמדד במעלות בכיוון השעון
ממיקום ברירת המחדל. כשהסמן שטוח על המפה, ברירת המחדל
הוא צפון. כאשר הסמן אינו שטוח, מיקום ברירת המחדל הוא מצביע
למעלה והסיבוב כך שהסמן תמיד פונה למצלמה.
בדוגמה הבאה מסובבים את הסמן ב-90°. הגדרת נקודת העוגן ל-
0.5,0.5
גורם לסיבוב של הסמן סביב המרכז במקום
הבסיס.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .anchor(0.5f, 0.5f) .rotation(90.0f) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .anchor(0.5f,0.5f) .rotation(90.0f));
סמן Z-index
ה-z-index מציין את סדר הערימה של הסמן הזה, ביחס לסמנים אחרים.
במפה. סמן עם מדד z גבוה מצויר על גבי סמנים בחלק התחתון
ואינדקסים של z. ערך ברירת המחדל של z-index הוא 0
.
הגדרת ה-z-index באובייקט האפשרויות של הסמן באמצעות קריאה
MarkerOptions.zIndex()
, כפי שמוצג בקטע הקוד הבא:
Kotlin
map.addMarker( MarkerOptions() .position(LatLng(10.0, 10.0)) .title(Ma"rker z1) " .zIndex(1.0f) )
Java
map.addMarker(new MarkerOptions() .position(new LatLng(10, 10)) .title(M"arker z1)" .zIndex(1.0f));
אפשר לגשת ל-z-index של הסמן על ידי קריאה ל-Marker.getZIndex()
,
כדי לשנות אותו, צריך להתקשר למספר Marker.setZIndex()
.
הסמנים תמיד משורטטים מעל שכבות משבצות ושכבות-על אחרות שאינן סמנים (קרקע שכבות-על, קווים פוליגוניים, מצולעים וצורות אחרות) ללא קשר ל-z שכבות-העל האחרות. סמנים נחשבים בדרך כלל ל קבוצת z-index בהשוואה לשכבות-על אחרות.
בהמשך תוכלו לקרוא על ההשפעה של אינדקס z על אירועים מסוג קליק.
טיפול באירועי סמנים
ה-API של מפות Google מאפשר לכם להאזין לאירועי סמנים ולהגיב. האזנה ל:
צריך להגדיר את המאזינים המתאימים בGoogleMap
שאליו הסמנים שייכים. כשהאירוע מתרחש באחד
סמנים במפה, הקריאה החוזרת של המאזין תופעל באמצעות
האובייקט Marker
התואם שמועבר כפרמטר. כדי להשוות בין הנתונים האלה
אובייקט Marker
עם הפניה משלך לאובייקט Marker
, חובה להשתמש
equals()
ולא ==
.
ניתן להאזין לאירועים הבאים:
אירועי קליקים על סמנים
אפשר להשתמש ב-OnMarkerClickListener
כדי להאזין
לאירועי קליק בסמן. כדי להגדיר את ה-listener הזה במפה, צריך להתקשר
GoogleMap.setOnMarkerClickListener(OnMarkerClickListener)
כשמשתמש
קליקים על סמן, תתבצע קריאה אל onMarkerClick(Marker)
והסמן
יועבר כארגומנט. השיטה הזו מחזירה ערך בוליאני שמציין
האם צרכת את האירוע (כלומר, ברצונך להסתיר את ברירת המחדל?
התנהגות בלתי הולמת). אם הפונקציה מחזירה את הערך false
, התנהגות ברירת המחדל תתבצע
בנוסף להתנהגות המותאמת אישית. התנהגות ברירת המחדל של לחיצה על סמן
להציג את חלון המידע שלו (אם הוא זמין) ולהעביר את
מצלמה כך שהסמן יתמקד במפה.
ההשפעה של מדד z על אירועים מסוג קליק:
- כשמשתמש לוחץ על אשכול של סמנים, האירוע מסוג קליק מופעל עבור את הסמן עם מדד ה-z הגבוה ביותר.
- אירוע אחד מופעל לכל היותר לכל קליק. במילים אחרות, הקליק מועברות אל הסמנים או אל שכבות-על אחרות עם ערכים נמוכים יותר של z-index.
- לחיצה על קבוצה של סמנים גורמת לקליקים הבאים לעבור דרך וכל אחת מהן בתורה. למחזור יש עדיפות גבוהה יותר z-index, ואז קרבה לנקודת הקליק.
- אם המשתמש לוחץ מחוץ לקרבה לאשכול, ה-API יבצע חישוב מחדש האשכול ומאפס את המצב של מחזור הקליקים כך שהוא יתחיל מתחיל.
- אירוע הקליק עובר בין אשכולות של סמנים לצורות ולשכבות-על אחרות לפני שמפעילים מחדש את המחזור.
- סמנים נחשבים בפועל לקבוצה נפרדת של מדד z, לשכבות-על או לצורות אחרות (קווים פוליגוניים, מצולעים, מעגלים ו/או קרקע שכבות-על), בלי קשר ל-z-index של שאר שכבות-העל. אם מספר סמנים, שכבות-על או צורות מונחות כשכבת-על על גבי אירוע של הקליק קודם עובר דרך אשכול הסמנים, ואז מופעל שכבות-על או צורות שניתן ללחוץ עליהן, על סמך הערכים שלהן מאינדקס z.
אירועי גרירת סמן
אפשר להשתמש ב-OnMarkerDragListener
כדי להאזין
לגרור אירועים על סמן. כדי להגדיר את ה-listener הזה במפה, צריך להתקשר
GoogleMap.setOnMarkerDragListener
כדי לגרור סמן, המשתמש צריך ללחוץ לחיצה ארוכה
בסמן. כשהמשתמש מסיר את האצבע מהמסך, הסמן
יישאר במיקום הזה. כאשר ניתן לגרור סמן,
מתבצעת קריאה ראשונית אל onMarkerDragStart(Marker)
. בזמן שהסמן
גוררים, את onMarkerDrag(Marker)
קוראים כל הזמן. בסוף הגרירה
מתבצעת שיחה אל onMarkerDragEnd(Marker)
. ניתן לקבל את מיקום הסמן ב
בכל שלב, אפשר להתקשר אל Marker.getPosition()
.