Car and Pedestrian Routing

The Sygic Android SDK supports route calculation with multiple waypoints, optimized for walking or driving. A route describes a path between at least two waypoints, the starting point and the destination, with optional intermediate waypoints in between. Most of the managers need to be called asynchronously.
Applications can provide route information to users in two ways:

  • A line rendered on a map that displays a connecting path between all waypoints
  • Turn-by-turn directions in text format

RoutePlan is class containing all info about the route we want to calculate. It contains start, finish, viapoints and another route options.

RoutePlan routePlan = new RoutePlan();
routePlan.setStart(map.geoCoordinatesFromPoint(x1, y1));
routePlan.setDestination(map.geoCoordinatesFromPoint(x2, y2)); // x,y are screen coordinates

To receive notifications about progress of route computing, you can register RouteComputeListener. Convenience class RouteComputeAdapter is provided, so you can override only those methods you need. Please note that the onProgress callback gets continuous progress only in offline mode as the online routing's progress cannot be tracked.

mRouteComputeListener = new Router.RouteComputeListener() {
    @Override
    public void onComputeError(Router router, @Router.RouteComputeError int error) {
    }

    @Override
    public void onProgress(Router router, int progress, int routeIndex) {
        // update progress
    }

    @Override
    public void onComputeStarted(Router router) {
    }

    @Override
    public void onPrimaryComputeFinished(Router router, Route route) {
        // called when primary route is calculated
    }

    @Override
    public void onAlternativeComputeFinished(Router router, Route route) {
        // called when any alternative route is calculated. Can be called more than once
    }

    @Override
    public void onComputeFinished(Router router){
        // called when all routes are calculated
    }

    @Override
    public void onRecomputeStarted() {
        // called when recompute was invoked. Recompute can be invoked after leaving computed route
    }

    @Override
    public void onRecomputeFinished(Route route, @Router.RecomputeType int type) {
    }
};

And you can compute your route:

RouterProvider.getInstance(new InitializationCallback<Router>() {
    @Override
    public void onInstance(@NonNull Router router) {
        mRouter = router;
        mRouter.computeRoute(routePlan, mRouteComputeListener);
    }
    @Override
    public void onError(int i) {
    }
});

Then you can set you route for navigation.

NavigationManagerProvider.getInstance(new InitializationCallback<NavigationManager>() {
    @Override
    public void onInstance(@NonNull NavigationManager navigationManager) {
        navigationManager.setRouteForNavigation(mRoute); // mRoute is Route obtained via onComputeFinished() method
    }
    @Override
    public void onError(int i) {
    }
}); 

Sygic SDK supports alternative routes between two waypoints. This allows more than one route to be returned after a route calculation.

Handling rerouting can be done using the NavigationManager's onRouteChanged listener. Setting the new route for navigation is handled internally, all you need to do is check if the new route is not null, remove the old MapRoute and add the new one. Of course, if you have stored the RoutePlan or the RouteInfo, you need to assign the new ones to your variables and also you can update the traffic data for route etc.

The MapRoute map object

The MapRoute class is a type of MapObject that displays a calculated route on a map. Typically, an application creates a MapRoute after a route calculation, passing the relevant Route object as a parameter to the MapRoute(Route) constructor before adding the MapRoute to the map by calling MapView.addMapObject(MapRoute).

For primary route:

MapRoute primaryRoute = MapRoute.from(route).setType(MapRoute.RouteType.Primary).build(); // route is obtained via onPrimaryComputeFinished() method in RouteComputeListener
map.GetMapDataModel().addMapObject(mapRoute);

For alternative route:

MapRoute alternativeRoute = MapRoute.from(route).setType(MapRoute.RouteType.Alternative).build(); // route is obtained via onAlternativeComputeFinished() method in RouteComputeListener
map.GetMapDataModel().addMapObject(mapRoute);

// removing
map.GetMapDataModel().removeMapObject(mapRoute);

You can also process the Route without using it in map, eg. to get textual instructions:

StringBuilder instructionsList = new StringBuilder();
for (RouteManeuver maneuver : route.getManeuvers()) {
    switch (maneuver.getType()) {
        case RouteManeuver.Type.Left:
            instructionsList.append("Turn left onto ").append(maneuver.getNextRoadName()).append('\n');
            break;
        case RouteManeuver.Type.RoundaboutN:
            instructionsList.append("On the roundabout, continue straight with exit #")
                    .append(maneuver.getRoundaboutExit()).append('\n');
            break;
        // ...
    }
}

Route Serialization

If you wish to save a route you have computed, you can use Route.serializeToBriefJSON()

String json = route.serializeToBriefJSON();
// use the serialized route - save it to a file, send it over network, sky is the limit...

To deserialize the json and get the Route you can use Router.computeRouteFromJSONString().

mRouter.computeRouteFromJSONString(json, new Router.RouteComputeAdapter() {
    @Override
    public void onPrimaryComputeFinished(final Router router, final Route route) {
        // use route
    }
});

You can also extract RoutePlan first, eg. if you want to edit it before computing:

RoutePlan routePlan = mRouter.createRoutePlanFronJSONString(json);
routePlan.addViaPoint(new GeoCoordinates(51.515436, -0.122045));
mRouter.computeRoute(routePlan, mRouteComputeListener);

Routing Options

You can edit parameters of route before computing using RoutingOptions.

RoutingOptions options = new RoutingOptions();
options.setTransportMode(RoutingOptions.TransportMode.Car);
options.setRoutingType(RoutingOptions.RoutingType.Economic);

routePlan.setRoutingOptions(options);
mRouter.computeRoute(routePlan, mRouteComputeListener);

Avoids

To avoid certain elements on route like toll roads or unpaved roads, you can set flags on RoutingOptions.

RoutingOptions options = new RoutingOptions();
options.setTollRoadAvoided(true);
options.setUnpavedRoadAvoided(true);

routePlan.setRoutingOptions(options);
mRouter.computeRoute(routePlan, mRouteComputeListener);

After the route is computed, you can extract RoutingOptions from Route in order to further edit the route. You can eg. get countries on route and set avoids individually for each, or you can avoid country altogether as shown below.

RoutingOptions routingOptions = route.getRoutingOptions();
Set<String> avoidableCountries = routingOptions.getAvoidableCountries();

for (final String country : avoidableCountries) {
    if (country.equals("fr")) {
        routingOptions.setTollRoadAvoided("fr", true);
    }
    if (country.equals("ch")) {
        routingOptions.getDynamicPenalty().addCountryAvoid("ch");
    }
}

routePlan.setRoutingOptions(routingOptions);
mRouter.computeRoute(routePlan, mRouteComputeListener);