Bearing
This commit is contained in:
@@ -48,7 +48,6 @@ import androidx.compose.material3.SnackbarHostState
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -152,7 +151,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
val curLocation = Location(LocationManager.GPS_PROVIDER)
|
val curLocation = Location(LocationManager.GPS_PROVIDER)
|
||||||
curLocation.longitude = loc[0]
|
curLocation.longitude = loc[0]
|
||||||
curLocation.latitude = loc[1]
|
curLocation.latitude = loc[1]
|
||||||
routeModel.findManeuver(curLocation)
|
routeModel.updateLocation(curLocation)
|
||||||
val leftTime = routeModel.travelLeftTime()
|
val leftTime = routeModel.travelLeftTime()
|
||||||
val leftDistance = routeModel.travelLeftDistance()
|
val leftDistance = routeModel.travelLeftDistance()
|
||||||
Log.i(TAG, " leftTime: ${leftTime / 60}")
|
Log.i(TAG, " leftTime: ${leftTime / 60}")
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ class NavigationSession : Session() {
|
|||||||
fun update(location: Location) {
|
fun update(location: Location) {
|
||||||
surfaceRenderer.updateLocation(location)
|
surfaceRenderer.updateLocation(location)
|
||||||
if (routeModel.isNavigating()) {
|
if (routeModel.isNavigating()) {
|
||||||
routeModel.findManeuver(location)
|
routeModel.updateLocation(location)
|
||||||
// if (routeModel.distanceToRoute > 50) {
|
// if (routeModel.distanceToRoute > 50) {
|
||||||
// routeModel.stopNavigation()
|
// routeModel.stopNavigation()
|
||||||
// locationIndex = 0
|
// locationIndex = 0
|
||||||
|
|||||||
@@ -11,11 +11,9 @@ import androidx.car.app.AppManager
|
|||||||
import androidx.car.app.CarContext
|
import androidx.car.app.CarContext
|
||||||
import androidx.car.app.SurfaceCallback
|
import androidx.car.app.SurfaceCallback
|
||||||
import androidx.car.app.SurfaceContainer
|
import androidx.car.app.SurfaceContainer
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@@ -28,8 +26,8 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.setViewTreeLifecycleOwner
|
import androidx.lifecycle.setViewTreeLifecycleOwner
|
||||||
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
||||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||||
|
import com.kouros.navigation.model.RouteModel
|
||||||
import com.kouros.navigation.utils.NavigationUtils
|
import com.kouros.navigation.utils.NavigationUtils
|
||||||
import kotlinx.coroutines.flow.onSubscription
|
|
||||||
import org.maplibre.compose.camera.CameraPosition
|
import org.maplibre.compose.camera.CameraPosition
|
||||||
import org.maplibre.compose.camera.rememberCameraState
|
import org.maplibre.compose.camera.rememberCameraState
|
||||||
import org.maplibre.compose.expressions.dsl.const
|
import org.maplibre.compose.expressions.dsl.const
|
||||||
@@ -65,6 +63,7 @@ class SurfaceRenderer(
|
|||||||
|
|
||||||
val previewRouteData = MutableLiveData("")
|
val previewRouteData = MutableLiveData("")
|
||||||
|
|
||||||
|
lateinit var centerLocation : Location
|
||||||
var preview = false
|
var preview = false
|
||||||
|
|
||||||
lateinit var mapView: ComposeView
|
lateinit var mapView: ComposeView
|
||||||
@@ -72,7 +71,7 @@ class SurfaceRenderer(
|
|||||||
val tilt = 55.0
|
val tilt = 55.0
|
||||||
val padding = PaddingValues(start = 150.dp, top = 250.dp)
|
val padding = PaddingValues(start = 150.dp, top = 250.dp)
|
||||||
|
|
||||||
val prePadding = PaddingValues(start = 150.dp, bottom = 300.dp)
|
val prePadding = PaddingValues(start = 150.dp, bottom = 0.dp)
|
||||||
|
|
||||||
val mSurfaceCallback: SurfaceCallback = object : SurfaceCallback {
|
val mSurfaceCallback: SurfaceCallback = object : SurfaceCallback {
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ class SurfaceRenderer(
|
|||||||
this.setViewTreeLifecycleOwner(lifecycleOwner)
|
this.setViewTreeLifecycleOwner(lifecycleOwner)
|
||||||
this.setViewTreeSavedStateRegistryOwner(lifecycleOwner)
|
this.setViewTreeSavedStateRegistryOwner(lifecycleOwner)
|
||||||
setContent {
|
setContent {
|
||||||
Map()
|
MapView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
presentation = Presentation(carContext, virtualDisplay.display)
|
presentation = Presentation(carContext, virtualDisplay.display)
|
||||||
@@ -154,7 +153,9 @@ class SurfaceRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Map() {
|
fun MapView() {
|
||||||
|
val locationProvider = rememberDefaultLocationProvider()
|
||||||
|
val locationState = rememberUserLocationState(locationProvider)
|
||||||
val position: CameraPosition? by cameraPosition.observeAsState()
|
val position: CameraPosition? by cameraPosition.observeAsState()
|
||||||
val route: String? by routeData.observeAsState()
|
val route: String? by routeData.observeAsState()
|
||||||
val previewRoute: String? by previewRouteData.observeAsState()
|
val previewRoute: String? by previewRouteData.observeAsState()
|
||||||
@@ -171,8 +172,6 @@ class SurfaceRenderer(
|
|||||||
padding = getPaddingValues()
|
padding = getPaddingValues()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val locationProvider = rememberDefaultLocationProvider()
|
|
||||||
val locationState = rememberUserLocationState(locationProvider)
|
|
||||||
MaplibreMap(
|
MaplibreMap(
|
||||||
cameraState = cameraState,
|
cameraState = cameraState,
|
||||||
//baseStyle = BaseStyle.Uri("https://tiles.openfreemap.org/styles/liberty"),
|
//baseStyle = BaseStyle.Uri("https://tiles.openfreemap.org/styles/liberty"),
|
||||||
@@ -191,17 +190,32 @@ class SurfaceRenderer(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(position) {
|
if (!preview) {
|
||||||
cameraState.animateTo(
|
LaunchedEffect(position) {
|
||||||
finalPosition = CameraPosition(
|
cameraState.animateTo(
|
||||||
bearing = position!!.bearing,
|
finalPosition = CameraPosition(
|
||||||
zoom = position!!.zoom,
|
bearing = position!!.bearing,
|
||||||
target = position!!.target,
|
zoom = position!!.zoom,
|
||||||
tilt = tilt,
|
target = position!!.target,
|
||||||
padding = getPaddingValues()
|
tilt = tilt,
|
||||||
),
|
padding = getPaddingValues()
|
||||||
duration = 3.seconds
|
),
|
||||||
)
|
duration = 3.seconds
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LaunchedEffect(position) {
|
||||||
|
cameraState.animateTo(
|
||||||
|
finalPosition = CameraPosition(
|
||||||
|
bearing = 0.0,
|
||||||
|
zoom = 9.0,
|
||||||
|
target = Position(centerLocation.longitude, centerLocation.latitude),
|
||||||
|
tilt = 0.0,
|
||||||
|
padding = getPaddingValues()
|
||||||
|
),
|
||||||
|
duration = 3.seconds
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,41 +280,52 @@ class SurfaceRenderer(
|
|||||||
|
|
||||||
fun updateLocation(location: Location) {
|
fun updateLocation(location: Location) {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
var bearing: Double
|
if (!preview) {
|
||||||
if (routeModel.isNavigating()) {
|
var bearing: Double
|
||||||
bearing = routeModel.currentStep().bearing
|
if (routeModel.isNavigating()) {
|
||||||
} else {
|
bearing = routeModel.currentStep().bearing
|
||||||
bearing = cameraPosition.value!!.bearing
|
} else {
|
||||||
if (lastLocation.latitude != location.latitude) {
|
bearing = cameraPosition.value!!.bearing
|
||||||
if (lastLocation.distanceTo(location) > 5) {
|
if (lastLocation.latitude != location.latitude) {
|
||||||
bearing = lastLocation.bearingTo(location).toDouble()
|
if (lastLocation.distanceTo(location) > 5) {
|
||||||
|
bearing = lastLocation.bearingTo(location).toDouble()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
val zoom = NavigationUtils().calculateZoom(location.speed.toDouble())
|
||||||
var zoom = NavigationUtils().calculateZoom(location.speed.toDouble())
|
cameraPosition.postValue(
|
||||||
if (preview) {
|
cameraPosition.value!!.copy(
|
||||||
bearing = 0.0
|
bearing = bearing,
|
||||||
zoom = 11.0
|
zoom = zoom,
|
||||||
}
|
padding = getPaddingValues(),
|
||||||
cameraPosition.postValue(
|
target = Position(location.longitude, location.latitude),
|
||||||
cameraPosition.value!!.copy(
|
)
|
||||||
bearing = bearing,
|
|
||||||
zoom = zoom,
|
|
||||||
padding = getPaddingValues(),
|
|
||||||
target = Position(location.longitude, location.latitude),
|
|
||||||
)
|
)
|
||||||
)
|
lastLocation = location
|
||||||
lastLocation = location
|
} else {
|
||||||
|
val bearing = 0.0
|
||||||
|
val zoom = 11.0
|
||||||
|
cameraPosition.postValue(
|
||||||
|
cameraPosition.value!!.copy(
|
||||||
|
bearing = bearing,
|
||||||
|
zoom = zoom,
|
||||||
|
tilt = 0.0,
|
||||||
|
target = Position(centerLocation.longitude, centerLocation.latitude)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun setRouteData() {
|
fun setRouteData() {
|
||||||
routeData.value = routeModel.route
|
routeData.value = routeModel.route
|
||||||
preview = false
|
preview = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setPreviewRouteData(route: String) {
|
fun setPreviewRouteData(routeModel: RouteModel) {
|
||||||
previewRouteData.value = route
|
previewRouteData.value = routeModel.route
|
||||||
|
centerLocation = routeModel.centerLocation
|
||||||
preview = true
|
preview = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class RouteCarModel() : RouteModel() {
|
|||||||
|
|
||||||
ManeuverType.Left.value -> {
|
ManeuverType.Left.value -> {
|
||||||
type = Maneuver.TYPE_TURN_NORMAL_LEFT
|
type = Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_slight_left)
|
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_normal_left)
|
||||||
}
|
}
|
||||||
|
|
||||||
ManeuverType.RampLeft.value -> {
|
ManeuverType.RampLeft.value -> {
|
||||||
@@ -149,7 +149,7 @@ class RouteCarModel() : RouteModel() {
|
|||||||
|
|
||||||
ManeuverType.StayLeft.value -> {
|
ManeuverType.StayLeft.value -> {
|
||||||
type = Maneuver.TYPE_KEEP_LEFT
|
type = Maneuver.TYPE_KEEP_LEFT
|
||||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_slight_left)
|
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_name_change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maneuverType = type
|
maneuverType = type
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class PlaceListScreen(
|
|||||||
}
|
}
|
||||||
if (category == Constants.CONTACTS) {
|
if (category == Constants.CONTACTS) {
|
||||||
viewModel.contactAddress.observe(this, observerAddress)
|
viewModel.contactAddress.observe(this, observerAddress)
|
||||||
viewModel.loadContacts(carContext)
|
viewModel.loadContacts(carContext, location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ import com.kouros.navigation.car.navigation.RouteCarModel
|
|||||||
import com.kouros.navigation.data.NavigationRepository
|
import com.kouros.navigation.data.NavigationRepository
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.model.ViewModel
|
import com.kouros.navigation.model.ViewModel
|
||||||
|
import java.math.BigDecimal
|
||||||
|
import java.math.RoundingMode
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/** Creates a screen using the new [androidx.car.app.navigation.model.MapWithContentTemplate] */
|
/** Creates a screen using the new [androidx.car.app.navigation.model.MapWithContentTemplate] */
|
||||||
class RoutePreviewScreen(
|
class RoutePreviewScreen(
|
||||||
@@ -68,7 +71,7 @@ class RoutePreviewScreen(
|
|||||||
val observer = Observer<String> { route ->
|
val observer = Observer<String> { route ->
|
||||||
if (route.isNotEmpty()) {
|
if (route.isNotEmpty()) {
|
||||||
routeModel.startNavigation(route)
|
routeModel.startNavigation(route)
|
||||||
surfaceRenderer.setPreviewRouteData(routeModel.route)
|
surfaceRenderer.setPreviewRouteData(routeModel)
|
||||||
val geocoder = Geocoder(carContext)
|
val geocoder = Geocoder(carContext)
|
||||||
geocoder.getFromLocation(destination.latitude, destination.longitude, 1) {
|
geocoder.getFromLocation(destination.latitude, destination.longitude, 1) {
|
||||||
for (address in it) {
|
for (address in it) {
|
||||||
@@ -198,8 +201,9 @@ class RoutePreviewScreen(
|
|||||||
|
|
||||||
|
|
||||||
private fun createRouteText(index: Int): CarText {
|
private fun createRouteText(index: Int): CarText {
|
||||||
val time = routeModel.summary.getInt("time")
|
val time = routeModel.routeTime
|
||||||
val length = routeModel.summary.getInt("length")
|
|
||||||
|
val length = BigDecimal(routeModel.routeDistance).setScale(1, RoundingMode.HALF_EVEN)
|
||||||
val firstRoute = SpannableString(" \u00b7 $length km")
|
val firstRoute = SpannableString(" \u00b7 $length km")
|
||||||
firstRoute.setSpan(
|
firstRoute.setSpan(
|
||||||
DurationSpan.create(time.toLong()), 0, 1,0
|
DurationSpan.create(time.toLong()), 0, 1,0
|
||||||
@@ -208,7 +212,6 @@ class RoutePreviewScreen(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun onNavigate() {
|
private fun onNavigate() {
|
||||||
setResult(destination)
|
setResult(destination)
|
||||||
finish()
|
finish()
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.kouros.navigation.model.RouteModel
|
|||||||
import com.kouros.navigation.model.ViewModel
|
import com.kouros.navigation.model.ViewModel
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.kouros.navigation.data
|
package com.kouros.navigation.data
|
||||||
|
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
|
import com.kouros.navigation.model.RouteModel
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import java.net.Authenticator
|
import java.net.Authenticator
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
@@ -47,6 +48,13 @@ class NavigationRepository {
|
|||||||
return fetchUrl(routeUrl + routeLocation)
|
return fetchUrl(routeUrl + routeLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getRouteDistance(currentLocation : Location, location: Location): Double {
|
||||||
|
val route = getRoute(currentLocation, location)
|
||||||
|
val routeModel = RouteModel()
|
||||||
|
routeModel.startNavigation(route)
|
||||||
|
return routeModel.routeDistance
|
||||||
|
}
|
||||||
|
|
||||||
fun getPlaces(): List<Place> {
|
fun getPlaces(): List<Place> {
|
||||||
val places: MutableList<Place> = ArrayList()
|
val places: MutableList<Place> = ArrayList()
|
||||||
val placesStr = fetchUrl(placesUrl)
|
val placesStr = fetchUrl(placesUrl)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class Contacts(private var context: Context) {
|
|||||||
if (name.contains("Jola")
|
if (name.contains("Jola")
|
||||||
|| name.contains("Dominic")
|
|| name.contains("Dominic")
|
||||||
|| name.contains("Martha")
|
|| name.contains("Martha")
|
||||||
|| name.contains("Μεντή")
|
|| name.contains("Μεντη")
|
||||||
|| name.contains("David")) {
|
|| name.contains("David")) {
|
||||||
val mimeType: String = getString(getColumnIndex(ContactsContract.Data.MIMETYPE))
|
val mimeType: String = getString(getColumnIndex(ContactsContract.Data.MIMETYPE))
|
||||||
if (mimeType == ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE) {
|
if (mimeType == ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE) {
|
||||||
|
|||||||
@@ -4,22 +4,26 @@ import android.location.Location
|
|||||||
import android.location.LocationManager
|
import android.location.LocationManager
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.StepData
|
import com.kouros.navigation.data.StepData
|
||||||
|
import com.kouros.navigation.utils.NavigationUtils
|
||||||
import com.kouros.navigation.utils.NavigationUtils.Utils.createGeoJson
|
import com.kouros.navigation.utils.NavigationUtils.Utils.createGeoJson
|
||||||
import com.kouros.navigation.utils.NavigationUtils.Utils.decodePolyline
|
import com.kouros.navigation.utils.NavigationUtils.Utils.decodePolyline
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
// Source - https://stackoverflow.com/a
|
|
||||||
// Posted by Dmitrii Bychkov
|
|
||||||
// Retrieved 2025-11-14, License - CC BY-SA 4.0
|
|
||||||
open class RouteModel () {
|
open class RouteModel () {
|
||||||
var polylineLocations: List<List<Double>> = emptyList()
|
var polylineLocations: List<List<Double>> = emptyList()
|
||||||
lateinit var maneuvers: JSONArray
|
lateinit var maneuvers: JSONArray
|
||||||
lateinit var locations: JSONArray
|
lateinit var locations: JSONArray
|
||||||
lateinit var summary: JSONObject
|
private lateinit var summary: JSONObject
|
||||||
|
var routeDistance = 0.0
|
||||||
|
|
||||||
|
var routeTime = 0.0
|
||||||
|
|
||||||
|
lateinit var centerLocation: Location
|
||||||
lateinit var destination: Place
|
lateinit var destination: Place
|
||||||
|
|
||||||
var navigating = false
|
var navigating = false
|
||||||
var arrived = false
|
var arrived = false
|
||||||
var maneuverIndex = 0
|
var maneuverIndex = 0
|
||||||
@@ -28,12 +32,13 @@ open class RouteModel () {
|
|||||||
|
|
||||||
var distanceToStepEnd = 0F
|
var distanceToStepEnd = 0F
|
||||||
|
|
||||||
|
var bearing = 0F
|
||||||
|
|
||||||
var beginIndex = 0
|
var beginIndex = 0
|
||||||
|
|
||||||
var endIndex = 0
|
var endIndex = 0
|
||||||
var routingManeuvers = mutableListOf<JSONObject>()
|
|
||||||
|
|
||||||
var distanceToRoute = 0F
|
var routingManeuvers = mutableListOf<JSONObject>()
|
||||||
|
|
||||||
var route = ""
|
var route = ""
|
||||||
|
|
||||||
@@ -56,11 +61,20 @@ open class RouteModel () {
|
|||||||
locations = trip.getJSONArray("locations")
|
locations = trip.getJSONArray("locations")
|
||||||
val legs = trip.getJSONArray("legs")
|
val legs = trip.getJSONArray("legs")
|
||||||
summary = trip.getJSONObject("summary")
|
summary = trip.getJSONObject("summary")
|
||||||
|
routeTime = summary.getDouble("time")
|
||||||
|
routeDistance = summary.getDouble("length")
|
||||||
|
centerLocation = createCenterLocation()
|
||||||
maneuvers = legs.getJSONObject(0).getJSONArray("maneuvers")
|
maneuvers = legs.getJSONObject(0).getJSONArray("maneuvers")
|
||||||
val shape = legs.getJSONObject(0).getString("shape")
|
val shape = legs.getJSONObject(0).getString("shape")
|
||||||
polylineLocations = decodePolyline(shape)
|
polylineLocations = decodePolyline(shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createCenterLocation() : Location {
|
||||||
|
val latitude = summary.getDouble("max_lat") - (summary.getDouble("max_lat") - summary.getDouble("min_lat"))
|
||||||
|
val longitude = summary.getDouble("max_lon") - (summary.getDouble("max_lon") - summary.getDouble("min_lon"))
|
||||||
|
return NavigationUtils().location(latitude, longitude)
|
||||||
|
}
|
||||||
|
|
||||||
fun startNavigation(valhallaRoute: String) {
|
fun startNavigation(valhallaRoute: String) {
|
||||||
decodeValhallaRoute(valhallaRoute)
|
decodeValhallaRoute(valhallaRoute)
|
||||||
for (i in 0..<maneuvers.length()) {
|
for (i in 0..<maneuvers.length()) {
|
||||||
@@ -77,7 +91,7 @@ open class RouteModel () {
|
|||||||
return ((leftStepDistance() * 1000).roundToInt().toDouble() / 10.0).roundToInt() * 10.0
|
return ((leftStepDistance() * 1000).roundToInt().toDouble() / 10.0).roundToInt() * 10.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findManeuver(location: Location) {
|
fun updateLocation(location: Location) {
|
||||||
var nearestDistance = 100000.0f
|
var nearestDistance = 100000.0f
|
||||||
maneuverIndex = -1
|
maneuverIndex = -1
|
||||||
// find maneuver
|
// find maneuver
|
||||||
@@ -92,18 +106,18 @@ open class RouteModel () {
|
|||||||
calculateCurrentIndex(beginShapeIndex, endShapeIndex, location)
|
calculateCurrentIndex(beginShapeIndex, endShapeIndex, location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
distanceToRoute = nearestDistance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun currentStep(): StepData {
|
fun currentStep(): StepData {
|
||||||
var bearing = 0
|
|
||||||
val maneuver = (maneuvers[maneuverIndex] as JSONObject)
|
val maneuver = (maneuvers[maneuverIndex] as JSONObject)
|
||||||
var text = ""
|
var text = ""
|
||||||
if (maneuver.optJSONArray("street_names") != null) {
|
if (maneuver.optJSONArray("street_names") != null) {
|
||||||
text = maneuver.getJSONArray("street_names").get(0) as String
|
text = maneuver.getJSONArray("street_names").get(0) as String
|
||||||
}
|
}
|
||||||
if (maneuver.has("bearing_after")) {
|
if (bearing == 0F) {
|
||||||
bearing = maneuver.getInt("bearing_after")
|
if (maneuver.has("bearing_after")) {
|
||||||
|
bearing = maneuver.getInt("bearing_after").toFloat()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val distanceStepLeft = leftStepDistance() * 1000
|
val distanceStepLeft = leftStepDistance() * 1000
|
||||||
when (distanceStepLeft) {
|
when (distanceStepLeft) {
|
||||||
@@ -120,7 +134,6 @@ open class RouteModel () {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Calculates the index in a maneuver. */
|
/** Calculates the index in a maneuver. */
|
||||||
private fun calculateCurrentIndex(
|
private fun calculateCurrentIndex(
|
||||||
beginShapeIndex: Int,
|
beginShapeIndex: Int,
|
||||||
@@ -139,9 +152,14 @@ open class RouteModel () {
|
|||||||
beginIndex = beginShapeIndex
|
beginIndex = beginShapeIndex
|
||||||
endIndex = endShapeIndex
|
endIndex = endShapeIndex
|
||||||
distanceToStepEnd = 0F
|
distanceToStepEnd = 0F
|
||||||
|
val loc1 = Location(LocationManager.GPS_PROVIDER)
|
||||||
|
val loc2 = Location(LocationManager.GPS_PROVIDER)
|
||||||
|
loc1.longitude = polylineLocations[i][0]
|
||||||
|
loc1.latitude = polylineLocations[i][1]
|
||||||
|
loc2.longitude = polylineLocations[i+1][0]
|
||||||
|
loc2.latitude = polylineLocations[i+1][1]
|
||||||
|
bearing = loc1.bearingTo(loc2).absoluteValue
|
||||||
for (j in i + 1..endShapeIndex) {
|
for (j in i + 1..endShapeIndex) {
|
||||||
val loc1 = Location(LocationManager.GPS_PROVIDER)
|
|
||||||
val loc2 = Location(LocationManager.GPS_PROVIDER)
|
|
||||||
loc1.longitude = polylineLocations[j - 1][0]
|
loc1.longitude = polylineLocations[j - 1][0]
|
||||||
loc1.latitude = polylineLocations[j - 1][1]
|
loc1.latitude = polylineLocations[j - 1][1]
|
||||||
loc2.longitude = polylineLocations[j][0]
|
loc2.longitude = polylineLocations[j][0]
|
||||||
@@ -228,7 +246,6 @@ open class RouteModel () {
|
|||||||
maneuverIndex = 0
|
maneuverIndex = 0
|
||||||
currentIndex = 0
|
currentIndex = 0
|
||||||
distanceToStepEnd = 0F
|
distanceToStepEnd = 0F
|
||||||
distanceToRoute = 0F
|
|
||||||
beginIndex = 0
|
beginIndex = 0
|
||||||
endIndex = 0
|
endIndex = 0
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.kouros.navigation.data.NavigationRepository
|
|||||||
import com.kouros.navigation.data.ObjectBox.boxStore
|
import com.kouros.navigation.data.ObjectBox.boxStore
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.Place_
|
import com.kouros.navigation.data.Place_
|
||||||
|
import com.kouros.navigation.utils.NavigationUtils
|
||||||
import io.objectbox.kotlin.boxFor
|
import io.objectbox.kotlin.boxFor
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -42,11 +43,9 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
val placeBox = boxStore.boxFor(Place::class)
|
val placeBox = boxStore.boxFor(Place::class)
|
||||||
pl.addAll(placeBox.all)
|
pl.addAll(placeBox.all)
|
||||||
for (place in pl) {
|
for (place in pl) {
|
||||||
val plLocation = Location(LocationManager.GPS_PROVIDER)
|
val plLocation = NavigationUtils().location(place.latitude, place.longitude)
|
||||||
plLocation.longitude = place.longitude
|
val distance = repository.getRouteDistance(location, plLocation)
|
||||||
plLocation.latitude = place.latitude
|
place.distance = distance.toFloat()
|
||||||
val distance: Float = location.distanceTo(plLocation)
|
|
||||||
place.distance = distance / 1000
|
|
||||||
}
|
}
|
||||||
places.postValue(pl)
|
places.postValue(pl)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -75,7 +74,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadContacts(context: Context) {
|
fun loadContacts(context: Context, currentLocation: Location) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val geocoder = Geocoder(context)
|
val geocoder = Geocoder(context)
|
||||||
@@ -83,22 +82,28 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
val contacts = Contacts(context = context)
|
val contacts = Contacts(context = context)
|
||||||
val addresses = contacts.retrieveContacts()
|
val addresses = contacts.retrieveContacts()
|
||||||
for (address in addresses) {
|
for (address in addresses) {
|
||||||
val lines = address.address.split("\n")
|
val addressLines = address.address.split("\n")
|
||||||
geocoder.getFromLocationName(
|
geocoder.getFromLocationName(
|
||||||
address.address, 5) {
|
address.address, 5) {
|
||||||
for (adr in it) {
|
for (adr in it) {
|
||||||
contactList.add(
|
if (addressLines.size > 1) {
|
||||||
Place(
|
val plLocation = NavigationUtils().location(adr.latitude, adr.longitude)
|
||||||
id = address.contactId,
|
val distance = repository.getRouteDistance(currentLocation, plLocation)
|
||||||
name = address.name + " " + lines[0] + " " + lines[1],
|
contactList.add(
|
||||||
Constants.CONTACTS,
|
Place(
|
||||||
street = lines[0],
|
id = address.contactId,
|
||||||
city = lines[1],
|
name = address.name + " " + addressLines[0] + " " + addressLines[1],
|
||||||
latitude = adr.latitude,
|
Constants.CONTACTS,
|
||||||
longitude = adr.longitude,
|
street = addressLines[0],
|
||||||
avatar = address.avatar
|
city = addressLines[1],
|
||||||
|
latitude = adr.latitude,
|
||||||
|
longitude = adr.longitude,
|
||||||
|
avatar = address.avatar,
|
||||||
|
distance = distance.toFloat()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
contactAddress.postValue(contactList)
|
contactAddress.postValue(contactList)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,4 +121,11 @@ class NavigationUtils() {
|
|||||||
}
|
}
|
||||||
return zoom.toDouble()
|
return zoom.toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun location(latitude: Double, longitude: Double): Location {
|
||||||
|
val location = Location(LocationManager.GPS_PROVIDER)
|
||||||
|
location.longitude = longitude
|
||||||
|
location.latitude = latitude
|
||||||
|
return location
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user