Mapbox Android: How to get directions from current location to a destination you choose?

邮差的信 提交于 2020-01-11 04:12:10

问题


Okay so I am fairly new to Mapbox, I have used GMaps prior to this but I found that Mapbox is more capable of doing what I need, the problem is I have hit a bit of a wall.

I have used a combination of the examples available on their site e.g.

https://www.mapbox.com/android-sdk/examples/geocoding and https://www.mapbox.com/android-sdk/examples/directions

I am trying to allow the user to search a destination and then have it turned into coordinates which will be used to plot in the map. I then want to draw a route from their current location to their destination, this is where my problem comes in.

 mapView.getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(MapboxMap mapboxMap) {

            map = mapboxMap;


            // Set the origin waypoint to the devices location
            Position origin = Position.fromCoordinates(mapboxMap.getMyLocation().getLongitude(), mapboxMap.getMyLocation().getLatitude());

            // Set the destination waypoint to the location point long clicked by the user
            final Position destination = updateMap(feature.getLongitude(), feature.getLatitude());

            mapboxMap.addMarker(new MarkerOptions()
                    .position(new LatLng(origin.getLatitude(), origin.getLongitude()))
                    .title("Origin")
                    .snippet("Alhambra"));
            mapboxMap.addMarker(new MarkerOptions()
                    .position(new LatLng(latitude, destination.getLongitude()))
                    .title("Destination")
                    .snippet("Plaza del Triunfo"));

            // Get route from API
            try {
                getRoute(origin, destination);
            } catch (ServicesException e) {
                e.printStackTrace();
            }
        }
    });

    AndroidGeocoder geocoder = new AndroidGeocoder(context, Locale.getDefault());
    geocoder.setAccessToken(MAPBOX_ACCESS_TOKEN);
    addresses = geocoder.getFromLocation(
            location.getLatitude(),
            location.getLongitude(),
            1);

    // Set up autocomplete widget
    GeocoderAutoCompleteView autocomplete = (GeocoderAutoCompleteView) findViewById(R.id.query);
    autocomplete.setAccessToken("pk.eyJ1IjoiYmV1dHJveCIsImEiOiJjaW5ybzlwYnQwMGlqdnhtMno3cmtwNTlqIn0.y16mZzmertL4-eEfQNGeqQ");
    autocomplete.setType(GeocodingCriteria.TYPE_POI);
    autocomplete.setOnFeatureListener(new GeocoderAutoCompleteView.OnFeatureListener() {
        @Override
        public void OnFeatureClick(GeocodingFeature feature) {
            Position position = feature.asPosition();
            updateMap(position.getLatitude(), position.getLongitude());
        }
    });
}


private void getRoute(Position origin, Position destination) throws ServicesException {

    MapboxDirections client = new MapboxDirections.Builder()
            .setOrigin(origin)
            .setDestination(destination)
            .setProfile(DirectionsCriteria.PROFILE_CYCLING)
            .setAccessToken("pk.eyJ1IjoiYmV1dHJveCIsImEiOiJjaW5ybzlwYnQwMGlqdnhtMno3cmtwNTlqIn0.y16mZzmertL4-eEfQNGeqQ")
            .build();

    client.enqueueCall(new Callback<DirectionsResponse>() {
        @Override
        public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
            // You can get the generic HTTP info about the response
            Log.d(TAG, "Response code: " + response.code());
            if (response.body() == null) {
                Log.e(TAG, "No routes found, make sure you set the right user and access token.");
                return;
            }

            // Display some info about the route
            currentRoute = response.body().getRoutes().get(0);
            Log.d(TAG, "Distance: " + currentRoute.getDistance());
            Toast.makeText(MainActivity.this, "Route is " +  currentRoute.getDistance() + " meters long.", Toast.LENGTH_SHORT).show();

            // Draw the route on the map
            drawRoute(currentRoute);
        }

        @Override
        public void onFailure(Call<DirectionsResponse> call, Throwable t) {
            Log.e(TAG, "Error: " + t.getMessage());
            Toast.makeText(MainActivity.this, "Error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

private void drawRoute(DirectionsRoute route) {
    // Convert LineString coordinates into LatLng[]
    LineString lineString = LineString.fromPolyline(route.getGeometry(), Constants.OSRM_PRECISION_V5);
    List<Position> coordinates = lineString.getCoordinates();
    LatLng[] points = new LatLng[coordinates.size()];
    for (int i = 0; i < coordinates.size(); i++) {
        points[i] = new LatLng(
                coordinates.get(i).getLatitude(),
                coordinates.get(i).getLongitude());
    }

    // Draw Points on MapView
    map.addPolyline(new PolylineOptions()
            .add(points)
            .color(Color.parseColor("#009688"))
            .width(5));

}

private void myLocation() {

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }

    mapView.setMyLocationEnabled(true);
    mapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
    mapView.getMyLocation();
}

So somewhere in here is my problem, I can't find much about Mapbox online since their new sdk is very different to the previous versions, mainly because MapView and MapboxMap are now seperated (this still confuses me).

Any help would be greatly appreciated :D

:Edit: I'm struggling mainly with setting a destination, and because of this a lot of my current variables are mixed up. If you need explaining, I will happily.


回答1:


A few mistakes in your code, biggest being you are still using MapView to get location information when you can use MapboxMap instead. Heres some rough code that will do what you ask for. It doesn't check for user permission like you should but it will show you how to do the Mapbox stuff.

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.services.Constants;
import com.mapbox.services.android.geocoder.ui.GeocoderAutoCompleteView;
import com.mapbox.services.commons.ServicesException;
import com.mapbox.services.commons.geojson.LineString;
import com.mapbox.services.commons.models.Position;
import com.mapbox.services.directions.v5.DirectionsCriteria;
import com.mapbox.services.directions.v5.MapboxDirections;
import com.mapbox.services.directions.v5.models.DirectionsResponse;
import com.mapbox.services.directions.v5.models.DirectionsRoute;
import com.mapbox.services.geocoding.v5.GeocodingCriteria;
import com.mapbox.services.geocoding.v5.models.GeocodingFeature;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends Activity {

    private final static String TAG = "MainActivity";

    private MapView mapView;
    private MapboxMap map;
    private DirectionsRoute currentRoute;

    private Position origin;
    private Position destination;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Setup the MapView
        mapView = (MapView) findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(MapboxMap mapboxMap) {
                map = mapboxMap;

                mapboxMap.setMyLocationEnabled(true);

                // Set up autocomplete widget
                GeocoderAutoCompleteView autocomplete = (GeocoderAutoCompleteView) findViewById(R.id.query);
            autocomplete.setAccessToken("<your access token>");
            autocomplete.setType(GeocodingCriteria.TYPE_POI);
            autocomplete.setOnFeatureListener(new GeocoderAutoCompleteView.OnFeatureListener() {
                @Override
                public void OnFeatureClick(GeocodingFeature feature) {

                    if(map.getMyLocation() != null) {
                        // Set the origin as user location only if we can get their location
                        origin = Position.fromCoordinates(map.getMyLocation().getLongitude(), map.getMyLocation().getLatitude());
                    }else{
                        return;
                    }

                    destination = feature.asPosition();

                    // Add origin and destination to the map
                    map.addMarker(new MarkerOptions()
                            .position(new LatLng(origin.getLatitude(), origin.getLongitude())));
                    map.addMarker(new MarkerOptions()
                            .position(new LatLng(destination.getLatitude(), destination.getLongitude())));

                    // Get route from API
                    try {
                        getRoute(origin, destination);
                    } catch (ServicesException e) {
                        e.printStackTrace();
                    }

                }
            });
        }
    });
}

private void getRoute(Position origin, Position destination) throws ServicesException {

    MapboxDirections client = new MapboxDirections.Builder()
            .setOrigin(origin)
            .setDestination(destination)
            .setProfile(DirectionsCriteria.PROFILE_CYCLING)
            .setAccessToken("<your access token>")
            .build();

    client.enqueueCall(new Callback<DirectionsResponse>() {
        @Override
        public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
            // You can get the generic HTTP info about the response
            Log.d(TAG, "Response code: " + response.code());
            if (response.body() == null) {
                Log.e(TAG, "No routes found, make sure you set the right user and access token.");
                return;
            }

            // Print some info about the route
            currentRoute = response.body().getRoutes().get(0);
            Log.d(TAG, "Distance: " + currentRoute.getDistance());
            Toast.makeText(MainActivity.this, "Route is " +  currentRoute.getDistance() + " meters long.", Toast.LENGTH_SHORT).show();

            // Draw the route on the map
            drawRoute(currentRoute);
        }

        @Override
        public void onFailure(Call<DirectionsResponse> call, Throwable t) {
            Log.e(TAG, "Error: " + t.getMessage());
            Toast.makeText(MainActivity.this, "Error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

private void drawRoute(DirectionsRoute route) {
    // Convert LineString coordinates into LatLng[]
    LineString lineString = LineString.fromPolyline(route.getGeometry(), Constants.OSRM_PRECISION_V5);
    List<Position> coordinates = lineString.getCoordinates();
    LatLng[] points = new LatLng[coordinates.size()];
    for (int i = 0; i < coordinates.size(); i++) {
        points[i] = new LatLng(
                coordinates.get(i).getLatitude(),
                coordinates.get(i).getLongitude());
    }

    // Draw Points on MapView
    map.addPolyline(new PolylineOptions()
            .add(points)
            .color(Color.parseColor("#009688"))
            .width(5));
}

@Override
public void onResume() {
    super.onResume();
    mapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mapView.onPause();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
}

Hope this helps!



来源:https://stackoverflow.com/questions/37149805/mapbox-android-how-to-get-directions-from-current-location-to-a-destination-you

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!