Refactoring some dirty code with some more kotlin spirit

master
Arthur VALIN 2 years ago
parent 8e1e373572
commit e470e37101

@ -54,4 +54,8 @@ dependencies {
implementation 'com.github.MKergall:osmbonuspack:6.9.0' implementation 'com.github.MKergall:osmbonuspack:6.9.0'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.7.2'
} }

@ -4,7 +4,6 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission <uses-permission

@ -5,6 +5,7 @@ import androidx.annotation.RequiresApi
import androidx.room.TypeConverter import androidx.room.TypeConverter
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import org.osmdroid.util.GeoPoint
import uca.baptistearthur.geocaching.model.Place import uca.baptistearthur.geocaching.model.Place
import uca.baptistearthur.geocaching.model.RoadTripEntity import uca.baptistearthur.geocaching.model.RoadTripEntity
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -22,13 +23,13 @@ class Converters {
} }
@TypeConverter @TypeConverter
fun toString(places: List<Place>): String { fun toString(places: List<GeoPoint>): String {
return Gson().toJson(places) return Gson().toJson(places)
} }
@TypeConverter @TypeConverter
fun toPlaces(value: String): List<Place> { fun toPlaces(value: String): List<GeoPoint> {
val listType = object : TypeToken<List<Place>>() {}.type val listType = object : TypeToken<List<GeoPoint>>() {}.type
return Gson().fromJson(value, listType) return Gson().fromJson(value, listType)
} }

@ -1,5 +1,6 @@
package uca.baptistearthur.geocaching.data package uca.baptistearthur.geocaching.data
import org.osmdroid.util.GeoPoint
import uca.baptistearthur.geocaching.model.Place import uca.baptistearthur.geocaching.model.Place
import uca.baptistearthur.geocaching.model.RoadTripEntity import uca.baptistearthur.geocaching.model.RoadTripEntity
import java.util.Date import java.util.Date
@ -11,25 +12,25 @@ class Stub {
1, 1,
"France", "France",
Date(), Date(),
listOf(Place(49.3, 49.3)).toMutableList() listOf(GeoPoint(49.3, 49.3)).toMutableList()
), ),
RoadTripEntity( RoadTripEntity(
2, 2,
"Italie", "Italie",
Date(), Date(),
listOf(Place(48.866667, 2.34533), Place(98.866667, 2.333333)).toMutableList() listOf(GeoPoint(48.866667, 2.34533), GeoPoint(98.866667, 2.333333)).toMutableList()
), ),
RoadTripEntity( RoadTripEntity(
3, 3,
"Danemark", "Danemark",
Date(), Date(),
listOf(Place(48.866667, 2.333333), Place(48.866667, 2.333333)).toMutableList() listOf(GeoPoint(48.866667, 2.333333), GeoPoint(48.866667, 2.333333)).toMutableList()
), ),
RoadTripEntity( RoadTripEntity(
4, 4,
"Islande", "Islande",
Date(), Date(),
listOf(Place(48.866667, 2.333333), Place(48.866667, 2.333333), Place(48.866667, 2.333333)).toMutableList() listOf(GeoPoint(48.866667, 2.333333), GeoPoint(48.866667, 2.333333), GeoPoint(48.866667, 2.333333)).toMutableList()
), ),
) )
return list.toMutableList() return list.toMutableList()

@ -4,6 +4,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.google.gson.Gson import com.google.gson.Gson
import org.osmdroid.util.GeoPoint
import java.util.Date import java.util.Date
@Entity(tableName = "Roadtrip") @Entity(tableName = "Roadtrip")
@ -11,11 +12,10 @@ class RoadTripEntity(
@PrimaryKey(autoGenerate = true) val id: Int, @PrimaryKey(autoGenerate = true) val id: Int,
@ColumnInfo(name="name") val name: String, @ColumnInfo(name="name") val name: String,
@ColumnInfo(name="date") val date: Date, @ColumnInfo(name="date") val date: Date,
@ColumnInfo(name="places") val places: MutableList<Place> @ColumnInfo(name="places") val places: MutableList<GeoPoint>
){ ){
fun addPlaceToRoadTripList(place: GeoPoint) = places.add(place)
fun addPlaceToRoadTripList(place: Place) = places.add(place) fun addPlaceToRoadTripList(latitude: Double, longitude: Double) = places.add(GeoPoint(latitude, longitude))
fun addPlaceToRoadTripList(latitude: Double, longitude: Double) = places.add(Place(latitude, longitude))
fun toJSON(): String = Gson().toJson(this) fun toJSON(): String = Gson().toJson(this)
} }

@ -4,11 +4,12 @@ import android.annotation.SuppressLint
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.osmdroid.util.GeoPoint
import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.R
import uca.baptistearthur.geocaching.model.Place import uca.baptistearthur.geocaching.model.Place
class PlacesAdapter (val places: List<Place>) : RecyclerView.Adapter<PlacesViewHolder>(){ class PlacesAdapter (val places: List<GeoPoint>) : RecyclerView.Adapter<PlacesViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlacesViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlacesViewHolder {
return PlacesViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.cell_place, parent, false)) return PlacesViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.cell_place, parent, false))

@ -2,18 +2,13 @@ package uca.baptistearthur.geocaching.ui.activity
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.R
import uca.baptistearthur.geocaching.application.RTApplication
import uca.baptistearthur.geocaching.ui.fragment.Map
import uca.baptistearthur.geocaching.viewModels.RoadTripViewModel
import uca.baptistearthur.geocaching.viewModels.RoadTripViewModelFactory
class MainWindow: AppCompatActivity() { class MainWindow: AppCompatActivity() {

@ -30,72 +30,48 @@ import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.R
import uca.baptistearthur.geocaching.model.Place
import uca.baptistearthur.geocaching.ui.overlay.AddMarkerOverlay import uca.baptistearthur.geocaching.ui.overlay.AddMarkerOverlay
import uca.baptistearthur.geocaching.ui.overlay.RecenterOverlay import uca.baptistearthur.geocaching.ui.overlay.RecenterOverlay
class Map : Fragment() { open class Map : Fragment() {
private lateinit var map : MapView protected lateinit var map : MapView
private lateinit var spinner: ProgressBar companion object{
private lateinit var locationManager: LocationManager private val minimumZoomLevel = 4.0
private val userAgent = "RoadTrip" private val defaultZoomLevel = 21.0
private val userAgent = "RoadTrip"
val defaultPoint = GeoPoint(48.8583, 2.2944) private val defaultPoint = GeoPoint(48.8583, 2.2944)
var isMapCentered = false;
val locationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
val geoPoint = GeoPoint(location.latitude, location.longitude)
if(!isMapCentered){
map.controller.setCenter(geoPoint)
spinner.visibility=View.GONE;
isMapCentered=true;
}
map.invalidate()
}
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Configuration.getInstance().userAgentValue = userAgent; Configuration.getInstance().userAgentValue = userAgent;
} }
protected fun configureMap() = map.apply {
val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) setTileSource(TileSourceFactory.MAPNIK)
{ map.controller.setCenter(defaultPoint) } minZoomLevel = minimumZoomLevel
controller.apply {
private fun configureMap(view: View){ setCenter(defaultPoint)
Log.d("GeoMap", "MAP CONFIGURE") setZoom(defaultZoomLevel)
map = view.findViewById(R.id.mapView) }
map.setTileSource(TileSourceFactory.MAPNIK); addMapOverlays(mapView = this)
spinner = view.findViewById(R.id.mapLoading);
spinner.visibility=View.VISIBLE;
map.minZoomLevel = 4.0
map.controller.setZoom(21.0);
if (ContextCompat.checkSelfPermission(requireActivity(), ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissionLauncher.launch(ACCESS_FINE_LOCATION)
} }
map.controller.setCenter(defaultPoint)
open fun addMapOverlays(mapView: MapView){
// Compass Overlay
val compassOverlay = CompassOverlay(context, InternalCompassOrientationProvider(context), map); val compassOverlay = CompassOverlay(context, InternalCompassOrientationProvider(context), map);
compassOverlay.enableCompass(); compassOverlay.enableCompass();
map.getOverlays().add(compassOverlay); map.overlays.add(compassOverlay);
// Scale Bar Overlay
val scaleBarOverlay = ScaleBarOverlay(map) val scaleBarOverlay = ScaleBarOverlay(map)
scaleBarOverlay.setAlignRight(true) scaleBarOverlay.setAlignRight(true)
map.overlays.add(scaleBarOverlay) map.overlays.add(scaleBarOverlay)
val myLocation = MyLocationNewOverlay(GpsMyLocationProvider(context), map) // Add Marker Overlay
myLocation.enableMyLocation()
map.overlays.add(myLocation)
val recenter = RecenterOverlay(GpsMyLocationProvider(context), map)
recenter.enableMyLocation()
map.overlays.add(recenter);
val addMarker = AddMarkerOverlay(OSRMRoadManager(context, userAgent)) val addMarker = AddMarkerOverlay(OSRMRoadManager(context, userAgent))
map.overlays.add(addMarker); map.overlays.add(addMarker);
addMarker.addPlaces(listOf(GeoPoint(50.5, 10.1), GeoPoint(52.5, 33.33), GeoPoint(66.0, 33.35)), map)
} }
override fun onCreateView( override fun onCreateView(
@ -103,30 +79,19 @@ class Map : Fragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
Log.d("GeoMap", "MAP ON CREATE VIEW") Log.d("GeoMap", "MAP ON CREATE VIEW")
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_map, container, false) val view = inflater.inflate(R.layout.fragment_map, container, false)
configureMap(view) map = view.findViewById(R.id.mapView)
configureMap()
return view return view
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
Log.d("GeoMap", "MAP RESUME")
if (ContextCompat.checkSelfPermission(requireActivity(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, locationListener)
}
map.onResume() //needed for compass, my location overlays, v6.0.0 and up map.onResume() //needed for compass, my location overlays, v6.0.0 and up
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
Log.d("GeoMap", "MAP PAUSE")
if (ContextCompat.checkSelfPermission(requireActivity(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.removeUpdates(locationListener)
isMapCentered=false;
}
map.onPause() //needed for compass, my location overlays, v6.0.0 and up map.onPause() //needed for compass, my location overlays, v6.0.0 and up
} }
} }

@ -0,0 +1,99 @@
package uca.baptistearthur.geocaching.ui.fragment
import android.content.Context
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Bundle
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.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import uca.baptistearthur.geocaching.R
import uca.baptistearthur.geocaching.ui.overlay.RecenterOverlay
class MyLocationMap : Map() {
private lateinit var spinner: ProgressBar
private lateinit var locationManager: LocationManager
private var isMapCentered = false;
private val locationListener = LocationListener { location ->
val geoPoint = GeoPoint(location.latitude, location.longitude)
if(!isMapCentered){
map.controller.setCenter(geoPoint)
spinner.visibility=View.GONE;
isMapCentered=true;
}
map.invalidate()
}
private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()){}
private fun displaySpinner(view: View){
spinner = view.findViewById(R.id.mapLoading)
spinner.visibility=View.VISIBLE
if (ContextCompat.checkSelfPermission(requireActivity(), ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissionLauncher.launch(ACCESS_FINE_LOCATION)
}
}
override fun addMapOverlays(mapView: MapView){
super.addMapOverlays(mapView)
Log.d("GeoMap", "MyLocationOverlay")
// Recenter Overlay
val recenter = RecenterOverlay(GpsMyLocationProvider(context), map)
recenter.enableMyLocation()
map.overlays.add(recenter);
// My Location Overlay
val myLocation = MyLocationNewOverlay(GpsMyLocationProvider(context), map)
myLocation.enableMyLocation()
map.overlays.add(myLocation)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d("GeoMap", "MAP ON CREATE VIEW")
val view = inflater.inflate(R.layout.fragment_map, container, false)
map = view.findViewById(R.id.mapView)
configureMap()
displaySpinner(view)
return view
}
override fun onResume() {
super.onResume()
Log.d("GeoMap", "MAP RESUME")
if (ContextCompat.checkSelfPermission(requireActivity(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, locationListener)
}
}
override fun onPause() {
super.onPause()
Log.d("GeoMap", "MAP PAUSE")
if (ContextCompat.checkSelfPermission(requireActivity(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.removeUpdates(locationListener)
isMapCentered=false;
}
}
}

@ -14,6 +14,7 @@ import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Overlay import org.osmdroid.views.overlay.Overlay
import org.osmdroid.views.overlay.Polyline import org.osmdroid.views.overlay.Polyline
import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.R
import uca.baptistearthur.geocaching.model.Place
class AddMarkerOverlay(val roadManager: RoadManager) : Overlay() { class AddMarkerOverlay(val roadManager: RoadManager) : Overlay() {
@ -21,27 +22,35 @@ class AddMarkerOverlay(val roadManager: RoadManager) : Overlay() {
private var locations: MutableSet<PlaceMarker> = mutableSetOf() private var locations: MutableSet<PlaceMarker> = mutableSetOf()
private lateinit var roadOverlay: Polyline private lateinit var roadOverlay: Polyline
private var newRoadtripOverlayVisible = false; 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 { override fun onDoubleTap(e: MotionEvent?, mapView: MapView?): Boolean {
Log.d("GeoMap", "Longpress")
val proj = mapView?.projection; val proj = mapView?.projection;
if(proj!=null){ if(proj!=null){
val loc = proj.fromPixels(e?.x?.toInt()!!, e.y.toInt() ) as GeoPoint val geoPoint = proj.fromPixels(e?.x?.toInt()!!, e.y.toInt() ) as GeoPoint
val marker = PlaceMarker(mapView, this) addMarkerAtGeopoint(geoPoint, mapView)
marker.position = loc
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()
} }
return true; return true;
} }
fun computeIcons(context: Context){ fun computeIcons(context: Context) {
if(locations.isNotEmpty()) { if (locations.isNotEmpty()) {
val flagIcon = ContextCompat.getDrawable(context, R.drawable.roadtrip_marker)!! val flagIcon = ContextCompat.getDrawable(context, R.drawable.roadtrip_marker)!!
locations.last().icon = flagIcon locations.last().icon = flagIcon
locations.first().icon = flagIcon locations.first().icon = flagIcon
@ -52,7 +61,7 @@ class AddMarkerOverlay(val roadManager: RoadManager) : Overlay() {
mapView.overlays.remove(mapView.overlays.find { it is Polyline}) mapView.overlays.remove(mapView.overlays.find { it is Polyline})
if (locations.size > 1) { if (locations.size > 1) {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
val road = roadManager.getRoad(ArrayList(locations.map{it -> it.position})) val road = roadManager.getRoad(ArrayList(locations.map{it.position}))
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
roadOverlay = RoadManager.buildRoadOverlay(road) roadOverlay = RoadManager.buildRoadOverlay(road)
mapView.overlays.add(roadOverlay) mapView.overlays.add(roadOverlay)

@ -12,6 +12,7 @@ import android.view.MotionEvent
import android.widget.EditText import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Overlay import org.osmdroid.views.overlay.Overlay
@ -75,7 +76,7 @@ class NewRoadtripOverlay(val points: Collection<PlaceMarker>) : Overlay() {
.setPositiveButton(R.string.confirm) { _, _ -> .setPositiveButton(R.string.confirm) { _, _ ->
val userInput = input.text.toString() val userInput = input.text.toString()
if (userInput.isNotBlank()) { if (userInput.isNotBlank()) {
val places: MutableList<Place> = points.map { Place(it.position.latitude, it.position.longitude) }.toMutableList() val places: MutableList<GeoPoint> = points.map { GeoPoint(it.position.latitude, it.position.longitude) }.toMutableList()
val newRoadTrip = RoadTripEntity( val newRoadTrip = RoadTripEntity(
id = 0, // auto-generated ID id = 0, // auto-generated ID
name = input.text.toString(), name = input.text.toString(),

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.fragment.Map"> tools:context=".ui.fragment.MyLocationMap">
<org.osmdroid.views.MapView <org.osmdroid.views.MapView
android:id="@+id/mapView" android:id="@+id/mapView"

@ -24,7 +24,7 @@
tools:layout="@layout/roadtrip_detail" /> tools:layout="@layout/roadtrip_detail" />
<fragment <fragment
android:id="@+id/map" android:id="@+id/map"
android:name="uca.baptistearthur.geocaching.ui.fragment.Map" android:name="uca.baptistearthur.geocaching.ui.fragment.MyLocationMap"
android:label="fragment_map" android:label="fragment_map"
tools:layout="@layout/fragment_map" /> tools:layout="@layout/fragment_map" />
</navigation> </navigation>
Loading…
Cancel
Save