Introduction
This is the last of three tutorials on designing a mapping application for mobile devices. The first tutorial in this series can be found here; the second tutorial can be found here.
The focus of this tutorial is advanced routing techniques. Routing is the process of selecting a route (path) through a road network. By default GeoBase will look for the fastest route, although this behavior can be modified to find the shortest route, or a route that matches criteria you specify.
Typically you would adjust the Route object's RoutingStrategy or VehicleSpec to control routing behavior. In this tutorial we will use a VehicleSpec to prevent GeoBase from routing our (hypothetical) truck under low bridges. Then, we will modify the routingStrategy to avoid toll-roads, U-turns and discourage road-crossings.
For a comprehensive description of GeoBase routing features please refer to the GeoBase API documentation. This documentation is included with your GeoBase installation and is also available online: http://docs.geobase.info/
Truck Attributes
GeoBase maps contain metadata that allows features (such as roads, tunnels and bridges) to be described in significant detail. This detail allows GeoBase to prevent vehicles from travelling along inappropriate routes. To do this, GeoBase must be given a description of the vehicle. This can be done using the VehicleSpec enumeration. Attributes supported in the VehicleSpec structure include:
- Vehicle height, length and width
- Unladen and gross vehicle weights
- Vehicle type (such as truck, emergency vehicle or bus)
In the code section below we will create a VehicleSpec describing a typical truck, and apply the VehicleSpec to our Navigator (which, in turn, is managed by our NavigationManager). This means that any route the NavigationManager calculates will be suitable for the truck described in the VehicleSpec.
Code
Open your Visual Studio mobile device project from the previous tutorial in this series. Open Form1 in the form designer. Add a sub-menu item named 'Truck Attributes' to the 'Map' menu item. Beneath the 'Truck Attributes' menu item, add the following three menu items: None, Small Truck and Big Truck.
Each menu item will apply a different VehicleSpec to any route that we create.
None
Append the following line of code to the 'None' menu item's click event. This code will apply an empty VehicleSpec, meaning that routing decisions will not be affected by the size of our vehicle.
nMan.Navigator.VehicleSpec = new VehicleSpec();
Small Truck
Add the following code snippet to the 'Small Truck' menu item's click event. This code will apply a VehicleSpec describing a small truck. Because this truck is small it's unlikely you will notice the effects of routing with this VehicleSpec. However, it is good practice to use the appropriate VehicleSpec where possible to avoid the potential for dangerous and/or damaging situations.
VehicleSpec vs = new VehicleSpec(); vs.Height_cm = MathUtil.ConvertUnitsInt(10.5, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.Width_cm = MathUtil.ConvertUnitsInt(7, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.Length_cm = MathUtil.ConvertUnitsInt(16.5, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.UnladenWeight_kg = 5750; nMan.Navigator.VehicleSpec = vs;
Big Truck
Add the following code snippet to the 'Big Truck' menu item's click event. This code will apply a VehicleSpec describing a truck approximately large enough to transport a 20' shipping container. Note that the VehicleSpec describes the truck as having a single 24' long trailer. This truck is large enough such that variations to accommodate the height and length of the truck
should be quite noticeable in the route generated. An example of this is shown in Figure 1.
VehicleSpec vs = new VehicleSpec(); vs.Height_cm = MathUtil.ConvertUnitsInt(14, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.Width_cm = MathUtil.ConvertUnitsInt(9.5, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.Length_cm = MathUtil.ConvertUnitsInt(37, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.NumberOfTrailers = 1; vs.MaxTrailerLength_cm = MathUtil.ConvertUnitsInt(24, DistanceUnit.FEET, DistanceUnit.CENTIMETERS); vs.UnladenWeight_kg = 8100; nMan.Navigator.VehicleSpec = vs;
Note that the vehicle dimensions are specified in feet and converted to centimeters using the MathUtil.ConvertUnitsInt() method. The MathUtil class contains other useful speed, distance and unit conversion methods.
Testing
Build and run your application. The effect of the VehicleSpec may not be immediately obvious, but to illustrate the importance of a VehicleSpec consider the route near 40.858409, -73.981039 (Fort Lee Rd, Leonia, New Jersey) shown in Figure 1.

Figure 1 Testing using the 'Big Truck' VehicleSpec option
GeoBase has determined that the truck described by our 'Big Truck' VehicleSpec is too tall to fit under the bridge (left-hand image), so GeoBase adjusts the route to avoid the bridge (right-hand image).
Custom Routing Strategies
GeoBase uses a strategy to determine which route is 'optimum'. Often you would access the routing strategy directly through a Route object. However, because we are using a NavigationManager (created in the first tutorial of this series) to manage our routing, we should obtain the routing strategy through the NavigationManager. The code snippet below illustrates this.
nMan.Navigator.Strategy
In this section of the tutorial we will make some common modifications to the routing strategy.
Avoiding U-Turns
U-turns are illegal in many areas. GeoBase can be instructed to avoid U-turns by setting the Route object's AllowUTurns property to false. By default, GeoBase will allow U-turns (Strategy.AllowUTurns = true).
Code
Open Form1 in the form designer. Add a sub-menu item named 'U-Turns' to the 'Map' menu item. Beneath the 'U-Turns' menu item, add the following two menu items:
- Allowed
- Not allowed
In the 'Allowed' menu item's click event, place the following line of code:
nMan.Navigator.Strategy.AllowUTurns = true;
In the 'Not allowed' menu item's click event, place the following line of code:
nMan.Navigator.Strategy.AllowUTurns = false;
Avoiding Toll Roads
Often it is desirable to avoid toll roads to avoid a financial penalty. Using digital map data GeoBase can identify and avoid toll roads. By default, GeoBase will direct the user along a toll road when appropriate (Strategy.UseTollRoads = true).
Code
Open Form1 in the form designer. Add a sub-menu item named 'Toll Roads' to the 'Map' menu item. Beneath the 'Toll Roads' menu item, add the following two menu items:
- Allowed
- Not allowed
In the 'Allowed' menu item's click event, place the following line of code:
nMan.Navigator.Strategy.UseTollRoads = true;
In the 'Not allowed' menu item's click event, place the following line of code:
nMan.Navigator.Strategy.UseTollRoads = false;
Avoiding Road-Crossings
You may wish to discourage (or prevent) left-hand turns across oncoming traffic (or in left-hand drive countries such as England, right-hand turns across oncoming traffic). By preventing these turns (known as 'road-crossings'), it ensures that stops on a route are approached on the side of the road on which the stop lies. This is illustrated in Figure 2.
By forbidding road-crossings, delivery routes (such as those used by postal services) may be created simply by placing a RouteStop on the appropriate side of each road where deliveries should be made and by setting the road-crossing behavior as desired.

Figure 2 - GeoBase prevents turns marked in red for a given road-crossing behavior
The ability to modify the road-crossing behavior is also useful for:
- Waste collection, when the mechanical arm is on a fixed side of the truck
- Deliveries, when it is difficult to turn the truck around after a delivery has been made
- Advertising campaigns, where promotional material is to be delivered only to one side of a street
When road-crossings are discouraged a road-crossing will be avoided unless the cost of avoiding the road-crossing is significantly high, in which case a road-crossing will be allowed. GeoBase's default behavior is to allow road-crossings (RoadCrossingBehavior.Allowed).
Code
Open Form1 in the form designer. Add a sub-menu item named 'Road-Crossing Behavior' to the 'Map' menu item. Beneath the 'Road-Crossing Behavior' menu item, add the following two menu items:
- Allowed
- Forbidden
By selecting an appropriate option, the user will be able to toggle between behaviors as desired. In the 'Allowed' menu item's click event, place the following line of code:
nMan.Navigator.Strategy.RoadCrossingBehavior = RoadCrossingBehavior.Allowed;
In the 'Forbidden' menu item's click event, place the following line of code:
nMan.Navigator.Strategy.RoadCrossingBehavior = RoadCrossingBehavior.Forbidden;
Modifying the LinkCost
When GeoBase is optimizing a route, each link in a street is assigned a 'cost'. This cost usually represents a time penalty incurred by travelling through an intersection or by navigating through a complex road network. By selecting a route with a low cost, GeoBase can generate fast and efficient routes.
Each RouteStrategy object may be assigned a delegate RouteCustomEval function. This is a function that you write to modify the cost of streets matching specific criteria. Your delegate function will be passed a number of important criteria specific to each link. These criteria include:
- Start and end locations of the link, as latitude-longitude coordinates
- Length of the link, in meters
- Cost of travelling this link, as determined by GeoBase
- Time of day that GeoBase estimates this link will be traversed
- RouteFlag objects representing attributes of this link, and the previous link in the road network
Add the following function to your 'Form1.cs' source file. This function will act as our RouteCustomEval delegate. It will use the RouteFlag object to check if this link has only one lane. If this link has more than one lane, the function will double the cost of travelling this link thereby discouraging GeoBase from including this link in the optimum route.
void myCustomEval(LatLon LinkStart, LatLon LinkEnd, float length,
RouteFlag flags, RouteFlag lastFlags, ulong link_id,
LinkCost cumulativeCost, ref LinkCost linkCost,
RoutingStrategy strat, DateTime dateTime, Nullable<Telogis.GeoBase.TimeZone> timeZone){
/* encourage the use of single-lane roads - see Routing.RouteFlag */
if (flags.LANE_CAT != '1') linkCost.addCost(linkCost.Cost);
}
Next, instruct the routing strategy to use this function to evaluate the cost of travelling a link. Add the following line of code to the end of the Form1_Load() method.
nMan.Navigator.Strategy.CustomEvalFunction = new RouteCustomEval (this.myCustomEval);
This example is trivial, but demonstrates that GeoBase provides an advanced yet flexible platform for developing complex navigation and routing applications. It's recommended that you explore the Telogis.GeoBase.Routing.RouteFlags API documentation (included with your GeoBase installation, or available online at http://docs.geobase.info) to discover the criteria you can use to modify GeoBase's routing behavior.
Published, Jun 20th 2010, 20:22
Tagged under: dotnet mobile geobase vehicle attributes and constraints routing navigation maps
