Overpass
This commit is contained in:
@@ -134,6 +134,13 @@ data class ValhallaLocation (
|
||||
var language: String
|
||||
)
|
||||
|
||||
data class BoundingBox (
|
||||
var southernLat : Double,
|
||||
var westernLon: Double,
|
||||
var northerLat : Double,
|
||||
var easternLon : Double
|
||||
)
|
||||
|
||||
object Constants {
|
||||
|
||||
const val STYLE: String = "https://kouros-online.de/liberty.json"
|
||||
@@ -141,12 +148,22 @@ object Constants {
|
||||
//const val STYLE: String = "https://tiles.openfreemap.org/styles/liberty"
|
||||
const val TAG: String = "Navigation"
|
||||
|
||||
const val CATEGORIES: String = "Categories"
|
||||
|
||||
const val CONTACTS: String = "Contacts"
|
||||
|
||||
const val RECENT: String = "Recent"
|
||||
|
||||
const val FAVORITES: String = "Favorites"
|
||||
|
||||
const val GAS_STATION: String ="GasStation"
|
||||
|
||||
const val PHARMACY: String ="pharmacy"
|
||||
|
||||
const val CHARGING_STATION: String ="charging_station"
|
||||
|
||||
|
||||
val categories = listOf("Tankstelle", "Apotheke", "Ladestationen")
|
||||
/** The initial location to use as an anchor for searches. */
|
||||
val homeLocation: Location = Location(LocationManager.GPS_PROVIDER)
|
||||
val home2Location: Location = Location(LocationManager.GPS_PROVIDER)
|
||||
@@ -176,7 +193,7 @@ object Constants {
|
||||
|
||||
const val MAXIMAL_ROUTE_DEVIATION = 100.0
|
||||
|
||||
const val DESTINATION_ARRIVAL_DISTANCE = 20.0
|
||||
const val DESTINATION_ARRIVAL_DISTANCE = 40.0
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.kouros.navigation.data
|
||||
|
||||
import android.location.Location
|
||||
import com.kouros.navigation.data.overpass.Elements
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBoundingBox
|
||||
import org.json.JSONArray
|
||||
import java.net.Authenticator
|
||||
import java.net.HttpURLConnection
|
||||
@@ -98,7 +98,6 @@ class NavigationRepository {
|
||||
return places
|
||||
}
|
||||
|
||||
|
||||
private fun fetchUrl(url: String, authenticator : Boolean): String {
|
||||
try {
|
||||
if (authenticator) {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.kouros.navigation.data
|
||||
|
||||
import android.location.Location
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.kouros.navigation.data.overpass.Amenity
|
||||
import com.kouros.navigation.data.overpass.Elements
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBoundingBox2
|
||||
import com.kouros.navigation.utils.NavigationUtils.getOverpassBbox
|
||||
import hu.supercluster.overpasser.library.output.OutputFormat
|
||||
import hu.supercluster.overpasser.library.output.OutputModificator
|
||||
import hu.supercluster.overpasser.library.output.OutputOrder
|
||||
import hu.supercluster.overpasser.library.output.OutputVerbosity
|
||||
import hu.supercluster.overpasser.library.query.OverpassQuery
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
||||
|
||||
class Overpass {
|
||||
|
||||
fun getAmenities(category: String, location: Location) : List<Elements> {
|
||||
val boundingBox = getOverpassBbox(location, 2.0)
|
||||
val bb = getBoundingBox2(location, 2.0)
|
||||
val url = "https://overpass.kumi.systems/api/interpreter"
|
||||
val httpURLConnection = URL(url).openConnection() as HttpURLConnection
|
||||
httpURLConnection.requestMethod = "POST"
|
||||
httpURLConnection.setRequestProperty(
|
||||
"Accept",
|
||||
"application/json"
|
||||
)
|
||||
httpURLConnection.setDoOutput(true);
|
||||
val query = OverpassQuery()
|
||||
.format(OutputFormat.JSON)
|
||||
.timeout(30)
|
||||
.filterQuery()
|
||||
.node()
|
||||
.amenity("charging_station")
|
||||
.tagNot("access", "private")
|
||||
.boundingBox(bb.southernLat, bb.westernLon, bb.northerLat, bb.easternLon)
|
||||
.end()
|
||||
.output(OutputVerbosity.BODY, OutputModificator.CENTER, OutputOrder.QT, 100)
|
||||
.build()
|
||||
// define a query
|
||||
val test = """
|
||||
|[out:json];
|
||||
|(
|
||||
| node[amenity=$category]
|
||||
| ($boundingBox);
|
||||
|);
|
||||
|out body;
|
||||
""".trimMargin()
|
||||
|
||||
// Send the JSON we created
|
||||
val outputStreamWriter = OutputStreamWriter(httpURLConnection.outputStream)
|
||||
outputStreamWriter.write(test)
|
||||
outputStreamWriter.flush()
|
||||
// Check if the connection is successful
|
||||
val responseCode = httpURLConnection.responseCode
|
||||
println("Overpass: $responseCode")
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val response = httpURLConnection.inputStream.bufferedReader()
|
||||
.use { it.readText() } // defaults to UTF-8
|
||||
|
||||
|
||||
val gson = GsonBuilder().serializeNulls().create()
|
||||
val overpass = gson.fromJson(response, Amenity::class.java)
|
||||
println("Overpass: $response")
|
||||
return overpass.elements
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.kouros.navigation.data.overpass
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
|
||||
data class Amenity (
|
||||
|
||||
@SerializedName("version" ) var version : Double? = null,
|
||||
@SerializedName("generator" ) var generator : String? = null,
|
||||
@SerializedName("osm3s" ) var osm3s : Osm3s? = Osm3s(),
|
||||
@SerializedName("elements" ) var elements : ArrayList<Elements> = arrayListOf()
|
||||
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.kouros.navigation.data.overpass
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
|
||||
data class Elements (
|
||||
|
||||
@SerializedName("type" ) var type : String? = null,
|
||||
@SerializedName("id" ) var id : Long? = null,
|
||||
@SerializedName("lat" ) var lat : Double? = null,
|
||||
@SerializedName("lon" ) var lon : Double? = null,
|
||||
@SerializedName("tags" ) var tags : Tags? = Tags()
|
||||
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.kouros.navigation.data.overpass
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
|
||||
data class Osm3s (
|
||||
|
||||
@SerializedName("timestamp_osm_base" ) var timestampOsmBase : String? = null,
|
||||
@SerializedName("copyright" ) var copyright : String? = null
|
||||
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.kouros.navigation.data.overpass
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
|
||||
data class Tags (
|
||||
|
||||
@SerializedName("amenity" ) var amenity : String? = null,
|
||||
@SerializedName("authentication:none" ) var authenticationNone : String? = null,
|
||||
@SerializedName("capacity" ) var capacity : String? = null,
|
||||
@SerializedName("motorcar" ) var motorcar : String? = null,
|
||||
@SerializedName("network" ) var network : String? = null,
|
||||
@SerializedName("opening_hours" ) var openingHours : String? = null,
|
||||
@SerializedName("operator" ) var operator : String? = null,
|
||||
@SerializedName("operator:short" ) var operatorShort : String? = null,
|
||||
@SerializedName("operator:wikidata" ) var operatorWikidata : String? = null,
|
||||
@SerializedName("operator:wikipedia" ) var operatorWikipedia : String? = null,
|
||||
@SerializedName("ref" ) var ref : String? = null,
|
||||
@SerializedName("socket:type2" ) var socketType2 : String? = null,
|
||||
@SerializedName("socket:type2:output" ) var socketType2Ooutput : String? = null
|
||||
|
||||
)
|
||||
@@ -22,7 +22,7 @@
|
||||
"id": "background",
|
||||
"type": "background",
|
||||
"layout": {"visibility": "visible"},
|
||||
"paint": {"background-color": "rgba(28, 28, 35, 1)"}
|
||||
"paint": {"background-color": "rgba(39, 46, 57, 1)"}
|
||||
},
|
||||
{
|
||||
"id": "natural_earth",
|
||||
@@ -903,7 +903,11 @@
|
||||
["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true],
|
||||
["match", ["get", "class"], ["service", "track"], true, false]
|
||||
],
|
||||
"layout": {"line-cap": "round", "line-join": "round"},
|
||||
"layout": {
|
||||
"line-cap": "round",
|
||||
"line-join": "round",
|
||||
"visibility": "visible"
|
||||
},
|
||||
"paint": {
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
@@ -916,7 +920,7 @@
|
||||
20,
|
||||
11
|
||||
],
|
||||
"line-color": "rgba(65, 74, 92, 1)"
|
||||
"line-color": "rgba(77, 94, 123, 1)"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1005,7 +1009,7 @@
|
||||
],
|
||||
"layout": {"line-cap": "round", "line-join": "round"},
|
||||
"paint": {
|
||||
"line-color": "#e9ac77",
|
||||
"line-color": "rgba(65, 74, 92, 1)",
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
["exponential", 1.2],
|
||||
@@ -1029,7 +1033,7 @@
|
||||
],
|
||||
"layout": {"line-join": "round"},
|
||||
"paint": {
|
||||
"line-color": "#e9ac77",
|
||||
"line-color": "rgba(65, 74, 92, 1)",
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
["exponential", 1.2],
|
||||
@@ -1059,7 +1063,7 @@
|
||||
],
|
||||
"layout": {"line-cap": "round", "line-join": "round"},
|
||||
"paint": {
|
||||
"line-color": "#e9ac77",
|
||||
"line-color": "rgba(65, 74, 92, 1)",
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
["exponential", 1.2],
|
||||
@@ -1245,7 +1249,7 @@
|
||||
],
|
||||
"layout": {"line-cap": "round", "line-join": "round"},
|
||||
"paint": {
|
||||
"line-color": "rgba(105, 170, 87, 1)",
|
||||
"line-color": "rgba(65, 74, 92, 1)",
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
["exponential", 1.2],
|
||||
@@ -1271,7 +1275,7 @@
|
||||
],
|
||||
"layout": {"line-join": "round"},
|
||||
"paint": {
|
||||
"line-color": "#fea",
|
||||
"line-color": "rgba(65, 74, 92, 1)",
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
["exponential", 1.2],
|
||||
@@ -1306,7 +1310,7 @@
|
||||
5,
|
||||
"hsl(26,87%,62%)",
|
||||
6,
|
||||
"#fc8"
|
||||
"#ab9"
|
||||
],
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
@@ -1847,7 +1851,7 @@
|
||||
],
|
||||
"layout": {"line-join": "round"},
|
||||
"paint": {
|
||||
"line-color": "#fea",
|
||||
"line-color": "rgba(65, 74, 92, 34)",
|
||||
"line-width": [
|
||||
"interpolate",
|
||||
["exponential", 1.2],
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.location.Location
|
||||
import androidx.car.app.navigation.model.Maneuver
|
||||
import androidx.car.app.navigation.model.Step
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||
import com.kouros.navigation.data.Constants.NEXT_STEP_THRESHOLD
|
||||
import com.kouros.navigation.data.ManeuverType
|
||||
import com.kouros.navigation.data.Place
|
||||
@@ -35,6 +37,7 @@ open class RouteModel() {
|
||||
set(value) {
|
||||
routeState = routeState.copy(route = value)
|
||||
}
|
||||
|
||||
fun startNavigation(routeString: String) {
|
||||
val newRoute = Route.Builder()
|
||||
.route(routeString)
|
||||
@@ -49,7 +52,7 @@ open class RouteModel() {
|
||||
this.routeState = routeState.copy(
|
||||
route = null,
|
||||
isNavigating = false,
|
||||
// destination = Place(),
|
||||
// destination = Place(),
|
||||
arrived = false,
|
||||
maneuverType = 0,
|
||||
currentShapeIndex = 0,
|
||||
@@ -100,30 +103,31 @@ open class RouteModel() {
|
||||
}
|
||||
|
||||
fun currentStep(): StepData {
|
||||
val currentManeuver = route.currentManeuver()
|
||||
// Determine if we should display the current or the next maneuver
|
||||
val distanceToNextStep = leftStepDistance()
|
||||
val isNearNextManeuver = distanceToNextStep in 0.0..NEXT_STEP_THRESHOLD
|
||||
val shouldAdvance =
|
||||
isNearNextManeuver && route.currentManeuverIndex < (route.maneuvers.size - 1)
|
||||
isNearNextManeuver && route.currentManeuverIndex < (route.maneuvers.size)
|
||||
|
||||
// Determine the maneuver type and corresponding icon
|
||||
var maneuverType = if (hasArrived(currentManeuver.type)) {
|
||||
currentManeuver.type
|
||||
} else {
|
||||
ManeuverType.None.value
|
||||
}
|
||||
// Get the single, correct maneuver for this state
|
||||
val relevantManeuver = if (shouldAdvance) {
|
||||
route.nextManeuver() // This advances the route's state
|
||||
} else {
|
||||
route.currentManeuver()
|
||||
}
|
||||
|
||||
// Safely get the street name from the maneuver
|
||||
val streetName = relevantManeuver.streetNames?.firstOrNull() ?: ""
|
||||
|
||||
// Determine the maneuver type and corresponding icon
|
||||
val maneuverType = if (hasArrived(relevantManeuver.type)) {
|
||||
relevantManeuver.type
|
||||
} else {
|
||||
ManeuverType.None.value
|
||||
if (shouldAdvance) {
|
||||
maneuverType = relevantManeuver.type
|
||||
}
|
||||
val maneuverIconPair = maneuverIcon(maneuverType)
|
||||
|
||||
// Construct and return the final StepData object
|
||||
return StepData(
|
||||
streetName,
|
||||
@@ -135,6 +139,40 @@ open class RouteModel() {
|
||||
)
|
||||
}
|
||||
|
||||
fun currentStepOld(): StepData {
|
||||
val maneuver = route.currentManeuver()
|
||||
var text = ""
|
||||
if (maneuver.streetNames != null && maneuver.streetNames.isNotEmpty()) {
|
||||
text = maneuver.streetNames[0]
|
||||
}
|
||||
val distanceStepLeft = leftStepDistance()
|
||||
when (distanceStepLeft) {
|
||||
in 0.0..Constants.NEXT_STEP_THRESHOLD -> {
|
||||
if (route.currentManeuverIndex < route.maneuvers.size) {
|
||||
val maneuver = route.nextManeuver()
|
||||
if (maneuver.streetNames != null && maneuver.streetNames.isNotEmpty()) {
|
||||
text = maneuver.streetNames[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val type = if (hasArrived(maneuver.type)) {
|
||||
maneuver.type
|
||||
} else {
|
||||
ManeuverType.None.value
|
||||
}
|
||||
var routing: (Pair<Int, Int>) = maneuverIcon(type)
|
||||
when (distanceStepLeft) {
|
||||
in 0.0..NEXT_STEP_THRESHOLD -> {
|
||||
if (route.currentManeuverIndex < route.maneuvers.size) {
|
||||
val maneuver = route.nextManeuver()
|
||||
val maneuverType = maneuver.type
|
||||
routing = maneuverIcon(maneuverType)
|
||||
}
|
||||
}
|
||||
}
|
||||
return StepData(text, distanceStepLeft, routing.first, routing.second, arrivalTime(), travelLeftDistance())
|
||||
}
|
||||
fun nextStep(): StepData {
|
||||
val maneuver = route.nextManeuver()
|
||||
val maneuverType = maneuver.type
|
||||
@@ -290,12 +328,10 @@ open class RouteModel() {
|
||||
return routeState.isNavigating
|
||||
}
|
||||
|
||||
fun isArrived(): Boolean {
|
||||
return routeState.arrived
|
||||
}
|
||||
|
||||
fun hasArrived(type: Int): Boolean {
|
||||
return type == ManeuverType.DestinationRight.value
|
||||
// return leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE && type == ManeuverType.DestinationRight.value
|
||||
return type == ManeuverType.DestinationRight.value
|
||||
|| routeState.maneuverType == ManeuverType.Destination.value
|
||||
|| routeState.maneuverType == ManeuverType.DestinationLeft.value
|
||||
}
|
||||
|
||||
@@ -13,11 +13,13 @@ import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Locations
|
||||
import com.kouros.navigation.data.NavigationRepository
|
||||
import com.kouros.navigation.data.ObjectBox.boxStore
|
||||
import com.kouros.navigation.data.Overpass
|
||||
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.data.overpass.Elements
|
||||
import com.kouros.navigation.utils.NavigationUtils
|
||||
import com.kouros.navigation.utils.location
|
||||
import io.objectbox.kotlin.boxFor
|
||||
@@ -55,6 +57,9 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
MutableLiveData<List<Place>>()
|
||||
}
|
||||
|
||||
val elements: MutableLiveData<List<Elements>> by lazy {
|
||||
MutableLiveData<List<Elements>>()
|
||||
}
|
||||
|
||||
fun loadRecentPlace(location: Location) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
@@ -113,6 +118,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
.orderDesc(Place_.lastDate)
|
||||
.build()
|
||||
val results = query.find()
|
||||
println("Favorites $results")
|
||||
query.close()
|
||||
for (place in results) {
|
||||
val plLocation = location(place.longitude, place.latitude)
|
||||
@@ -231,6 +237,13 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
return place.address.road
|
||||
}
|
||||
|
||||
fun getAmenities(category: String, location: Location) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val amenities = Overpass().getAmenities(category, location)
|
||||
elements.postValue(amenities)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveFavorite(place: Place) {
|
||||
place.category = Constants.FAVORITES
|
||||
savePlace(place)
|
||||
@@ -258,7 +271,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
||||
val current = LocalDateTime.now(ZoneOffset.UTC)
|
||||
place.lastDate = current.atZone(ZoneOffset.UTC).toEpochSecond()
|
||||
placeBox.put(place)
|
||||
println("Save Recent $place")
|
||||
println("Save Place $place")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import androidx.core.content.edit
|
||||
import com.kouros.navigation.data.BoundingBox
|
||||
import com.kouros.navigation.data.Constants.SHARED_PREF_KEY
|
||||
import com.kouros.navigation.data.GeoJsonFeature
|
||||
import com.kouros.navigation.data.GeoJsonFeatureCollection
|
||||
@@ -158,6 +159,23 @@ object NavigationUtils {
|
||||
return jsonString
|
||||
}
|
||||
|
||||
fun getOverpassBbox(location: Location, radius: Double): String {
|
||||
val bbox = getBoundingBox(location.longitude, location.latitude, radius)
|
||||
val neLon = bbox["ne"]?.get("lon")
|
||||
val neLat = bbox["ne"]?.get("lat")
|
||||
val swLon = bbox["sw"]?.get("lon")
|
||||
val swLat = bbox["sw"]?.get("lat")
|
||||
return "$swLon,$swLat,$neLon,$neLat"
|
||||
}
|
||||
|
||||
fun getBoundingBox2(location: Location, radius: Double): BoundingBox {
|
||||
val bbox = getBoundingBox(location.longitude, location.latitude, radius)
|
||||
val neLon = bbox["ne"]?.get("lon")
|
||||
val neLat = bbox["ne"]?.get("lat")
|
||||
val swLon = bbox["sw"]?.get("lon")
|
||||
val swLat = bbox["sw"]?.get("lat")
|
||||
return BoundingBox(swLat ?: 0.0 , swLon ?: 0.0, neLat ?: 0.0, neLon ?: 0.0)
|
||||
}
|
||||
fun getBoundingBox(
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
@@ -176,30 +194,6 @@ object NavigationUtils {
|
||||
"se" to mapOf("lat" to minLat, "lon" to maxLon)
|
||||
)
|
||||
}
|
||||
|
||||
fun computeOffset(from: Location, distance: Double, heading: Double): Location {
|
||||
val earthRadius = 6371009.0
|
||||
var distance = distance
|
||||
var heading = heading
|
||||
distance /= earthRadius
|
||||
heading = toRadians(heading)
|
||||
val fromLat: Double = toRadians(from.latitude)
|
||||
val fromLng: Double = toRadians(from.longitude)
|
||||
val cosDistance: Double = cos(distance)
|
||||
val sinDistance = sin(distance)
|
||||
val sinFromLat = sin(fromLat)
|
||||
val cosFromLat: Double = cos(fromLat)
|
||||
val sinLat: Double = cosDistance * sinFromLat + sinDistance * cosFromLat * cos(heading)
|
||||
val dLng: Double = atan2(
|
||||
sinDistance * cosFromLat * sin(heading),
|
||||
cosDistance - sinFromLat * sinLat
|
||||
)
|
||||
val snap = Location(LocationManager.GPS_PROVIDER)
|
||||
snap.latitude = toDegrees(asin(sinLat))
|
||||
snap.longitude = toDegrees(fromLng + dLng)
|
||||
return snap
|
||||
//return LatLng(toDegrees(asin(sinLat)), toDegrees(fromLng + dLng))
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateZoom(speed: Double?): Double {
|
||||
@@ -208,11 +202,12 @@ fun calculateZoom(speed: Double?): Double {
|
||||
}
|
||||
val speedKmh = (speed * 3.6).toInt()
|
||||
val zoom = when (speedKmh) {
|
||||
in 0..10 -> 17.0
|
||||
in 11..30 -> 16.0
|
||||
in 31..50 -> 16.0
|
||||
in 0..10 -> 18.0
|
||||
in 11..30 -> 17.0
|
||||
in 21..40 -> 16.0
|
||||
in 31..50 -> 15.0
|
||||
in 51..60 -> 15.0
|
||||
else -> 15
|
||||
else -> 14
|
||||
}
|
||||
return zoom.toDouble()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user