mapbox-vision-android icon indicating copy to clipboard operation
mapbox-vision-android copied to clipboard

Hi, I'd like to play Mapbox vision tutorial but need help

Open Sae-Ba opened this issue 3 years ago • 0 comments

From Republic of Korea, one of student in TUK universary

I become interested in Mapbox vision docs so i follow basic tutorial https://docs.mapbox.com/android/vision/examples/basic-ar-navigation/

in this docs i find this comments // This dummy points will be used to build route. For real world test this needs to be changed to real values for // source and target locations.

so i tried change Points but i blocked it

I hope intent Point to tutorial activity

Here are my codes named by 'arnavigation_search, and arnavigation' and I want to putExtra data destinationPoint = Point.fromLngLat(point.longitude, point.latitude) which in arnavigation_search values send to arnavigation.kt

arnavigation_search.kt `package com.tuk.tukar

import android.annotation.SuppressLint import android.content.Intent import android.graphics.BitmapFactory import android.graphics.Color import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.os.Parcel import android.os.Parcelable import android.os.PersistableBundle import android.util.Log import android.view.View import android.widget.Toast import androidx.core.content.res.ResourcesCompat import com.mapbox.android.core.permissions.PermissionsListener import com.mapbox.android.core.permissions.PermissionsManager import com.mapbox.api.directions.v5.models.DirectionsResponse import com.mapbox.api.directions.v5.models.DirectionsRoute import com.mapbox.geojson.Feature import com.mapbox.geojson.FeatureCollection import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.Mapbox import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.location.LocationComponent import com.mapbox.mapboxsdk.location.modes.CameraMode import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import com.mapbox.mapboxsdk.maps.Style import com.mapbox.mapboxsdk.plugins.places.autocomplete.PlaceAutocomplete import com.mapbox.mapboxsdk.plugins.places.autocomplete.model.PlaceOptions import com.mapbox.mapboxsdk.style.layers.PropertyFactory import com.mapbox.mapboxsdk.style.layers.SymbolLayer import com.mapbox.mapboxsdk.style.sources.GeoJsonSource import com.mapbox.mapboxsdk.utils.BitmapUtils import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute import kotlinx.android.parcel.Parceler import kotlinx.android.parcel.Parcelize import retrofit2.Call import retrofit2.Callback import retrofit2.Response import kotlinx.android.synthetic.main.activity_arnavigation_search.*

class Arnavigationsearch : AppCompatActivity(), OnMapReadyCallback, PermissionsListener, MapboxMap.OnMapClickListener {

private val REQUEST_CODE_AUTOCOMPLETE = 7171
private var mapboxMap: MapboxMap? = null
private var permissionsManager: PermissionsManager? = null
private var locationComponent: LocationComponent? = null
private var currentRoute: DirectionsRoute? = null
private var navigationMapRoute: NavigationMapRoute? = null
private val TAG = "DirectionsActivity"
private val geoJsonSourceLayerId = "GeoJsonSourceLayerId"
private val symbolIconId = "SymbolIconId"

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Mapbox.getInstance(this, getString(R.string.mapbox_access_token))
    setContentView(R.layout.activity_arnavigation_search)
    mapView.onCreate(savedInstanceState)
    mapView.getMapAsync(this)
}
override fun onMapReady(mapboxMap: MapboxMap) {
    this.mapboxMap = mapboxMap
    mapboxMap.setStyle(getString(com.mapbox.services.android.navigation.ui.v5.R.string.navigation_guidance_day)) {
            style: Style? ->
        enableLocationComponent(style)
        addDestinationIconSymbolLayer(style)
        mapboxMap.addOnMapClickListener(this)

        btnStart.setOnClickListener { v: View? ->
            val simulateRoute = true
            val options = NavigationLauncherOptions.builder()
                .directionsRoute(currentRoute)
                .shouldSimulateRoute(simulateRoute)
                .build()

            // Call this method with Context from within an Activity
            NavigationLauncher.startNavigation(this, options)
        }
        btnStartwithar.setOnClickListener{
            val intent = Intent(this,arnavigation::class.java)
            startActivity(intent);
        }

        initSearchFab()

        setUpSource(style!!)

        setUpLayer(style!!)

        val drawable = ResourcesCompat.getDrawable(resources, R.drawable.ic_location_on_red_24dp, null)
        val bitmapUtils = BitmapUtils.getBitmapFromDrawable(drawable)
        style!!.addImage(symbolIconId, bitmapUtils!!)
    }
}
private fun setUpLayer(loadedMapStyle: Style) {
    loadedMapStyle.addLayer(SymbolLayer("SYMBOL_LAYER_ID", geoJsonSourceLayerId).withProperties(
        PropertyFactory.iconImage(symbolIconId),
        PropertyFactory.iconOffset(arrayOf(0f, -8f))
    ))
}

private fun setUpSource(loadedMapStyle: Style) {
    loadedMapStyle.addSource(GeoJsonSource(geoJsonSourceLayerId))
}

private fun initSearchFab() {
    fab_location_search.setOnClickListener{v: View? ->
        val intent = PlaceAutocomplete.IntentBuilder()
            .accessToken(
                (if (Mapbox.getAccessToken() != null) Mapbox.getAccessToken() else getString(R.string.mapbox_access_token))!!
            ).placeOptions(PlaceOptions.builder()
                .backgroundColor(Color.parseColor("#EEEEEE"))
                .limit(10)
                .build(PlaceOptions.MODE_CARDS))
            .build(this@Arnavigationsearch)
        startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE)
    }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_AUTOCOMPLETE) {
        val selectedCarmenFeature = PlaceAutocomplete.getPlace(data)
        if (mapboxMap != null) {
            val style = mapboxMap!!.style
            if (style != null) {
                val source = style.getSourceAs<GeoJsonSource>(geoJsonSourceLayerId)
                source?.setGeoJson(FeatureCollection.fromFeatures(arrayOf(Feature.fromJson(selectedCarmenFeature.toJson()))))
                mapboxMap!!.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.Builder()
                    .target(LatLng((selectedCarmenFeature.geometry() as Point?)!!.latitude(),
                        (selectedCarmenFeature.geometry() as Point?)!!.longitude()))
                    .zoom(14.0)
                    .build()), 4000)
            }
        }
    }
}

private fun addDestinationIconSymbolLayer(loadedMapStyle: Style?) {
    loadedMapStyle!!.addImage("destination-icon-id", BitmapFactory.decodeResource(this.resources, R.drawable.red_marker))

    val geoJsonSource = GeoJsonSource("destination-source-id")
    loadedMapStyle.addSource(geoJsonSource)
    val destinationSymbolLayer = SymbolLayer("destination-symbol-layer-id", "destination-source-id")
    destinationSymbolLayer.withProperties(PropertyFactory.iconImage("destination-icon-id"),
        PropertyFactory.iconAllowOverlap(true),
        PropertyFactory.iconIgnorePlacement(true))

    loadedMapStyle.addLayer(destinationSymbolLayer)
}

override fun onMapClick(point: LatLng): Boolean {
    val destinationPoint = Point.fromLngLat(point.longitude, point.latitude)
    val originPoint = Point.fromLngLat(
        locationComponent!!.lastKnownLocation!!.longitude,
        locationComponent!!.lastKnownLocation!!.latitude
    )

    val source = mapboxMap!!.style!!.getSourceAs<GeoJsonSource>("destination-source-id")
    source?.setGeoJson(Feature.fromGeometry(destinationPoint))

    getRoute(originPoint, destinationPoint)
    btnStart!!.isEnabled = true
    btnStart!!.setBackgroundResource(R.color.mapboxBlue)
    return true

    btnStartwithar.setOnClickListener {
        val intent = Intent(this, arnavigation::class.java)
        intent.putExtra("desti",destinationPoint)
        startActivity(intent);
    }


}

private fun getRoute(origin: Point, destination: Point) {
    NavigationRoute.builder(this).accessToken(Mapbox.getAccessToken()!!)
        .origin(origin)
        .destination(destination)
        .build()
        .getRoute(object : Callback<DirectionsResponse> {
            override fun onResponse(call: Call<DirectionsResponse>, response: Response<DirectionsResponse>) {
                // You can get the generic HTTP info about the response
                Log.d(TAG, "Response code: " + response.body())
                if (response.body() == null) {
                    Log.d(TAG, "No routes found, make sure you set the right user and access token")
                    return
                }
                else if (response.body()!!.routes().size < 1){
                    Log.e(TAG, "No routes found")
                    return
                }
                currentRoute = response.body()!!.routes()[0]

                //Draw the route on the map
                if (navigationMapRoute != null) {
                    navigationMapRoute!!.removeRoute()
                }
                else {
                    navigationMapRoute = NavigationMapRoute(null, mapView, mapboxMap!!, com.mapbox.services.android.navigation.ui.v5.R.style.NavigationMapRoute)
                }
                navigationMapRoute!!.addRoute(currentRoute)
            }

            override fun onFailure(call: Call<DirectionsResponse>, t: Throwable) {
                Log.e(TAG, "Error: " + t.message)
            }

        })
}

@SuppressLint("MissingPermission")
private fun enableLocationComponent(loadedMapStyle: Style?) {
    //Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {
        // Activity the MapboxMap LocationComponent to show user location
        // Adding in LocationComponentOptions is also an optional parameter
        locationComponent = mapboxMap!!.locationComponent
        locationComponent!!.activateLocationComponent(this, loadedMapStyle!!)
        locationComponent!!.setLocationComponentEnabled(true)

        //Set the component's camera mode
        locationComponent!!.setCameraMode(CameraMode.TRACKING)
    }

    else {
        permissionsManager = PermissionsManager(this)
        permissionsManager!!.requestLocationPermissions(this)
    }
}

override fun onExplanationNeeded(permissionsToExplain: MutableList<String>?) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_SHORT).show()
}

override fun onPermissionResult(granted: Boolean) {
    if (granted) {
        enableLocationComponent(mapboxMap!!.style)
    }
    else {
        Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_SHORT).show()
        finish()
    }
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

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

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

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

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

override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
    super.onSaveInstanceState(outState, outPersistentState)
    mapView.onSaveInstanceState(outState)
}

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

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

} `

and here is tutorial code about change LngLat arnavigation.kt

`package com.tuk.tukar

import android.content.Intent import android.location.Location import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import com.mapbox.android.core.location.LocationEngineCallback import com.mapbox.android.core.location.LocationEngineProvider import com.mapbox.android.core.location.LocationEngineRequest import com.mapbox.android.core.location.LocationEngineResult import com.mapbox.api.directions.v5.models.DirectionsResponse import com.mapbox.api.directions.v5.models.DirectionsRoute import com.mapbox.core.constants.Constants import com.mapbox.geojson.Point import com.mapbox.geojson.utils.PolylineUtils import com.mapbox.mapboxsdk.location.LocationComponent import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener import com.mapbox.services.android.navigation.v5.route.RouteFetcher import com.mapbox.services.android.navigation.v5.route.RouteListener import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress import com.mapbox.vision.VisionManager import com.mapbox.vision.ar.VisionArManager import com.mapbox.vision.ar.core.models.ManeuverType import com.mapbox.vision.ar.core.models.Route import com.mapbox.vision.ar.core.models.RoutePoint import com.mapbox.vision.ar.view.gl.VisionArView import com.mapbox.vision.mobile.core.interfaces.VisionEventsListener import com.mapbox.vision.mobile.core.models.position.GeoCoordinate import com.mapbox.vision.performance.ModelPerformance import com.mapbox.vision.performance.ModelPerformanceMode import com.mapbox.vision.performance.ModelPerformanceRate import com.mapbox.vision.utils.VisionLogger import kotlinx.android.synthetic.main.activity_arnavigation.* import java.lang.Exception import retrofit2.Call import retrofit2.Callback import retrofit2.Response

open class arnavigation : baseActivity(), RouteListener, ProgressChangeListener, OffRouteListener {

companion object {
    private var TAG = arnavigation::class.java.simpleName
}

private lateinit var mapboxNavigation: MapboxNavigation
private lateinit var routeFetcher: RouteFetcher
private lateinit var lastRouteProgress: RouteProgress
private lateinit var directionsRoute: DirectionsRoute
private var locationComponent: LocationComponent? = null

private var visionManagerWasInit = false
private var navigationWasStarted = false

private val arLocationEngine by lazy {
    LocationEngineProvider.getBestLocationEngine(this)
}
private val locationCallback by lazy {
    object : LocationEngineCallback<LocationEngineResult> {
        override fun onSuccess(result: LocationEngineResult?) {}

        override fun onFailure(exception: Exception) {}
    }
}
private val arLocationEngineRequest by lazy {
    LocationEngineRequest.Builder(0)
        .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
        .setFastestInterval(1000)
        .build()
}

protected open fun setArRenderOptions(visionArView: VisionArView) {
    visionArView.setFenceVisible(true)
}

override fun onPermissionsGranted() {
    startVisionManager()
    startNavigation()
}

override fun initViews() {
    setContentView(R.layout.activity_arnavigation)
}

override fun onStart() {
    super.onStart()
    startVisionManager()
    startNavigation()
}

override fun onStop() {
    super.onStop()
    stopVisionManager()
    stopNavigation()
}

private fun startVisionManager() {
    if (allPermissionsGranted() && !visionManagerWasInit) {
        // Create and start VisionManager.
        VisionManager.create()
        VisionManager.setModelPerformance(
            ModelPerformance.On(
                ModelPerformanceMode.DYNAMIC,
                ModelPerformanceRate.LOW
            )
        )
        VisionManager.start()
        VisionManager.visionEventsListener = object : VisionEventsListener {}

        // Create VisionArManager.
        VisionArManager.create(VisionManager)
        mapbox_ar_view.setArManager(VisionArManager)
        setArRenderOptions(mapbox_ar_view)

        visionManagerWasInit = true
    }
}

private fun stopVisionManager() {
    if (visionManagerWasInit) {
        VisionArManager.destroy()
        VisionManager.stop()
        VisionManager.destroy()

        visionManagerWasInit = false
    }
}

private fun startNavigation() {
    val originPoint = Point.fromLngLat(
        locationComponent!!.lastKnownLocation!!.longitude,
        locationComponent!!.lastKnownLocation!!.latitude
    )
    if (allPermissionsGranted() && !navigationWasStarted) {
        // Initialize navigation with your Mapbox access token.
        mapboxNavigation = MapboxNavigation(
            this,
            getString(R.string.mapbox_access_token),
            MapboxNavigationOptions.builder().build()
        )

        // Initialize route fetcher with your Mapbox access token.
        routeFetcher = RouteFetcher(this, getString(R.string.mapbox_access_token))
        routeFetcher.addRouteListener(this)

        try {
            arLocationEngine.requestLocationUpdates(
                arLocationEngineRequest,
                locationCallback,
                mainLooper
            )
        } catch (se: SecurityException) {
            VisionLogger.e(TAG, se.toString())
        }
        **val destinationPoint = ("desti") // how i intent getExtra data about Point?
        initDirectionsRoute(originPoint, destinationPoint)**

        // Route need to be reestablished if off route happens.
        mapboxNavigation.addOffRouteListener(this)
        mapboxNavigation.addProgressChangeListener(this)

        navigationWasStarted = true
    }
}

private fun stopNavigation() {
    if (navigationWasStarted) {
        arLocationEngine.removeLocationUpdates(locationCallback)

        mapboxNavigation.removeProgressChangeListener(this)
        mapboxNavigation.removeOffRouteListener(this)
        mapboxNavigation.stopNavigation()

        navigationWasStarted = false
    }
}

private fun initDirectionsRoute(origin:Point, destination: Point) {
    NavigationRoute.builder(this)
        .accessToken(getString(R.string.mapbox_access_token))
        .origin(origin)
        .destination(destination)
        .build()
        .getRoute(object : Callback<DirectionsResponse> {
            override fun onResponse(
                call: Call<DirectionsResponse>,
                response: Response<DirectionsResponse>
            ) {
                if (response.body() == null || response.body()!!.routes().isEmpty()) {
                    return
                }

                directionsRoute = response.body()!!.routes()[0]
                mapboxNavigation.startNavigation(directionsRoute)

                // Set route progress.
                VisionArManager.setRoute(
                    Route(
                        directionsRoute.getRoutePoints(),
                        directionsRoute.duration()?.toFloat() ?: 0f,
                        "",
                        ""
                    )
                )
            }

            override fun onFailure(call: Call<DirectionsResponse>, t: Throwable) {
                t.printStackTrace()
            }
        })
}

override fun onErrorReceived(throwable: Throwable?) {
    throwable?.printStackTrace()

    mapboxNavigation.stopNavigation()
    Toast.makeText(this, "Can not calculate the route requested", Toast.LENGTH_SHORT).show()
}

override fun onResponseReceived(response: DirectionsResponse, routeProgress: RouteProgress?) {
    mapboxNavigation.stopNavigation()
    if (response.routes().isEmpty()) {
        Toast.makeText(this, "Can not calculate the route requested", Toast.LENGTH_SHORT).show()
    } else {
        mapboxNavigation.startNavigation(response.routes()[0])

        val route = response.routes()[0]

        // Set route progress.
        VisionArManager.setRoute(
            Route(
                route.getRoutePoints(),
                route.duration()?.toFloat() ?: 0f,
                "",
                ""
            )
        )
    }
}

override fun onProgressChange(location: Location, routeProgress: RouteProgress) {
    lastRouteProgress = routeProgress
}

override fun userOffRoute(location: Location) {
    routeFetcher.findRouteFromRouteProgress(location, lastRouteProgress)
}

private fun DirectionsRoute.getRoutePoints(): Array<RoutePoint> {
    val routePoints = arrayListOf<RoutePoint>()
    legs()?.forEach { leg ->
        leg.steps()?.forEach { step ->
            val maneuverPoint = RoutePoint(
                GeoCoordinate(
                    latitude = step.maneuver().location().latitude(),
                    longitude = step.maneuver().location().longitude()
                ),
                step.maneuver().type().mapToManeuverType()
            )
            routePoints.add(maneuverPoint)

            step.geometry()
                ?.buildStepPointsFromGeometry()
                ?.map { geometryStep ->
                    RoutePoint(
                        GeoCoordinate(
                            latitude = geometryStep.latitude(),
                            longitude = geometryStep.longitude()
                        )
                    )
                }
                ?.let { stepPoints ->
                    routePoints.addAll(stepPoints)
                }
        }
    }

    return routePoints.toTypedArray()
}

private fun String.buildStepPointsFromGeometry(): List<Point> {
    return PolylineUtils.decode(this, Constants.PRECISION_6)
}

private fun String?.mapToManeuverType(): ManeuverType = when (this) {
    "turn" -> ManeuverType.Turn
    "depart" -> ManeuverType.Depart
    "arrive" -> ManeuverType.Arrive
    "merge" -> ManeuverType.Merge
    "on ramp" -> ManeuverType.OnRamp
    "off ramp" -> ManeuverType.OffRamp
    "fork" -> ManeuverType.Fork
    "roundabout" -> ManeuverType.Roundabout
    "exit roundabout" -> ManeuverType.RoundaboutExit
    "end of road" -> ManeuverType.EndOfRoad
    "new name" -> ManeuverType.NewName
    "continue" -> ManeuverType.Continue
    "rotary" -> ManeuverType.Rotary
    "roundabout turn" -> ManeuverType.RoundaboutTurn
    "notification" -> ManeuverType.Notification
    "exit rotary" -> ManeuverType.RoundaboutExit
    else -> ManeuverType.None
}

} `

how can I get data about destination Point?

It would be nice if there was an example of coordinate setting in the tutorial.

Sae-Ba avatar Apr 01 '22 14:04 Sae-Ba