Markers
Markers are used to indicate specific locations on the map. The Map Display SDK provides a default icon, but a custom drawable can be used as well. Markers are added as annotations to the fully initialized TomTomMap
object. To add the map to your app, see the Adding a map guide.
Import the following frameworks to continue with this guide:
1import CoreLocation2import SwiftUI3import TomTomSDKCommon4import TomTomSDKMapDisplay
The first step is to create a MarkerOptions
object that describes the properties of the marker. The most important property is the CLLocationCoordinate2D
where the marker should be added. The other properties are optional.
let amsterdam = CLLocationCoordinate2D(latitude: 52.379189, longitude: 4.899431)let markerOptions = MarkerOptions(coordinate: amsterdam)
Add a defined MarkerOptions
to the TomTomMap
. The marker will be displayed at the provided coordinates. The AnnotationsActions.addMarker(options:)
method returns the instance of the added Marker
. If the coordinates are invalid or adding the marker failed, the method will throw AnnotationServiceError.invalidCoordinate
or AnnotationServiceError.failedToCreateAnnotation
respectively.
Customizing the marker
The appearance of the marker can be customized using MarkerOptions
. It provides several properties to do this:
MarkerOptions.pinImage
- Defines the image of the pin and its shape.markerOptions.pinImage = UIImage(systemName: "square.fill")MarkerOptions.pinImageURI
- Defines the pin image by specifying its URI. If it is set, theMarkerOptions.pinImage
is ignored. To make it work, you also need COMPRESS_PNG_FILES and STRIP_PNG_TEXT set to NO in the Xcode build settings.markerOptions.pinImageURI = "pin-image-URI"MarkerOptions.iconImage
- The image displayed on the top of the pin.markerOptions.iconImage = UIImage(systemName: "bicycle")MarkerOptions.iconImageURI
- The icon image specified using a URI. If it is set, theMarkerOptions.iconImage
is ignored. To make it work, you also need COMPRESS_PNG_FILES and STRIP_PNG_TEXT set to NO in the Xcode build settings.markerOptions.iconImageURI = "icon-image-URI"MarkerOptions.isSelectable
- Property which defines whether the marker is selectable. By default, every marker is set to be selectable.markerOptions.isSelectable = false
Marker fading and shrinking
To prevent the map becoming overloaded with markers, you can set custom fading and shrinking ranges. Use the AnnotationsActions.setMarkerDistanceFadingRange(range:)
and AnnotationsActions.setMarkerDistanceShrinkingRange(range:)
methods of the TomTomMap
instance. Distances are in meters. For example:
1map.setMarkerDistanceFadingRange(range: ClosedRange(uncheckedBounds: (2 lower: Measurement<UnitLength>(value: 200, unit: .meters),3 upper: Measurement<UnitLength>(4 value: 500,5 unit: .meters6 )7)))8map9 .setMarkerDistanceShrinkingRange(range: ClosedRange(uncheckedBounds: (10 lower: Measurement<UnitLength>(11 value: 200,12 unit: .meters13 ),14 upper: Measurement<UnitLength>(15 value: 500,16 unit: .meters17 )18 )))
You can also completely disable marker fading and shrinking by setting AnnotationsActions.isMarkersFadingEnabled
and AnnotationsActions.isMarkersShrinkingEnabled
to false.
map.isMarkersFadingEnabled = falsemap.isMarkersShrinkingEnabled = false
Removing a marker
All the markers added to a specific instance of the TomTomMap
can be removed using AnnotationsActions.removeAnnotations()
. Note that this method removes all annotations added to the map, including shapes like Circle
or Polygon
.
map.removeAnnotations()
You can also remove a single marker by using AnnotationsActions.remove(annotation:)
. Interacting with the reference to a removed marker will have no effect.
map.remove(annotation: marker)
Marker events
You can observe click events performed on markers via MapDelegate
. To register these actions, override the following method. It provides the Annotation
object of the marker that was clicked with its coordinates and the TomTomMap
instance.
1func map(_ map: TomTomMap, onInteraction interaction: MapInteraction) {2 switch interaction {3 case let .tappedOnAnnotation(annotation, coordinate):4 /* YOUR CODE GOES HERE */5 break6 default:7 break8 }9}
Zooming to markers
The Map Display SDK provides simple methods for zooming a camera to markers. You can zoom to a view containing all of the markers that have been added to the TomTomMap
.
map.zoomToMarkers()
You can also set the margin around the area to which the camera is zoomed. The margin is expressed in pixels.
map.zoomToMarkers(marginPx: 16)
Balloons
Balloons are popup views that appear on top of the map when the user taps a marker. They do not appear by default. To show a balloon, provide the MapDataSource
delegate to its TomTomMap.dataSource
property. It has a method for providing a UIView
when an Annotation
is selected.
1func map(_: TomTomMap, viewForSelected marker: Annotation) -> UIView? {2 guard let marker = marker as? Marker else { return nil }3 let coordinates = marker.coordinate4 let coordinatesText = "\(coordinates.latitude), \(coordinates.longitude)"5 let annotationView =6 UIHostingController(rootView: CustomMarkerBalloonView(locationCoordinates: coordinatesText))7 return annotationView.view8}
The view for the marker balloon can be defined using SwiftUI
, for example:
1struct CustomMarkerBalloonView: View {2 var locationCoordinates: String34 var body: some View {5 VStack(alignment: .center) {6 Image(systemName: "mappin")7 .font(.system(size: 48))8 Text(locationCoordinates)9 }10 .padding()11 }12}
Inside the previously described method, create a UIView
that will represent the balloon.
1func map(_: TomTomMap, viewForSelected marker: Annotation) -> UIView? {2 guard let marker = marker as? Marker else { return nil }3 let coordinates = marker.coordinate4 let coordinatesText = "\(coordinates.latitude), \(coordinates.longitude)"5 let annotationView =6 UIHostingController(rootView: CustomMarkerBalloonView(locationCoordinates: coordinatesText))7 return annotationView.view8}
Now if a Marker
was set to be selectable, clicking on it causes the CustomMarkerBalloonView to appear above it. An Annotation
can also be selected programmatically. To do this, call the AnnotationsActions.select(annotation:)
method with the Marker
as a parameter. You can deselect the Annotation
in a similar way.
map.select(annotation: marker)map.deselect(annotation: marker)