Reroute
This commit is contained in:
@@ -16,14 +16,19 @@
|
||||
|
||||
package com.kouros.navigation.data
|
||||
|
||||
import android.R
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.net.Uri
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.kouros.navigation.data.valhalla.Maneuvers
|
||||
import com.kouros.navigation.data.valhalla.ValhallaJson
|
||||
import com.kouros.navigation.utils.NavigationUtils.createGeoJson
|
||||
import com.kouros.navigation.utils.NavigationUtils.decodePolyline
|
||||
import io.objectbox.annotation.Entity
|
||||
import io.objectbox.annotation.Id
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.time.LocalDate
|
||||
import java.util.Date
|
||||
import org.maplibre.geojson.Point
|
||||
|
||||
data class Category(
|
||||
val id: String,
|
||||
@@ -60,29 +65,6 @@ data class StepData (
|
||||
var bearing: Double
|
||||
)
|
||||
|
||||
val dataPlaces = listOf(
|
||||
Place(
|
||||
id = 0,
|
||||
name = "Vogelhartstr. 17",
|
||||
category = "Favorites",
|
||||
latitude = 48.1857475,
|
||||
longitude = 11.5793627,
|
||||
postalCode = "80807",
|
||||
city = "München",
|
||||
street = "Vogelhartstr. 17"
|
||||
|
||||
),
|
||||
Place(
|
||||
id = 0,
|
||||
name = "Hohenwaldeckstr. 27",
|
||||
category = "Recent",
|
||||
latitude = 48.1165005,
|
||||
longitude = 11.594349,
|
||||
postalCode = "81541",
|
||||
city = "München",
|
||||
street = "Hohenwaldeckstr. 27",
|
||||
)
|
||||
)
|
||||
|
||||
// GeoJSON data classes
|
||||
@Serializable
|
||||
@@ -107,9 +89,41 @@ data class GeoJsonFeatureCollection(
|
||||
data class Locations (
|
||||
var lat : Double,
|
||||
var lon : Double,
|
||||
var street : String = ""
|
||||
var street : String = "",
|
||||
val search_filter: SearchFilter,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SearchFilter(
|
||||
var max_road_class: String = "",
|
||||
var exclude_toll : Boolean = false
|
||||
) {
|
||||
|
||||
class Builder {
|
||||
private var avoidMotorway = false
|
||||
private var avoidTollway = false
|
||||
|
||||
fun avoidMotorway (value: Boolean ) = apply {
|
||||
avoidMotorway = value
|
||||
}
|
||||
|
||||
fun avoidTollway (value: Boolean ) = apply {
|
||||
avoidTollway = value
|
||||
}
|
||||
|
||||
fun build(): SearchFilter {
|
||||
val filter = SearchFilter()
|
||||
if (avoidMotorway) {
|
||||
filter.max_road_class = "trunk"
|
||||
}
|
||||
if (avoidTollway) {
|
||||
filter.exclude_toll = true
|
||||
}
|
||||
return filter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ValhallaLocation (
|
||||
var locations: List<Locations>,
|
||||
@@ -149,6 +163,10 @@ object Constants {
|
||||
|
||||
const val SHOW_THREED_BUILDING = "Show3D"
|
||||
|
||||
const val AVOID_MOTORWAY = "AvoidMotorway"
|
||||
|
||||
const val AVOID_TOLLWAY = "AvoidTollway"
|
||||
|
||||
const val NEXT_STEP_THRESHOLD = 100.0
|
||||
|
||||
const val MAXIMAL_SNAP_CORRECTION = 50.0
|
||||
|
||||
@@ -34,10 +34,15 @@ class NavigationRepository {
|
||||
|
||||
private val nominatimUrl = "https://nominatim.openstreetmap.org/"
|
||||
|
||||
fun getRoute(currentLocation : Location, location: Location): String {
|
||||
// Road classes from highest to lowest are:
|
||||
// motorway, trunk, primary, secondary, tertiary, unclassified, residential, service_other.
|
||||
|
||||
// exclude_toll
|
||||
fun getRoute(currentLocation: Location, location: Location, SearchFilter: SearchFilter): String {
|
||||
SearchFilter
|
||||
val vLocation = listOf(
|
||||
Locations(lat = currentLocation.latitude, lon = currentLocation.longitude),
|
||||
Locations(lat = location.latitude, lon = location.longitude)
|
||||
Locations(lat = currentLocation.latitude, lon = currentLocation.longitude, search_filter = SearchFilter),
|
||||
Locations(lat = location.latitude, lon = location.longitude, search_filter = SearchFilter)
|
||||
)
|
||||
val valhallaLocation = ValhallaLocation(
|
||||
locations = vLocation,
|
||||
@@ -50,8 +55,8 @@ class NavigationRepository {
|
||||
return fetchUrl(routeUrl + routeLocation, true)
|
||||
}
|
||||
|
||||
fun getRouteDistance(currentLocation : Location, location: Location): Double {
|
||||
val route = getRoute(currentLocation, location)
|
||||
fun getRouteDistance(currentLocation: Location, location: Location, searchFilter: SearchFilter): Double {
|
||||
val route = getRoute(currentLocation, location, searchFilter)
|
||||
val routeModel = RouteModel()
|
||||
routeModel.startNavigation(route)
|
||||
return routeModel.route.distance
|
||||
@@ -108,7 +113,6 @@ class NavigationRepository {
|
||||
httpURLConnection.setRequestProperty("User-Agent", "email=nominatim@kouros-online.de");
|
||||
httpURLConnection.requestMethod = "GET"
|
||||
val responseCode = httpURLConnection.responseCode
|
||||
println(responseCode)
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val response = httpURLConnection.inputStream.bufferedReader()
|
||||
.use { it.readText() } // defaults to UTF-8
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.kouros.navigation.utils.location
|
||||
import org.maplibre.geojson.FeatureCollection
|
||||
import org.maplibre.geojson.Point
|
||||
import org.maplibre.turf.TurfMeasurement
|
||||
import org.maplibre.turf.TurfMisc
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@@ -72,7 +73,7 @@ open class RouteModel() {
|
||||
if (distance < nearestDistance) {
|
||||
nearestDistance = distance
|
||||
route.currentManeuverIndex = i
|
||||
calculateCurrentIndex(beginShapeIndex, endShapeIndex, location)
|
||||
calculateCurrentShapeIndex(beginShapeIndex, endShapeIndex, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,16 +84,17 @@ open class RouteModel() {
|
||||
if (maneuver.streetNames != null && maneuver.streetNames.isNotEmpty()) {
|
||||
text = maneuver.streetNames[0]
|
||||
}
|
||||
// TODO: +1 check
|
||||
val curLocation = location(
|
||||
route.pointLocations[currentShapeIndex].latitude(),
|
||||
route.pointLocations[currentShapeIndex].longitude()
|
||||
)
|
||||
val nextLocation = location(
|
||||
route.pointLocations[currentShapeIndex + 1].latitude(),
|
||||
route.pointLocations[currentShapeIndex + 1].longitude()
|
||||
)
|
||||
bearing = curLocation.bearingTo(nextLocation)
|
||||
if (currentShapeIndex < route.pointLocations.size) {
|
||||
val nextLocation = location(
|
||||
route.pointLocations[currentShapeIndex + 1].latitude(),
|
||||
route.pointLocations[currentShapeIndex + 1].longitude()
|
||||
)
|
||||
bearing = curLocation.bearingTo(nextLocation).absoluteValue
|
||||
}
|
||||
val distanceStepLeft = leftStepDistance() * 1000
|
||||
when (distanceStepLeft) {
|
||||
in 0.0..NEXT_STEP_THRESHOLD -> {
|
||||
@@ -108,7 +110,7 @@ open class RouteModel() {
|
||||
}
|
||||
|
||||
/** Calculates the index in a maneuver. */
|
||||
private fun calculateCurrentIndex(
|
||||
private fun calculateCurrentShapeIndex(
|
||||
beginShapeIndex: Int,
|
||||
endShapeIndex: Int,
|
||||
location: Location
|
||||
|
||||
@@ -3,8 +3,6 @@ package com.kouros.navigation.model
|
||||
import android.content.Context
|
||||
import android.location.Geocoder
|
||||
import android.location.Location
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
@@ -14,13 +12,14 @@ import com.kouros.navigation.data.NavigationRepository
|
||||
import com.kouros.navigation.data.ObjectBox.boxStore
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.Place_
|
||||
import com.kouros.navigation.data.SearchFilter
|
||||
import com.kouros.navigation.data.nominatim.Search
|
||||
import com.kouros.navigation.data.nominatim.SearchResult
|
||||
import com.kouros.navigation.utils.NavigationUtils
|
||||
import com.kouros.navigation.utils.location
|
||||
import io.objectbox.kotlin.boxFor
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
|
||||
@@ -66,7 +65,6 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
//place.distance = distance.toFloat()
|
||||
if (place.distance == 0F) {
|
||||
recentPlace.postValue(place)
|
||||
println("RecentPlace $recentPlace")
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
@@ -75,7 +73,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
fun loadPlaces(location: Location) {
|
||||
fun loadPlaces(context: Context, location: Location) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val placeBox = boxStore.boxFor(Place::class)
|
||||
@@ -87,7 +85,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
query.close()
|
||||
for (place in results) {
|
||||
val plLocation = location(place.latitude, place.longitude)
|
||||
val distance = repository.getRouteDistance(location, plLocation)
|
||||
val distance = repository.getRouteDistance(location, plLocation, getSearchFilter(context))
|
||||
place.distance = distance.toFloat()
|
||||
}
|
||||
places.postValue(results)
|
||||
@@ -97,20 +95,20 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun loadRoute(currentLocation: Location, location: Location) {
|
||||
fun loadRoute(context: Context, currentLocation: Location, location: Location) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
route.postValue(repository.getRoute(currentLocation, location))
|
||||
route.postValue(repository.getRoute(currentLocation, location, getSearchFilter(context)))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadPreviewRoute(currentLocation: Location, location: Location) {
|
||||
fun loadPreviewRoute(context: Context, currentLocation: Location, location: Location) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
previewRoute.postValue(repository.getRoute(currentLocation, location))
|
||||
previewRoute.postValue(repository.getRoute(currentLocation, location, getSearchFilter(context)))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
@@ -133,7 +131,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
if (addressLines.size > 1) {
|
||||
val plLocation = location(adr.latitude, adr.longitude)
|
||||
val distance =
|
||||
repository.getRouteDistance(currentLocation, plLocation)
|
||||
repository.getRouteDistance(currentLocation, plLocation, getSearchFilter(context))
|
||||
contactList.add(
|
||||
Place(
|
||||
id = address.contactId,
|
||||
@@ -179,7 +177,6 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
|
||||
fun reverseAddress(location: Location ): String {
|
||||
val address = repository.reverseAddress(location)
|
||||
println(address)
|
||||
val gson = GsonBuilder().serializeNulls().create()
|
||||
val place = gson.fromJson(address, SearchResult::class.java)
|
||||
println(place.address.road)
|
||||
@@ -226,5 +223,21 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getSearchFilter(context: Context): SearchFilter {
|
||||
|
||||
val avoidMotorway = NavigationUtils.getBooleanKeyValue(
|
||||
context = context,
|
||||
Constants.AVOID_MOTORWAY
|
||||
)
|
||||
val avoidTollway = NavigationUtils.getBooleanKeyValue(
|
||||
context = context,
|
||||
Constants.AVOID_TOLLWAY
|
||||
)
|
||||
return SearchFilter.Builder()
|
||||
.avoidMotorway(avoidMotorway)
|
||||
.avoidTollway(avoidTollway)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user