From 9cee2c65127c7c41e5341079e7fd52792a041fbe Mon Sep 17 00:00:00 2001 From: "arthur.valin" Date: Sat, 8 Apr 2023 20:53:05 +0200 Subject: [PATCH] Implementing edition map into roadtrip detail --- .../geocaching/data/RoadTripDAO.kt | 2 +- .../geocaching/ui/fragment/EditRoadtripMap.kt | 44 ++++++++ .../geocaching/ui/fragment/Map.kt | 14 +-- .../geocaching/ui/fragment/MyLocationMap.kt | 14 ++- .../geocaching/ui/fragment/RoadtripDetail.kt | 27 ++--- .../geocaching/ui/overlay/AddMarkerOverlay.kt | 97 +--------------- .../ui/overlay/ConfirmationOverlay.kt | 59 ++++++++++ .../ui/overlay/EditMarkerOverlay.kt | 17 +++ .../ui/overlay/EditRoadtripOverlay.kt | 48 ++++++++ .../geocaching/ui/overlay/MarkerOverlay.kt | 95 ++++++++++++++++ .../ui/overlay/NewRoadtripOverlay.kt | 104 +++++------------- .../geocaching/ui/overlay/PlaceMarker.kt | 12 +- app/src/main/res/layout/roadtrip_detail.xml | 3 +- app/src/main/res/navigation/navgraph.xml | 6 +- app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 16 files changed, 330 insertions(+), 214 deletions(-) create mode 100644 app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/EditRoadtripMap.kt create mode 100644 app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/ConfirmationOverlay.kt create mode 100644 app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditMarkerOverlay.kt create mode 100644 app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditRoadtripOverlay.kt create mode 100644 app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/MarkerOverlay.kt diff --git a/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt b/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt index d11f627..5505aec 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt @@ -16,7 +16,7 @@ interface RoadTripDAO { @Delete suspend fun deleteRoadTrip(r: RoadTripEntity) - @Query("SELECT * FROM Roadtrip") + @Query("SELECT * FROM Roadtrip ORDER BY date") fun getAllRoadTrips(): Flow> @Query("SELECT * FROM Roadtrip WHERE id = :id") diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/EditRoadtripMap.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/EditRoadtripMap.kt new file mode 100644 index 0000000..e8e861d --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/EditRoadtripMap.kt @@ -0,0 +1,44 @@ +package uca.baptistearthur.geocaching.ui.fragment + +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import org.osmdroid.bonuspack.routing.OSRMRoadManager +import org.osmdroid.views.MapView +import uca.baptistearthur.geocaching.model.RoadTripEntity +import uca.baptistearthur.geocaching.ui.overlay.AddMarkerOverlay +import uca.baptistearthur.geocaching.ui.overlay.EditMarkerOverlay +import uca.baptistearthur.geocaching.ui.overlay.MarkerOverlay +import uca.baptistearthur.geocaching.ui.overlay.EditRoadtripOverlay + +class EditRoadtripMap : Map() { + + companion object{ + const val defaultZoomLevel = 10.0 + } + + var roadTrip: RoadTripEntity? = null + set(value) { + roadTrip?: + value?.let { + val editMarkerOverlay = EditMarkerOverlay(OSRMRoadManager(context, userAgent), value) + editMarkerOverlay.addPlaces(value.places, map) + map.overlays.add(editMarkerOverlay); + map.controller.setCenter(value.places.first()) + field = value + } + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + Log.d("GeoMap", "CREATE EDIT MAP") + val view = super.onCreateView(inflater, container, savedInstanceState) + map.controller.setZoom(defaultZoomLevel) + return view + } + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/Map.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/Map.kt index fb6ee20..2374d29 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/Map.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/Map.kt @@ -10,20 +10,18 @@ import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView import org.osmdroid.views.overlay.ScaleBarOverlay import android.util.Log -import org.osmdroid.bonuspack.routing.OSRMRoadManager import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.views.overlay.compass.CompassOverlay import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider import uca.baptistearthur.geocaching.R -import uca.baptistearthur.geocaching.ui.overlay.AddMarkerOverlay open class Map : Fragment() { protected lateinit var map : MapView companion object{ - private val minimumZoomLevel = 4.0 - private val defaultZoomLevel = 21.0 - private val userAgent = "RoadTrip" - private val defaultPoint = GeoPoint(48.8583, 2.2944) + const val minimumZoomLevel = 4.0 + const val defaultZoomLevel = 21.0 + const val userAgent = "RoadTrip" + val defaultPoint = GeoPoint(48.8583, 2.2944) } override fun onCreate(savedInstanceState: Bundle?) { @@ -50,10 +48,6 @@ open class Map : Fragment() { val scaleBarOverlay = ScaleBarOverlay(map) scaleBarOverlay.setAlignRight(true) map.overlays.add(scaleBarOverlay) - - // Add Marker Overlay - val addMarker = AddMarkerOverlay(OSRMRoadManager(context, userAgent)) - map.overlays.add(addMarker); } override fun onCreateView( diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/MyLocationMap.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/MyLocationMap.kt index ba98c03..ae72a67 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/MyLocationMap.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/MyLocationMap.kt @@ -8,20 +8,20 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat -import androidx.fragment.app.Fragment -import org.osmdroid.config.Configuration import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView -import org.osmdroid.views.overlay.ScaleBarOverlay import android.Manifest.permission.ACCESS_FINE_LOCATION -import android.location.Location import android.location.LocationListener import android.util.Log import android.widget.ProgressBar import androidx.activity.result.contract.ActivityResultContracts +import org.osmdroid.bonuspack.routing.OSRMRoadManager import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay import uca.baptistearthur.geocaching.R +import uca.baptistearthur.geocaching.ui.overlay.AddMarkerOverlay +import uca.baptistearthur.geocaching.ui.overlay.MarkerOverlay +import uca.baptistearthur.geocaching.ui.overlay.NewRoadtripOverlay import uca.baptistearthur.geocaching.ui.overlay.RecenterOverlay class MyLocationMap : Map() { @@ -62,8 +62,12 @@ class MyLocationMap : Map() { // My Location Overlay val myLocation = MyLocationNewOverlay(GpsMyLocationProvider(context), map) myLocation.enableMyLocation() - map.overlays.add(myLocation) + + // Add Marker Overlay + val addMarker = AddMarkerOverlay(OSRMRoadManager(context, userAgent)) + map.overlays.add(addMarker); + } override fun onCreateView( diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt index 07577b3..d6e5256 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt @@ -6,13 +6,12 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.fragment.app.Fragment import android.util.Log import android.widget.Button import android.widget.TextView import android.widget.Toast import androidx.annotation.RequiresApi -import androidx.fragment.app.viewModels +import androidx.fragment.app.* import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager @@ -21,6 +20,7 @@ import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.application.RTApplication import uca.baptistearthur.geocaching.converters.Converters import uca.baptistearthur.geocaching.converters.toFrenchFormat +import uca.baptistearthur.geocaching.model.RoadTripEntity import uca.baptistearthur.geocaching.recyclerview.PlacesAdapter import uca.baptistearthur.geocaching.viewModels.RoadTripViewModel import uca.baptistearthur.geocaching.viewModels.RoadTripViewModelFactory @@ -30,8 +30,9 @@ import java.util.* class RoadtripDetail : Fragment() { private var placesRecyclerView : RecyclerView? = null - - private val roadTripViewModel: RoadTripViewModel by viewModels { + private val map: EditRoadtripMap = EditRoadtripMap() + private lateinit var roadTrip: RoadTripEntity; + private val roadTripViewModel: RoadTripViewModel by viewModels { RoadTripViewModelFactory((requireActivity().application as RTApplication).db.roadTripDAO()) } @@ -39,16 +40,14 @@ class RoadtripDetail : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // Inflate the layout for this fragment val view = inflater.inflate(R.layout.roadtrip_detail, container, false) - - var roadTripJSON = arguments?.getString("roadTrip") - val roadTrip = Converters().toRoadTripEntity(roadTripJSON) + roadTrip = Converters().toRoadTripEntity(arguments?.getString("roadTrip")) + childFragmentManager.beginTransaction() + .add(R.id.roadTripDetailMapView, map) + .commit() placesRecyclerView = view?.findViewById(R.id.recyclerViewPlacesList) placesRecyclerView?.adapter = PlacesAdapter(roadTrip.places) placesRecyclerView?.layoutManager = LinearLayoutManager(context) - - - view?.findViewById(R.id.roadTripDetailTitle)?.text = roadTrip.name view?.findViewById(R.id.roadTripDetailDate)?.text = roadTrip.date.toFrenchFormat() @@ -69,10 +68,12 @@ class RoadtripDetail : Fragment() { Toast.LENGTH_SHORT ).show() } - - } - return view } + + override fun onStart() { + super.onStart() + map.roadTrip=roadTrip + } } \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/AddMarkerOverlay.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/AddMarkerOverlay.kt index 39b683e..d9ff13b 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/AddMarkerOverlay.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/AddMarkerOverlay.kt @@ -1,99 +1,8 @@ package uca.baptistearthur.geocaching.ui.overlay -import android.content.Context -import android.util.Log -import android.view.MotionEvent -import androidx.core.content.ContextCompat -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import org.osmdroid.bonuspack.routing.RoadManager -import org.osmdroid.util.GeoPoint -import org.osmdroid.views.MapView -import org.osmdroid.views.overlay.Overlay -import org.osmdroid.views.overlay.Polyline -import uca.baptistearthur.geocaching.R - - -class AddMarkerOverlay(val roadManager: RoadManager) : Overlay() { - - private var locations: MutableSet = mutableSetOf() - private lateinit var roadOverlay: Polyline - private var newRoadtripOverlayVisible = false; - - fun addPlaces(geoPoints: Collection, mapView: MapView)= - geoPoints.forEach { addMarkerAtGeopoint(it, mapView)} - - private fun addMarkerAtGeopoint(geoPoint: GeoPoint, mapView: MapView){ - val marker = PlaceMarker(mapView, this) - marker.position = geoPoint - if(locations.isNotEmpty()) locations.last().setDefaultIcon() - locations.add(marker) - locations.forEach{ it.closeInfoWindow()} - computeIcons(mapView.context) - mapView.overlays.add(marker) - computeRoad(mapView) - computeNewRoadtripOverlay(mapView); - mapView.invalidate() - } - - override fun onDoubleTap(e: MotionEvent?, mapView: MapView?): Boolean { - - val proj = mapView?.projection; - if(proj!=null){ - val geoPoint = proj.fromPixels(e?.x?.toInt()!!, e.y.toInt() ) as GeoPoint - addMarkerAtGeopoint(geoPoint, mapView) - } - return true; - } - - fun computeIcons(context: Context) { - if (locations.isNotEmpty()) { - val flagIcon = ContextCompat.getDrawable(context, R.drawable.roadtrip_marker)!! - locations.last().icon = flagIcon - locations.first().icon = flagIcon - } - } - - fun computeRoad(mapView: MapView) { - mapView.overlays.removeAll{ it is Polyline } - if (locations.size > 1) { - CoroutineScope(Dispatchers.IO).launch { - val road = roadManager.getRoad(ArrayList(locations.map{it.position})) - withContext(Dispatchers.Main) { - roadOverlay = RoadManager.buildRoadOverlay(road) - mapView.overlays.add(roadOverlay) - } - } - } - } - - fun computeNewRoadtripOverlay(mapView: MapView){ - if (locations.size > 1) { - if(!newRoadtripOverlayVisible) { - mapView.overlays.add(NewRoadtripOverlay(locations)) - newRoadtripOverlayVisible = true - } - }else{ - Log.d("GeoRoad", "TRY DELETE ROADTRIP OVERLAY" + locations.size) - Log.d("GeoRoad", ""+mapView.overlays.size) - mapView.overlays.removeAll{ it is NewRoadtripOverlay } - newRoadtripOverlayVisible=false - } - } - fun removeMarker(placeMarker: PlaceMarker) = locations.remove(placeMarker); - fun getMarkerLabel(placeMarker: PlaceMarker) = - when (placeMarker) { - locations.first() -> { - "Start" - } - locations.last() -> { - "Finish" - } - else -> { - "Step " + locations.indexOf(placeMarker); - } - } +import uca.baptistearthur.geocaching.model.RoadTripEntity +class AddMarkerOverlay(roadManager: RoadManager) : MarkerOverlay(roadManager) { + override fun createNewConfirmationOverlay(): NewRoadtripOverlay = NewRoadtripOverlay(places) } \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/ConfirmationOverlay.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/ConfirmationOverlay.kt new file mode 100644 index 0000000..7f40ad3 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/ConfirmationOverlay.kt @@ -0,0 +1,59 @@ +package uca.baptistearthur.geocaching.ui.overlay + +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.RectF +import android.util.Log +import android.view.MotionEvent +import androidx.core.content.ContextCompat +import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.Overlay +import uca.baptistearthur.geocaching.R + +abstract class ConfirmationOverlay(val points: MutableCollection) : Overlay() { + + private var circleRectF=RectF() + + override fun draw(canvas: Canvas, mapView: MapView, shadow: Boolean) { + + val circleSize = 300f + val circlePadding = 20f + val circleY = canvas.height - circleSize - circlePadding + circleRectF= RectF(circlePadding, circleY, circlePadding + circleSize, circleY + circleSize) + + val paint = Paint().apply { + color = Color.WHITE + style = Paint.Style.FILL + } + + canvas.drawCircle( + circleSize / 2 + circlePadding, + circleY + circleSize / 2, + circleSize / 2, + paint + ) + + val iconSize = 180 + val icon = ContextCompat.getDrawable(mapView.context, R.drawable.check) + + val iconX = (circleSize / 2 - iconSize / 2 + circlePadding).toInt() + val iconY = (circleY + circleSize / 2 - iconSize / 2).toInt() + + icon?.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize) + icon?.draw(canvas) + } + + override fun onSingleTapConfirmed(e: MotionEvent?, mapView: MapView?) = + if (e != null && circleRectF.contains(e.x, e.y)) { + mapView?.let{ + confirm(it) + } + true + }else{ + false + } + + abstract fun confirm(mapView: MapView) + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditMarkerOverlay.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditMarkerOverlay.kt new file mode 100644 index 0000000..5f0de1c --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditMarkerOverlay.kt @@ -0,0 +1,17 @@ +package uca.baptistearthur.geocaching.ui.overlay + +import android.graphics.Canvas +import org.osmdroid.bonuspack.routing.RoadManager +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.MapView +import uca.baptistearthur.geocaching.model.RoadTripEntity + +class EditMarkerOverlay(roadManager: RoadManager, val roadTrip: RoadTripEntity) : MarkerOverlay(roadManager) { + + fun addPlaces(geopoints: Collection, mapView: MapView)= + geopoints.forEach { + addMarkerAtGeopoint(it, mapView) + } + + override fun createNewConfirmationOverlay(): EditRoadtripOverlay = EditRoadtripOverlay(places, roadTrip) +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditRoadtripOverlay.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditRoadtripOverlay.kt new file mode 100644 index 0000000..09dd4bd --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/EditRoadtripOverlay.kt @@ -0,0 +1,48 @@ +package uca.baptistearthur.geocaching.ui.overlay + +import android.content.Context +import android.widget.Toast +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelStoreOwner +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.MapView +import uca.baptistearthur.geocaching.R +import uca.baptistearthur.geocaching.application.RTApplication +import uca.baptistearthur.geocaching.model.Place +import uca.baptistearthur.geocaching.model.RoadTripEntity +import uca.baptistearthur.geocaching.viewModels.RoadTripViewModel +import uca.baptistearthur.geocaching.viewModels.RoadTripViewModelFactory + +class EditRoadtripOverlay(points: MutableCollection, val roadTripEntity: RoadTripEntity) : ConfirmationOverlay(points) { + + fun getRoadTripViewModelFromOverlay(overlayContext: Context): RoadTripViewModel { + val roadTripDao = (overlayContext.applicationContext as RTApplication).db.roadTripDAO() + val viewModelFactory = RoadTripViewModelFactory(roadTripDao) + return ViewModelProvider(overlayContext as ViewModelStoreOwner, viewModelFactory).get( + RoadTripViewModel::class.java) + } + + override fun confirm(mapView: MapView) { + val places: MutableList = points.map { Place(it.position.latitude, it.position.longitude) }.toMutableList() + CoroutineScope(Dispatchers.Main).launch { + places.filter{it.address.displayName==="unknown"}.forEach{ it.initAddress() } + val newRoadTrip = RoadTripEntity( + id = roadTripEntity.id, + name = roadTripEntity.name, + date = roadTripEntity.date, + places = places + ) + getRoadTripViewModelFromOverlay(mapView.context).deleteRoadTrip(roadTripEntity) + getRoadTripViewModelFromOverlay(mapView.context).insertRoadTrip(newRoadTrip) + Toast.makeText( + mapView.context, + R.string.changesSaved, + Toast.LENGTH_SHORT + ).show() + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/MarkerOverlay.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/MarkerOverlay.kt new file mode 100644 index 0000000..f2b4f45 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/MarkerOverlay.kt @@ -0,0 +1,95 @@ +package uca.baptistearthur.geocaching.ui.overlay + +import android.content.Context +import android.view.MotionEvent +import androidx.core.content.ContextCompat +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.osmdroid.bonuspack.routing.RoadManager +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.Overlay +import org.osmdroid.views.overlay.Polyline +import uca.baptistearthur.geocaching.R + + +abstract class MarkerOverlay(val roadManager: RoadManager) : Overlay() { + + protected var places: MutableSet = mutableSetOf() + private lateinit var roadOverlay: Polyline + private var confirmationOverlayIsVisible = false; + + protected fun addMarkerAtGeopoint(geoPoint: GeoPoint, mapView: MapView){ + val marker = PlaceMarker(mapView, this) + marker.position = geoPoint + if(places.isNotEmpty()) places.last().setDefaultIcon() + places.add(marker) + places.forEach{ it.closeInfoWindow()} + computeIcons(mapView.context) + mapView.overlays.add(marker) + computeRoad(mapView) + computeConfirmationOverlay(mapView); + mapView.invalidate() + } + + override fun onDoubleTap(e: MotionEvent?, mapView: MapView?): Boolean { + + val proj = mapView?.projection; + if(proj!=null){ + val geoPoint = proj.fromPixels(e?.x?.toInt()!!, e.y.toInt() ) as GeoPoint + addMarkerAtGeopoint(geoPoint, mapView) + } + return true; + } + + fun computeIcons(context: Context) { + if (places.isNotEmpty()) { + val flagIcon = ContextCompat.getDrawable(context, R.drawable.roadtrip_marker)!! + places.last().icon = flagIcon + places.first().icon = flagIcon + } + } + + fun computeRoad(mapView: MapView) { + mapView.overlays.removeAll{ it is Polyline } + if (places.size > 1) { + CoroutineScope(Dispatchers.IO).launch { + val road = roadManager.getRoad(ArrayList(places.map{it.position})) + withContext(Dispatchers.Main) { + roadOverlay = RoadManager.buildRoadOverlay(road) + mapView.overlays.add(roadOverlay) + } + } + } + } + + abstract fun createNewConfirmationOverlay(): T + + fun computeConfirmationOverlay(mapView: MapView){ + if (places.size > 1) { + if(!confirmationOverlayIsVisible) { + mapView.overlays.add(createNewConfirmationOverlay()) + confirmationOverlayIsVisible = true + } + }else{ + mapView.overlays.removeAll{ it is ConfirmationOverlay } + confirmationOverlayIsVisible=false + } + } + fun removeMarker(placeMarker: PlaceMarker) = places.remove(placeMarker); + fun getMarkerLabel(placeMarker: PlaceMarker) = + when (placeMarker) { + places.first() -> { + "Start" + } + places.last() -> { + "Finish" + } + else -> { + "Step " + places.indexOf(placeMarker); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/NewRoadtripOverlay.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/NewRoadtripOverlay.kt index 14f0b1e..c495117 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/NewRoadtripOverlay.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/NewRoadtripOverlay.kt @@ -2,17 +2,10 @@ package uca.baptistearthur.geocaching.ui.overlay import android.app.AlertDialog import android.content.Context -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.graphics.RectF import android.text.InputFilter import android.util.Log -import android.view.MotionEvent import android.widget.EditText import android.widget.Toast -import androidx.core.content.ContextCompat -import androidx.fragment.app.viewModels import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner import kotlinx.coroutines.CoroutineScope @@ -20,7 +13,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.osmdroid.views.MapView -import org.osmdroid.views.overlay.Overlay import org.osmdroid.views.overlay.Polyline import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.application.RTApplication @@ -32,9 +24,7 @@ import uca.baptistearthur.geocaching.viewModels.RoadTripViewModelFactory import java.util.* -class NewRoadtripOverlay(val points: MutableCollection) : Overlay() { - - private var circleRectF=RectF() +class NewRoadtripOverlay(points: MutableCollection) : ConfirmationOverlay(points) { fun getRoadTripViewModelFromOverlay(overlayContext: Context): RoadTripViewModel { val roadTripDao = (overlayContext.applicationContext as RTApplication).db.roadTripDAO() @@ -42,86 +32,48 @@ class NewRoadtripOverlay(val points: MutableCollection) : Overlay() return ViewModelProvider(overlayContext as ViewModelStoreOwner, viewModelFactory).get(RoadTripViewModel::class.java) } - override fun draw(canvas: Canvas, mapView: MapView, shadow: Boolean) { - - val circleSize = 300f - val circlePadding = 20f - val circleY = canvas.height - circleSize - circlePadding - circleRectF= RectF(circlePadding, circleY, circlePadding + circleSize, circleY + circleSize) - - val paint = Paint().apply { - color = Color.WHITE - style = Paint.Style.FILL - } - - canvas.drawCircle( - circleSize / 2 + circlePadding, - circleY + circleSize / 2, - circleSize / 2, - paint - ) - - val iconSize = 180 - val icon = ContextCompat.getDrawable(mapView.context, R.drawable.check) - - val iconX = (circleSize / 2 - iconSize / 2 + circlePadding).toInt() - val iconY = (circleY + circleSize / 2 - iconSize / 2).toInt() - - icon?.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize) - icon?.draw(canvas) + private fun clearMap(mapView: MapView){ + mapView.overlays.removeAll { it is PlaceMarker || it is Polyline || it is NewRoadtripOverlay } } - override fun onSingleTapConfirmed(e: MotionEvent?, mapView: MapView?) = - if (e != null && circleRectF.contains(e.x, e.y)) { - mapView?.let{ - createDialog(it) + private fun onValidation(mapView: MapView, input: String){ + val places: MutableList = points.map { Place(it.position.latitude, it.position.longitude) }.toMutableList() + CoroutineScope(Dispatchers.Main).launch { + places.forEach{ + it.initAddress() + Log.d("GeoMap", it.address.displayName) } - Log.d("GeoRoad", "CONFIRM : "+points.size) - true - }else{ - false + val newRoadTrip = RoadTripEntity( + id = 0, // auto-generated ID + name = input, + date = Date(), + places = places + ) + getRoadTripViewModelFromOverlay(mapView.context).insertRoadTrip(newRoadTrip); + Toast.makeText( + mapView.context, + R.string.roadtripAdded, + Toast.LENGTH_SHORT + ).show() + points.clear() } - - private fun clearMap(mapView: MapView){ - mapView.overlays.removeAll { it is PlaceMarker || it is Polyline || it is NewRoadtripOverlay } + clearMap(mapView) } - private fun createDialog(mapView: MapView){ - val context = mapView.context - val input = EditText(context) + override fun confirm(mapView: MapView){ + val input = EditText(mapView.context) input.filters = arrayOf(InputFilter.LengthFilter(50)) - val dialog = AlertDialog.Builder(context) + val dialog = AlertDialog.Builder(mapView.context) .setTitle(R.string.newRoadtripDialog) .setView(input) .setPositiveButton(R.string.confirm) { _, _ -> val userInput = input.text.toString() if (userInput.isNotBlank()) { - val places: MutableList = points.map { Place(it.position.latitude, it.position.longitude) }.toMutableList() - CoroutineScope(Dispatchers.Main).launch { - places.forEach{ - it.initAddress() - Log.d("GeoMap", it.address.displayName) - } - val newRoadTrip = RoadTripEntity( - id = 0, // auto-generated ID - name = input.text.toString(), - date = Date(), - places = places - ) - getRoadTripViewModelFromOverlay(context).insertRoadTrip(newRoadTrip); - Toast.makeText( - context, - R.string.roadtripAdded, - Toast.LENGTH_SHORT - ).show() - points.clear() - } - clearMap(mapView) - + onValidation(mapView, input.text.toString()) } else { Toast.makeText( - context, + mapView.context, R.string.emptyTextError, Toast.LENGTH_SHORT ).show() diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/PlaceMarker.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/PlaceMarker.kt index ca07bb1..e25996d 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/PlaceMarker.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/overlay/PlaceMarker.kt @@ -1,18 +1,10 @@ package uca.baptistearthur.geocaching.ui.overlay -import android.graphics.drawable.Drawable -import android.util.Log import android.view.MotionEvent -import androidx.core.content.ContextCompat -import org.osmdroid.bonuspack.routing.OSRMRoadManager -import org.osmdroid.bonuspack.routing.RoadManager -import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView import org.osmdroid.views.overlay.Marker -import org.osmdroid.views.overlay.infowindow.InfoWindow -import uca.baptistearthur.geocaching.R -class PlaceMarker(val mapView: MapView, val parent : AddMarkerOverlay) : Marker(mapView) { +class PlaceMarker(val mapView: MapView, val parent : MarkerOverlay<*>) : Marker(mapView) { override fun getTitle() = parent.getMarkerLabel(this) override fun onLongPress(e: MotionEvent?, mapView: MapView?): Boolean { @@ -22,7 +14,7 @@ class PlaceMarker(val mapView: MapView, val parent : AddMarkerOverlay) : Marker( mapView.overlays.remove(this) parent.computeIcons(mapView.context) parent.computeRoad(mapView) - parent.computeNewRoadtripOverlay(mapView) + parent.computeConfirmationOverlay(mapView) mapView.invalidate() return true } diff --git a/app/src/main/res/layout/roadtrip_detail.xml b/app/src/main/res/layout/roadtrip_detail.xml index 702239d..0ce7f7f 100644 --- a/app/src/main/res/layout/roadtrip_detail.xml +++ b/app/src/main/res/layout/roadtrip_detail.xml @@ -32,8 +32,7 @@ android:paddingRight="10dp" android:paddingBottom="5dp"/> - + app:destination="@id/roadTripDetailMapView" /> \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index ef7cc8a..5444cc6 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -14,4 +14,5 @@ Une erreur est survenue lors de la suppresion du voyage Aucun voyage n\'a été trouvé, utilisez la carte Roadtrip ajouté + Changements sauvegardés \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fed5472..2fdac24 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -14,4 +14,5 @@ An error occurred while deleting the road trip. No trip was found, add one with the map. Roadtrip added + Changes saved \ No newline at end of file