-
I want to render a base64 image in a boundingBox on the map. The image has data about AQI (marks cleaner areas as green, polluted as amber or red depending on the pollution level). Here is my component wrapper around maplibre-compose. I have added props for overlay but I can't seem to figure out how I can render on the map. I tried using RasterLayer but didn't work Original Map Wrapper component: import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import dev.sargunv.maplibrecompose.compose.MaplibreMap
import dev.sargunv.maplibrecompose.compose.rememberCameraState
import dev.sargunv.maplibrecompose.compose.CameraState
import dev.sargunv.maplibrecompose.compose.layer.RasterLayer
import dev.sargunv.maplibrecompose.core.CameraPosition
import dev.sargunv.maplibrecompose.core.source.RasterSource
import dev.sargunv.maplibrecompose.core.source.TileSetOptions
import io.github.dellisd.spatialk.geojson.BoundingBox
import io.github.dellisd.spatialk.geojson.Position
import kotlinx.coroutines.CoroutineScope
import kotlin.io.encoding.ExperimentalEncodingApi
data class Overlay(
val bounds: List<Position>,
val base64Image: String,
)
@OptIn(ExperimentalEncodingApi::class)
@Composable
fun MapComponent(
modifier: Modifier = Modifier,
styleUri: String = "https://tiles.openfreemap.org/styles/liberty",
initialPosition: Position = Position(latitude = 45.521, longitude = -122.675),
initialZoom: Double = 13.0,
overlay: Overlay? = null,
content: @Composable BoxScope.(cameraState: CameraState, coroutineScope: CoroutineScope) -> Unit = { _, _ -> }
) {
val camera = rememberCameraState(
firstPosition = CameraPosition(target = initialPosition, zoom = initialZoom)
)
val coroutineScope = rememberCoroutineScope()
Box(modifier = modifier.fillMaxSize()) {
MaplibreMap(
styleUri = styleUri,
cameraState = camera,
modifier = Modifier.matchParentSize()
)
content(camera, coroutineScope)
}
} My attempt to render the base64 image import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import dev.sargunv.maplibrecompose.compose.MaplibreMap
import dev.sargunv.maplibrecompose.compose.rememberCameraState
import dev.sargunv.maplibrecompose.compose.CameraState
import dev.sargunv.maplibrecompose.compose.layer.RasterLayer
import dev.sargunv.maplibrecompose.core.CameraPosition
import dev.sargunv.maplibrecompose.core.source.RasterSource
import dev.sargunv.maplibrecompose.core.source.TileSetOptions
import io.github.dellisd.spatialk.geojson.BoundingBox
import io.github.dellisd.spatialk.geojson.Position
import kotlinx.coroutines.CoroutineScope
import kotlin.io.encoding.ExperimentalEncodingApi
data class Overlay(
val bounds: List<Position>,
val base64Image: String,
)
@OptIn(ExperimentalEncodingApi::class)
@Composable
fun MapComponent(
modifier: Modifier = Modifier,
styleUri: String = "https://tiles.openfreemap.org/styles/liberty",
initialPosition: Position = Position(latitude = 45.521, longitude = -122.675),
initialZoom: Double = 13.0,
overlay: Overlay? = null,
content: @Composable BoxScope.(cameraState: CameraState, coroutineScope: CoroutineScope) -> Unit = { _, _ -> }
) {
val camera = rememberCameraState(
firstPosition = CameraPosition(target = initialPosition, zoom = initialZoom)
)
val coroutineScope = rememberCoroutineScope()
Box(modifier = modifier.fillMaxSize()) {
MaplibreMap(
styleUri = styleUri,
cameraState = camera,
modifier = Modifier.matchParentSize()
)
// Only add the image overlay if both the image and bounds exist
if (overlay?.base64Image != null && overlay?.bounds != null && overlay.bounds.size == 4) {
// Add the raster layer
RasterLayer(
id = "aqi-overlay-layer",
source = RasterSource(
id = "aqi-overlay-source",
tiles = listOf("data:image/png;base64," + overlay.base64Image),
options = TileSetOptions(
boundingBox = BoundingBox(
west = overlay.bounds[1].longitude,
south = overlay.bounds[0].latitude,
east = overlay.bounds[3].longitude,
north = overlay.bounds[2].latitude
),
)
)
)
}
content(camera, coroutineScope)
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 8 replies
-
RasterSource is for when you have a URL serving image tiles, like For just an arbitrary image not necessarily pre-formatted as tiles, you'll want ImageSource, coming in the next release. You can try it out today by using the snapshot builds. I don't think we've tested ImageSource with base64 images, but if it works with MapLibre Native, it should work. If MapLibre Native doesn't support base64 images, you can also provide a Bitmap. If/when you try it out, do report back on whether a base64 url works. |
Beta Was this translation helpful? Give feedback.
RasterSource is for when you have a URL serving image tiles, like
https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
.For just an arbitrary image not necessarily pre-formatted as tiles, you'll want ImageSource, coming in the next release. You can try it out today by using the snapshot builds.
I don't think we've tested ImageSource with base64 images, but if it works with MapLibre Native, it should work. If MapLibre Native doesn't support base64 images, you can also provide a Bitmap.
If/when you try it out, do report back on whether a base64 url works.