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.
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.

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, RouteInfo route) {
        // called when primary route is calculated
    }

    @Override
    public void onAlternativeComputeFinished(Router router, RouteInfo 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(RouteInfo route, @Router.RecomputeType int type) {
    }
};

And you can compute your route:

mRouter = new Router();
mRouter.computeRoute(routePlan, mRouteComputeListener);

Then you can set you route for navigation.

NavigationManager.getInstance().setRouteForNavigation(mRoute); // mRoute is RouteInfo obtained via onComputeFinished() method

Sygic SDK supports alternate routes between two waypoints. The alternate route feature allows more than one route to be returned after a route calculation.

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 RouteInfo object as a parameter to the MapRoute(RouteInfo) constructor before adding the MapRoute to the map by calling MapView.addMapObject(MapRoute).

For primary route:

MapRoute mapRoute = new MapRoute(routeInfo, MapRoute.RouteType.Primary); // routeInfo  is obtained via onPrimaryComputeFinished() method in RouteComputeListener
map.addMapObject(mapRoute);

For alternative route:

MapRoute mapRoute = new MapRoute(routeInfo, MapRoute.RouteType.Alternative); // routeInfo  is obtained via onAlternativeComputeFinished() method in RouteComputeListener
map.addMapObject(mapRoute);

// removing
map.removeMapObject(mapRoute);

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

StringBuilder instructionsList = new StringBuilder();
for (RouteManeuver maneuver : routeInfo.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;
        // ...
    }
}

If you do not need detailed information about route, but instead only want distance and/or duration, you can use Router.computeRouteStats():

mRouter.computeRouteStats(routePlan, new Router.RouteStatsListener() {
    @Override
    public void onRouteStats(Router router, RouteStats routeStats) {
        int duration = routeStats.getDuration();
        int distance = routeStats.getLength();
    }

    @Override
    public void onComputeError(Router router, @Router.RouteComputeError int error) {}
});

Route Serialization

If you wish to save a route you have computed, you can use RouteInfo.serializeToJSONString()

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

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

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

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 RouteInfo 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 = routeInfo.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);