parent
fd33116210
commit
9cee2c6512
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,99 +1,8 @@
|
|||||||
package uca.baptistearthur.geocaching.ui.overlay
|
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.bonuspack.routing.RoadManager
|
||||||
import org.osmdroid.util.GeoPoint
|
import uca.baptistearthur.geocaching.model.RoadTripEntity
|
||||||
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<PlaceMarker> = mutableSetOf()
|
|
||||||
private lateinit var roadOverlay: Polyline
|
|
||||||
private var newRoadtripOverlayVisible = false;
|
|
||||||
|
|
||||||
fun addPlaces(geoPoints: Collection<GeoPoint>, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
class AddMarkerOverlay(roadManager: RoadManager) : MarkerOverlay<NewRoadtripOverlay>(roadManager) {
|
||||||
|
override fun createNewConfirmationOverlay(): NewRoadtripOverlay = NewRoadtripOverlay(places)
|
||||||
}
|
}
|
@ -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<PlaceMarker>) : 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)
|
||||||
|
|
||||||
|
}
|
@ -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<EditRoadtripOverlay>(roadManager) {
|
||||||
|
|
||||||
|
fun addPlaces(geopoints: Collection<GeoPoint>, mapView: MapView)=
|
||||||
|
geopoints.forEach {
|
||||||
|
addMarkerAtGeopoint(it, mapView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createNewConfirmationOverlay(): EditRoadtripOverlay = EditRoadtripOverlay(places, roadTrip)
|
||||||
|
}
|
@ -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<PlaceMarker>, 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<Place> = 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()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<T : ConfirmationOverlay>(val roadManager: RoadManager) : Overlay() {
|
||||||
|
|
||||||
|
protected var places: MutableSet<PlaceMarker> = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue