Skip to content

Commit

Permalink
Synchronize all navigator method calls
Browse files Browse the repository at this point in the history
  • Loading branch information
danesfeder committed Sep 18, 2018
1 parent c2dfe79 commit 81571d9
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 87 deletions.
2 changes: 1 addition & 1 deletion gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ext {
mapboxMapSdk : '6.5.0',
mapboxSdkServices : '3.4.1',
mapboxEvents : '3.2.0',
mapboxNavigator : 'offline_build-SNAPSHOT-44',
mapboxNavigator : 'offline_build-SNAPSHOT-54',
locationLayerPlugin: '0.8.1',
autoValue : '1.5.4',
autoValueParcel : '0.2.5',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.mapbox.api.directions.v5.models.RouteOptions;
import com.mapbox.geojson.Point;
import com.mapbox.navigator.FixLocation;
import com.mapbox.navigator.Navigator;
import com.mapbox.services.android.navigation.v5.milestone.BannerInstructionMilestone;
import com.mapbox.services.android.navigation.v5.milestone.Milestone;
import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
Expand All @@ -35,6 +34,7 @@
import com.mapbox.services.android.navigation.v5.route.FasterRouteListener;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.snap.Snap;
import com.mapbox.services.android.navigation.v5.utils.ValidationUtils;

import java.util.ArrayList;
import java.util.Date;
Expand Down Expand Up @@ -187,7 +187,7 @@ private void initializeForTest() {
*/
private void initialize() {
// Initialize event dispatcher and add internal listeners
synchronizedNavigator = new SynchronizedNavigator(new Navigator());
synchronizedNavigator = new SynchronizedNavigator();
navigationEventDispatcher = new NavigationEventDispatcher();
navigationEngineFactory = new NavigationEngineFactory();
initializeDefaultLocationEngine();
Expand Down Expand Up @@ -421,84 +421,6 @@ public void startNavigation(@NonNull DirectionsRoute directionsRoute) {
startNavigationWith(directionsRoute);
}

public void initializeOfflineData(String tileFilePath, String translationsDirPath) {
synchronizedNavigator.retrieveNavigator().configureRouter(tileFilePath, translationsDirPath);

// Prime Navigator
ArrayList<FixLocation> nullIsland = new ArrayList<>();
nullIsland.add(buildFixLocationFrom(Point.fromLngLat(0.0, 0.0)));
nullIsland.add(buildFixLocationFrom(Point.fromLngLat(0.0, 0.0)));
synchronizedNavigator.getRoute(nullIsland);
}

@Nullable
public DirectionsRoute findOfflineRouteFor(@Nullable Location currentLocation,
ArrayList<Point> waypoints) {
ArrayList<FixLocation> fixLocations = buildFixLocationListFrom(currentLocation, waypoints);
String responseJson = synchronizedNavigator.getRoute(fixLocations);
if (responseJson.contains("error")) {
JsonObject jsonObject = new JsonParser().parse(responseJson).getAsJsonObject();
Timber.e("Error occurred fetching offline route: %s - Code: %s",
jsonObject.get("error").getAsString(),
jsonObject.get("error_code").getAsString());
return null;
}
DirectionsRoute route = DirectionsResponse.fromJson(responseJson).routes().get(0);
return route.toBuilder().routeOptions(generateRouteOptionsFrom(fixLocations)).build();
}

private RouteOptions generateRouteOptionsFrom(List<FixLocation> fixLocations) {
List<Point> coordinates = new ArrayList<>();
for (FixLocation fixLocation : fixLocations) {
coordinates.add(fixLocation.getLocation());
}
return RouteOptions.builder()
.accessToken(accessToken)
.baseUrl("valhalla_base_url")
.requestUuid("valhalla")
.user("test_user")
.geometries("valhalla_geometries")
.coordinates(coordinates)
.profile(DirectionsCriteria.PROFILE_DRIVING)
.voiceInstructions(true)
.bannerInstructions(true)
.build();
}

private ArrayList<FixLocation> buildFixLocationListFrom(@Nullable Location currentLocation,
ArrayList<Point> waypoints) {
ArrayList<FixLocation> fixLocations = new ArrayList<>();
if (currentLocation != null) {
fixLocations.add(buildFixLocationFrom(currentLocation));
}
for (Point point : waypoints) {
fixLocations.add(buildFixLocationFrom(point));
}
return fixLocations;
}

private FixLocation buildFixLocationFrom(Location location) {
Point point = Point.fromLngLat(location.getLongitude(), location.getLatitude());
return new FixLocation(
point,
new Date(location.getTime()),
location.getSpeed(),
location.getBearing(),
(float) location.getAltitude(),
location.getAccuracy(),
"mapbox_navigation"
);
}

private FixLocation buildFixLocationFrom(Point point) {
return new FixLocation(
point,
new Date(),
0f, 0f, 0f, 0f,
"mapbox_navigation"
);
}

/**
* Call this when the navigation session needs to end before the user reaches their final
* destination. There isn't a need to manually end the navigation session using this API when the
Expand All @@ -524,6 +446,49 @@ public void stopNavigation() {
}
}

/**
* Initializes the offline data used for fetching offline routes.
* <p>
* This method must be called before {@link MapboxNavigation#findOfflineRouteFor(Location, ArrayList)}.
*
* @param tileFilePath path to directory containing tile data
* @param translationsDirPath path to directory containing OSRMTI translations
*/
public void initializeOfflineData(String tileFilePath, String translationsDirPath) {
synchronizedNavigator.configureRouter(tileFilePath, translationsDirPath);
}

/**
* Once {@link MapboxNavigation#initializeOfflineData(String, String)} has been called, you may
* call this method to retrieve routes without internet connectivity.
* <p>
* This first parameter, <code>currentLocation</code>, is optional and is used when provided to find a more
* accurate route (for example, in the direction of the location bearing).
*
* @param currentLocation optional to increase route accuracy
* @param waypoints of the route
* @return an offline <code>DirectionsRoute</code>
*/
@Nullable
public DirectionsRoute findOfflineRouteFor(@Nullable Location currentLocation,
ArrayList<Point> waypoints) {
ArrayList<FixLocation> fixLocations = buildFixLocationListFrom(currentLocation, waypoints);
if (fixLocations.size() < 2) {
Timber.e("Error occurred fetching offline route: invalid way point data");
return null;
}
String responseJson = synchronizedNavigator.getRoute(fixLocations);
if (responseJson.contains("error")) {
JsonObject jsonObject = new JsonParser().parse(responseJson).getAsJsonObject();
Timber.e("Error occurred fetching offline route: %s - Code: %s",
jsonObject.get("error").getAsString(),
jsonObject.get("error_code").getAsString());
return null;
}
DirectionsRoute route = DirectionsResponse.fromJson(responseJson).routes().get(0);
return route.toBuilder().routeOptions(generateRouteOptionsFrom(fixLocations)).build();
}

// Listeners

/**
Expand Down Expand Up @@ -909,9 +874,9 @@ SynchronizedNavigator retrieveSynchronizedNavigator() {
}

private void startNavigationWith(@NonNull DirectionsRoute directionsRoute) {
// ValidationUtils.validDirectionsRoute(directionsRoute, options.defaultMilestonesEnabled());
ValidationUtils.validDirectionsRoute(directionsRoute, options.defaultMilestonesEnabled());
this.directionsRoute = directionsRoute;
synchronizedNavigator.retrieveNavigator().setDirections(directionsRoute.toJson());
synchronizedNavigator.setRoute(directionsRoute.toJson());
if (!isBound) {
navigationTelemetry.startSession(directionsRoute);
startNavigationService();
Expand Down Expand Up @@ -939,6 +904,58 @@ private boolean isServiceAvailable() {
return navigationService != null && isBound;
}

private RouteOptions generateRouteOptionsFrom(List<FixLocation> fixLocations) {
List<Point> coordinates = new ArrayList<>();
for (FixLocation fixLocation : fixLocations) {
coordinates.add(fixLocation.getLocation());
}
return RouteOptions.builder()
.accessToken(accessToken)
.baseUrl("valhalla_base_url")
.requestUuid("valhalla")
.user("test_user")
.geometries("valhalla_geometries")
.coordinates(coordinates)
.profile(DirectionsCriteria.PROFILE_DRIVING)
.voiceInstructions(true)
.bannerInstructions(true)
.build();
}

private ArrayList<FixLocation> buildFixLocationListFrom(@Nullable Location currentLocation,
ArrayList<Point> waypoints) {
ArrayList<FixLocation> fixLocations = new ArrayList<>();
if (currentLocation != null) {
fixLocations.add(buildFixLocationFrom(currentLocation));
}
for (Point point : waypoints) {
fixLocations.add(buildFixLocationFrom(point));
}
return fixLocations;
}

private FixLocation buildFixLocationFrom(Location location) {
Point point = Point.fromLngLat(location.getLongitude(), location.getLatitude());
return new FixLocation(
point,
new Date(location.getTime()),
location.getSpeed(),
location.getBearing(),
(float) location.getAltitude(),
location.getAccuracy(),
"mapbox_navigation"
);
}

private FixLocation buildFixLocationFrom(Point point) {
return new FixLocation(
point,
new Date(),
0f, 0f, 0f, 0f,
"mapbox_navigation"
);
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Timber.d("Connected to service.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@ class SynchronizedNavigator {

private final Navigator navigator;

SynchronizedNavigator(Navigator navigator) {
this.navigator = navigator;
SynchronizedNavigator() {
this.navigator = new Navigator();
}

Navigator retrieveNavigator() {
return navigator;
synchronized void configureRouter(String tileFilePath, String translationsDirPath) {
navigator.configureRouter(tileFilePath, translationsDirPath);
}

synchronized String getRoute(ArrayList<FixLocation> waypoints) {
return navigator.getRoute(waypoints);
}

synchronized NavigationStatus setRoute(String routeJson) {
return navigator.setDirections(routeJson);
}

synchronized NavigationStatus getStatus(Date date) {
return navigator.getStatus(date);
}
Expand Down

0 comments on commit 81571d9

Please sign in to comment.