Routing
This chapter describes how to build a route for different types of transport and display it on the map. To build any type of route, you need to define the following components:
- Route points: the starting one, the finishing one, and (if needed) intermediate ones. Ways of getting point coordinates are described below.
- Route search parameters. A set of parameters depends on the transport type that the route is built for.
Building a route
To build a route on the map, you need to create two objects:
- TrafficRouter object to find an optimal route.
- RouteMapObjectSource data source to display the route on the map.
To find a route between two points, call the findRoute() method, specifying the coordinates of the start points and the end points as RouteSearchPoint objects. You can additionally specify route parameters (RouteSearchOptions) and a list of intermediate points of the route (a list of RouteSearchPoint objects).
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final routeSearchOptions = sdk.RouteSearchOptions.car(sdk.CarRouteSearchOptions());
final startPoint = sdk.RouteSearchPoint(coordinates: GeoPoint(latitude: 55.759909, longitude: 37.618806));
final finishPoint = sdk.RouteSearchPoint(coordinates: GeoPoint(latitude: 55.752425, longitude: 37.613983));
final trafficRouter = sdk.TrafficRouter(sdkContext);
final routesFuture = trafficRouter.findRoute(startPoint, finishPoint, routeSearchOptions);
The call returns a deferred result with a list of TrafficRoute objects. To display the found route on the map, you need to use these objects to create RouteMapObject objects and add them to a RouteMapObjectSource data source.
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
// Create a data source
final sdk.RouteMapObjectSource routeMapObjectSource = sdk.RouteMapObjectSource(sdkContext, RouteVisualizationType.NORMAL)
map.addSource(routeMapObjectSource)
// Find a route
final trafficRouter = sdk.TrafficRouter(sdkContext);
final List<sdk.TrafficRoute> routes = await trafficRouter.findRoute(startSearchPoint, finishSearchPoint).value;
// After receiving the route, add it to the map
int routeIdx = 0;
bool isActive = true;
routes.forEach((sdk.TrafficRoute route) {
routeMapObjectSource.addObject(sdk.RouteMapObject(route, isActive, routeIdx));
routeIdx += 1;
isActive = false;
})
Instead of using TrafficRouter and RouteMapObjectSource objects and manually processing a list of TrafficRoute objects, you can use RouteEditor and RouteEditorSource objects. In that case, you can simply pass the coordinates of the route as a RouteEditorRouteParams object to the setRouteParams() method. The route displays automatically.
final routeEditor = sdk.RouteEditor(sdkContext);
final routeEditorSource = sdk.RouteEditorSource(sdkContext, routeEditor);
map.addSource(routeEditorSource);
routeEditor.setRouteParams(
sdk.RouteEditorRouteParams(
startPoint: startPoint,
finishPoint: finishPoint,
routeSearchOptions: routeSearchOptions,
),
);
Route points
To build a route, you need to get GeoPoint points, which are used to create a RouteSearchPoint object. One of the ways to do this is described below.
Getting coordinates of an object at the tap spot

You can get the coordinates of the object (e.g., building, road) at the place where the user taps on the map. Use the getRenderedObjects() method to get a DgisMapObject object with an id
field. This identifier is a stable numeric identifier of the object directory that can help you perform a search query and get information about the object, including the geographical coordinates of its center.
import 'package:dgis_mobile_sdk_map/dgis.dart' as sdk;
map.getRenderedObjects(sdk.ScreenPoint()).then((List<sdk.RenderedObjectInfo> info) {
// Get the closest object to the tap spot inside the specified radius
final sdk.RenderedObject obj = info.first.item;
// In this example, we want to search for information about the selected object in the directory.
// To do this, make sure that the type of this object can be found
if (obj.source is sdk.DgisSource && obj.item is sdk.DgisMapObject) {
final source = obj.source as sdk.DgisSource;
// Search
final foundObject =
await sdk.SearchManager.createOnlineManager(sdkContext)
.searchByDirectoryObjectId((obj.item as sdk.DgisMapObject).id)
.value;
final sdk.GeoPoint? geoPoint = foundObject.markerPosition?.point;
}
});
Important
Coordinates of a center of a large object (for example, long and complicated ring roads) can be located far away from the camera viewport as the received object does not contain information on the camera location or the map tap spot. In such cases, use other methods to get coordinates.
Passing intermediate points
For a route with intermediate points, a user is expected to visit each point in the defined order. If an intermediate point is missed, a route may be rebuilt:
- If the GPS data shows that the user is moving not in the direction of the expected intermediate point, the route is rebuilt relatively to the current user location so that they visit the missed point. When the visit of the intermediate point is detected, the route continues.
- If the moment of visiting the intermediate point is not detected due to a weak GPS signal but later the user location is detected on the route or next to it towards the next point, the previous intermediate point is considered visited and the route continues.
Route search parameters
For cars
To build a route for a car, specify the car
property in RouteSearchOptions. Additionally, you can configure route search parameters CarRouteSearchOptions:
avoidTollRoads
: whether to avoid toll roads (false
by default).avoidUnpavedRoads
: whether to avoid unpaved roads (false
by default).avoidFerries
: whether to avoid ferry crossings (false
by default).avoidLockedRoads
: whether to avoid roads that are closed for passage (true
by default).routeSearchType
: a way of considering traffic jam data when building a route. You can build a route based on real-time (jam
) or statistical (statistic
) traffic jam data or you can build the shortest route in distance even if it is not optimal in time (shortest
).excludedAreas
: a list of areas (not more than 25) to avoid when building a route. For details, see the Excluding areas section below.
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final carOptions = sdk.CarRouteSearchOptions(
avoidTollRoads: true,
avoidUnpavedRoads: true,
avoidFerries: true,
avoidLockedRoads: true,
routeSearchType: sdk.RouteSearchType.jam,
excludedAreas: []
);
final routeSearchOptions = sdk.RouteSearchOptions.car(carOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
For taxi
To build a route for a taxi, specify the taxi
property in RouteSearchOptions.
Additionally, you can configure route search parameters TaxiRouteSearchOptions. To build a taxi route, you need to define search parameters for common car routes first and then reuse them in the car
parameter:
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final taxiOptions = sdk.TaxiRouteSearchOptions(
car: carOptions
);
final routeSearchOptions = sdk.RouteSearchOptions.taxi(taxiOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
For trucks
To build a route for a truck, specify the truck
property in RouteSearchOptions. Additionally, you can configure route search parameters TruckRouteSearchOptions:
car
: common parameters for any car routes: see search parameters for car routes.truckLength
: truck length in millimeters.truckHeight
: truck height in millimeters.truckWidth
: truck width in millimeters.actualMass
: actual mass of the truck in kilograms.maxPermittedMass
: maximum permitted of a truck in kilograms.axleLoad
: axle load in kilograms.dangerousCargo
: whether dangerous cargo is transported (false
by default).explosiveCargo
: whether explosive cargo is transported (false
by default).passIds
: a list of IDs of the passes that allow the truck to drive through pass zones (TruckPassZonePassId).fallbackOnCar
: whether to switch to car routing if a truck route with specified parameters cannot be built (false
by default).
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final truckOptions = sdk.TruckRouteSearchOptions(
car: carOptions,
truckLength: 12000, // 12 meters
truckHeight: 4200, // 4.2 meters
truckWidth: 2500, // 2.5 meters
actualMass: 18000, // 18 tons
maxPermittedMass: 20000, // 20 tons
axleLoad: 8000, // 8 tons
dangerousCargo: true,
explosiveCargo: false,
passIds: <sdk.TruckPassZonePassId>{},
fallbackOnCar: true
);
final routeSearchOptions = sdk.RouteSearchOptions.truck(truckOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
For public transport
To build a route for a public transport, specify the publicTransport
property in RouteSearchOptions. Additionally, you can configure route search parameters PublicTransportRouteSearchOptions:
startTime
: route start time in UTC. If not specified, the current time is used.useSchedule
: whether to consider the public transport schedule.transportTypes
: a list of public transport types that can be used for completing the route. If the list is empty, a route is built for all supported transport types. See the full list of types in PublicTransportTypeOptionSet.
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final publicTransportOptions = sdk.PublicTransportRouteSearchOptions(
startTime: DateTime.now().toUtc(),
useSchedule: true,
transportTypes: sdk.PublicTransportTypeEnumSet({
sdk.PublicTransportType.bus,
sdk.PublicTransportType.trolleybus,
sdk.PublicTransportType.tram,
sdk.PublicTransportType.metro,
sdk.PublicTransportType.suburbanTrain,
});
);
final routeSearchOptions = sdk.RouteSearchOptions.publicTransport(publicTransportOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
For bicycles
To build a route for a bicycle, specify the bicycle
property in RouteSearchOptions. Additionally, you can configure route search parameters BicycleRouteSearchOptions:
avoidCarRoads
: whether to avoid car roads (false
by default).avoidStairways
: whether to avoid stairways (false
by default).avoidUnderpassesAndOverpasses
: whether to avoid underpasses and overpasses (false
by default).excludedAreas
: a list of areas (not more than 25) to avoid when building a route. For details, see the Excluding areas section below.
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final bicycleOptions = sdk.BicycleRouteSearchOptions(
avoidCarRoads: true,
avoidStairways: true,
avoidUnderpassesAndOverpasses: true,
excludedAreas: []
);
final routeSearchOptions = sdk.RouteSearchOptions.bicycle(bicycleOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
For scooters
To build a route for a scooter, specify the scooter
property in RouteSearchOptions. Additionally, you can configure route search parameters ScooterRouteSearchOptions:
avoidCarRoads
: whether to avoid car roads (true
by default).avoidStairways
: whether to avoid stairways (true
by default).avoidUnderpassesAndOverpasses
: whether to avoid underpasses and overpasses (true
by default).excludedAreas
: a list of areas (not more than 25) to avoid when building a route. For details, see the Excluding areas section below.
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final scooterOptions = sdk.ScooterRouteSearchOptions(
avoidCarRoads: true,
avoidStairways: true,
avoidUnderpassesAndOverpasses: true,
excludedAreas: []
);
final routeSearchOptions = sdk.RouteSearchOptions.scooter(scooterOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
For pedestrians
Pedestrian routes can include moving inside a building (for example, you can build a route to a specific shop in a shopping mall). If some route point is located indoors, you must specify additional parameters for it: objectId
(ID of the object to build a route to) and levelId
(ID of the building floor where the object is located).
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final finishPoint = sdk.RouteSearchPoint(
coordinates: GeoPoint(latitude: 55.752425, longitude: 37.613983),
objectId: sdk.DgisObjectId(
objectId: 67890,
entranceId: 2
),
levelId: sdk.LevelId(value: 3));
For more information about indoor navigation, see the Navigation chapter.
To build a pedestrian route, specify the pedestrian
property in RouteSearchOptions. Additionally, you can configure route search parameters PedestrianRouteSearchOptions:
avoidStairways
: whether to avoid stairways (false
by default).avoidUnderpassesAndOverpasses
: whether to avoid underpasses and overpasses (false
by default).useIndoor
: whether to build indoor routes (true
by default).excludedAreas
: a list of areas (not more than 25) to avoid when building a route. For details, see the Excluding areas section below.
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
final pedestrianOptions = sdk.PedestrianRouteSearchOptions(
avoidStairways: false,
avoidUnderpassesAndOverpasses: false,
useIndoor: false,
excludedAreas: []
);
final routeSearchOptions = sdk.RouteSearchOptions.pedestrian(pedestrianOptions);
Pass the created routeSearchOptions
to the findRoute()
function call when building a route.
Excluding areas
To exclude a specific area when building a route, create an ExcludedArea object with the following parameters:
type
: geometry of the excluded area. See the list of available values in ExcludedAreaType.severity
: priority of excluding the area (how critical it is to avoid the area). See the list of available values in ExcludedAreaSeverity.extent
: size of the excluded area (not more than 25 km).points
: coordinates of excluded area points of the GeoPoint type (not more than 500).
Example of an excluded polygon:
import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;
// Polygon vertices
final points = [
sdk.GeoPoint(latitude: 55.759909, longitude: 37.618806),
sdk.GeoPoint(latitude: 55.752425, longitude: 37.613983),
sdk.GeoPoint(latitude: 55.753567, longitude: 37.622995),
sdk.GeoPoint(latitude: 55.760523, longitude: 37.625613)
];
final polygonExcludedArea = sdk.ExcludedArea(
type: sdk.ExcludedAreaType.polygon,
severity: sdk.ExcludedAreaSeverity.hard,
extent: sdk.RouteDistance(500.0),
points: points
);
Offline mode
By default, routing works in hybrid mode: using data from Urbi servers is prioritized. If a route cannot be built from online data after a defined timeout, preloaded data is used.
To load data for offline usage, you must get respective rights for your access key and download required territories. See preparation steps for working with offline data.