Restaurants

This commit is contained in:
Dimitris
2026-05-05 14:27:00 +02:00
parent 202c2dfcea
commit 25ba7d7bf6
19 changed files with 134 additions and 83 deletions
@@ -11,4 +11,14 @@ val SpeedColor = Color(0xFF262525)
val MaxSpeedColor = Color(0xFFB71515)
val PlaceColor = Color(0xFF868005)
val PlaceColor = Color(0xFF868005)
val QueuingColor = Color(0xFFC46E53)
val SlowColor = Color(0xFFC43E3E)
val StationaryColor = Color(0xFF910A0A)
val HeavyColor = Color(0xFF6B0404)
val RoadworksColor = Color(0xFFDAA707)
val ClosedColor = Color(0xFF280C10)
val LaneColor = Color(0xFFEFBAC1)
val PharmacyColor = Color(0xFF054603)
@@ -122,6 +122,8 @@ object Constants {
const val CHARGING_STATION: String ="charging_station"
const val RESTAURANT: String ="restaurant"
/** The initial location to use as an anchor for searches. */
val homeVogelhart = location(11.5793748, 48.185749)
val homeHohenwaldeck = location( 11.594322, 48.1164817)
@@ -75,7 +75,7 @@ abstract class NavigationRepository {
"Accept",
"application/json"
) // The format of response we want to get from the server
httpURLConnection.setRequestProperty("User-Agent", "email=nominatim@kouros-online.de")
httpURLConnection.setRequestProperty("User-Agent", "email=online@kouros-online.de")
httpURLConnection.requestMethod = "GET"
val responseCode = httpURLConnection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
@@ -136,6 +136,7 @@ class Overpass {
}
}
Log.w("OverpassApi", searchQuery)
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
val response = connection.inputStream.bufferedReader().use { it.readText() }
@@ -21,7 +21,7 @@ data class Tags(
val capacity: String = "",
val motorcar: String = "",
val network: String = "",
val openingHours: String = "",
@SerializedName("opening_hours") val openingHours: String = "",
val operator: String = "",
val operatorShort: String = "",
val operatorWikidata: String = "",
@@ -19,7 +19,6 @@ import com.kouros.navigation.data.NavigationRepository
import com.kouros.navigation.data.Place
import com.kouros.navigation.data.Places
import com.kouros.navigation.data.SearchFilter
import com.kouros.navigation.data.fuel.FuelPrice
import com.kouros.navigation.data.fuel.FuelPrices
import com.kouros.navigation.data.fuel.Station
import com.kouros.navigation.data.fuel.Stations
@@ -28,15 +27,14 @@ import com.kouros.navigation.data.nominatim.SearchResult
import com.kouros.navigation.data.overpass.ElementSearch
import com.kouros.navigation.data.overpass.Elements
import com.kouros.navigation.data.overpass.Overpass
import com.kouros.navigation.repository.SettingsRepository
import com.kouros.navigation.utils.GeoUtils.snapLocation
import com.kouros.navigation.utils.GeoUtils.transferCoordinates
import com.kouros.navigation.utils.bearingPositive
import com.kouros.navigation.utils.countryCodeSpeedLimit
import com.kouros.navigation.utils.getSettingsRepository
import com.kouros.navigation.utils.getSettingsViewModel
import com.kouros.navigation.utils.isNumeric
import com.kouros.navigation.utils.location
import com.kouros.navigation.utils.settingsViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
@@ -220,7 +218,11 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
* Fetches traffic incident data and categorizes by severity.
* Posts categorized traffic map to traffic LiveData.
*/
fun loadTraffic(context: Context, currentLocation: Location, carOrientation: Float) {
fun loadTraffic(
context: Context,
currentLocation: Location,
carOrientation: Float,
) {
viewModelScope.launch(Dispatchers.IO) {
try {
val data = repository.getTraffic(
@@ -400,18 +402,8 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
fun getAmenities(carContext: Context, category: String, location: Location, lastFuelUpdate: Long = 0) {
viewModelScope.launch(Dispatchers.IO) {
val repository = getSettingsRepository(carContext)
var fuelPrices: List<Station>
val amenities = Overpass().getAmenities("amenity", category, location, 5.0)
val now = System.currentTimeMillis()
if (category == Constants.FUEL_STATION && ((now - lastFuelUpdate) > TANKER_KOENIG_DELAY)) {
fuelPrices = FuelPrices().getFuelPrices(location, 5)
repository.setLastFuelPrices(System.currentTimeMillis())
repository.setFuelPrices(gson.toJson(Stations(fuelPrices)))
} else {
val fuels = repository.fuelPricesFlow.first()
fuelPrices =
gson.fromJson(fuels, Stations::class.java).stations
}
val fuelPrices = fuelStations(category, lastFuelUpdate, location, repository)
val distAmenities = mutableListOf<Elements>()
amenities.forEach {
val plLocation =
@@ -428,6 +420,28 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
}
}
private suspend fun fuelStations(
category: String,
lastFuelUpdate: Long,
location: Location,
repository: SettingsRepository
): List<Station> {
var fuelPrices = emptyList<Station>()
if (category == Constants.FUEL_STATION) {
val now = System.currentTimeMillis()
if ((now - lastFuelUpdate) > TANKER_KOENIG_DELAY) {
fuelPrices = FuelPrices().getFuelPrices(location, 5)
repository.setLastFuelPrices(System.currentTimeMillis())
repository.setFuelPrices(gson.toJson(Stations(fuelPrices)))
} else {
val fuels = repository.fuelPricesFlow.first()
fuelPrices =
gson.fromJson(fuels, Stations::class.java).stations
}
}
return fuelPrices
}
fun addFuelPrice(fuel: Elements, fuelPrices: List<Station>, location: Location) {
fuelPrices.forEach {
if (fuel.tags.name.equals(it.brand, ignoreCase = true)) {
@@ -1,7 +1,6 @@
package com.kouros.navigation.utils
import android.location.Location
import android.util.Log
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import org.maplibre.geojson.FeatureCollection
@@ -24,6 +23,8 @@ import kotlin.math.sin
object GeoUtils {
const val EARTH_RADIUS = 6371.0 // in km
fun snapLocation(location: Location, stepCoordinates: List<Point>): Location {
val newLocation = Location(location)
val oldPoint = Point.fromLngLat(location.longitude, location.latitude)
@@ -151,11 +152,10 @@ object GeoUtils {
* @return latMin, latMax, lngMin, lngMax
*/
fun calculateSquareRadius(lat: Double, lng: Double, radius: Double): String {
val earthRadius = 6371.0 // earth radius in km
val latMin = lat - toDegrees(radius / earthRadius)
val latMax = lat + toDegrees(radius / earthRadius)
val lngMin = lng - toDegrees(radius / earthRadius / cos(toRadians(lat)))
val lngMax = lng + toDegrees(radius / earthRadius / cos(toRadians(lat)))
val latMin = lat - toDegrees(radius / EARTH_RADIUS)
val latMax = lat + toDegrees(radius / EARTH_RADIUS)
val lngMin = lng - toDegrees(radius / EARTH_RADIUS / cos(toRadians(lat)))
val lngMax = lng + toDegrees(radius / EARTH_RADIUS / cos(toRadians(lat)))
return "$lngMin,$latMin,$lngMax,$latMax"
}
@@ -165,11 +165,10 @@ object GeoUtils {
lon: Double,
radius: Double
): String {
val earthRadius = 6371.0
val maxLat = lat + toDegrees(radius / earthRadius)
val minLat = lat - toDegrees(radius / earthRadius)
val maxLon = lon + toDegrees(radius / earthRadius / cos(toRadians(lat)))
val minLon = lon - toDegrees(radius / earthRadius / cos(toRadians(lat)))
val maxLat = lat + toDegrees(radius / EARTH_RADIUS)
val minLat = lat - toDegrees(radius / EARTH_RADIUS)
val maxLon = lon + toDegrees(radius / EARTH_RADIUS / cos(toRadians(lat)))
val minLon = lon - toDegrees(radius / EARTH_RADIUS / cos(toRadians(lat)))
return "$minLat,$minLon,$maxLat,$maxLon"
}
@@ -229,21 +228,21 @@ object GeoUtils {
fun movePoint(
latitude: Double,
longitude: Double,
distanceMeters: Double = 7.0,
distanceMeters: Double = 8.0,
bearingDegrees: Double = 0.0
): org.maplibre.spatialk.geojson.Point {
val earthRadius = 6371000.0 // meters
val radius = EARTH_RADIUS * 1000 // meters
val bearingRadians = toRadians(bearingDegrees)
val lat1 = toRadians(latitude)
val lon1 = toRadians(longitude)
val lat2 = asin(
sin(lat1) * cos(distanceMeters / earthRadius) +
cos(lat1) * sin(distanceMeters / earthRadius) * cos(bearingRadians)
sin(lat1) * cos(distanceMeters / radius) +
cos(lat1) * sin(distanceMeters / radius) * cos(bearingRadians)
)
val lon2 = lon1 + atan2(
sin(bearingRadians) * sin(distanceMeters / earthRadius) * cos(lat1),
cos(distanceMeters / earthRadius) - sin(lat1) * sin(lat2)
sin(bearingRadians) * sin(distanceMeters / radius) * cos(lat1),
cos(distanceMeters / radius) - sin(lat1) * sin(lat2)
)
return org.maplibre.spatialk.geojson.Point(toDegrees(lon2), toDegrees(lat2))
}
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M280,880L280,514Q229,500 194.5,458Q160,416 160,360L160,80L240,80L240,360L280,360L280,80L360,80L360,360L400,360L400,80L480,80L480,360Q480,416 445.5,458Q411,500 360,514L360,880L280,880ZM680,880L680,560L560,560L560,280Q560,197 618.5,138.5Q677,80 760,80L760,880L680,880Z"/>
</vector>
@@ -73,4 +73,5 @@
<string name="engine_type">Motortyp</string>
<string name="alternative_routes">Alternative Routen</string>
<string name="wait">Warten</string>
<string name="restaurant">Restaurant</string>
</resources>
@@ -57,4 +57,5 @@
<string name="engine_type">Τύπος κινητήρα</string>
<string name="alternative_routes">Εναλλακτικές διαδρομές</string>
<string name="wait">Περιμένετε</string>
<string name="restaurant">Restaurant</string>
</resources>
@@ -57,4 +57,5 @@
<string name="engine_type">Typ silnika</string>
<string name="alternative_routes">Alternatywne trasy</string>
<string name="wait">Czekaj</string>
<string name="restaurant">Restaurant</string>
</resources>
@@ -60,4 +60,5 @@
<string name="engine_type">Engine type</string>
<string name="alternative_routes">Alternative routes</string>
<string name="wait">Wait</string>
<string name="restaurant">Restaurant</string>
</resources>