Skip to content

Add live realtime data

Note

You can find the full source code of this example in RealTimeGeoJsonActivity.kt of the MapLibreAndroidTestApp.

In this example you will learn how to add a live GeoJSON source. We have set up a lambda function that returns a new GeoJSON point every time it is called.

First we will create a GeoJSONSource.

Adding GeoJSON source
try {
    style.addSource(GeoJsonSource(ID_GEOJSON_SOURCE, URI(URL_GEOJSON_SOURCE)))
} catch (malformedUriException: URISyntaxException) {
    Timber.e(malformedUriException, "Invalid URL")
}

Next we will create a SymbolLayer that uses the source.

Adding a SymbolLayer source
val layer = SymbolLayer(ID_GEOJSON_LAYER, ID_GEOJSON_SOURCE)
layer.setProperties(
    PropertyFactory.iconImage("plane"),
    PropertyFactory.iconAllowOverlap(true)
)
style.addLayer(layer)

We use define a Runnable and use android.os.Handler with a android.os.Looper to update the GeoJSON source every 2 seconds.

Defining a Runnable for updating the GeoJSON source
private inner class RefreshGeoJsonRunnable(
    private val maplibreMap: MapLibreMap,
    private val handler: Handler
) : Runnable {
    override fun run() {
        val geoJsonSource = maplibreMap.style!!.getSource(ID_GEOJSON_SOURCE) as GeoJsonSource
        geoJsonSource.setUri(URL_GEOJSON_SOURCE)
        val features = geoJsonSource.querySourceFeatures(null)
        setIconRotation(features)
        handler.postDelayed(this, 2000)
    }
}

Bonus: set icon rotation

You can set the icon rotation of the icon when ever the point is updated based on the last two points.

Defining a Runnable for updating the GeoJSON source
if (features.size != 1) {
    Timber.e("Expected only one feature")
    return
}

val feature = features[0]
val geometry = feature.geometry()
if (geometry !is Point) {
    Timber.e("Expected geometry to be a point")
    return
}

if (lastLocation == null) {
    lastLocation = geometry
    return
}

maplibreMap.style!!.getLayer(ID_GEOJSON_LAYER)!!.setProperties(
    PropertyFactory.iconRotate(calculateRotationAngle(lastLocation!!, geometry)),
)