Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0ff2c3b authored by Ellen Poe's avatar Ellen Poe
Browse files

Merge branch 'ellenhp/map_annotation_bugfixes' into 'main'

Map marker and annotation bugfixes

See merge request e/os/cardinal!40
parents 0a3f9c7f 07c910d4
Loading
Loading
Loading
Loading
Loading
+31 −6
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import earth.maps.cardinal.data.PolylineUtils
import earth.maps.cardinal.data.desaturate
import earth.maps.cardinal.data.formatDuration
import earth.maps.cardinal.data.room.OfflineArea
import earth.maps.cardinal.data.room.SavedPlace
import earth.maps.cardinal.transit.Itinerary
import earth.maps.cardinal.transit.Mode
import earth.maps.cardinal.ui.map.LocationPuck
@@ -76,7 +77,10 @@ import kotlinx.serialization.json.encodeToJsonElement
import org.maplibre.compose.camera.CameraState
import org.maplibre.compose.expressions.dsl.Feature.get
import org.maplibre.compose.expressions.dsl.Feature.has
import org.maplibre.compose.expressions.dsl.asString
import org.maplibre.compose.expressions.dsl.collator
import org.maplibre.compose.expressions.dsl.const
import org.maplibre.compose.expressions.dsl.feature
import org.maplibre.compose.expressions.dsl.image
import org.maplibre.compose.expressions.dsl.offset
import org.maplibre.compose.expressions.dsl.rgbColor
@@ -181,9 +185,7 @@ fun MapView(
                val location by mapViewModel.locationFlow.collectAsState()
                val sensorHeading by mapViewModel.heading.collectAsState()
                val savedPlaces by mapViewModel.savedPlacesFlow.collectAsState(FeatureCollection())
                location?.let { LocationPuck(it, sensorHeading) }

                FavoritesLayer(savedPlaces, isSystemInDarkTheme())
                FavoritesLayer(savedPlaces, mapPins, isSystemInDarkTheme())

                OfflineBoundsLayer(selectedOfflineArea)

@@ -192,6 +194,8 @@ fun MapView(
                TransitLayer(currentTransitItinerary)

                PinsLayer(pinFeatures, isSystemInDarkTheme())

                location?.let { LocationPuck(it, sensorHeading) }
            }
        } else {
            // Handle invalid port - could show an error message
@@ -218,11 +222,17 @@ fun MapView(
}

@Composable
private fun FavoritesLayer(savedPlaces: FeatureCollection, isSystemInDarkTheme: Boolean) {
private fun FavoritesLayer(
    savedPlaces: FeatureCollection,
    activeMarkers: List<Place>,
    isSystemInDarkTheme: Boolean
) {
    val textColor = MaterialTheme.colorScheme.onSurface
    val activeMarkerIds = activeMarkers.mapNotNull { it.id }
    SymbolLayer(
        id = "user_favorites",
        source = rememberGeoJsonSource(GeoJsonData.Features(savedPlaces)),
        iconAllowOverlap = const(true),
        iconImage = image(
            if (isSystemInDarkTheme) {
                painterResource(drawable.ic_stars_dark)
@@ -230,8 +240,21 @@ private fun FavoritesLayer(savedPlaces: FeatureCollection, isSystemInDarkTheme:
                painterResource(drawable.ic_stars_light)
            }
        ),
        // Make the icon transparent if there's a pin symbol above it.
        iconOpacity = if (activeMarkerIds.isNotEmpty()) {
            org.maplibre.compose.expressions.dsl.switch(
                input = feature["saved_poi_id"].asString(),
                org.maplibre.compose.expressions.dsl.case(
                    activeMarkers.mapNotNull { it.id },
                    const(0f),
                ),
                fallback = const(1f)
            )
        } else {
            const(1f)
        },
        iconSize = const(0.8f),
        textField = org.maplibre.compose.expressions.dsl.Feature["name"].cast(),
        textField = feature["name"].asString(),
        textSize = const(0.8.em),
        textColor = rgbColor(
            const((textColor.red * 255.0f).toInt()),
@@ -498,6 +521,8 @@ private fun PinsLayer(pinFeatures: List<Feature>, isSystemInDarkTheme: Boolean)
    SymbolLayer(
        id = "map_pins",
        source = rememberGeoJsonSource(GeoJsonData.Features(FeatureCollection(features = pinFeatures))),
        iconAllowOverlap = const(true),
        iconAnchor = const(SymbolAnchor.Bottom),
        iconImage = image(
            if (isSystemInDarkTheme) {
                painterResource(drawable.map_pin_dark)
+2 −1
Original line number Diff line number Diff line
@@ -104,9 +104,10 @@ class MapViewModel @Inject constructor(
    fun createFeatureFromPlace(place: Place): Feature {
        val properties = mutableMapOf(
            "name" to escapeJsonString(place.name),
            "description" to escapeJsonString(place.description)
            "description" to escapeJsonString(place.description),
        )

        place.id?.let { properties["id"] = escapeJsonString(it) }
        place.address?.houseNumber?.let { properties["addr:housenumber"] = escapeJsonString(it) }
        place.address?.road?.let { properties["addr:street"] = escapeJsonString(it) }
        place.address?.city?.let { properties["addr:city"] = escapeJsonString(it) }
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ fun LocationPuckLayers(idPrefix: String, locationSource: Source, headingDegrees:
    SymbolLayer(
        id = "${idPrefix}-puck",
        source = locationSource,
        iconAllowOverlap = const(true),
        iconImage = image(puckDrawable),
        iconRotate = const(headingDegrees ?: 0f),
    )