Get started with routing
Here’s a quick overview of what you can do with routing:
- Calculate routes from a start point to a destination.
- Include intermediary waypoints for multi-stop routes.
- Compute range routes to determine areas reachable within a specific range.
- Plan routes over predefined tracks.
- Customize routes with preferences like route types, restrictions, and more.
- Retrieve maneuvers and turn-by-turn instructions.
- Access detailed route profiles for further analysis.
Calculate routes
You can calculate a route with the code below. This route is navigable, which means that later it is possible to do a navigation/ simulation on it.
// Define the departure.
final departureLandmark =
Landmark.withLatLng(latitude: 48.85682, longitude: 2.34375);
// Define the destination.
final destinationLandmark =
Landmark.withLatLng(latitude: 50.84644, longitude: 4.34587);
// Define the route preferences (all default).
final routePreferences = RoutePreferences();
TaskHandler? taskHandler = RoutingService.calculateRoute(
[departureLandmark, destinationLandmark], routePreferences,
(err, routes) {
if (err == GemError.success) {
showSnackbar("Number of routes: ${routes.length}");
} else if (err == GemError.cancel) {
showSnackbar("Route computation canceled");
} else {
showSnackbar("Error: $err");
}
});
The RoutingService.calculateRoute
method returns null
only when the computation fails to initiate. In such cases, calling RouteService.cancelRoute(taskHandler)
is not possible. Error details will be delivered through the onCompleteCallback
function of the RoutingService.calculateRoute
method.
The err
provided by the callback function can have the following values:
Value | Significance |
---|---|
GemError.success | successfully completed |
GemError.cancel | cancelled by the user |
GemError.waypointAccess | couldn't be found with the current preferences |
GemError.connectionRequired | if allowOnlineCalculation = false in the routing preferences and the calculation can't be done on the client side due to missing data |
GemError.expired | calculation can't be done on client side due to missing necessary data and the client world map data version is no longer supported by the online routing service |
GemError.routeTooLong | routing was executed on the online service and the operation took too much time to complete (usually more than 1 min, depending on the server overload state) |
GemError.invalidated | the offline map data changed ( offline map downloaded, erased, updated ) during the calculation |
GemError.noMemory | routing engine couldn't allocate the necessary memory for the calculation |
The previous example shows how to define your start and end points, set route preferences, and handle the callback for results. If needed, you can cancel the ongoing computation:
RoutingService.cancelRoute(taskHandler);
When the route is canceled, the callback will return err
= GemError.cancel
.
Get ETA and traffic information
Once the route is computed, you can retrieve additional details like the estimated time of arrival (ETA) and traffic information. Here’s how you can access these:
TimeDistance td = route.getTimeDistance(activePart: false);
final totalDistance = td.totalDistanceM;
// same with:
//final totalDistance = td.unrestrictedDistanceM + td.restrictedDistanceM;
final totalDuration = td.totalTimeS;
// same with:
//final totalDuration = td.unrestrictedTimeS + td.restrictedTimeS;
// by default activePart = true
TimeDistance remainTd = route.getTimeDistance(activePart: true);
final totalRemainDistance = remainTd.totalDistanceM;
final totalRemainDuration = remainTd.totalTimeS;
By using the method Route.getTimeDistance
we can get the time and distance for a route. If the activePart
parameter is false
, it means the distance is computed for the entire route initially computed, otherwise it is computed only for the active part (the part still remaining to be navigated). The default value for this parameter is true
.
In the example unrestricted
means the part of the route that is on public property and restricted
the part of the route that is on private property. Time is measured in seconds and distance in meters.
If you want to gather traffic details, you can do so like this:
List<RouteTrafficEvent> trafficEvents = route.trafficEvents;
for (final event in trafficEvents) {
Set<TrafficTransportMode> transportMode = event.affectedTransportModes;
String description = event.description;
TrafficEventClass eventClass = event.eventClass;
TrafficEventSeverity eventSeverity = event.eventSeverity;
Coordinates from = event.from;
Coordinates to = event.to;
bool isRoadBlock = event.isRoadblock;
}
Traffic events provide insights into road conditions, delays, closures, and more. Some events provided by the TrafficEventClass
are:
- trafficRestrictions
- roadworks
- parking
- delays
- accidents
- roadConditions
TrafficEventSeverity
possible values are: stationary, queuing, slowTraffic, possibleDelay, unknown.
Display routes on map
After calculating the routes, they are not automatically displayed on the map. To visualize and center the map on the route, refer to the display routes on maps related documentation. The Maps SDK for Flutter offers extensive customization options, allowing for flexible preferences to tailor the display to your needs.
Get the Terrain Profile
When computing the route we can choose to also build the TerrainProfile
for the route.
In order to do that RoutePreferences
must specify we want to also generate the BuildTerrainProfile
:
final routePreferences = RoutePreferences(
buildTerrainProfile: const BuildTerrainProfile(enable: true),
);
Setting the BuildTerrainProfile
with the enable
flag set to true to the preferences used within calculateRoute
is mandatory for getting route terrain profile data.
Later, use the profile for elevation data or other terrain-related details:
RouteTerrainProfile? terrainProfile = route.terrainProfile;
if (terrainProfile != null) {
double minElevation = terrainProfile.minElevation;
double maxElevation = terrainProfile.maxElevation;
int minElevDist = terrainProfile.minElevationDistance;
int maxElevDist = terrainProfile.maxElevationDistance;
double totalUp = terrainProfile.totalUp;
double totalDown = terrainProfile.totalDown;
// elevation at 100m from the route start
double elevation = terrainProfile.getElevation(100);
for (final section in terrainProfile.roadTypeSections) {
RoadType roadType = section.type;
int startDistance = section.startDistanceM;
}
for (final section in terrainProfile.surfaceSections) {
SurfaceType surfaceType = section.type;
int startDistance = section.startDistanceM;
}
for (final section in terrainProfile.climbSections) {
Grade grade = section.grade;
double slope = section.slope;
int startDistanceM = section.startDistanceM;
int endDistanceM = section.endDistanceM;
}
List<double> categs = [-16, -10, -7, -4, -1, 1, 4, 7, 10, 16];
List<SteepSection> steepSections = terrainProfile.getSteepSections(categs);
for (final section in steepSections) {
int categ = section.categ;
int startDistanceM = section.startDistanceM;
}
}
RoadType
possible values are: motorways, stateRoad, road, street, cycleway, path, singleTrack.
SurfaceType
possible values are: asphalt, paved, unpaved, unknown.
![]() | ![]() |
---|---|
Example showcasing route profile chart | Example showcasing route profile sections |
For more information see the Route Profile example.
Get the route segments and instructions
Once a route has been successfully computed, you can retrieve a detailed list of its segments
. Each segment represents the portion of the route between two consecutive waypoints and includes its own set of route instructions
.
For instance, if a route is computed with five waypoints, it will consist of four segments, each with distinct instructions.
In the case of public transit routes, segments can represent either pedestrian paths or public transit sections.
Here’s an example of how to access and use this information, focusing on some key RouteInstruction
properties:
Field | Type | Explanation |
---|---|---|
traveledTimeDistance | TimeDistance | Time and distance from the beginning of the route. |
remainingTravelTimeDistance | TimeDistance | Time and distance to the end of the route. |
coordinates | Coordinates | The coordinates indicating the location of the instruction. |
remainTravelTimeDistToNextWaypoint | TimeDistance | Time and distance until the next waypoint. |
timeDistanceToNextTurn | TimeDistance | Time and distance until the next instruction. |
turnDetails | TurnDetails | Get full details for the turn. |
turnInstruction | String | Get textual description for the turn. |
roadInfo | List<RoadInfo> | Get road information. |
hasFollowRoadInfo | bool | Check is the road has follow road information. |
followRoadInstruction | String | Get textual description for the follow road information. |
countryCodeISO | String | Get ISO 3166-1 alpha-3 country code for the navigation instruction. |
exitDetails | String | Get the exit route instruction text. |
signpostInstruction | String | Get textual description for the signpost information. |
signpostDetails | SignpostDetails | Get extended signpost details. |
roadInfoImg | RoadInfoImg | Get customizable road image. The user is resposible to check if the image is valid. |
turnImg | Img | Get turn image. The user is resposible to check if the image is valid. |
realisticNextTurnImg | AbstractGeometryImg | Get customizable image for the realistic turn information. The user is resposible to check if the image is valid. |
![]() |
---|
List containing route instructions |
Data from the instruction list above is obtained via the following methods of RouteInstruction
:
turnInstruction
: Bear left onto A 5.followRoadInstruction
: Follow A 5 for 132m.traveledTimeDistance.totalDistanceM
: 6.2km. (after formatting to km)turnDetails.abstractGeometryImg.getRenderableImageBytes(renderSettings: AbstractGeometryImageRenderSettings(),size: Size(100, 100))
: Instruction image or null when image is invalid.