Garmin/app/src/main/java/eu/ztsh/garmin/mapbox/MapControl.kt

158 lines
No EOL
6.3 KiB
Kotlin

package eu.ztsh.garmin.mapbox
import android.content.res.Configuration
import android.content.res.Resources
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.maps.ImageHolder
import com.mapbox.maps.plugin.LocationPuck2D
import com.mapbox.maps.plugin.animation.camera
import com.mapbox.maps.plugin.locationcomponent.location
import com.mapbox.navigation.base.options.NavigationOptions
import com.mapbox.navigation.core.MapboxNavigation
import com.mapbox.navigation.core.directions.session.RoutesObserver
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver
import com.mapbox.navigation.core.trip.session.LocationObserver
import com.mapbox.navigation.core.trip.session.RouteProgressObserver
import com.mapbox.navigation.core.trip.session.VoiceInstructionsObserver
import com.mapbox.navigation.ui.maps.camera.NavigationCamera
import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource
import com.mapbox.navigation.ui.maps.camera.lifecycle.NavigationBasicGesturesHandler
import com.mapbox.navigation.ui.maps.camera.state.NavigationCameraState
import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider
import eu.ztsh.garmin.MainActivity
import eu.ztsh.garmin.UI
import eu.ztsh.garmin.mock.ReplayResources
class MapControl(
val context: AppCompatActivity,
val ui: UI,
private val resources: Resources
) : MapboxNavigationObserver {
/**
* Used to execute camera transitions based on the data generated by the [viewportDataSource].
* This includes transitions from route overview to route following and continuously updating the camera as the location changes.
*/
lateinit var navigationCamera: NavigationCamera
/**
* Produces the camera frames based on the location and routing data for the [navigationCamera] to execute.
*/
lateinit var viewportDataSource: MapboxNavigationViewportDataSource
/**
* [NavigationLocationProvider] is a utility class that helps to provide location updates generated by the Navigation SDK
* to the Maps SDK in order to update the user location indicator on the map.
*/
val navigationLocationProvider = NavigationLocationProvider()
val replay = ReplayResources(this)
// Observers
private lateinit var routeControl: RouteControl
private lateinit var voiceControl: VoiceControl
private lateinit var routesObserver: RoutesObserver
private lateinit var locationObserver: LocationObserver
private lateinit var routeProgressObserver: RouteProgressObserver
private lateinit var voiceInstructionsObserver: VoiceInstructionsObserver
fun init() {
viewportDataSource = MapboxNavigationViewportDataSource(ui.mapView.mapboxMap)
if (this.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
viewportDataSource.overviewPadding = UI.landscapeOverviewPadding
} else {
viewportDataSource.overviewPadding = UI.overviewPadding
}
if (this.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
viewportDataSource.followingPadding = UI.landscapeFollowingPadding
} else {
viewportDataSource.followingPadding = UI.followingPadding
}
navigationCamera = NavigationCamera(
ui.mapView.mapboxMap,
ui.mapView.camera,
viewportDataSource
)
// set the animations lifecycle listener to ensure the NavigationCamera stops
// automatically following the user location when the map is interacted with
ui.mapView.camera.addCameraAnimationsLifecycleListener(
NavigationBasicGesturesHandler(navigationCamera)
)
navigationCamera.registerNavigationCameraStateChangeObserver { navigationCameraState ->
// shows/hide the recenter button depending on the camera state
when (navigationCameraState) {
NavigationCameraState.TRANSITION_TO_FOLLOWING,
NavigationCameraState.FOLLOWING -> ui.recenter.visibility = View.INVISIBLE
NavigationCameraState.TRANSITION_TO_OVERVIEW,
NavigationCameraState.OVERVIEW,
NavigationCameraState.IDLE -> ui.recenter.visibility = View.VISIBLE
}
}
routeControl = RouteControl(this, ui, context)
voiceControl = VoiceControl(ui, context)
routesObserver = routeControl.routesObserver
locationObserver = LocationObserver(this)
routeProgressObserver = routeControl.routeProgressObserver
voiceInstructionsObserver = voiceControl.voiceInstructionsObserver
}
fun initNavigation() {
MapboxNavigationApp.setup(
NavigationOptions.Builder(context)
.build()
)
// initialize location puck
ui.mapView.location.apply {
setLocationProvider(navigationLocationProvider)
this.locationPuck = LocationPuck2D(
bearingImage = ImageHolder.Companion.from(
com.mapbox.navigation.ui.maps.R.drawable.mapbox_navigation_puck_icon
)
)
puckBearingEnabled = true
enabled = true
}
replay.replayOriginLocation()
}
fun mapboxNavigation(): MapboxNavigation {
return (context as MainActivity).mapboxNavigation
}
override fun onAttached(mapboxNavigation: MapboxNavigation) {
mapboxNavigation.registerRoutesObserver(routesObserver)
mapboxNavigation.registerLocationObserver(locationObserver)
mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)
mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)
replay.onAttached(mapboxNavigation)
}
override fun onDetached(mapboxNavigation: MapboxNavigation) {
mapboxNavigation.unregisterRoutesObserver(routesObserver)
mapboxNavigation.unregisterLocationObserver(locationObserver)
mapboxNavigation.unregisterRouteProgressObserver(routeProgressObserver)
mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver)
replay.onDetached(mapboxNavigation)
}
fun onDestroy() {
routeControl.cancel()
voiceControl.cancel()
}
companion object {
const val TAG = "MAPCTRL"
}
}