Skip to content

Observe Map Events

Note

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

You can observe-low level map events that are happening by registering listeners to a MapView. Below you can see the the map events that are currently available.

override fun onPreCompileShader(id: Int, type: Int, defines: String) {
    shaderTimes["${id}-${type}-${defines}"] = TimeSource.Monotonic.markNow()
    Logger.i(TAG, "A new shader is being compiled, shaderID:${id}, backend type:${type}, program configuration:${defines}")
}

override fun onPostCompileShader(id: Int, type: Int, defines: String) {
    val startTime = shaderTimes.get("${id}-${type}-${defines}")
    if (startTime != null) {
        Logger.i(TAG, "A shader has been compiled in ${startTime.elapsedNow()}, shaderID:${id}, backend type:${type}, program configuration:${defines}")
    }
}

override fun onGlyphsRequested(fontStack: Array<String>, rangeStart: Int, rangeEnd: Int) {
    Logger.i(TAG, "Glyphs are being requested for the font stack $fontStack, ranging from $rangeStart to $rangeEnd")
}

override fun onGlyphsLoaded(fontStack: Array<String>, rangeStart: Int, rangeEnd: Int) {
    Logger.i(TAG, "Glyphs have been loaded for the font stack $fontStack, ranging from $rangeStart to $rangeEnd")
}

override fun onSpriteRequested(id: String, url: String) {
    Logger.i(TAG, "The sprite $id has been requested from $url")
}

override fun onSpriteLoaded(id: String, url: String) {
    Logger.i(TAG, "The sprite $id has been loaded from $url")
}

override fun onTileAction(op: TileOperation, x: Int, y: Int, z: Int, wrap: Int, overscaledZ: Int, sourceID: String) {
    val tile = "X:${x}, Y:${y}, Z:${z}, Wrap:${wrap}, OverscaledZ:${overscaledZ}, SourceID:${sourceID}"
    when (op) {
        TileOperation.RequestedFromCache -> Logger.i(TAG, "Requesting tile ${tile} from the cache")
        TileOperation.RequestedFromNetwork -> Logger.i(TAG, "Requesting tile ${tile} from the network")
        TileOperation.LoadFromCache -> Logger.i(TAG, "Loading tile ${tile}, requested from the cache")
        TileOperation.LoadFromNetwork -> Logger.i(TAG, "Loading tile ${tile}, requested from the network")
        TileOperation.StartParse -> Logger.i(TAG, "Parsing tile ${tile}")
        TileOperation.EndParse -> Logger.i(TAG, "Completed parsing tile ${tile}")
        TileOperation.Error -> Logger.e(TAG, "An error occured during proccessing for tile ${tile}")
        TileOperation.Cancelled -> Logger.i(TAG, "Pending work on tile ${tile} was cancelled")
        TileOperation.NullOp -> Logger.e(TAG, "An unknown tile operation was emitted for tile ${tile}")
    }
}

override fun onDidFinishRenderingFrame(fully: Boolean, stats: RenderingStats) {

}

You need to register them with these APIs:

mapView.addOnPreCompileShaderListener(this)
mapView.addOnPostCompileShaderListener(this)
mapView.addOnTileActionListener(this)
mapView.addOnGlyphsLoadedListener(this)
mapView.addOnGlyphsRequestedListener(this)
mapView.addOnSpriteLoadedListener(this)
mapView.addOnSpriteRequestedListener(this)
mapView.addOnDidFinishRenderingFrameListener(this)

In this case we implement them by implementing the interfaces below in the activity class, but you could also use lambdas.

/**
 * Test activity showcasing logging observer actions from the core
 */
class ObserverActivity : AppCompatActivity(),
    MapView.OnPreCompileShaderListener,
    MapView.OnPostCompileShaderListener,
    MapView.OnTileActionListener,
    MapView.OnGlyphsLoadedListener,
    MapView.OnGlyphsRequestedListener,
    MapView.OnSpriteLoadedListener,
    MapView.OnSpriteRequestedListener,
    MapView.OnDidFinishRenderingFrameWithStatsListener {