Markers

VERSION 0.45.0
PUBLIC PREVIEW

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 CoreLocation
2import SwiftUI
3import TomTomSDKCommon
4import 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, the MarkerOptions.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, the MarkerOptions.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: .meters
6 )
7)))
8map
9 .setMarkerDistanceShrinkingRange(range: ClosedRange(uncheckedBounds: (
10 lower: Measurement<UnitLength>(
11 value: 200,
12 unit: .meters
13 ),
14 upper: Measurement<UnitLength>(
15 value: 500,
16 unit: .meters
17 )
18 )))

You can also completely disable marker fading and shrinking by setting AnnotationsActions.isMarkersFadingEnabled and AnnotationsActions.isMarkersShrinkingEnabled to false.

map.isMarkersFadingEnabled = false
map.isMarkersShrinkingEnabled = false
Fading and Shrinking

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 break
6 default:
7 break
8 }
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.coordinate
4 let coordinatesText = "\(coordinates.latitude), \(coordinates.longitude)"
5 let annotationView =
6 UIHostingController(rootView: CustomMarkerBalloonView(locationCoordinates: coordinatesText))
7 return annotationView.view
8}

The view for the marker balloon can be defined using SwiftUI, for example:

1struct CustomMarkerBalloonView: View {
2 var locationCoordinates: String
3
4 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.coordinate
4 let coordinatesText = "\(coordinates.latitude), \(coordinates.longitude)"
5 let annotationView =
6 UIHostingController(rootView: CustomMarkerBalloonView(locationCoordinates: coordinatesText))
7 return annotationView.view
8}

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)