@castelio-it/capacitor-mapboxnav 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapacitorMapboxnav.podspec +17 -0
- package/Package.swift +28 -0
- package/README.md +146 -0
- package/android/build.gradle +92 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/android/gradle.properties +22 -0
- package/android/gradlew +251 -0
- package/android/gradlew.bat +94 -0
- package/android/proguard-rules.pro +17 -0
- package/android/settings.gradle +2 -0
- package/android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java +26 -0
- package/android/src/main/AndroidManifest.xml +24 -0
- package/android/src/main/java/com/castelioit/capacitormapboxnav/FreeDriveActivity.kt +126 -0
- package/android/src/main/java/com/castelioit/capacitormapboxnav/NavigationActivity.kt +276 -0
- package/android/src/main/java/com/castelioit/capacitormapboxnav/TurnByTurnExperienceActivity.kt +683 -0
- package/android/src/main/java/com/castelioit/capacitormapboxnav/capacitormapboxnav.kt +51 -0
- package/android/src/main/java/com/castelioit/capacitormapboxnav/capacitormapboxnavPlugin.java +142 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/layout/mapbox_activity_free_drive.xml +25 -0
- package/android/src/main/res/layout/mapbox_activity_turn_by_turn_experience.xml +80 -0
- package/android/src/test/java/com/castelioit/capacitormapboxnav/capacitormapboxnavTest.kt +15 -0
- package/android/src/test/java/com/getcapacitor/ExampleUnitTest.java +18 -0
- package/dist/docs.json +89 -0
- package/dist/esm/definitions.d.ts +58 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +35 -0
- package/dist/esm/web.js +20 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +34 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +37 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/capacitormapboxnavPlugin/capacitormapboxnav.swift +8 -0
- package/ios/Sources/capacitormapboxnavPlugin/capacitormapboxnavPlugin.swift +33 -0
- package/ios/Tests/capacitormapboxnavPluginTests/capacitormapboxnavTests.swift +23 -0
- package/package.json +93 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package com.getcapacitor.android;
|
|
2
|
+
|
|
3
|
+
import static org.junit.Assert.*;
|
|
4
|
+
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|
7
|
+
import androidx.test.platform.app.InstrumentationRegistry;
|
|
8
|
+
import org.junit.Test;
|
|
9
|
+
import org.junit.runner.RunWith;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Instrumented test, which will execute on an Android device.
|
|
13
|
+
*
|
|
14
|
+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
|
15
|
+
*/
|
|
16
|
+
@RunWith(AndroidJUnit4.class)
|
|
17
|
+
public class ExampleInstrumentedTest {
|
|
18
|
+
|
|
19
|
+
@Test
|
|
20
|
+
public void useAppContext() throws Exception {
|
|
21
|
+
// Context of the app under test.
|
|
22
|
+
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
|
23
|
+
|
|
24
|
+
assertEquals("com.getcapacitor.android", appContext.getPackageName());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
3
|
+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
4
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
5
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
|
6
|
+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
7
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
8
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
9
|
+
|
|
10
|
+
<application>
|
|
11
|
+
<activity
|
|
12
|
+
android:name=".NavigationActivity"
|
|
13
|
+
android:theme="@style/Theme.AppCompat.NoActionBar"
|
|
14
|
+
android:exported="false" />
|
|
15
|
+
<activity
|
|
16
|
+
android:name=".TurnByTurnExperienceActivity"
|
|
17
|
+
android:theme="@style/Theme.AppCompat.NoActionBar"
|
|
18
|
+
android:exported="false" />
|
|
19
|
+
<activity
|
|
20
|
+
android:name=".FreeDriveActivity"
|
|
21
|
+
android:theme="@style/Theme.AppCompat.NoActionBar"
|
|
22
|
+
android:exported="false" />
|
|
23
|
+
</application>
|
|
24
|
+
</manifest>
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
package com.castelioit.capacitormapboxnav
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import android.view.View
|
|
6
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
7
|
+
import com.mapbox.common.location.Location
|
|
8
|
+
import com.mapbox.geojson.Point
|
|
9
|
+
import com.mapbox.maps.plugin.LocationPuck2D
|
|
10
|
+
import com.mapbox.maps.plugin.animation.camera
|
|
11
|
+
import com.mapbox.maps.plugin.locationcomponent.location
|
|
12
|
+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
|
|
13
|
+
import com.mapbox.navigation.core.MapboxNavigation
|
|
14
|
+
import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver
|
|
15
|
+
import com.mapbox.navigation.core.lifecycle.requireMapboxNavigation
|
|
16
|
+
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
|
|
17
|
+
import com.mapbox.navigation.core.trip.session.LocationObserver
|
|
18
|
+
import com.castelioit.capacitormapboxnav.databinding.MapboxActivityFreeDriveBinding
|
|
19
|
+
import com.mapbox.navigation.ui.maps.NavigationStyles
|
|
20
|
+
import com.mapbox.navigation.ui.maps.camera.NavigationCamera
|
|
21
|
+
import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource
|
|
22
|
+
import com.mapbox.navigation.ui.maps.camera.lifecycle.NavigationBasicGesturesHandler
|
|
23
|
+
import com.mapbox.navigation.ui.maps.camera.state.NavigationCameraState
|
|
24
|
+
import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* This example demonstrates a basic free-drive experience by showing the user location puck on the map.
|
|
28
|
+
*/
|
|
29
|
+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
|
|
30
|
+
class FreeDriveActivity : AppCompatActivity() {
|
|
31
|
+
|
|
32
|
+
private lateinit var binding: MapboxActivityFreeDriveBinding
|
|
33
|
+
private lateinit var navigationCamera: NavigationCamera
|
|
34
|
+
private lateinit var viewportDataSource: MapboxNavigationViewportDataSource
|
|
35
|
+
private val navigationLocationProvider = NavigationLocationProvider()
|
|
36
|
+
|
|
37
|
+
private val locationObserver = object : LocationObserver {
|
|
38
|
+
override fun onNewRawLocation(rawLocation: Location) {
|
|
39
|
+
// not handled
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override fun onNewLocationMatcherResult(locationMatcherResult: LocationMatcherResult) {
|
|
43
|
+
val enhancedLocation = locationMatcherResult.enhancedLocation
|
|
44
|
+
navigationLocationProvider.changePosition(
|
|
45
|
+
location = enhancedLocation,
|
|
46
|
+
keyPoints = locationMatcherResult.keyPoints,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
viewportDataSource.onLocationChanged(enhancedLocation)
|
|
50
|
+
viewportDataSource.evaluate()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private val mapboxNavigation: MapboxNavigation by requireMapboxNavigation(
|
|
55
|
+
onResumedObserver = object : MapboxNavigationObserver {
|
|
56
|
+
@SuppressLint("MissingPermission")
|
|
57
|
+
override fun onAttached(mapboxNavigation: MapboxNavigation) {
|
|
58
|
+
mapboxNavigation.registerLocationObserver(locationObserver)
|
|
59
|
+
mapboxNavigation.startTripSession()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
override fun onDetached(mapboxNavigation: MapboxNavigation) {
|
|
63
|
+
mapboxNavigation.unregisterLocationObserver(locationObserver)
|
|
64
|
+
mapboxNavigation.stopTripSession()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
70
|
+
super.onCreate(savedInstanceState)
|
|
71
|
+
binding = MapboxActivityFreeDriveBinding.inflate(layoutInflater)
|
|
72
|
+
setContentView(binding.root)
|
|
73
|
+
|
|
74
|
+
viewportDataSource = MapboxNavigationViewportDataSource(binding.mapView.mapboxMap)
|
|
75
|
+
navigationCamera = NavigationCamera(
|
|
76
|
+
binding.mapView.mapboxMap,
|
|
77
|
+
binding.mapView.camera,
|
|
78
|
+
viewportDataSource
|
|
79
|
+
)
|
|
80
|
+
binding.mapView.camera.addCameraAnimationsLifecycleListener(
|
|
81
|
+
NavigationBasicGesturesHandler(navigationCamera)
|
|
82
|
+
)
|
|
83
|
+
navigationCamera.registerNavigationCameraStateChangeObserver { navigationCameraState ->
|
|
84
|
+
when (navigationCameraState) {
|
|
85
|
+
NavigationCameraState.TRANSITION_TO_FOLLOWING,
|
|
86
|
+
NavigationCameraState.FOLLOWING -> binding.recenter.visibility = View.INVISIBLE
|
|
87
|
+
NavigationCameraState.TRANSITION_TO_OVERVIEW,
|
|
88
|
+
NavigationCameraState.OVERVIEW,
|
|
89
|
+
NavigationCameraState.IDLE -> binding.recenter.visibility = View.VISIBLE
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
binding.recenter.setOnClickListener {
|
|
94
|
+
navigationCamera.requestNavigationCameraToFollowing()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
binding.mapView.mapboxMap.loadStyle(NavigationStyles.NAVIGATION_DAY_STYLE) {
|
|
98
|
+
binding.mapView.location.apply {
|
|
99
|
+
setLocationProvider(navigationLocationProvider)
|
|
100
|
+
this.locationPuck = LocationPuck2D()
|
|
101
|
+
puckBearingEnabled = true
|
|
102
|
+
enabled = true
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
override fun onStart() {
|
|
108
|
+
super.onStart()
|
|
109
|
+
binding.mapView.onStart()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
override fun onStop() {
|
|
113
|
+
super.onStop()
|
|
114
|
+
binding.mapView.onStop()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
override fun onLowMemory() {
|
|
118
|
+
super.onLowMemory()
|
|
119
|
+
binding.mapView.onLowMemory()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
override fun onDestroy() {
|
|
123
|
+
super.onDestroy()
|
|
124
|
+
binding.mapView.onDestroy()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
package com.castelioit.capacitormapboxnav
|
|
2
|
+
|
|
3
|
+
import android.Manifest
|
|
4
|
+
import android.annotation.SuppressLint
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
import android.content.pm.PackageManager
|
|
7
|
+
import android.os.Bundle
|
|
8
|
+
import android.widget.Toast
|
|
9
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
10
|
+
import androidx.core.app.ActivityCompat
|
|
11
|
+
import com.mapbox.api.directions.v5.models.RouteOptions
|
|
12
|
+
import com.mapbox.common.location.Location
|
|
13
|
+
import com.mapbox.geojson.Point
|
|
14
|
+
import com.mapbox.maps.CameraOptions
|
|
15
|
+
import com.mapbox.maps.EdgeInsets
|
|
16
|
+
import com.mapbox.maps.MapInitOptions
|
|
17
|
+
import com.mapbox.maps.MapView
|
|
18
|
+
import com.mapbox.maps.MapboxExperimental
|
|
19
|
+
import com.mapbox.maps.plugin.LocationPuck2D
|
|
20
|
+
import com.mapbox.maps.plugin.PuckBearing
|
|
21
|
+
import com.mapbox.maps.plugin.locationcomponent.createDefault2DPuck
|
|
22
|
+
import com.mapbox.maps.plugin.animation.camera
|
|
23
|
+
import com.mapbox.maps.plugin.attribution.attribution
|
|
24
|
+
import com.mapbox.maps.plugin.compass.compass
|
|
25
|
+
import com.mapbox.maps.plugin.locationcomponent.location
|
|
26
|
+
import com.mapbox.maps.plugin.logo.logo
|
|
27
|
+
import com.mapbox.maps.plugin.scalebar.scalebar
|
|
28
|
+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
|
|
29
|
+
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
|
|
30
|
+
import com.mapbox.navigation.base.route.NavigationRoute
|
|
31
|
+
import com.mapbox.navigation.base.route.NavigationRouterCallback
|
|
32
|
+
import com.mapbox.navigation.base.route.RouterFailure
|
|
33
|
+
import com.mapbox.navigation.core.MapboxNavigation
|
|
34
|
+
import com.mapbox.navigation.core.directions.session.RoutesObserver
|
|
35
|
+
import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver
|
|
36
|
+
import com.mapbox.navigation.core.lifecycle.requireMapboxNavigation
|
|
37
|
+
import com.mapbox.navigation.core.replay.route.ReplayProgressObserver
|
|
38
|
+
import com.mapbox.navigation.core.replay.route.ReplayRouteMapper
|
|
39
|
+
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
|
|
40
|
+
import com.mapbox.navigation.core.trip.session.LocationObserver
|
|
41
|
+
import com.mapbox.navigation.ui.maps.camera.NavigationCamera
|
|
42
|
+
import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource
|
|
43
|
+
import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider
|
|
44
|
+
import com.mapbox.navigation.ui.maps.route.line.api.MapboxRouteLineApi
|
|
45
|
+
import com.mapbox.navigation.ui.maps.route.line.api.MapboxRouteLineView
|
|
46
|
+
import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineApiOptions
|
|
47
|
+
import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineViewOptions
|
|
48
|
+
|
|
49
|
+
class NavigationActivity : AppCompatActivity() {
|
|
50
|
+
private lateinit var mapView: MapView
|
|
51
|
+
private lateinit var viewportDataSource: MapboxNavigationViewportDataSource
|
|
52
|
+
private lateinit var navigationCamera: NavigationCamera
|
|
53
|
+
private lateinit var routeLineApi: MapboxRouteLineApi
|
|
54
|
+
private lateinit var routeLineView: MapboxRouteLineView
|
|
55
|
+
private lateinit var replayProgressObserver: ReplayProgressObserver
|
|
56
|
+
private val navigationLocationProvider = NavigationLocationProvider()
|
|
57
|
+
private val replayRouteMapper = ReplayRouteMapper()
|
|
58
|
+
|
|
59
|
+
private var originLat: Double = 0.0
|
|
60
|
+
private var originLng: Double = 0.0
|
|
61
|
+
private var destLat: Double = 0.0
|
|
62
|
+
private var destLng: Double = 0.0
|
|
63
|
+
private var simulateRoute: Boolean = false
|
|
64
|
+
|
|
65
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
66
|
+
super.onCreate(savedInstanceState)
|
|
67
|
+
|
|
68
|
+
originLat = intent.getExtraDouble("originLat", 0.0)
|
|
69
|
+
originLng = intent.getExtraDouble("originLng", 0.0)
|
|
70
|
+
destLat = intent.getExtraDouble("destLat", 0.0)
|
|
71
|
+
destLng = intent.getExtraDouble("destLng", 0.0)
|
|
72
|
+
simulateRoute = intent.getBooleanExtra("simulateRoute", false)
|
|
73
|
+
|
|
74
|
+
val permissions = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION)
|
|
75
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
|
76
|
+
permissions.add(Manifest.permission.POST_NOTIFICATIONS)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
val missingPermissions = permissions.filter {
|
|
80
|
+
ActivityCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (missingPermissions.isNotEmpty()) {
|
|
84
|
+
ActivityCompat.requestPermissions(this, missingPermissions.toTypedArray(), 1)
|
|
85
|
+
} else {
|
|
86
|
+
initializeMapComponents()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private fun Intent.getExtraDouble(key: String, defaultValue: Double): Double {
|
|
91
|
+
return if (hasExtra(key)) getDoubleExtra(key, defaultValue) else defaultValue
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
|
95
|
+
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
96
|
+
if (requestCode == 1) {
|
|
97
|
+
val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
|
|
98
|
+
if (allGranted) {
|
|
99
|
+
initializeMapComponents()
|
|
100
|
+
} else {
|
|
101
|
+
Toast.makeText(this, "Permissions denied. Navigation cannot start.", Toast.LENGTH_SHORT).show()
|
|
102
|
+
finish()
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@OptIn(MapboxExperimental::class)
|
|
108
|
+
private fun initializeMapComponents() {
|
|
109
|
+
mapView = MapView(this, MapInitOptions(
|
|
110
|
+
this,
|
|
111
|
+
cameraOptions = CameraOptions.Builder()
|
|
112
|
+
.center(Point.fromLngLat(originLng, originLat))
|
|
113
|
+
.zoom(14.0)
|
|
114
|
+
.build(),
|
|
115
|
+
))
|
|
116
|
+
|
|
117
|
+
mapView.scalebar.marginTop = 200f
|
|
118
|
+
mapView.compass.marginTop = 200f
|
|
119
|
+
mapView.logo.marginBottom = 140f
|
|
120
|
+
mapView.attribution.marginBottom = 140f
|
|
121
|
+
|
|
122
|
+
mapView.location.apply {
|
|
123
|
+
setLocationProvider(navigationLocationProvider)
|
|
124
|
+
locationPuck = createDefault2DPuck( true)
|
|
125
|
+
enabled = true
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
setContentView(mapView)
|
|
129
|
+
|
|
130
|
+
viewportDataSource = MapboxNavigationViewportDataSource(mapView.mapboxMap)
|
|
131
|
+
val pixelDensity = this.resources.displayMetrics.density
|
|
132
|
+
viewportDataSource.followingPadding = EdgeInsets(
|
|
133
|
+
180.0 * pixelDensity,
|
|
134
|
+
40.0 * pixelDensity,
|
|
135
|
+
150.0 * pixelDensity,
|
|
136
|
+
40.0 * pixelDensity
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
navigationCamera = NavigationCamera(mapView.mapboxMap, mapView.camera, viewportDataSource)
|
|
142
|
+
routeLineApi = MapboxRouteLineApi(MapboxRouteLineApiOptions.Builder().build())
|
|
143
|
+
routeLineView = MapboxRouteLineView(MapboxRouteLineViewOptions.Builder(this).build())
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override fun onStart() {
|
|
147
|
+
super.onStart()
|
|
148
|
+
if (::mapView.isInitialized) {
|
|
149
|
+
mapView.onStart()
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
override fun onStop() {
|
|
154
|
+
super.onStop()
|
|
155
|
+
if (::mapView.isInitialized) {
|
|
156
|
+
mapView.onStop()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
override fun onDestroy() {
|
|
161
|
+
super.onDestroy()
|
|
162
|
+
if (::mapView.isInitialized) {
|
|
163
|
+
mapView.onDestroy()
|
|
164
|
+
}
|
|
165
|
+
if (::routeLineApi.isInitialized) {
|
|
166
|
+
routeLineApi.cancel()
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
override fun onLowMemory() {
|
|
171
|
+
super.onLowMemory()
|
|
172
|
+
if (::mapView.isInitialized) {
|
|
173
|
+
mapView.onLowMemory()
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private val routesObserver = RoutesObserver { routeUpdateResult ->
|
|
178
|
+
if (routeUpdateResult.navigationRoutes.isNotEmpty()) {
|
|
179
|
+
routeLineApi.setNavigationRoutes(routeUpdateResult.navigationRoutes) { value ->
|
|
180
|
+
mapView.mapboxMap.style?.apply { routeLineView.renderRouteDrawData(this, value) }
|
|
181
|
+
}
|
|
182
|
+
viewportDataSource.onRouteChanged(routeUpdateResult.navigationRoutes.first())
|
|
183
|
+
viewportDataSource.evaluate()
|
|
184
|
+
navigationCamera.requestNavigationCameraToOverview()
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private val locationObserver = object : LocationObserver {
|
|
189
|
+
override fun onNewRawLocation(rawLocation: Location) {}
|
|
190
|
+
override fun onNewLocationMatcherResult(locationMatcherResult: LocationMatcherResult) {
|
|
191
|
+
val enhancedLocation = locationMatcherResult.enhancedLocation
|
|
192
|
+
navigationLocationProvider.changePosition(
|
|
193
|
+
location = enhancedLocation,
|
|
194
|
+
keyPoints = locationMatcherResult.keyPoints,
|
|
195
|
+
)
|
|
196
|
+
viewportDataSource.onLocationChanged(enhancedLocation)
|
|
197
|
+
viewportDataSource.evaluate()
|
|
198
|
+
navigationCamera.requestNavigationCameraToFollowing()
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
|
|
203
|
+
private val mapboxNavigation: MapboxNavigation by requireMapboxNavigation(
|
|
204
|
+
onResumedObserver = object : MapboxNavigationObserver {
|
|
205
|
+
@SuppressLint("MissingPermission")
|
|
206
|
+
override fun onAttached(mapboxNavigation: MapboxNavigation) {
|
|
207
|
+
mapboxNavigation.registerRoutesObserver(routesObserver)
|
|
208
|
+
mapboxNavigation.registerLocationObserver(locationObserver)
|
|
209
|
+
if (simulateRoute) {
|
|
210
|
+
replayProgressObserver = ReplayProgressObserver(mapboxNavigation.mapboxReplayer)
|
|
211
|
+
mapboxNavigation.registerRouteProgressObserver(replayProgressObserver)
|
|
212
|
+
mapboxNavigation.startReplayTripSession()
|
|
213
|
+
} else {
|
|
214
|
+
mapboxNavigation.startTripSession()
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
override fun onDetached(mapboxNavigation: MapboxNavigation) {
|
|
218
|
+
mapboxNavigation.unregisterRoutesObserver(routesObserver)
|
|
219
|
+
mapboxNavigation.unregisterLocationObserver(locationObserver)
|
|
220
|
+
if (simulateRoute && ::replayProgressObserver.isInitialized) {
|
|
221
|
+
mapboxNavigation.unregisterRouteProgressObserver(replayProgressObserver)
|
|
222
|
+
}
|
|
223
|
+
mapboxNavigation.stopTripSession()
|
|
224
|
+
if (simulateRoute) {
|
|
225
|
+
mapboxNavigation.mapboxReplayer.finish()
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
onInitialize = this::initNavigation
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
|
|
233
|
+
private fun initNavigation() {
|
|
234
|
+
// MapboxNavigationApp.setup is already called in the plugin implementation
|
|
235
|
+
|
|
236
|
+
mapView.location.apply {
|
|
237
|
+
setLocationProvider(navigationLocationProvider)
|
|
238
|
+
this.locationPuck = createDefault2DPuck( true)
|
|
239
|
+
puckBearingEnabled = true
|
|
240
|
+
puckBearing = PuckBearing.COURSE
|
|
241
|
+
enabled = true
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
val origin = Point.fromLngLat(originLng, originLat)
|
|
245
|
+
val destination = Point.fromLngLat(destLng, destLat)
|
|
246
|
+
|
|
247
|
+
mapboxNavigation.requestRoutes(
|
|
248
|
+
RouteOptions.builder()
|
|
249
|
+
.applyDefaultNavigationOptions()
|
|
250
|
+
.coordinatesList(listOf(origin, destination))
|
|
251
|
+
.layersList(listOf(mapboxNavigation.getZLevel(), null))
|
|
252
|
+
.build(),
|
|
253
|
+
object : NavigationRouterCallback {
|
|
254
|
+
override fun onCanceled(routeOptions: RouteOptions, routerOrigin: String) {}
|
|
255
|
+
override fun onFailure(reasons: List<RouterFailure>, routeOptions: RouteOptions) {
|
|
256
|
+
val errorMessage = reasons.joinToString(", ") { it.message }
|
|
257
|
+
android.util.Log.e("NavigationActivity", "Route request failed: $errorMessage")
|
|
258
|
+
Toast.makeText(this@NavigationActivity, "Route failed: $errorMessage", Toast.LENGTH_LONG).show()
|
|
259
|
+
}
|
|
260
|
+
override fun onRoutesReady(routes: List<NavigationRoute>, routerOrigin: String) {
|
|
261
|
+
if (routes.isEmpty()) {
|
|
262
|
+
Toast.makeText(this@NavigationActivity, "No routes found", Toast.LENGTH_SHORT).show()
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
mapboxNavigation.setNavigationRoutes(routes)
|
|
266
|
+
if (simulateRoute) {
|
|
267
|
+
val replayData = replayRouteMapper.mapDirectionsRouteGeometry(routes.first().directionsRoute)
|
|
268
|
+
mapboxNavigation.mapboxReplayer.pushEvents(replayData)
|
|
269
|
+
mapboxNavigation.mapboxReplayer.seekTo(replayData[0])
|
|
270
|
+
mapboxNavigation.mapboxReplayer.play()
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
}
|