commit 053f80631c6e5c783efed28e90e3cb0cbf24ed35 Author: Fabio Mazza Date: Mon Oct 5 12:42:13 2026 +0200 Fix map zooming on user location when opening a stop Summary: Test Plan: Reviewers: Subscribers: diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt index 915b4f3..25873eb 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt @@ -104,9 +104,11 @@ import kotlin.time.Duration.Companion.milliseconds abstract class GeneralMapLibreFragment: ScreenBaseFragment(), OnMapReadyCallback { protected var map: MapLibreMap? = null - protected var shownStopInBottomSheet : Stop? = null - //protected var savedMapStateOnPause : Bundle? = null + /** + * Stop to show in Bottom Sheet, if it is null, no stop is shown + */ + protected var shownStopInBottomSheet : Stop? = null protected var fragmentListener: CommonFragmentListener? = null @@ -190,6 +192,9 @@ abstract class GeneralMapLibreFragment: ScreenBaseFragment(), OnMapReadyCallback //BUS POSITIONS protected val updatesByVehDict = HashMap(5) protected val animatorsByVeh = HashMap() + /** + * Label of the vehicle to show in Bottom Sheet, if it is null, no vehicle is shown + */ protected var vehShowing: String? = null protected var lastUpdateTime:Long = -2 protected var jobUpdate: Job? = null @@ -1191,6 +1196,9 @@ abstract class GeneralMapLibreFragment: ScreenBaseFragment(), OnMapReadyCallback } } } + protected fun showingBusStopOrVehicle(): Boolean{ + return !(shownStopInBottomSheet == null && vehShowing == null) + } /** * Clear all buses from the map diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt index 6309490..367d933 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt @@ -28,14 +28,12 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageButton -import android.widget.RelativeLayout import android.widget.Toast import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.preference.PreferenceManager import androidx.room.concurrent.AtomicBoolean -import com.google.android.material.bottomsheet.BottomSheetBehavior import it.reyboz.bustorino.R import it.reyboz.bustorino.backend.Stop import it.reyboz.bustorino.backend.gtfs.LivePositionUpdate @@ -252,17 +250,15 @@ class MapLibreFragment : GeneralMapLibreFragment() { val builder = Style.Builder().fromJson(mjson!!) mapReady.setStyle(builder) { style -> - mapStyle = style //setupLayers(style) addImagesStyle(style) //init stop layer with this val stopsInCache = stopsViewModel.stopsToShow.value - if(stopsInCache.isNullOrEmpty()) - initStopsLayer(style, null) - else - displayStops(stopsInCache) + if(stopsInCache.isNullOrEmpty()) initStopsLayer(style, null) + else displayStops(stopsInCache) + if(showBusLayer) setupBusLayer(style, withLabels = true, busIconsScale = 1.2f) // Start observing data now that everything is set up @@ -275,12 +271,8 @@ class MapLibreFragment : GeneralMapLibreFragment() { mapReady.addOnCameraIdleListener { map?.let { val newBbox = it.projection.visibleRegion.latLngBounds - stopsViewModel.loadStopsInLatLngBounds(newBbox) lastBBox = newBbox - - - } } @@ -326,8 +318,7 @@ class MapLibreFragment : GeneralMapLibreFragment() { } if(!boundsRestored){ // we have not restored the bounds, open normally in target location - // TODO: check that the map is reopened in the same location - val lastLoc = mapStateViewModel.locationToShow + val lastLoc = mapStateViewModel.userLocationToShow val defaultLoc = LatLng(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON) val proposedLoc = lastLoc?.let{ LatLng(lastLoc.latitude, lastLoc.longitude)} val targetLoc = if(proposedLoc == null || proposedLoc.distanceTo(defaultLoc) > MAX_DIST_KM*1000) @@ -372,7 +363,6 @@ class MapLibreFragment : GeneralMapLibreFragment() { //isBottomSheetShowing = true //move camera if (newstop.latitude != null && newstop.longitude != null) - //mapReady.cameraPosition = CameraPosition.Builder().target(LatLng(it.latitude!!, it.longitude!!)).build() mapReady.animateCamera( CameraUpdateFactory.newLatLng(LatLng(newstop.latitude!!, newstop.longitude!!)), 750 @@ -511,6 +501,10 @@ class MapLibreFragment : GeneralMapLibreFragment() { ) } } + private fun hasToShowInitialStop(): Boolean{ + return if(initialStopToShow==null) false + else !initialStopShown + } private fun observeStops() { // Observe stops stopsViewModel.stopsToShow.observe(viewLifecycleOwner) { stops -> @@ -608,13 +602,12 @@ class MapLibreFragment : GeneralMapLibreFragment() { res?.lastLocation?.let { loc -> if(mapInitialized){ val newLocation = LatLng(loc.latitude, loc.longitude) - //center the position only if it is close enough - if(newLocation.distanceTo(DEFAULT_LATLNG) < MAX_DIST_KM * 1000) + //center the position only if it is close enough and we are not showing a stop + if(!showingBusStopOrVehicle() && newLocation.distanceTo(DEFAULT_LATLNG) < MAX_DIST_KM * 1000) map?.cameraPosition = CameraPosition.Builder().target(LatLng(loc.latitude, loc.longitude)).build() - } else - mapStateViewModel.locationToShow = loc + mapStateViewModel.userLocationToShow = loc } } @@ -628,7 +621,7 @@ class MapLibreFragment : GeneralMapLibreFragment() { }) } if(locationEnabledOnDevice){ - if(shownStopInBottomSheet == null && vehShowing == null) + if(!showingBusStopOrVehicle() && !hasToShowInitialStop()) setFollowUserLocation(true) } @@ -637,7 +630,7 @@ class MapLibreFragment : GeneralMapLibreFragment() { override fun onMapLocationEnabled(active: Boolean) { //Extra stuff to do // this check should always pass - if(shownStopInBottomSheet == null && vehShowing == null) + if(!(showingBusStopOrVehicle()) || hasToShowInitialStop()) setFollowUserLocation(active) } @@ -645,7 +638,7 @@ class MapLibreFragment : GeneralMapLibreFragment() { override fun onFirstReceivedLocation(location: Location) { val it = location - val notShowingStopOrVehicle = vehShowing.isNullOrEmpty() && shownStopInBottomSheet != null + //val notShowingStopOrVehicle = s//vehShowing.isNullOrEmpty() && shownStopInBottomSheet != null if(locationInitialized && !receivedFirstLocation) { //only zoom if the user position is close enough to the center val newPoint = LatLng(it.latitude, it.longitude) @@ -659,7 +652,7 @@ class MapLibreFragment : GeneralMapLibreFragment() { //Update UI Status mapStateViewModel.locationUserActive.value = false mapStateViewModel.followingUserPosition.value = false - } else if(notShowingStopOrVehicle) { + } else if(!(showingBusStopOrVehicle()||hasToShowInitialStop())) { map?.apply { animateCamera( CameraUpdateFactory.newCameraPosition( @@ -680,7 +673,7 @@ class MapLibreFragment : GeneralMapLibreFragment() { } else{ //check for this is when the map is used - mapStateViewModel.locationToShow = location + mapStateViewModel.userLocationToShow = location } } diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/MapStateViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/MapStateViewModel.kt index 3a53046..dd11e50 100644 --- a/app/src/main/java/it/reyboz/bustorino/viewmodels/MapStateViewModel.kt +++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/MapStateViewModel.kt @@ -33,7 +33,7 @@ class MapStateViewModel : ViewModel() { return restoreMapState(map, this.savedCameraState) } - var locationToShow: Location? = null + var userLocationToShow: Location? = null val locationUserActive = MutableLiveData(false) val followingUserPosition = MutableLiveData(false)