add more optimalization and speed mareker

This commit is contained in:
PoliEcho 2026-02-13 12:28:19 +01:00
parent 67fea51949
commit 0e2208d104
4 changed files with 109 additions and 48 deletions

View File

@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-01-28T21:00:38.307279245Z"> <DropdownSelection timestamp="2026-02-13T11:13:35.143900668Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=BS98317AA1341400032" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=BS98317AA1341400032" />

View File

@ -13,6 +13,7 @@ import androidx.compose.ui.unit.dp
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import ovh.plrapps.mapcompose.api.addClusterer
import ovh.plrapps.mapcompose.api.addMarker import ovh.plrapps.mapcompose.api.addMarker
import ovh.plrapps.mapcompose.api.removeMarker import ovh.plrapps.mapcompose.api.removeMarker
import ovh.plrapps.mapcompose.ui.state.markers.model.RenderingStrategy import ovh.plrapps.mapcompose.ui.state.markers.model.RenderingStrategy
@ -81,12 +82,13 @@ val gtfshttpClient = OkHttpClient.Builder()
private val GTFSMainHandler = Handler(Looper.getMainLooper()) private val GTFSMainHandler = Handler(Looper.getMainLooper())
private var GTFSTrackingThread: Thread? = null private var GTFSTrackingThread: Thread? = null
private var GTFSIsTracking = false private var GTFSIsTracking = false
private var GTFSIsInitialized = false // Prevent duplicate initialization
private fun fetchGTFSPosition(gtfsUrl: URL,api_key: String, callee: Activity) { private fun fetchGTFSPosition(gtfsUrl: URL,api_key: String, callee: Activity) {
try { try {
val request = Request.Builder() val request = Request.Builder()
.url("${gtfsUrl.protocol}://${gtfsUrl.host}${"/"}") .url("${gtfsUrl.protocol}://${gtfsUrl.host}${"/"}.pd")
.header("User-Agent", "${BuildConfig.APPLICATION_ID}/${BuildConfig.VERSION_NAME} (Android)") .header("User-Agent", "${BuildConfig.APPLICATION_ID}/${BuildConfig.VERSION_NAME} (Android)")
.build() .build()
@ -116,7 +118,7 @@ fun startGTFSTracking(url: String, api_key: String, callee: Activity) {
GTFSTrackingThread = Thread { GTFSTrackingThread = Thread {
val gtfsUrl = URL(url); val gtfsUrl = URL(url);
try { try {
if(gtfsRoutes.isEmpty()) { if(gtfsRoutes.isEmpty() && !GTFSIsInitialized) {
GTFSMainHandler.post { GTFSMainHandler.post {
Toast.makeText(callee, "Fetching routes...", Toast.LENGTH_SHORT).show()} Toast.makeText(callee, "Fetching routes...", Toast.LENGTH_SHORT).show()}
@ -170,23 +172,49 @@ fun startGTFSTracking(url: String, api_key: String, callee: Activity) {
offset += messageParsed.features.size; offset += messageParsed.features.size;
}while(messageParsed.features.isNotEmpty()) }while(messageParsed.features.isNotEmpty())
} }
// put all stops on the map // put all stops on the map in batches to prevent ANR
GTFSMainHandler.post { GTFSMainHandler.post {
Toast.makeText(callee, "Drawing stops...", Toast.LENGTH_SHORT).show()} Toast.makeText(callee, "Drawing stops...", Toast.LENGTH_SHORT).show()}
for (stop in gtfsStops!!.features) {
if (stop.properties.parent_station == null) { val stopsToAdd = gtfsStops!!.features.filter { it.properties.parent_station == null }
mapState.addMarker(stop.properties.stop_id, x = longitudeToXNormalized(stop.geometry.coordinates[0]), y = latitudeToYNormalized(stop.geometry.coordinates[1]), renderingStrategy = RenderingStrategy.LazyLoading("default")) { val batchSize = 50 // Process 50 markers at a time
Icon( val totalStops = stopsToAdd.size
painter = painterResource(id = R.drawable.outline_directions_bus_24), var processed = 0
contentDescription = null,
modifier = Modifier.size(12.dp), for (batch in stopsToAdd.chunked(batchSize)) {
tint = Color(0xFF0000FF) if (!GTFSIsTracking) break // Stop if tracking was cancelled
)
}} GTFSMainHandler.post {
for (stop in batch) {
try {
mapState.addMarker(
stop.properties.stop_id,
x = longitudeToXNormalized(stop.geometry.coordinates[0]),
y = latitudeToYNormalized(stop.geometry.coordinates[1]),
renderingStrategy = RenderingStrategy.LazyLoading("default")
) {
Icon(
painter = painterResource(id = R.drawable.outline_directions_bus_24),
contentDescription = null,
modifier = Modifier.size(12.dp),
tint = Color(0xFF0000FF)
)
}
} catch (e: Exception) {
// Skip markers that fail to add
}
}
}
processed += batch.size
// Small delay between batches to let UI breathe
Thread.sleep(50)
} }
GTFSMainHandler.post { GTFSMainHandler.post {
Toast.makeText(callee, "Done drawing ${gtfsStops.features.size} stops", Toast.LENGTH_SHORT).show()} Toast.makeText(callee, "Done drawing ${totalStops} stops", Toast.LENGTH_SHORT).show()}
GTFSIsInitialized = true // Mark as initialized to prevent duplicate additions
} catch(e: Exception) { } catch(e: Exception) {
GTFSMainHandler.post { GTFSMainHandler.post {
@ -208,6 +236,7 @@ fun startGTFSTracking(url: String, api_key: String, callee: Activity) {
fun stopGTFSTracking() { fun stopGTFSTracking() {
GTFSIsTracking = false GTFSIsTracking = false
GTFSIsInitialized = false
for (stop in gtfsStops!!.features) { for (stop in gtfsStops!!.features) {
if (stop.properties.parent_station == null) { if (stop.properties.parent_station == null) {
mapState.removeMarker(stop.properties.stop_id); mapState.removeMarker(stop.properties.stop_id);

View File

@ -53,11 +53,17 @@ private fun fetchHaukPosition(haukUrl: String, callee: Activity) {
val lat = hauk_response.points.last()?.getOrNull(0) val lat = hauk_response.points.last()?.getOrNull(0)
val lon = hauk_response.points.last()?.getOrNull(1) val lon = hauk_response.points.last()?.getOrNull(1)
if (lat != null && lon != null) { if (lat != null && lon != null) {
HaukMainHandler.post { HaukMainHandler.post {
mapState.moveMarker("target_position", x = longitudeToXNormalized(lon), y = latitudeToYNormalized(lat)) try {
} mapState.moveMarker("target_position", x = longitudeToXNormalized(lon), y = latitudeToYNormalized(lat))
} catch (e: Exception) {
// Marker might not exist yet, ignore
}
}
} else { } else {
Toast.makeText(callee, "TARGET LOCATION NOT AVAILABLE", Toast.LENGTH_SHORT).show() HaukMainHandler.post {
Toast.makeText(callee, "TARGET LOCATION NOT AVAILABLE", Toast.LENGTH_SHORT).show()
}
}} }}
} catch (e: Exception) { } catch (e: Exception) {
// Post UI update to main thread // Post UI update to main thread

View File

@ -53,6 +53,7 @@ import java.net.URL
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
import android.os.StrictMode import android.os.StrictMode
import androidx.compose.ui.unit.sp
// Thread pool for tile downloading to prevent blocking UI thread // Thread pool for tile downloading to prevent blocking UI thread
@ -364,39 +365,64 @@ fun OpenStreetMapScreen(context: Context? = null) {
} }
} }
mapState.addLazyLoader("default"); // Track if map has been initialized to prevent duplicate operations
var mapInitialized by remember { mutableStateOf(false) }
/* Add a marker at the center of the map */ // Add the tile layer, markers, and set initial position - all in LaunchedEffect to avoid blocking main thread
mapState.addMarker("target_position", x = longitudeToXNormalized(14.4058031), y = latitudeToYNormalized(50.0756083)) {
Icon(
painter = painterResource(id = R.drawable.target),
contentDescription = null,
modifier = Modifier.size(20.dp),
tint = Color(0xFFFF0000)
)
}
/* Add a marker for current position */
mapState.addMarker("current_position", x = longitudeToXNormalized(14.4378), y = latitudeToYNormalized(50.0755)) {
Icon(
painter = painterResource(id = R.drawable.user_location),
contentDescription = null,
modifier = Modifier.size(20.dp),
tint = Color(0xFF0000FF) // Blue color for current position
)
}
// Add the tile layer and set initial position
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
mapState.addLayer(tileStreamProvider) if (!mapInitialized) {
// Add lazy loader first
mapState.addLazyLoader("default")
// Scroll to Prague, Czech Republic // Add tile layer
// Prague coordinates: latitude 50.0755, longitude 14.4378 mapState.addLayer(tileStreamProvider)
val normalizedX = longitudeToXNormalized(14.4378)
val normalizedY = latitudeToYNormalized(50.0755)
// Use a higher scale to zoom in more (closer to 1.0 = more zoomed in) /* Add a marker at the center of the map */
mapState.scrollTo(normalizedX, normalizedY, destScale = 0.1) mapState.addMarker("target_position", x = longitudeToXNormalized(14.0), y = latitudeToYNormalized(50.0)) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Icon(
painter = painterResource(id = R.drawable.target),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color(0xFFFF0000)
)
Surface(
color = Color.Red,
shadowElevation = 4.dp,
shape = MaterialTheme.shapes.small,
modifier = Modifier.padding(1.dp)
) {
Text(
text = "0.0km/h",
modifier = Modifier.padding(1.dp),
style = MaterialTheme.typography.bodyMedium,
fontSize = 8.sp,
color = Color.Blue
)
}
}
}
/* Add a marker for current position */
mapState.addMarker("current_position", x = longitudeToXNormalized(14.0), y = latitudeToYNormalized(50.0)) {
Icon(
painter = painterResource(id = R.drawable.user_location),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color(0xFF004802)
)
}
// Scroll to Prague, Czech Republic
// Prague coordinates: latitude 50.0755, longitude 14.4378
val normalizedX = longitudeToXNormalized(14.4378)
val normalizedY = latitudeToYNormalized(50.0755)
// Use a higher scale to zoom in more (closer to 1.0 = more zoomed in)
mapState.scrollTo(normalizedX, normalizedY, destScale = 0.1)
mapInitialized = true
}
} }
// Display the map // Display the map