Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions examples/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@
android:value=".CoreActivity"/>
</activity>

<activity android:name=".core.BasicNavSdkOnlyActivity"
android:label="@string/title_basic_navigation_sdk_only_kotlin"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".CoreActivity"/>
</activity>

<activity android:name=".core.FreeDriveNavigationActivity"
android:label="@string/title_free_drive_kotlin"
android:screenOrientation="portrait">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
import com.mapbox.navigation.examples.core.BasicNavSdkOnlyActivity
import com.mapbox.navigation.examples.core.BasicNavigationActivity
import com.mapbox.navigation.examples.core.DebugMapboxNavigationKt
import com.mapbox.navigation.examples.core.FasterRouteActivity
Expand Down Expand Up @@ -110,6 +111,11 @@ class CoreActivity : AppCompatActivity() {
getString(R.string.description_basic_navigation_kotlin),
BasicNavigationActivity::class.java
),
SampleItem(
getString(R.string.title_basic_navigation_sdk_only_kotlin),
getString(R.string.description_basic_navigation_sdk_only_kotlin),
BasicNavSdkOnlyActivity::class.java
),
SampleItem(
getString(R.string.title_free_drive_kotlin),
getString(R.string.description_free_drive_kotlin),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package com.mapbox.navigation.examples.core

import android.annotation.SuppressLint
import android.graphics.Color.parseColor
import android.os.Bundle
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_SHORT
import com.mapbox.android.core.location.LocationEngineProvider
import com.mapbox.api.directions.v5.DirectionsCriteria
import com.mapbox.api.directions.v5.models.DirectionsRoute
import com.mapbox.api.directions.v5.models.RouteOptions
import com.mapbox.geojson.LineString
import com.mapbox.geojson.Point
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
import com.mapbox.mapboxsdk.location.modes.CameraMode
import com.mapbox.mapboxsdk.location.modes.RenderMode
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.style.expressions.Expression.color
import com.mapbox.mapboxsdk.style.expressions.Expression.interpolate
import com.mapbox.mapboxsdk.style.expressions.Expression.lineProgress
import com.mapbox.mapboxsdk.style.expressions.Expression.linear
import com.mapbox.mapboxsdk.style.expressions.Expression.stop
import com.mapbox.mapboxsdk.style.layers.LineLayer
import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND
import com.mapbox.mapboxsdk.style.layers.Property.LINE_JOIN_ROUND
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineCap
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineGradient
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth
import com.mapbox.mapboxsdk.style.layers.SymbolLayer
import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
import com.mapbox.mapboxsdk.utils.BitmapUtils
import com.mapbox.navigation.base.extensions.applyDefaultParams
import com.mapbox.navigation.base.extensions.coordinates
import com.mapbox.navigation.core.MapboxNavigation
import com.mapbox.navigation.core.directions.session.RoutesRequestCallback
import com.mapbox.navigation.examples.R
import com.mapbox.navigation.examples.utils.Utils
import com.mapbox.navigation.examples.utils.extensions.toPoint
import kotlinx.android.synthetic.main.activity_basic_navigation_sdk_only_layout.*
import timber.log.Timber

/**
* This example demonstrates how to combine Maps SDK with ONLY the
* Navigation SDK. There is no Navigation UI SDK code of any kind in this example.
*/
class BasicNavSdkOnlyActivity : AppCompatActivity(), OnMapReadyCallback, MapboxMap.OnMapLongClickListener {

private var mapboxNavigation: MapboxNavigation? = null
private var mapboxMap: MapboxMap? = null
private val ORIGIN_COLOR = "#32a852" // Green
private val DESTINATION_COLOR = "#F84D4D" // Red

@SuppressLint("MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_basic_navigation_sdk_only_layout)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(this)

val mapboxNavigationOptions = MapboxNavigation.defaultNavigationOptions(
this,
Utils.getMapboxAccessToken(this)
)

mapboxNavigation = MapboxNavigation(
applicationContext,
Utils.getMapboxAccessToken(this),
mapboxNavigationOptions,
LocationEngineProvider.getBestLocationEngine(this)
)
Snackbar.make(container, R.string.msg_long_press_map_to_place_waypoint, LENGTH_SHORT).show()
}

override fun onMapReady(mapboxMap: MapboxMap) {
mapboxMap.setStyle(Style.LIGHT) {
this.mapboxMap = mapboxMap

enableLocationComponent()

// Add the click and route sources
it.addSource(GeoJsonSource("CLICK_SOURCE"))
it.addSource(GeoJsonSource("ROUTE_LINE_SOURCE_ID", GeoJsonOptions().withLineMetrics(true)))

// Add the destination marker image
it.addImage("ICON_ID", BitmapUtils.getBitmapFromDrawable(
ContextCompat.getDrawable(this,
R.drawable.mapbox_marker_icon_default))!!)

// Add the LineLayer below the LocationComponent's bottom layer, which is the
// circular accuracy layer. The LineLayer will display the directions route.
it.addLayerBelow(LineLayer("ROUTE_LAYER_ID", "ROUTE_LINE_SOURCE_ID")
.withProperties(
lineCap(LINE_CAP_ROUND),
lineJoin(LINE_JOIN_ROUND),
lineWidth(6f),
lineGradient(interpolate(
linear(), lineProgress(),
stop(0f, color(parseColor(ORIGIN_COLOR))),
stop(1f, color(parseColor(DESTINATION_COLOR)))
))), "mapbox-location-shadow-layer")

// Add the SymbolLayer to show the destination marker
it.addLayerAbove(SymbolLayer("CLICK_LAYER", "CLICK_SOURCE")
.withProperties(
iconImage("ICON_ID")
), "ROUTE_LAYER_ID")

mapboxMap.addOnMapLongClickListener(this)
Snackbar.make(container, R.string.msg_long_press_map_to_place_waypoint, LENGTH_SHORT)
.show()
}
}

override fun onMapLongClick(latLng: LatLng): Boolean {
route_retrieval_progress_spinner.visibility = VISIBLE
// Place the destination marker at the map long click location
mapboxMap?.getStyle {
val clickPointSource = it.getSourceAs<GeoJsonSource>("CLICK_SOURCE")
clickPointSource?.setGeoJson(Point.fromLngLat(latLng.longitude, latLng.latitude))
}
mapboxMap?.locationComponent?.lastKnownLocation?.let { originLocation ->
mapboxNavigation?.requestRoutes(
RouteOptions.builder().applyDefaultParams()
.accessToken(Utils.getMapboxAccessToken(applicationContext))
.coordinates(originLocation.toPoint(), null, latLng.toPoint())
.alternatives(true)
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
.build(),
routesReqCallback
)
}
return true
}

private val routesReqCallback = object : RoutesRequestCallback {
override fun onRoutesReady(routes: List<DirectionsRoute>) {
if (routes.isNotEmpty()) {
Snackbar.make(container, String.format(getString(R.string.steps_in_route),
routes[0].legs()?.get(0)?.steps()?.size), LENGTH_SHORT).show()

// Update a gradient route LineLayer's source with the Maps SDK. This will
// visually add/update the line on the map. All of this is being done
// directly with Maps SDK code and NOT the Navigation UI SDK.
mapboxMap?.getStyle {
val clickPointSource = it.getSourceAs<GeoJsonSource>("ROUTE_LINE_SOURCE_ID")
val routeLineString = LineString.fromPolyline(routes[0].geometry()!!,
6)
clickPointSource?.setGeoJson(routeLineString)
}
route_retrieval_progress_spinner.visibility = INVISIBLE
} else {
Snackbar.make(container, R.string.no_routes, LENGTH_SHORT).show()
}
}

override fun onRoutesRequestFailure(throwable: Throwable, routeOptions: RouteOptions) {
Timber.e("route request failure %s", throwable.toString())
Snackbar.make(container, R.string.route_request_failed, LENGTH_SHORT).show()
}

override fun onRoutesRequestCanceled(routeOptions: RouteOptions) {
Timber.d("route request canceled")
}
}

/**
* Enable the Maps SDK's LocationComponent
*/
private fun enableLocationComponent() {
mapboxMap?.getStyle {
mapboxMap?.locationComponent?.apply {
activateLocationComponent(
LocationComponentActivationOptions.builder(
this@BasicNavSdkOnlyActivity, it)
.build())
isLocationComponentEnabled = true
cameraMode = CameraMode.TRACKING
renderMode = RenderMode.COMPASS
}
}
}

override fun onStart() {
super.onStart()
mapView.onStart()
}

public override fun onResume() {
super.onResume()
mapView.onResume()
}

public override fun onPause() {
super.onPause()
mapView.onPause()
}

override fun onStop() {
super.onStop()
mapView.onStop()
}

override fun onDestroy() {
super.onDestroy()
mapboxNavigation?.onDestroy()
mapView.onDestroy()
}

override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView.onSaveInstanceState(outState)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".core.BasicNavSdkOnlyActivity">

<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ProgressBar
android:id="@+id/route_retrieval_progress_spinner"
android:layout_width="wrap_content"
android:visibility="invisible"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/mapView" />

</androidx.constraintlayout.widget.ConstraintLayout>
6 changes: 6 additions & 0 deletions examples/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
<string name="title_basic_navigation_kotlin" translatable="false">BasicNavigationActivity</string>
<string name="description_basic_navigation_kotlin" translatable="false">Demonstrates how to navigate from source to destination using Mapbox Navigation.</string>

<string name="title_basic_navigation_sdk_only_kotlin" translatable="false">BasicNavSdkOnlyActivity</string>
<string name="description_basic_navigation_sdk_only_kotlin" translatable="false">Demonstrates how to combine Maps SDK with only the Navigation SDK and no Navigation UI SDK code of any kind.</string>

<string name="title_free_drive_kotlin" translatable="false">FreeDriveNavigationActivity</string>
<string name="description_free_drive_kotlin" translatable="false">Demonstrates how to navigate in a free drive scenario using Mapbox Navigation.</string>

Expand Down Expand Up @@ -114,6 +117,9 @@
<string name="msg_long_press_map_to_place_waypoint" translatable="false">Long press on the map to place a waypoint</string>
<string name="msg_tap_map_to_place_waypoint" translatable="false">Tap on the map to place a waypoint</string>
<string name="only_two_waypoints_supported" translatable="false">Only two waypoints are supported for this example</string>
<string name="no_routes" translatable="false">No available routes to that destination</string>
<string name="steps_in_route" translatable="false">There are %1$d steps in the route</string>
<string name="route_request_failed" translatable="false">The route request failed</string>
<string name="offline_category_title" translatable="false">Offline</string>
<string name="offline_enabled_title" translatable="false">Offline routing enabled</string>
<string name="offline_version_title" translatable="false">Choose offline version</string>
Expand Down