mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
NearbyParentFragment.kt: fix bug where multiple user location overlays would appear
Before this commit, the user could see multiple user location overlays if they paused the app and reopened it when there are no Places/pins on the map. This was caused by a linear search failing to identify the target overlay because it compared Drawables between two Overlays, which was unreliable. This commit contains a better solution for replacing existing user location overlays by adding 2 instance variables to keep track of the overlays. The position of these overlays in the overlay list can then be found by using indexOf() with these instance variables rather than the linear search that was implemented before. Some refactoring was also done.
This commit is contained in:
parent
01b0d5251b
commit
c684008803
1 changed files with 57 additions and 41 deletions
|
|
@ -123,6 +123,7 @@ import org.osmdroid.views.CustomZoomButtonsController
|
|||
import org.osmdroid.views.MapView
|
||||
import org.osmdroid.views.overlay.MapEventsOverlay
|
||||
import org.osmdroid.views.overlay.Marker
|
||||
import org.osmdroid.views.overlay.Overlay
|
||||
import org.osmdroid.views.overlay.ScaleBarOverlay
|
||||
import org.osmdroid.views.overlay.ScaleDiskOverlay
|
||||
import org.osmdroid.views.overlay.TilesOverlay
|
||||
|
|
@ -267,6 +268,9 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
private var dataList: MutableList<BottomSheetItem>? = null
|
||||
private var bottomSheetAdapter: BottomSheetAdapter? = null
|
||||
|
||||
private var userLocationOverlay: Overlay? = null
|
||||
private var userLocationErrorOverlay: Overlay? = null
|
||||
|
||||
private val galleryPickLauncherForResult =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
controller?.handleActivityResultWithCallback(
|
||||
|
|
@ -2690,47 +2694,8 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
*/
|
||||
private fun updateUserLocationOverlays(geoPoint: GeoPoint?, invalidate: Boolean) {
|
||||
geoPoint?.let{
|
||||
val overlays = binding?.map?.overlays ?: return@let
|
||||
|
||||
// Multiply accuracy by 2 to get 95% confidence interval
|
||||
val accuracy = getCurrentLocationAccuracy() * 2
|
||||
|
||||
// Create disk overlay
|
||||
val errorOverlay = createCurrentLocationErrorOverlay(this.context, geoPoint,
|
||||
(accuracy).toInt(), UnitOfMeasure.meter)
|
||||
|
||||
// Create current location overlay
|
||||
val locationOverlay = createCurrentLocationOverlay(geoPoint)
|
||||
|
||||
var locationOverlayFound = false
|
||||
var errorOverlayFound = false
|
||||
|
||||
// Find and replace overlays
|
||||
for (i in overlays.indices) {
|
||||
val overlay = overlays[i]
|
||||
if (overlay is ScaleDiskOverlay) {
|
||||
overlays[i] = errorOverlay
|
||||
errorOverlayFound = true
|
||||
}
|
||||
|
||||
if (overlay is Marker && overlay.icon.equals(locationOverlay.icon)) {
|
||||
overlays[i] = locationOverlay
|
||||
locationOverlayFound = true
|
||||
}
|
||||
|
||||
if (errorOverlayFound && locationOverlayFound) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If the user location overlays were not found, add them
|
||||
if (!errorOverlayFound) {
|
||||
overlays.add(errorOverlay)
|
||||
}
|
||||
|
||||
if (!locationOverlayFound) {
|
||||
overlays.add(locationOverlay)
|
||||
}
|
||||
updateUserLocationOverlay(geoPoint)
|
||||
updateUserLocationErrorOverlay(geoPoint)
|
||||
}
|
||||
|
||||
if (invalidate) {
|
||||
|
|
@ -2738,6 +2703,57 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user location error overlay by either replacing it with or adding a new one.
|
||||
*
|
||||
* If the user location error overlay is null, the new overlay is added. If the
|
||||
* overlay is not null, it is replaced by the new overlay.
|
||||
*
|
||||
* @param geoPoint The GeoPoint representing the user's location
|
||||
*/
|
||||
private fun updateUserLocationErrorOverlay(geoPoint: GeoPoint) {
|
||||
val overlays = binding?.map?.overlays ?: return
|
||||
|
||||
// Multiply accuracy by 2 to get 95% confidence interval
|
||||
val accuracy = getCurrentLocationAccuracy() * 2
|
||||
val overlay = createCurrentLocationErrorOverlay(this.context, geoPoint,
|
||||
(accuracy).toInt(), UnitOfMeasure.meter)
|
||||
|
||||
val index = overlays.indexOf(userLocationErrorOverlay)
|
||||
|
||||
if (userLocationErrorOverlay == null || index == -1) {
|
||||
overlays.add(overlay)
|
||||
} else {
|
||||
overlays[index] = overlay
|
||||
}
|
||||
|
||||
userLocationErrorOverlay = overlay
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user location overlay by either replacing it with or adding a new one.
|
||||
*
|
||||
* If the user location overlay is null, the new overlay is added. If the
|
||||
* overlay is not null, it is replaced by the new overlay.
|
||||
*
|
||||
* @param geoPoint The GeoPoint representing the user's location
|
||||
*/
|
||||
private fun updateUserLocationOverlay(geoPoint: GeoPoint) {
|
||||
val overlays = binding?.map?.overlays ?: return
|
||||
|
||||
val overlay = createCurrentLocationOverlay(geoPoint)
|
||||
|
||||
val index = overlays.indexOf(userLocationOverlay)
|
||||
|
||||
if (userLocationOverlay == null || index == -1) {
|
||||
overlays.add(overlay)
|
||||
} else {
|
||||
overlays[index] = overlay
|
||||
}
|
||||
|
||||
userLocationOverlay = overlay
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The accuracy of the current location with a confidence at the 68th percentile.
|
||||
* Units are in meters. Returning 0 may indicate failure.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue