mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Merge branch 'main' into issue_6008
This commit is contained in:
commit
e0ec3d1ef5
1 changed files with 154 additions and 72 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(
|
||||
|
|
@ -724,7 +728,7 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
val targetP = GeoPoint(target.latitude, target.longitude)
|
||||
mapCenter = targetP
|
||||
binding?.map?.controller?.setCenter(targetP)
|
||||
recenterMarkerToPosition(targetP)
|
||||
updateUserLocationOverlays(targetP, true)
|
||||
if (!isCameFromExploreMap()) {
|
||||
moveCameraToPosition(targetP)
|
||||
}
|
||||
|
|
@ -1863,6 +1867,8 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
lastKnownLocation = latLng
|
||||
NearbyController.currentLocation = lastKnownLocation
|
||||
presenter!!.updateMapAndList(locationChangeType)
|
||||
|
||||
updateUserLocationOverlays(GeoPoint(latLng.latitude, latLng.longitude), true)
|
||||
}
|
||||
|
||||
override fun onLocationChangedSignificantly(latLng: LatLng) {
|
||||
|
|
@ -2644,43 +2650,14 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
*/
|
||||
override fun clearAllMarkers() {
|
||||
binding!!.map.overlayManager.clear()
|
||||
binding!!.map.invalidate()
|
||||
val geoPoint = mapCenter
|
||||
if (geoPoint != null) {
|
||||
val diskOverlay =
|
||||
ScaleDiskOverlay(
|
||||
this.context,
|
||||
geoPoint, 2000, UnitOfMeasure.foot
|
||||
)
|
||||
val circlePaint = Paint()
|
||||
circlePaint.color = Color.rgb(128, 128, 128)
|
||||
circlePaint.style = Paint.Style.STROKE
|
||||
circlePaint.strokeWidth = 2f
|
||||
diskOverlay.setCirclePaint2(circlePaint)
|
||||
val diskPaint = Paint()
|
||||
diskPaint.color = Color.argb(40, 128, 128, 128)
|
||||
diskPaint.style = Paint.Style.FILL_AND_STROKE
|
||||
diskOverlay.setCirclePaint1(diskPaint)
|
||||
diskOverlay.setDisplaySizeMin(900)
|
||||
diskOverlay.setDisplaySizeMax(1700)
|
||||
binding!!.map.overlays.add(diskOverlay)
|
||||
val startMarker = Marker(
|
||||
binding!!.map
|
||||
)
|
||||
startMarker.position = geoPoint
|
||||
startMarker.setAnchor(
|
||||
Marker.ANCHOR_CENTER,
|
||||
Marker.ANCHOR_BOTTOM
|
||||
)
|
||||
startMarker.icon =
|
||||
getDrawable(
|
||||
this.requireContext(),
|
||||
fr.free.nrw.commons.R.drawable.current_location_marker
|
||||
)
|
||||
startMarker.title = "Your Location"
|
||||
startMarker.textLabelFontSize = 24
|
||||
binding!!.map.overlays.add(startMarker)
|
||||
|
||||
var geoPoint = mapCenter
|
||||
val lastLatLng = locationManager.getLastLocation()
|
||||
if (lastLatLng != null) {
|
||||
geoPoint = GeoPoint(lastLatLng.latitude, lastLatLng.longitude)
|
||||
}
|
||||
updateUserLocationOverlays(geoPoint, false)
|
||||
|
||||
val scaleBarOverlay = ScaleBarOverlay(binding!!.map)
|
||||
scaleBarOverlay.setScaleBarOffset(15, 25)
|
||||
val barPaint = Paint()
|
||||
|
|
@ -2690,6 +2667,7 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
binding!!.map.overlays.add(scaleBarOverlay)
|
||||
binding!!.map.overlays.add(mapEventsOverlay)
|
||||
binding!!.map.setMultiTouchControls(true)
|
||||
binding!!.map.invalidate()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2700,45 +2678,149 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
|
|||
private fun recenterMarkerToPosition(geoPoint: GeoPoint?) {
|
||||
geoPoint?.let {
|
||||
binding?.map?.controller?.setCenter(it)
|
||||
val overlays = binding?.map?.overlays ?: return@let
|
||||
|
||||
// Remove markers and disks using index-based removal
|
||||
var i = 0
|
||||
while (i < overlays.size) {
|
||||
when (overlays[i]) {
|
||||
is Marker, is ScaleDiskOverlay -> overlays.removeAt(i)
|
||||
else -> i++
|
||||
}
|
||||
}
|
||||
|
||||
// Add disk overlay
|
||||
ScaleDiskOverlay(context, it, 2000, UnitOfMeasure.foot).apply {
|
||||
setCirclePaint2(Paint().apply {
|
||||
color = Color.rgb(128, 128, 128)
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = 2f
|
||||
})
|
||||
setCirclePaint1(Paint().apply {
|
||||
color = Color.argb(40, 128, 128, 128)
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
})
|
||||
setDisplaySizeMin(900)
|
||||
setDisplaySizeMax(1700)
|
||||
overlays.add(this)
|
||||
}
|
||||
|
||||
// Add marker
|
||||
Marker(binding?.map).apply {
|
||||
position = it
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
icon = getDrawable(context, R.drawable.current_location_marker)
|
||||
title = "Your Location"
|
||||
textLabelFontSize = 24
|
||||
overlays.add(this)
|
||||
}
|
||||
updateUserLocationOverlays(it, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user current location overlays (both the location and error overlays) by
|
||||
* replacing any existing location overlays with new overlays at the given GeoPoint. If there
|
||||
* are no existing location and error overlays, then new overlays are added.
|
||||
*
|
||||
* @param geoPoint The GeoPoint representing the user's current location.
|
||||
* @param invalidate If true, the map overlays will be invalidated after the user
|
||||
* location overlays are updated/added. If false, the overlays will not be invalidated.
|
||||
*/
|
||||
private fun updateUserLocationOverlays(geoPoint: GeoPoint?, invalidate: Boolean) {
|
||||
geoPoint?.let{
|
||||
updateUserLocationOverlay(geoPoint)
|
||||
updateUserLocationErrorOverlay(geoPoint)
|
||||
}
|
||||
|
||||
if (invalidate) {
|
||||
binding!!.map.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private fun getCurrentLocationAccuracy(): Float {
|
||||
var accuracy = 0f
|
||||
val lastLocation = locationManager.getLastLocation()
|
||||
if (lastLocation != null) {
|
||||
accuracy = lastLocation.accuracy
|
||||
}
|
||||
|
||||
return accuracy
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the current location overlay
|
||||
*
|
||||
* @param geoPoint The GeoPoint where the current location overlay will be placed.
|
||||
*
|
||||
* @return The current location overlay as a Marker
|
||||
*/
|
||||
private fun createCurrentLocationOverlay(geoPoint: GeoPoint): Marker {
|
||||
val currentLocationOverlay = Marker(
|
||||
binding!!.map
|
||||
)
|
||||
currentLocationOverlay.position = geoPoint
|
||||
currentLocationOverlay.icon =
|
||||
getDrawable(
|
||||
this.requireContext(),
|
||||
fr.free.nrw.commons.R.drawable.current_location_marker
|
||||
)
|
||||
currentLocationOverlay.title = "Your Location"
|
||||
currentLocationOverlay.textLabelFontSize = 24
|
||||
currentLocationOverlay.setAnchor(0.5f, 0.5f)
|
||||
|
||||
return currentLocationOverlay
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the location error overlay to show the user how accurate the current location
|
||||
* overlay is. The edge of the disk is the 95% confidence interval.
|
||||
*
|
||||
* @param context The Android context
|
||||
* @param point The user's location as a GeoPoint
|
||||
* @param value The radius of the disk
|
||||
* @param unitOfMeasure The unit of measurement of the value/disk radius.
|
||||
*
|
||||
* @return The location error overlay as a ScaleDiskOverlay.
|
||||
*/
|
||||
private fun createCurrentLocationErrorOverlay(context: Context?, point: GeoPoint, value: Int,
|
||||
unitOfMeasure: UnitOfMeasure): ScaleDiskOverlay {
|
||||
val scaleDisk = ScaleDiskOverlay(context, point, value, unitOfMeasure)
|
||||
|
||||
scaleDisk.setCirclePaint2(Paint().apply {
|
||||
color = Color.rgb(128, 128, 128)
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = 2f
|
||||
})
|
||||
|
||||
scaleDisk.setCirclePaint1(Paint().apply {
|
||||
color = Color.argb(40, 128, 128, 128)
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
})
|
||||
|
||||
return scaleDisk
|
||||
}
|
||||
|
||||
private fun moveCameraToPosition(geoPoint: GeoPoint) {
|
||||
binding!!.map.controller.animateTo(geoPoint)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue