All docsMaps SDK for AndroidGuidesMarkers and annotations

Markers and annotations

The Mapbox Maps SDK for Android offers several ways to add markers, annotations, and other shapes to a map. This guide helps you choose the best approach for your application based on factors like interaction requirements, number of features, the need for customizing the style of features, and data sources.

Annotations

You can add annotations to the map including point, circle, polyline, and polygon shapes using the Mapbox Maps SDK's Annotations API. Use the Annotations API to create annotation managers based on the type of annotation that you're interested in. Every annotation manager handles a collection of annotations. Once a manager has been created, you can create and add individually styled instances of the corresponding annotation type.

Benefits:

  • Built-in interaction support like selecting and dragging annotations around the map.
  • No external data file necessary.
  • Every annotation can be individually styled.
  • Every annotation layer can be adjusted to be above or below another layer.
  • Same performance benefits as using style layers.

Limitations:

  • Inefficient for adding many features (> 250) to the map.
  • No default marker image available.

Default markers

The Mapbox Maps SDK's Annotations API does not provide a default image for symbol layers. You must provide an image and add it to the style before using the PointAnnotationManager to add it to the map.

See the Add a marker to the map code example for a downloadable red marker image that you can use in your project and details on how to add the image to a map style at runtime. Once you have the image added to your project and to the map style, create a new Annotation API instance and get the PointAnnotationManager.

// Create an instance of the Annotation API and get the PointAnnotationManager.
val annotationApi = mapView?.annotations
val pointAnnotationManager = annotationApi?.createPointAnnotationManager(mapView)
// Set options for the resulting symbol layer.
val pointAnnotationOptions: PointAnnotationOptions = PointAnnotationOptions()
    // Define a geographic coordinate.
    .withPoint(Point.fromLngLat(18.06, 59.31))
    // Specify the bitmap you assigned to the point annotation
    // The bitmap will be added to map style automatically.
    .withIconImage(YOUR_ICON_BITMAP)
// Add the resulting pointAnnotation to the map.
pointAnnotationManager?.create(pointAnnotationOptions)
example
Add a default marker to the map

Use the Annotation API's PointAnnotationManager to add a single red marker pin to a map.

Other shapes

The Annotation API also supports putting other shapes on the map including circles using CircleAnnotationManager, polylines using PolylineAnnotationManager, and polygons using PolygonAnnotationManager. These annotations work like the point annotations described above, but do not require an image. The options available for each type of annotation varies and you can find a full list in the API reference documentation.

A circle annotation (CircleAnnotation) places a circle at a point on the map.

// Create an instance of the Annotation API and get the CircleAnnotationManager.
val annotationApi = mapView?.annotations
val circleAnnotationManager = annotationApi?.createCircleAnnotationManager(mapView)
// Set options for the resulting circle layer.
val circleAnnotationOptions: CircleAnnotationOptions = CircleAnnotationOptions()
    // Define a geographic coordinate.
    .withPoint(Point.fromLngLat(18.06, 59.31))
    // Style the circle that will be added to the map.
    .withCircleRadius(8.0)
    .withCircleColor("#ee4e8b")
    .withCircleStrokeWidth(2.0)
    .withCircleStrokeColor("#ffffff")
// Add the resulting circle to the map.
circleAnnotationManager?.create(circleAnnotationOptions)

A polyline annotation (PolylineAnnotation) connects a list of coordinates on the map with a polyline. The order of the coordinates in the list will determine the order in which to connect the points. Coordinate ordering works the same way as in the GeoJSON specification.

// Create an instance of the Annotation API and get the polyline manager.
val annotationApi = mapView?.annotations
polylineAnnotationManager = annotationApi.createPolylineAnnotationManager(mapView)
// Define a list of geographic coordinates to be connected.
val points = listOf(
    Point.fromLngLat(17.94, 59.25),
    Point.fromLngLat(18.18, 59.37)
)
// Set options for the resulting line layer.
val polylineAnnotationOptions: PolylineAnnotationOptions = PolylineAnnotationOptions()
    .withPoints(points)
    // Style the line that will be added to the map.
    .withLineColor("#ee4e8b")
    .withLineWidth(5.0)
// Add the resulting line to the map.
polylineAnnotationManager?.create(polylineAnnotationOptions)

A polygon annotation (PolygonAnnotation) takes a list of coordinates and will try to connect those coordinates and add the resulting polygonal shape to the map. The order of the coordinates in the list matters and works the same way as in the GeoJSON specification.

// Create an instance of the Annotation API and get the polygon manager.
val annotationApi = mapView?.annotations
val polygonAnnotationManager = annotationApi?.createPolygonAnnotationManager(mapView)
// Define a list of geographic coordinates to be connected.
val points = listOf(
    listOf(
        Point.fromLngLat(17.94, 59.25),
        Point.fromLngLat(18.18, 59.25),
        Point.fromLngLat(18.18, 59.37),
        Point.fromLngLat(17.94, 59.37)
    )
)
// Set options for the resulting fill layer.
val polygonAnnotationOptions: PolygonAnnotationOptions = PolygonAnnotationOptions()
    .withPoints(points)
    // Style the polygon that will be added to the map.
    .withFillColor("#ee4e8b")
    .withFillOpacity(0.4)
// Add the resulting polygon to the map.
polygonAnnotationManager?.create(polygonAnnotationOptions)

Interactivity

The Annotation API includes the ability make annotations draggable and handles drag gestures for you. You can specify that annotations should be draggable when adding the annotation to the map initially.

val pointAnnotationOptions: PointAnnotationOptions = PointAnnotationOptions()
    .withPoint(Point.fromLngLat(18.06, 59.31))
    .withIconImage(YOUR_ICON_BITMAP)
    // Make the annotation draggable.
    .withDraggable(true)
// Add the draggable pointAnnotation to the map.
pointAnnotationManager?.create(pointAnnotationOptions)

Or, you can update an annotation that's already been added to the map to be draggable.

// When a user clicks on a draggable menu item defined in the layout,
// then toggle whether all point annotations are draggable.
R.id.menu_action_draggable -> {
  pointAnnotationManager?.annotations?.forEach {
    it.isDraggable = !it.isDraggable
  }
}

Style layers

The Annotation API described above makes it unnecessary to write much of the code that would otherwise be required to implement runtime and data-driven styling. But, it is possible to add style layers directly, and in some circumstances doing so will be beneficial.

Benefits:

  • Efficient and performant when adding many features to the map.
  • Compatible with GeoJSON or vector sources.
  • Many style customization options.
  • Could exclude the Annotation API when installing the SDK to reduce the SDK size.

Limitations:

  • No default image available.
  • Most user interactions are not built-in and will require writing custom code.
  • Need to learn the APIs and usage of layers which can be time intensive.
  • Might need to learn how to use expressions to control the source data or use data-driven styling.
related
Map styles: Work with layers

Use the Mapbox Maps SDK for Android to add, remove, and modify layers rendered in a map style.