Skip to content

Commit b7f7eff

Browse files
committed
Add debug tree map
1 parent 8c37f50 commit b7f7eff

File tree

3 files changed

+286
-81
lines changed

3 files changed

+286
-81
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package org.greenstand.android.TreeTracker.map
2+
3+
import androidx.compose.foundation.layout.fillMaxSize
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.DisposableEffect
6+
import androidx.compose.runtime.remember
7+
import androidx.compose.ui.Modifier
8+
import androidx.compose.ui.platform.LocalContext
9+
import androidx.compose.ui.platform.LocalLifecycleOwner
10+
import androidx.compose.ui.viewinterop.AndroidView
11+
import androidx.lifecycle.Lifecycle
12+
import androidx.lifecycle.LifecycleEventObserver
13+
import org.maplibre.android.annotations.MarkerOptions
14+
import org.maplibre.android.camera.CameraPosition
15+
import org.maplibre.android.camera.CameraUpdateFactory
16+
import org.maplibre.android.geometry.LatLng
17+
import org.maplibre.android.geometry.LatLngBounds
18+
import org.maplibre.android.maps.MapView
19+
20+
@Composable
21+
fun LibreMap(
22+
markers: List<MapMarker>,
23+
selectedMarkerId: String?,
24+
modifier: Modifier = Modifier,
25+
styleUrl: String = "https://demotiles.maplibre.org/style.json"
26+
) {
27+
val context = LocalContext.current
28+
val lifecycleOwner = LocalLifecycleOwner.current
29+
30+
val mapView = remember {
31+
MapView(context).apply {
32+
getMapAsync { mapLibreMap ->
33+
mapLibreMap.setStyle(styleUrl) {
34+
// Set initial camera position (centered on equator with moderate zoom)
35+
val initialPosition = CameraPosition.Builder()
36+
.target(LatLng(0.0, 0.0))
37+
.zoom(2.0)
38+
.build()
39+
mapLibreMap.cameraPosition = initialPosition
40+
}
41+
}
42+
}
43+
}
44+
45+
// Handle lifecycle events
46+
DisposableEffect(lifecycleOwner) {
47+
val observer = LifecycleEventObserver { _, event ->
48+
when (event) {
49+
Lifecycle.Event.ON_START -> mapView.onStart()
50+
Lifecycle.Event.ON_RESUME -> mapView.onResume()
51+
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
52+
Lifecycle.Event.ON_STOP -> mapView.onStop()
53+
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
54+
else -> {}
55+
}
56+
}
57+
lifecycleOwner.lifecycle.addObserver(observer)
58+
onDispose {
59+
lifecycleOwner.lifecycle.removeObserver(observer)
60+
mapView.onDestroy()
61+
}
62+
}
63+
64+
AndroidView(
65+
modifier = modifier.fillMaxSize(),
66+
factory = { mapView },
67+
update = { view ->
68+
view.getMapAsync { mapLibreMap ->
69+
mapLibreMap.getStyle { style ->
70+
// Clear existing markers
71+
mapLibreMap.clear()
72+
73+
// Add markers in bulk
74+
if (markers.isNotEmpty()) {
75+
val markerOptions = markers.map { marker ->
76+
MarkerOptions()
77+
.position(LatLng(marker.latitude, marker.longitude))
78+
}
79+
80+
// Add all markers at once
81+
mapLibreMap.addMarkers(markerOptions)
82+
83+
// Handle selected marker zoom
84+
if (selectedMarkerId != null) {
85+
val selectedMarker = markers.find { it.id == selectedMarkerId }
86+
selectedMarker?.let { marker ->
87+
val position = CameraPosition.Builder()
88+
.target(LatLng(marker.latitude, marker.longitude))
89+
.zoom(14.0)
90+
.build()
91+
mapLibreMap.animateCamera(CameraUpdateFactory.newCameraPosition(position))
92+
}
93+
} else {
94+
// Calculate bounds to fit all markers
95+
val boundsBuilder = LatLngBounds.Builder()
96+
markers.forEach { marker ->
97+
boundsBuilder.include(LatLng(marker.latitude, marker.longitude))
98+
}
99+
100+
val bounds = boundsBuilder.build()
101+
val padding = 100 // padding in pixels
102+
103+
// Animate camera to show all markers
104+
mapLibreMap.animateCamera(
105+
CameraUpdateFactory.newLatLngBounds(bounds, padding)
106+
)
107+
}
108+
}
109+
}
110+
}
111+
}
112+
)
113+
}

0 commit comments

Comments
 (0)