Skip to content

Annotations

Annotations allow you to mark specific locations on your map with custom views. MapLayr provides a flexible annotation system through CoordinateAnnotationLayer.

Creating an Annotation Type

Start by defining a data type that represents your annotation. This can be a class that includes the location and any additional data needed to display the annotation.

data class Attraction(
    val name: String,
    val latitude: Double,
    val longitude: Double,
    val iconImage: Int
) {

    override fun toString() = name
}

An example can be found here: Attraction.kt

CoordinateAnnotationLayer.Adapter

To show annotations you must add a CoordinateAnnotationLayer to the MapView. The CoordinateAnnotationLayer requires a CoordinateAnnotationLayer.Adapter parameter. The CoordinateAnnotationLayer.Adapter class is parameterised by the data type that represents your annotation and is used to provide the CoordinateAnnotationLayer with the View and GeographicCoordinate for your annotation.

The SDK provides a LabeledAnnotationIcon class, which extends View that can be used for your annotation should you not wish to create your own View. The LabeledAnnotationIcon is composed of an image icon above an outlined text view.

Labeled Annotation Icon

 

class AnnotationLayerAdapter : CoordinateAnnotationLayer.Adapter<Attraction> {

    // Define a CoordinateAnnotationViewHolder containing a LabeledAnnotationIcon
    class LabeledAnnotationIconViewHolder(view: LabeledAnnotationIcon) : CoordinateAnnotationViewHolder(view)

    // Create an instance of the LabeledAnnotationIconViewHolder
    override fun createView(parent: ViewGroup, viewType: Int) = LabeledAnnotationIconViewHolder(LabeledAnnotationIcon(parent.context))

    // Bind the data for a given `Attraction` to the LabeledAnnotationIcon
    override fun bindView(coordinateAnnotationViewHolder: CoordinateAnnotationViewHolder, element: Attraction) {
        val labeledAnnotationIcon = coordinateAnnotationViewHolder.view as LabeledAnnotationIcon

        labeledAnnotationIcon.labelTextColor = ColorStateList.valueOf(Color.BLACK)
        labeledAnnotationIcon.labelText = element.name
        (labeledAnnotationIcon.annotationIcon as ImageView).setImageResource(element.iconImage)
    }

    // Provide the geographic coordinate for a given `Attraction`
    override fun annotationLocation(element: Attraction) = GeographicCoordinate(element.latitude, element.longitude)
}

An example can be found here: AnnotationLayerAdapter.kt

CoordinateAnnotationLayer

We can then create a CoordinateAnnotationLayer which takes as parameters a Context and a CoordinateAnnotationLayer.Adapter as so:

val annotationLayerAdapter = AnnotationLayerAdapter()
val coordinateAnnotationLayer = CoordinateAnnotationLayer(this, annotationLayerAdapter)

Then we are able to insert Attraction (the parameterised type specified in the AnnotationLayerAdapter) elements into the CoordinateAnnotationLayer. For example if we have a repository of attractions

object AttractionManager {

    val attractions = listOf(
        Attraction("Daeva", 52.8952, -1.8431, R.drawable.map_icon),
        Attraction("Eagle's Flight", 52.8982, -1.8463, R.drawable.map_icon),
        Attraction("Terragon", 52.8983, -1.8494, R.drawable.map_icon),
        Attraction("The Flying Dutchman", 52.8971, -1.8443, R.drawable.map_icon),
        Attraction("Wooden Warrior", 52.8949, -1.8445, R.drawable.map_icon)
    )
}

These can be inserted into the CoordinateAnnotationLayer as so:

coordinateAnnotationLayer.insert(AttractionManager.attractions)

Finally, add the coordinate annotation layer to the MapView as so:

mapView.addMapLayer(coordinateAnnotationLayer)

Listening to annotation selection and deselection events

To listen for events when an annotation is selected or deselected provide an implementation of the CoordinateAnnotationLayer.Listener interface, which is parameterised to the type specified in the AnnotationLayerAdapter. Then set the coordinateAnnotationLayer.listener to be that implementation.

coordinateAnnotationLayer.listener = object : CoordinateAnnotationLayer.Listener<Attraction> {

    override fun didDeselectAnnotation(
        element: Attraction,
        coordinateAnnotationLayer: CoordinateAnnotationLayer<Attraction>
    ) {
        // `element` has been deselected
    }

    override fun didSelectAnnotation(
        element: Attraction,
        coordinateAnnotationLayer: CoordinateAnnotationLayer<Attraction>
    ) {
        // `element` has been selected
    }
}

An example can be found here: ExtendedSampleActivity.kt

Annotations