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
6 changes: 5 additions & 1 deletion libandroid/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
android:label="Directions v5"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".directions.RouteUtilsV5Activity"
android:label="Route Utils v5"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".icons.DirectionsIconsActivity"
android:label="Directions icons"
Expand Down Expand Up @@ -100,7 +105,6 @@
android:label="Turf inside"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" />

<activity
android:name=".turf.TurfMidpointActivity"
android:label="Turf midpoint"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.mapbox.services.android.BuildConfig;
import com.mapbox.services.android.testapp.directions.DirectionsV4Activity;
import com.mapbox.services.android.testapp.directions.DirectionsV5Activity;
import com.mapbox.services.android.testapp.directions.RouteUtilsV5Activity;
import com.mapbox.services.android.testapp.geocoding.GeocodingReverseActivity;
import com.mapbox.services.android.testapp.geocoding.GeocodingServiceActivity;
import com.mapbox.services.android.testapp.geocoding.GeocodingWidgetActivity;
Expand Down Expand Up @@ -49,6 +50,7 @@ public class MainActivity extends AppCompatActivity {

private final static List<SampleItem> samples = new ArrayList<>(Arrays.asList(
new SampleItem("Directions v5", "", DirectionsV5Activity.class),
new SampleItem("Route Utils v5", "", RouteUtilsV5Activity.class),
new SampleItem("Directions v4", "", DirectionsV4Activity.class),
new SampleItem("Directions icons", "", DirectionsIconsActivity.class),
new SampleItem("Reverse geocoding", "", GeocodingReverseActivity.class),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import retrofit2.Call;
import retrofit2.Callback;
Expand All @@ -42,6 +43,7 @@ public class DirectionsV5Activity extends AppCompatActivity {
private MapboxMap mapboxMap = null;

private DirectionsRoute currentRoute = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -126,7 +128,7 @@ public void onResponse(Call<DirectionsResponse> call, Response<DirectionsRespons
// Print some info about the route
currentRoute = response.body().getRoutes().get(0);
Log.d(LOG_TAG, "Distance: " + currentRoute.getDistance());
showMessage(String.format("Route is %f meters long.", currentRoute.getDistance()));
showMessage(String.format(Locale.US, "Route is %.1f meters long.", currentRoute.getDistance()));

// Draw the route on the map
drawRoute(currentRoute);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
package com.mapbox.services.android.testapp.directions;

import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

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.annotations.MarkerViewOptions;
import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
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.testapp.MainActivity;
import com.mapbox.services.android.testapp.R;
import com.mapbox.services.android.testapp.Utils;
import com.mapbox.services.commons.ServicesException;
import com.mapbox.services.commons.geojson.LineString;
import com.mapbox.services.commons.models.Position;
import com.mapbox.services.commons.turf.TurfException;
import com.mapbox.services.commons.utils.PolylineUtils;
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.directions.v5.models.LegStep;
import com.mapbox.services.directions.v5.models.RouteLeg;
import com.mapbox.services.navigation.v5.RouteUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

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

public class RouteUtilsV5Activity extends AppCompatActivity implements OnMapReadyCallback {

private final static String LOG_TAG = "RouteUtilsV5Activity";

private MapView mapView = null;
private MapboxMap mapboxMap = null;

private LatLng from = null;
private LatLng to = null;
private DirectionsRoute currentRoute = null;

private Icon tapIcon;
private Marker userTap = null;
private List<Polyline> snapLines = null;

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

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

// Create an Icon object for the marker to use
IconFactory iconFactory = IconFactory.getInstance(this);
Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_my_location_black_24dp);
tapIcon = iconFactory.fromDrawable(iconDrawable);

// Set up a standard Mapbox map
mapView = (MapView) findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}

@Override
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;

mapboxMap.setStyleUrl(Style.MAPBOX_STREETS);

// Dupont Circle
LatLng target = new LatLng(38.90962, -77.04341);

// Move map
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(target)
.zoom(14)
.build();
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
@Override
public void onMapClick(@NonNull LatLng point) {
if (from == null) {
setFrom(point);
} else if (to == null) {
setTo(point);
} else {
try {
doUtils(point);
} catch (ServicesException e) {
Log.e(LOG_TAG, "Services exception: " + e.getMessage());
e.printStackTrace();
} catch (TurfException e) {
Log.e(LOG_TAG, "Turf exception: " + e.getMessage());
e.printStackTrace();
}
}
}
});
}

private void setFrom(LatLng point) {
from = point;
mapboxMap.addMarker(new MarkerOptions()
.position(point)
.title("From"));
}

private void setTo(LatLng point) {
to = point;
mapboxMap.addMarker(new MarkerOptions()
.position(point)
.title("To"));

try {
getRoute(Position.fromCoordinates(from.getLongitude(), from.getLatitude()), Position.fromCoordinates(to.getLongitude(), to.getLatitude()));
} catch (ServicesException e) {
showMessage(e.getMessage());
e.printStackTrace();
}
}

private void doUtils(LatLng point) throws ServicesException, TurfException {
// Remove previous
if (userTap != null) {
mapboxMap.removeMarker(userTap);
}

userTap = mapboxMap.addMarker(new MarkerOptions().position(point).setIcon(tapIcon));

RouteUtils routeUtils = new RouteUtils();
RouteLeg route = currentRoute.getLegs().get(0);
Position position = Position.fromCoordinates(point.getLongitude(), point.getLatitude());

// General situational message
String message = String.format(Locale.US, "You're closest to step %d/%d (%s)",
routeUtils.getClosestStep(position, route) + 1,
route.getSteps().size(),
routeUtils.isOffRoute(position, route) ? "off-route" : "not off-route");
showMessage(message);

// Remove previous lines
if (snapLines != null && snapLines.size() > 0) {
for (Polyline snapLine: snapLines) {
mapboxMap.removePolyline(snapLine);
}
}

// Draw snap to route lines
snapLines = new ArrayList<>();
for (int stepIndex = 0; stepIndex < route.getSteps().size(); stepIndex++) {
Position snapPoint = routeUtils.getSnapToRoute(position, route, stepIndex);
LatLng[] points = new LatLng[] {
point,
new LatLng(snapPoint.getLatitude(), snapPoint.getLongitude())};
snapLines.add(mapboxMap.addPolyline(new PolylineOptions()
.add(points)
.color(Color.parseColor("#f9886c"))
.width(2)));
}

// Log some extra info
for (int stepIndex = 0; stepIndex < route.getSteps().size(); stepIndex++) {
Log.d(LOG_TAG, String.format("Step %d: in step = %b, distance = %.1fkm",
stepIndex + 1,
routeUtils.isInStep(position, route, stepIndex),
routeUtils.getDistanceToStep(position, route, stepIndex)));
}
}

private void getRoute(Position origin, Position destination) throws ServicesException {
ArrayList<Position> positions = new ArrayList<>();
positions.add(origin);
positions.add(destination);

MapboxDirections client = new MapboxDirections.Builder()
.setAccessToken(Utils.getMapboxAccessToken(this))
.setCoordinates(positions)
.setProfile(DirectionsCriteria.PROFILE_DRIVING)
.setSteps(true)
.setOverview(DirectionsCriteria.OVERVIEW_FULL)
.build();

client.enqueueCall(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get generic HTTP info about the response
Log.d(LOG_TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(LOG_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(LOG_TAG, "Distance: " + currentRoute.getDistance());
showMessage(String.format(Locale.US, "Route has %d steps and it's %.1f meters long.",
currentRoute.getLegs().get(0).getSteps().size(),
currentRoute.getDistance()));

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

@Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
Log.e(LOG_TAG, "Error: " + t.getMessage());
showMessage("Error: " + t.getMessage());
}
});
}

private void drawRoute(DirectionsRoute route) {
// We're gonna draw each step in an alternating color
String[] colors = new String[] {"#3887be", "#56b881"}; // Blue, green

List<Position> coordinates;
LatLng[] points;
int colorIndex = 0;
for (int i = 0; i < route.getLegs().get(0).getSteps().size(); i++) {
LegStep step = route.getLegs().get(0).getSteps().get(i);
coordinates = PolylineUtils.decode(step.getGeometry(), Constants.OSRM_PRECISION_V5);
points = new LatLng[coordinates.size()];
for (int j = 0; j < coordinates.size(); j++) {
points[j] = new LatLng(
coordinates.get(j).getLatitude(),
coordinates.get(j).getLongitude());
}

colorIndex ^= 1;
mapboxMap.addPolyline(new PolylineOptions()
.add(points)
.color(Color.parseColor(colors[colorIndex]))
.width(5));
}
}

private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

@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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>
26 changes: 26 additions & 0 deletions libandroid/app/src/main/res/layout/activity_route_utils_v5.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.mapbox.services.android.testapp.directions.RouteUtilsV5Activity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_route_utils_v5" />

</android.support.design.widget.CoordinatorLayout>
Loading