Retrieve travel times between many points
NOTE
This example is a part of the Mapbox Android Demo app. You can find the values for all referenced resources in the res
directory. For example, see res/values/activity_strings.xml
for R.string.*
references used in this example.
Matrix API pricing
Products used within the Mapbox Java SDK, including the Matrix API, are individually billed. For pricing information, see the documentation for the Matrix API.
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:mapbox="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"> <com.mapbox.mapboxsdk.maps.MapViewandroid:id="@+id/mapView"android:layout_width="match_parent"android:layout_height="match_parent"mapbox:mapbox_cameraTargetLat="42.3600825"mapbox:mapbox_cameraTargetLng="-71.0588801"mapbox:mapbox_cameraZoom="11.193"/> <androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/matrix_api_recyclerview"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="top"android:layout_marginTop="16dp"/></FrameLayout>
package com.mapbox.mapboxandroiddemo.examples.javaservices; import android.content.Context;import android.os.Bundle;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.cardview.widget.CardView;import androidx.recyclerview.widget.DefaultItemAnimator;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.LinearSnapHelper;import androidx.recyclerview.widget.RecyclerView;import androidx.recyclerview.widget.SnapHelper;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.widget.Toast; import com.mapbox.api.directions.v5.DirectionsCriteria;import com.mapbox.api.matrix.v1.MapboxMatrix;import com.mapbox.api.matrix.v1.models.MatrixResponse;import com.mapbox.geojson.Feature;import com.mapbox.geojson.FeatureCollection;import com.mapbox.geojson.Point;import com.mapbox.mapboxandroiddemo.R;import com.mapbox.mapboxsdk.Mapbox;import com.mapbox.mapboxsdk.annotations.Icon;import com.mapbox.mapboxsdk.annotations.IconFactory;import com.mapbox.mapboxsdk.annotations.Marker;import com.mapbox.mapboxsdk.annotations.MarkerOptions;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.mapboxsdk.maps.Style;import com.mapbox.turf.TurfConversion; import java.io.InputStream;import java.nio.charset.Charset;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.List; import retrofit2.Call;import retrofit2.Callback;import retrofit2.Response;import timber.log.Timber; /*** Use the Mapbox Java Services SDK's Matrix API to retrieve travel times between many points.*/public class MatrixApiActivity extends AppCompatActivity { private MapView mapView;private MapboxMap mapboxMap;private List<Point> pointList;private FeatureCollection featureCollection;private RecyclerView recyclerView;private MatrixApiLocationRecyclerViewAdapter matrixApiLocationRecyclerViewAdapter;private ArrayList<SingleRecyclerViewMatrixLocation> matrixLocationList; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // Mapbox access token is configured here. This needs to be called either in your application// object or in the same activity which contains the mapview.Mapbox.getInstance(this, getString(R.string.access_token)); // This contains the MapView in XML and needs to be called after the access token is configured.setContentView(R.layout.activity_matrix_api); recyclerView = findViewById(R.id.matrix_api_recyclerview); // Create list of positions from local GeoJSON fileinitPositionListFromGeoJsonFile(); mapView = findViewById(R.id.mapView);mapView.onCreate(savedInstanceState);mapView.getMapAsync(new OnMapReadyCallback() {@Overridepublic void onMapReady(@NonNull final MapboxMap mapboxMap) {MatrixApiActivity.this.mapboxMap = mapboxMap; mapboxMap.setStyle(Style.LIGHT,new Style.OnStyleLoaded() {@Overridepublic void onStyleLoaded(@NonNull Style style) {// Add markers to the mapaddMarkers(); // Set up list of locations to pass to the recyclerviewinitMatrixLocationListForRecyclerView(); // Set up the recyclerview of charging station cardsinitRecyclerView(); mapboxMap.setOnMarkerClickListener(new MapboxMap.OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(@NonNull Marker marker) { // Make a call to the Mapbox Matrix APImakeMapboxMatrixApiCall(getClickedMarkerNumInPositionList(marker), Point.fromLngLat(marker.getPosition().getLongitude(), marker.getPosition().getLatitude()));return false;}});Toast.makeText(MatrixApiActivity.this, R.string.click_on_marker_instruction_toast,Toast.LENGTH_SHORT).show();}});}});} private int getClickedMarkerNumInPositionList(Marker clickedMarker) {int clickedMarkerIndexPositionInList = -1;if (clickedMarker != null) {for (Marker singleMarker : mapboxMap.getMarkers()) {if (singleMarker == clickedMarker) {clickedMarkerIndexPositionInList = mapboxMap.getMarkers().indexOf(singleMarker);}}return clickedMarkerIndexPositionInList;} else {return 0;}} private void initRecyclerView() {matrixApiLocationRecyclerViewAdapter = new MatrixApiLocationRecyclerViewAdapter(this,matrixLocationList);recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.HORIZONTAL, true));recyclerView.setItemAnimator(new DefaultItemAnimator());recyclerView.setAdapter(matrixApiLocationRecyclerViewAdapter);SnapHelper snapHelper = new LinearSnapHelper();snapHelper.attachToRecyclerView(recyclerView);} private void makeMapboxMatrixApiCall(final int markerPositionInList, Point pointOfClickedMarker) { // Build Mapbox Matrix API parametersMapboxMatrix directionsMatrixClient = MapboxMatrix.builder().accessToken(getString(R.string.access_token)).profile(DirectionsCriteria.PROFILE_DRIVING).coordinates(pointList).build(); // Handle the API responsedirectionsMatrixClient.enqueueCall(new Callback<MatrixResponse>() {@Overridepublic void onResponse(Call<MatrixResponse> call,Response<MatrixResponse> response) {if (response.body() != null) {List<Double[]> durationsToAllOfTheLocationsFromTheOrigin = response.body().durations();if (durationsToAllOfTheLocationsFromTheOrigin != null) {for (int x = 0; x < durationsToAllOfTheLocationsFromTheOrigin.size(); x++) {String finalConvertedFormattedDistance = String.valueOf(new DecimalFormat("#.##").format(TurfConversion.convertLength(durationsToAllOfTheLocationsFromTheOrigin.get(markerPositionInList)[x],"meters", "miles")));if (x == markerPositionInList) {matrixLocationList.get(x).setDistanceFromOrigin(finalConvertedFormattedDistance);}if (x != markerPositionInList) {matrixLocationList.get(x).setDistanceFromOrigin(finalConvertedFormattedDistance);matrixApiLocationRecyclerViewAdapter.notifyDataSetChanged();}}}}} @Overridepublic void onFailure(Call<MatrixResponse> call, Throwable throwable) {Toast.makeText(MatrixApiActivity.this, R.string.call_error,Toast.LENGTH_SHORT).show();Timber.d( "onResponse onFailure");}});} private void addMarkers() {Icon lightningBoltIcon = IconFactory.getInstance(MatrixApiActivity.this).fromResource(R.drawable.lightning_bolt);if (featureCollection.features() != null) {for (Feature feature : featureCollection.features()) {mapboxMap.addMarker(new MarkerOptions().position(new LatLng(feature.getProperty("Latitude").getAsDouble(),feature.getProperty("Longitude").getAsDouble())).snippet(feature.getStringProperty("Station_Name")).icon(lightningBoltIcon));}}} private String loadGeoJsonFromAsset(String filename) {try {// Load GeoJSON file from local asset folderInputStream is = getAssets().open(filename);int size = is.available();byte[] buffer = new byte[size];is.read(buffer);is.close();return new String(buffer, Charset.forName("UTF-8"));} catch (Exception exception) {Timber.d(exception.toString(), "Exception Loading GeoJSON: ");exception.printStackTrace();return null;}} private void initPositionListFromGeoJsonFile() { // Get GeoJSON features from GeoJSON file in the assets folderfeatureCollection = FeatureCollection.fromJson(loadGeoJsonFromAsset("boston_charge_stations.geojson")); // Initialize List<Position> for eventual use in the Matrix API callpointList = new ArrayList<>(); // Get the position of each GeoJSON feature and build the list of Position// objects for eventual use in the Matrix API callif (featureCollection.features() != null) {for (Feature singleLocation : featureCollection.features()) {pointList.add((Point) singleLocation.geometry());}}} private void initMatrixLocationListForRecyclerView() {matrixLocationList = new ArrayList<>();if (featureCollection.features() != null) {for (Feature feature : featureCollection.features()) {SingleRecyclerViewMatrixLocation singleRecyclerViewLocation = new SingleRecyclerViewMatrixLocation();singleRecyclerViewLocation.setName(feature.getStringProperty("Station_Name"));singleRecyclerViewLocation.setLocationLatLng(new LatLng(((Point)feature.geometry()).latitude(),((Point) feature.geometry()).longitude()));matrixLocationList.add(singleRecyclerViewLocation);}}} // Add the mapView lifecycle to the activity's lifecycle methods@Overridepublic void onResume() {super.onResume();mapView.onResume();} @Overrideprotected void onStart() {super.onStart();mapView.onStart();} @Overrideprotected void onStop() {super.onStop();mapView.onStop();} @Overridepublic void onPause() {super.onPause();mapView.onPause();} @Overridepublic void onLowMemory() {super.onLowMemory();mapView.onLowMemory();} @Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();} @Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);} /*** POJO model class for a single location in the recyclerview*/class SingleRecyclerViewMatrixLocation { private String name;private LatLng locationLatLng;private String distanceFromOrigin; public String getName() {return name;} public void setName(String name) {this.name = name;} public String getDistanceFromOrigin() {return distanceFromOrigin;} public void setDistanceFromOrigin(String distanceFromOrigin) {this.distanceFromOrigin = distanceFromOrigin;} public void setLocationLatLng(LatLng locationLatLng) {this.locationLatLng = locationLatLng;}} static class MatrixApiLocationRecyclerViewAdapter extendsRecyclerView.Adapter<MatrixApiLocationRecyclerViewAdapter.MyViewHolder> { private List<SingleRecyclerViewMatrixLocation> matrixLocationList;private Context context; public MatrixApiLocationRecyclerViewAdapter(Context context,List<SingleRecyclerViewMatrixLocation> matrixLocationList) {this.matrixLocationList = matrixLocationList;this.context = context;} @Overridepublic MatrixApiLocationRecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_matrix_card, parent, false);return new MatrixApiLocationRecyclerViewAdapter.MyViewHolder(itemView);} @Overridepublic void onBindViewHolder(MatrixApiLocationRecyclerViewAdapter.MyViewHolder holder, int position) {SingleRecyclerViewMatrixLocation singleRecyclerViewLocation = matrixLocationList.get(position);holder.name.setText(singleRecyclerViewLocation.getName()); String finalDistance = singleRecyclerViewLocation.getDistanceFromOrigin()== null ? "" : String.format(context.getString(R.string.miles_distance),singleRecyclerViewLocation.getDistanceFromOrigin());holder.distance.setText(finalDistance);} @Overridepublic int getItemCount() {return matrixLocationList.size();} static class MyViewHolder extends RecyclerView.ViewHolder {TextView name;TextView distance;CardView singleCard; MyViewHolder(View view) {super(view);name = view.findViewById(R.id.boston_matrix_api_location_title_tv);distance = view.findViewById(R.id.boston_matrix_api_location_distance_tv);singleCard = view.findViewById(R.id.single_location_cardview);}}}}
Was this example helpful?