diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 88573ebf..85ec08e2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -39,6 +39,7 @@ kotlin { implementation(libs.mpandroidchart) implementation(libs.coil.core) implementation(libs.coil.svg) + implementation(libs.maplibre) } commonMain.dependencies { implementation(libs.kotlinx.serialization) diff --git a/app/src/androidMain/kotlin/activity/Activity.kt b/app/src/androidMain/kotlin/activity/Activity.kt index fca0bb52..30b3d205 100644 --- a/app/src/androidMain/kotlin/activity/Activity.kt +++ b/app/src/androidMain/kotlin/activity/Activity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat import org.btcmap.databinding.ActivityBinding +import org.maplibre.android.MapLibre class Activity : AppCompatActivity() { @@ -11,6 +12,7 @@ class Activity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + MapLibre.getInstance(this) binding = ActivityBinding.inflate(layoutInflater) setContentView(binding.root) WindowCompat.setDecorFitsSystemWindows(window, false) diff --git a/app/src/androidMain/kotlin/element/ElementFragment.kt b/app/src/androidMain/kotlin/element/ElementFragment.kt index 33564932..8d704567 100644 --- a/app/src/androidMain/kotlin/element/ElementFragment.kt +++ b/app/src/androidMain/kotlin/element/ElementFragment.kt @@ -29,13 +29,17 @@ import kotlinx.coroutines.runBlocking import map.MapMarkersRepo import map.getErrorColor import map.getOnSurfaceColor +import map.initStyle import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.btcmap.R import org.btcmap.databinding.FragmentElementBinding import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.activityViewModel -import org.osmdroid.util.GeoPoint -import org.osmdroid.views.overlay.Marker +import org.maplibre.android.annotations.IconFactory +import org.maplibre.android.annotations.MarkerOptions +import org.maplibre.android.camera.CameraPosition +import org.maplibre.android.camera.CameraUpdateFactory +import org.maplibre.android.geometry.LatLng import search.SearchResultModel import java.time.ZonedDateTime @@ -94,20 +98,21 @@ class ElementFragment : Fragment() { findNavController().navigate(R.id.action_elementFragment_to_mapFragment) } - binding.map.post { - val mapController = binding.map.controller - mapController.setZoom(16.toDouble()) - val startPoint = GeoPoint(element.lat, element.lon) - mapController.setCenter(startPoint) - mapController.zoomTo(19.0) - + binding.map.getMapAsync { map -> + map.uiSettings.setAllGesturesEnabled(false) + map.initStyle(requireContext()) + map.cameraPosition = + CameraPosition.Builder().target(LatLng(element.lat, element.lon)).zoom(15.0) + .build() val markersRepo = MapMarkersRepo(requireContext()) - val marker = Marker(binding.map) - marker.position = GeoPoint(element.lat, element.lon) - marker.icon = markersRepo.getMarker( + val icon = markersRepo.getMarker( element.tags.optString("icon:android").ifBlank { "question_mark" }, 0 ) - binding.map.overlays.add(marker) + val markerOptions = MarkerOptions() + .position(LatLng(element.lat, element.lon)) + .icon(IconFactory.getInstance(requireContext()).fromBitmap(icon.bitmap)) + map.addMarker(markerOptions) + map.animateCamera(CameraUpdateFactory.zoomTo(17.0), 3_000) } } diff --git a/app/src/androidMain/kotlin/map/MapViewExtensions.kt b/app/src/androidMain/kotlin/map/MapViewExtensions.kt index d86f724d..59d7289a 100644 --- a/app/src/androidMain/kotlin/map/MapViewExtensions.kt +++ b/app/src/androidMain/kotlin/map/MapViewExtensions.kt @@ -1,7 +1,10 @@ package map +import android.content.Context +import android.content.res.Configuration import android.graphics.Color import org.locationtech.jts.geom.Polygon +import org.maplibre.android.maps.MapLibreMap import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView @@ -23,4 +26,15 @@ fun MapView.showPolygons(polygons: List, paddingPx: Int) { paddingPx, ) } +} + +fun MapLibreMap.initStyle(context: Context) { + val nightMode = + context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES + + if (nightMode) { + setStyle("https://tiles.openfreemap.org/styles/positron") + } else { + setStyle("https://tiles.openfreemap.org/styles/bright") + } } \ No newline at end of file diff --git a/app/src/androidMain/res/layout/fragment_element.xml b/app/src/androidMain/res/layout/fragment_element.xml index 58950d97..8483f23d 100644 --- a/app/src/androidMain/res/layout/fragment_element.xml +++ b/app/src/androidMain/res/layout/fragment_element.xml @@ -30,13 +30,13 @@ android:id="@+id/mapContainer" android:layout_width="match_parent" android:layout_height="192dp" - android:clickable="true" - android:focusable="true" android:paddingBottom="4dp" android:visibility="gone"> - diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e9facb27..e161b141 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -51,6 +51,8 @@ serialization = "1.7.3" # Platform-agnostic date and time handling # https://github.com/Kotlin/kotlinx-datetime/releases datetime = "0.6.1" +# https://github.com/maplibre/maplibre-native/releases +maplibre = "11.5.2" [libraries] kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" } @@ -75,6 +77,7 @@ jts = { module = "org.locationtech.jts:jts-core", version.ref = "jts" } mpandroidchart = { module = "com.github.PhilJay:MPAndroidChart", version.ref = "mpandroidchart" } coil-core = { module = "io.coil-kt:coil", version.ref = "coil" } coil-svg = { module = "io.coil-kt:coil-svg", version.ref = "coil" } +maplibre = { module = "org.maplibre.gl:android-sdk", version.ref = "maplibre" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" }