Annotation: Marker
This guide will show you how to add Markers in the map.
Annotation
is an overlay on top of a Map. In package
org.maplibre.android.annotations
, it has the following subclasses:
A Marker shows an icon image at a geographical location. By default, marker uses a provided image as its icon.
Or, the icon can be customized using IconFactory to generate an Icon using a provided image.
For more customization, please read the documentation about MarkerOptions.
In this showcase, we continue the code from the Quickstart,
rename Activity into JsonApiActivity
,
and pull the GeoJSON data from a free and public API.
Then add markers to the map with GeoJSON:
-
In your module Gradle file (usually
<project>/<app-module>/build.gradle
), addokhttp
to simplify code for making HTTP requests. -
Sync your Android project the with Gradle files.
-
In
JsonApiActivity
we add a new variable forMapLibreMap
. It is used to add annotations to the map instance. -
Call
mapview.getMapSync()
in order to get aMapLibreMap
object. AftermaplibreMap
is assigned, call thegetEarthQuakeDataFromUSGS()
method to make a HTTP request and transform data into the map annotations. -
Define a function
getEarthQuakeDataFromUSGS()
to fetch GeoJSON data from a public API. If we successfully get the response, calladdMarkersToMap()
on the UI thread.// Get Earthquake data from usgs.gov, read API doc at: // https://earthquake.usgs.gov/fdsnws/event/1/ private fun getEarthQuakeDataFromUSGS() { val url = "https://earthquake.usgs.gov/fdsnws/event/1/query".toHttpUrl().newBuilder() .addQueryParameter("format", "geojson") .addQueryParameter("starttime", "2022-01-01") .addQueryParameter("endtime", "2022-12-31") .addQueryParameter("minmagnitude", "5.8") .addQueryParameter("latitude", "24") .addQueryParameter("longitude", "121") .addQueryParameter("maxradius", "1.5") .build() val request: Request = Request.Builder().url(url).build() OkHttpClient().newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { Toast.makeText(this@JsonApiActivity, "Fail to fetch data", Toast.LENGTH_SHORT) .show() } override fun onResponse(call: Call, response: Response) { val featureCollection = response.body?.string() ?.let(FeatureCollection::fromJson) ?: return // If FeatureCollection in response is not null // Then add markers to map runOnUiThread { addMarkersToMap(featureCollection) } } }) }
-
Now it is time to add markers into the map.
- In the
addMarkersToMap()
method, we define two types of bitmap for the marker icon. - For each feature in the GeoJSON, add a marker with a snippet about earthquake details.
- If the magnitude of an earthquake is bigger than 6.0, we use the red icon. Otherwise, we use the blue one.
-
Finally, move the camera to the bounds of the newly added markers
private fun addMarkersToMap(data: FeatureCollection) { val bounds = mutableListOf<LatLng>() // Get bitmaps for marker icon val infoIconDrawable = ResourcesCompat.getDrawable( this.resources, // Intentionally specify package name // This makes copy from another project easier org.maplibre.android.R.drawable.maplibre_info_icon_default, theme )!! val bitmapBlue = infoIconDrawable.toBitmap() val bitmapRed = infoIconDrawable .mutate() .apply { setTint(Color.RED) } .toBitmap() // Add symbol for each point feature data.features()?.forEach { feature -> val geometry = feature.geometry()?.toJson() ?: return@forEach val point = Point.fromJson(geometry) ?: return@forEach val latLng = LatLng(point.latitude(), point.longitude()) bounds.add(latLng) // Contents in InfoWindow of each marker val title = feature.getStringProperty("title") val epochTime = feature.getNumberProperty("time") val dateString = SimpleDateFormat("yyyy/MM/dd HH:mm", Locale.TAIWAN).format(epochTime) // If magnitude > 6.0, show marker with red icon. If not, show blue icon instead val mag = feature.getNumberProperty("mag") val icon = IconFactory.getInstance(this) .fromBitmap(if (mag.toFloat() > 6.0) bitmapRed else bitmapBlue) // Use MarkerOptions and addMarker() to add a new marker in map val markerOptions = MarkerOptions() .position(latLng) .title(dateString) .snippet(title) .icon(icon) maplibreMap.addMarker(markerOptions) } // Move camera to newly added annotations maplibreMap.getCameraForLatLngBounds(LatLngBounds.fromLatLngs(bounds))?.let { val newCameraPosition = CameraPosition.Builder() .target(it.target) .zoom(it.zoom - 0.5) .build() maplibreMap.cameraPosition = newCameraPosition } }
-
Here is the final result. For the full contents of
JsonApiActivity
, please visit source code of our Test App.