From 75c61c2b5b3fbda316dc4e82b6027d80ff7132d3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 4 Jun 2026 06:35:07 +0000 Subject: Fix wind particles never appearing Two bugs prevented wind particles from rendering: 1. Retrofit URL-encoded commas in the batch lat/lon query strings (%2C instead of ,), so Open-Meteo rejected every grid fetch silently. Fixed with encoded=true on the @Query annotations. 2. loadWindGrid() was only called from onCameraIdleListener, so particles never started unless the user manually panned. Added an eager trigger on the first GPS fix using the map's current visible region. Also added a log warning when fetchWindGrid fails so future failures are visible in logcat. https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa --- .../app/src/main/kotlin/org/terst/nav/MainActivity.kt | 15 +++++++++++++++ .../kotlin/org/terst/nav/data/api/WeatherApiService.kt | 4 ++-- .../app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'android-app/app/src/main/kotlin') diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index 0a37eaf..94b9c81 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -38,6 +38,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.util.Locale import org.maplibre.android.MapLibre +import org.maplibre.android.maps.MapLibreMap import org.maplibre.android.maps.MapView import org.maplibre.android.maps.Style import org.maplibre.android.style.layers.RasterLayer @@ -71,10 +72,12 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { private var mobHandler: MobHandler? = null private var instrumentHandler: InstrumentHandler? = null private var mapHandler: MapHandler? = null + private var cachedMap: MapLibreMap? = null private val loadedStyleFlow = MutableStateFlow(null) private lateinit var layerManager: MapLayerManager private var particleWindView: ParticleWindView? = null private var weatherLoaded = false + private var windGridLoaded = false private var cameraIdleJob: Job? = null private lateinit var bottomSheetBehavior: BottomSheetBehavior @@ -624,6 +627,7 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { mapView?.onCreate(null) mapView?.getMapAsync { maplibreMap -> mapHandler = MapHandler(maplibreMap) + cachedMap = maplibreMap particleWindView?.attachMap(maplibreMap) lifecycleScope.launch { @@ -768,6 +772,17 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { weatherLoaded = true viewModel.loadWeather(gpsData.latitude, gpsData.longitude) } + if (!windGridLoaded) { + windGridLoaded = true + val r = cachedMap?.projection?.visibleRegion + val corners = listOfNotNull(r?.nearLeft, r?.nearRight, r?.farLeft, r?.farRight) + if (corners.size == 4) { + viewModel.loadWindGrid( + corners.minOf { it.latitude }, corners.maxOf { it.latitude }, + corners.minOf { it.longitude }, corners.maxOf { it.longitude } + ) + } + } } } lifecycleScope.launch { diff --git a/android-app/app/src/main/kotlin/org/terst/nav/data/api/WeatherApiService.kt b/android-app/app/src/main/kotlin/org/terst/nav/data/api/WeatherApiService.kt index bce3534..db5caee 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/data/api/WeatherApiService.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/data/api/WeatherApiService.kt @@ -19,8 +19,8 @@ interface WeatherApiService { /** Batch endpoint: comma-separated lat/lon → JSON array of WeatherResponse. */ @GET("v1/forecast") suspend fun getWeatherForecastBatch( - @Query("latitude") latitudes: String, - @Query("longitude") longitudes: String, + @Query(value = "latitude", encoded = true) latitudes: String, + @Query(value = "longitude", encoded = true) longitudes: String, @Query("hourly") hourly: String = "windspeed_10m,winddirection_10m", @Query("forecast_days") forecastDays: Int = 1, @Query("wind_speed_unit") windSpeedUnit: String = "kn" diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt index 7d0ab33..288fef4 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt @@ -381,7 +381,9 @@ class MainViewModel( windGridThrottle.update(centerLat, centerLon) viewModelScope.launch { val points = buildGrid(latMin, latMax, lonMin, lonMax, cols = 4, rows = 5) - repository.fetchWindGrid(points).getOrNull()?.let { _windGrid.value = it } + val result = repository.fetchWindGrid(points) + result.onFailure { NavLogger.w("windGrid", "fetchWindGrid failed: ${it.message}") } + result.getOrNull()?.let { _windGrid.value = it } } } -- cgit v1.2.3