Skip to content
Closed
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
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,34 @@ try {
>
> To avoid this, ensure that the SDK has provided a valid user location before calling the setDestinations function. You can do this by subscribing to the onLocationChanged navigation callback and waiting for the first valid location update.

### Using Custom Routes with Route Tokens

The Navigation SDK supports custom routes generated by the [Google Routes API](https://developers.google.com/maps/documentation/routes). You can create a route using the Routes API and then pass the generated route token to the Navigation SDK:

```tsx
try {
// First, obtain a route token from the Google Routes API
// This is typically done on your backend server
const routeToken = "your_route_token_from_routes_api";

const displayOptions = {
showDestinationMarkers: true,
showStopSigns: true,
showTrafficLights: true,
};

await navigationController.setRouteToken(routeToken, displayOptions);
await navigationController.startGuidance();
} catch (error) {
console.error("Error starting navigation with route token", error);
}
```

> [!NOTE]
> Route tokens must be generated using the Google Routes API. For more information on generating route tokens, see the [Routes API documentation](https://developers.google.com/maps/documentation/routes/overview).




#### Adding navigation listeners

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,40 @@ public void onResult(Navigator.RouteStatus code) {
});
}

@ReactMethod
public void setRouteToken(
String routeToken,
@Nullable ReadableMap displayOptions) {
if (mNavigator == null) {
// TODO: HANDLE THIS
return;
}

pendingRoute = null; // reset pendingRoute
mWaypoints.clear(); // reset waypoints

UiThreadUtil.runOnUiThread(
() -> {
if (displayOptions != null) {
pendingRoute =
mNavigator.setDestinationsWithRouteToken(
routeToken,
ObjectTranslationUtil.getDisplayOptionsFromMap(displayOptions.toHashMap()));
} else {
pendingRoute = mNavigator.setDestinationsWithRouteToken(routeToken);
}

setOnResultListener(
new IRouteStatusResult() {
@Override
public void onResult(Navigator.RouteStatus code) {
sendCommandToReactNative("onRouteStatusResult", code.toString());
}
});
});
}


@ReactMethod
public void clearDestinations() {
if (mNavigator != null) {
Expand Down
26 changes: 26 additions & 0 deletions example/src/controls/navigationControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,27 @@ const NavigationControls: React.FC<NavigationControlsProps> = ({
navigationController.clearDestinations();
};

const setCustomRouteWithToken = () => {
// Example route token - in practice, this would come from your Routes API call
const exampleRouteToken = 'route_token_from_google_routes_api';

const displayOptions: DisplayOptions = {
showDestinationMarkers: true,
showStopSigns: true,
showTrafficLights: true,
};

try {
navigationController.setRouteToken(exampleRouteToken, displayOptions);
Alert.alert(
'Route Token',
'Custom route set with route token (this is just an example)'
);
} catch (error) {
Alert.alert('Error', 'Failed to set route token: ' + error);
}
};

const startSimulation = () => {
navigationController.simulator.simulateLocationsAlongExistingRoute({
speedMultiplier: 5,
Expand Down Expand Up @@ -363,6 +384,11 @@ const NavigationControls: React.FC<NavigationControlsProps> = ({
<Button title="Set target as Destination" onPress={initWaypoint} />
<View style={styles.controlButtonGap} />
<Button title="Set multiple destinations" onPress={initWaypoints} />
<Button
title="Set route with token (example)"
onPress={setCustomRouteWithToken}
/>

<Button title="Dispose navigation" onPress={disposeNavigation} />
<Button
title="Continue to next destination"
Expand Down
38 changes: 38 additions & 0 deletions ios/react-native-navigation-sdk/NavModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,44 @@ - (void)showTermsAndConditionsDialog {
});
}

RCT_EXPORT_METHOD(setRouteToken
: (nonnull NSString *)routeToken displayOptions
: (NSDictionary *)displayOptions resolve
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
reject(@"internal_error", @"An internal error occurred", nil);
return;
}

GMSNavigator *navigator = nil;
if (![strongSelf checkNavigatorWithError:reject navigator:&navigator]) {
return;
}

if (displayOptions != NULL) {
[self setDisplayOptionsToViews:displayOptions];
}

// Clear existing destinations
strongSelf->_destinations = [[NSMutableArray alloc] init];

void (^routeStatusCallback)(GMSRouteStatus) = ^(GMSRouteStatus routeStatus) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) return;
[strongSelf onRouteStatusResult:routeStatus];
resolve(@(YES));
};

// Use the route token to set destinations
[navigator setDestinations:@[] routeToken:routeToken callback:routeStatusCallback];
});
}


- (void)setDisplayOptionsToViews:(NSDictionary *)options {
for (NavViewController *viewController in [NavViewModule sharedInstance]
.viewControllers.allValues) {
Expand Down
Loading