-
-
Notifications
You must be signed in to change notification settings - Fork 42
Open
Labels
api ergonomicsImproves API usability without net-new functionalityImproves API usability without net-new functionality
Description
What happened?
Icons are not reused and are added to Maplibre style again for each new layer instance.
Here is an example.
When only one layer is added (MovingSymbolWithSelection("layer_1")) Maplibre shows 11 painters added (which is expected for 10 markers + 1 fallback icon):
I Adding painter __MAPLIBRE_COMPOSE_painter_0
I Adding painter __MAPLIBRE_COMPOSE_painter_1
I Adding painter __MAPLIBRE_COMPOSE_painter_2
I Adding painter __MAPLIBRE_COMPOSE_painter_3
I Adding painter __MAPLIBRE_COMPOSE_painter_4
I Adding painter __MAPLIBRE_COMPOSE_painter_5
I Adding painter __MAPLIBRE_COMPOSE_painter_6
I Adding painter __MAPLIBRE_COMPOSE_painter_7
I Adding painter __MAPLIBRE_COMPOSE_painter_8
I Adding painter __MAPLIBRE_COMPOSE_painter_9
I Adding painter __MAPLIBRE_COMPOSE_painter_10
However, when more instances of the same layer are added Maplibre adds painters for each layer as if they were new drawables:
fun MovingSymbols() {
MovingSymbolWithSelection("layer_1")
MovingSymbolWithSelection("layer_2")
MovingSymbolWithSelection("layer_3")
}
Log:
I Adding painter __MAPLIBRE_COMPOSE_painter_0
I Adding painter __MAPLIBRE_COMPOSE_painter_1
I Adding painter __MAPLIBRE_COMPOSE_painter_2
I Adding painter __MAPLIBRE_COMPOSE_painter_3
I Adding painter __MAPLIBRE_COMPOSE_painter_4
I Adding painter __MAPLIBRE_COMPOSE_painter_5
I Adding painter __MAPLIBRE_COMPOSE_painter_6
I Adding painter __MAPLIBRE_COMPOSE_painter_7
I Adding painter __MAPLIBRE_COMPOSE_painter_8
I Adding painter __MAPLIBRE_COMPOSE_painter_9
I Adding painter __MAPLIBRE_COMPOSE_painter_10
I Adding painter __MAPLIBRE_COMPOSE_painter_11
I Adding painter __MAPLIBRE_COMPOSE_painter_12
I Adding painter __MAPLIBRE_COMPOSE_painter_13
I Adding painter __MAPLIBRE_COMPOSE_painter_14
I Adding painter __MAPLIBRE_COMPOSE_painter_15
I Adding painter __MAPLIBRE_COMPOSE_painter_16
I Adding painter __MAPLIBRE_COMPOSE_painter_17
I Adding painter __MAPLIBRE_COMPOSE_painter_18
I Adding painter __MAPLIBRE_COMPOSE_painter_19
I Adding painter __MAPLIBRE_COMPOSE_painter_20
I Adding painter __MAPLIBRE_COMPOSE_painter_21
I Adding painter __MAPLIBRE_COMPOSE_painter_22
I Adding painter __MAPLIBRE_COMPOSE_painter_23
I Adding painter __MAPLIBRE_COMPOSE_painter_24
I Adding painter __MAPLIBRE_COMPOSE_painter_25
I Adding painter __MAPLIBRE_COMPOSE_painter_26
I Adding painter __MAPLIBRE_COMPOSE_painter_27
I Adding painter __MAPLIBRE_COMPOSE_painter_28
I Adding painter __MAPLIBRE_COMPOSE_painter_29
I Adding painter __MAPLIBRE_COMPOSE_painter_30
I Adding painter __MAPLIBRE_COMPOSE_painter_31
I Adding painter __MAPLIBRE_COMPOSE_painter_32
In case of hundreds of different markers and several layers Maplibre quickly reaches its limit of around 7k-8k painters and then crashes.
Suggestion: Can we add all resources once and reuse them by hashCode() link like "Res.drawable.marker.hashCode()"? This worked well in native.
Affected Platforms
- Android
- iOS
- Desktop (JVM)
- Browser (JS)
- Browser (Wasm)
Platform Version
Android 15
Library Version
0.11.1
Sample Code
@Composable
fun MovingSymbols() {
MovingSymbolWithSelection("layer_1")
//MovingSymbolWithSelection("layer_2")
//MovingSymbolWithSelection("layer_3")
}
@Composable
fun MovingSymbolWithSelection(layerName: String) {
var pointPosition by remember { mutableStateOf(Position(latitude = 48.8, longitude = 9.2))}
var markerIcon by remember { mutableStateOf("marker")}
val source by derivedStateOf {
FeatureCollection( Feature(
geometry = Point(pointPosition),
properties = JsonObject(getIconGeoJson(markerIcon).toMap().mapValues { JsonPrimitive(it.value) }
)
))
}
val markersList = listOf("marker1", "marker2", "marker3", "marker4", "marker5", "marker6", "marker7", "marker8","marker9", "marker10" )
LaunchedEffect(Unit){
while (true){
pointPosition = Position(
latitude = pointPosition.latitude + Random.nextDouble(-0.02, 0.02),
longitude = pointPosition.longitude + Random.nextDouble(-0.02, 0.02),
)
markerIcon = markersList.random()
delay(50)
}
}
SymbolLayer(
id = layerName,
iconImage = switch(
feature["iconId"].asString(),
case(label = "marker1", output = image(painterResource(Res.drawable.marker1))),
case(label = "marker2", output = image(painterResource(Res.drawable.marker2))),
case(label = "marker3", output = image(painterResource(Res.drawable.marker3))),
case(label = "marker4", output = image(painterResource(Res.drawable.marker4))),
case(label = "marker5", output = image(painterResource(Res.drawable.marker5))),
case(label = "marker6", output = image(painterResource(Res.drawable.marker6))),
case(label = "marker7", output = image(painterResource(Res.drawable.marker7))),
case(label = "marker8", output = image(painterResource(Res.drawable.marker8))),
case(label = "marker9", output = image(painterResource(Res.drawable.marker9))),
case(label = "marker10", output = image(painterResource(Res.drawable.marker10))),
fallback = image(painterResource(Res.drawable.error_24px)),
),
source = rememberGeoJsonSource(data = GeoJsonData.Features(source)),
)
}
@Serializable
data class GeoJsonProperties(
val iconId: String? = null
)
fun getIconGeoJson(iconId: String?): GeoJsonProperties {
return GeoJsonProperties(
iconId = iconId
)
}
fun GeoJsonProperties.toMap(): Map<String, String?> = mapOf(
"iconId" to iconId,
)
mnalis
Metadata
Metadata
Assignees
Labels
api ergonomicsImproves API usability without net-new functionalityImproves API usability without net-new functionality