Developing routing functionality

Introduction

Routing is based on a few objects that leverage the NAVMAP data format and its routing capabilities. The core routing objects include a router, stops, barriers, directions, and tracker that can provide a route with turn-by-turn directions and track progress.

A routing service enables routing in the application by referencing a Routing Service file (*.rs extension). A Routing Service file, or RS file, is an XML-formatted file that maps the fields in the streets' network file to the fields required for routing. A Routing Service file also references the routing index files and any other supporting files, such as speed tables and signpost files. The routing service can be initialized by calling the RouterFactoryClass::CreateRouter method, which returns an IRouter object. Once the routing service is initialized, the router can be accessed for route calculations and route tracking. Only one routing service can be defined in a NAVMAP file.

If a routing service is present in the NAVMAP file, a route tracker object can also be initialized. The RouteTracker object is used to track a point along a route and provides information such as a user's progression along the route (time and distance remaining until the next maneuver), the point's current location on the route, and indicates an off-route condition, which can be used to trigger a route resolve. The route tracker is initialized by calling the RouteTrackerFactoryClass::CreateRouteTracker method, which returns IRouteTracker. See the Route tracking section below for more information about how to track along a route.

Routing

The most crucial component of a navigation system is its ability to accurately and rapidly route a client from one location to another, determine if the client strays from the route, and if they are off of the original route, quickly calculate a new route based on their current location.

The Router class, which is referred to as the router throughout this topic, is the key object used to calculate routes and generate driving directions. Initializing the router involves pointing to the location of a RS file on disk. The RS file, which is generally named streets.rs, is an XML-formatted file that maps the fields in the streets'network file to the fields required for routing, and also references the routing index files and any other supporting files, such as speed tables and signpost files.

RouterFactoryClass rfc = new RouterFactoryClass();
      _route = rfc.CreateRouter(@"C:\\data\StreetMap_Mobile\NorthAmerica\NAVTEQ_2011_Q4_NA_Mobile\Streets.rs");

Adding stops

The router calculates a route based on the stops that are passed to it with the StopsCollection object. StopsCollection is a container for Stop objects, which represent individual route stops. Before adding stops to the StopCollection, define the stop properties. At a minimum, the geometry of the stop must be specified by the Stop::geometry property. If only the Point property is defined for the route, then only simple point-to-point routing is available. To enable route tracking and map matching (network snapping), define the StopClass::Bearing, Speed, and Latency properties. Their values can be derived from the GPS connection through the SpeedGroupInfo properties.

Add the stop to the StopCollection using the Add method on IStopCollection. The StopCollection is then passed to the router to be used as the input for the IRouter::Solve method, which generates the route. Additional properties can be set on the Stop object as well, including the Duration and MinTimeToTurn properties. The Duration property is the amount of time, in minutes, that will be spent at the stop. This information is used by the router when calculating the overall drive time for the route, and is also used to determine the arrival time at the destination if the ITripPlanSettings::TripStart property is defined. The MinTimeToTurn property is used to define the minimum time that must be spent on the current road segment before a turn is allowed by the router. For instance, if a vehicle is following a route and misses a turn, the router will not direct the vehicle to turn on the next street if the time to it is less than the MinTimeToTurn value. Instead, the closest street that is an equal or greater time than the MinTimeToTurn is utilized. The purpose of this property is to provide sufficient reaction time when a client is re-routed. Also, of note, is the BearingTolerance property, which limits the streets to which a stop can be snapped based on the orientation of the streets. The acceptable orientation range is the current bearing value of the point +/- the BearingTolerance value. In other words, if the bearing of the point is 90 degrees (due east), and BearingTolerance = 15 degrees, the point only snaps to road segments with an orientation from 75 degrees to 105 degrees that are within the SearchTolerance distance from the point. The SearchTolerance defines the maximum allowed distance from the point's current location oto a road segment that the point can be snapped to.

Stop s = new Stop(result[i].Label, result[i].Coordinate);
        _addresses.Add(s);
        _addressesSketchLayer.GeometryBag.Add(s.Geometry);

Router parameters

There are several other parameters and options that can be defined for the router, including network barriers and restrictions, road type preferences, stop reordering, speed adjustment, trip planning, U-turn policy, and units of length for driving directions. These parameters are defined on the RouterSetupDescriptorClass class, which is accessed from the router through the IRouter::RouterSetup properties.

_route.RouterSetup.BacktrackPolicy = esriSMBacktrackPolicy.esriSMBTPAllow;

Barriers

Barriers are point locations along the network that are impassable by the router. They can represent road closures, traffic accidents, road construction, and so on. Barriers are defined using the IBarrier interface. First the x,y coordinates of the point are defined with the IPoint interface, which is then passed to IBarrier through the IBarrier::Point property. Individual barriers can be added to a barrier Collection, which represents a collection of barriers, through the IBarrierCollection::Add method. The barrier Collection is then passed to the router via the IRouterSetup::Barriers property for inclusion in the route calculation.

Restrictions

Network attribute restrictions are parameters defined by attributes in the street data whose values determine if a particular road segment is passable. Road segments can be restricted based on vehicle dimensions (height or weight restrictions), vehicle type (trucks, emergency vehicles, delivery vehicles, and so on), road type (freeways, paved roads, private roads, carpool lanes), features on roads (ferries, toll roads, bridges, and so on), and time of day and year. Restricted road segments are excluded from the route calculation.

There are two types of attribute restrictions:

.

It is important to note that restrictions are built into the data when the datasets are created, so only those restrictions that were defined at dataset creation will be available. Also note that time-based turn restrictions can only be applied if ITripPlanSettings::TripStartEnable is set to True, and a date/time is specified for ITripPlanSettings::TripStart. A list of network attributes that are available in a particular dataset can be obtained via INetworkAttributeCollection. The values of the attribute restrictions can be set and passed to the route solver by using the Restriction and RestrictionCollection classes.

Route type

The router can calculate the route with the shortest distance or shortest time (quickest). By default, it calculates the quickest route. The route type can be specified by setting the IRouterSetup::ImpedanceAttributeName property, which is a string representing the name of the attribute that is used in the route calculation. The value of the ImpedanceAttributeName can be StaticTime, which causes the quickest route to be calculated, or Length, which causes the shortest path route to be calculated. If this property is not specified, it defaults to StaticTime, resulting in the quickest path route calculation. Note that the Time network attribute can also be used to calculate the quickest route, but it is less efficient than using StaticTime and should only be used if the network speed values will be modified (with ISpeedGroupInfoCollection).

Road preference

A preference for highways or local roads can be defined for the router by using IRoadPreferences, which implements the Preferences property. The highway preference is set by specifying an esriSMRoadPreferences constant for the IRoadPreferences::Preference property. The Preference property requires an esriSMRoadType constant to be specified; in this case, specify esriSMRTHighways as the road type. Road segments are categorized as highways or local roads based on their feature classification code (FCC), which is an attribute in the street data.

Speed adjustment

Road segments are also classified according to the speed of travel allowed on the road, which is an attribute in the street data. The speed value is used by the router to calculate the route's drive time. Speed values can be increased or decreased by using the IRouterSetup::SpeedGroups property. The SpeedGroups property provides access to all of the speeds in the street data through the ISpeedGroupCollection interface. Through this interface individual speeds can be accessed and modified with the ISpeedGroupCollection::Item property, which returns the ISpeedGroup interface. The new speed value can be set with the ISpeedGroup::Speed property.

Trip planning

Time awareness can be configured for the router, which enables various functionality such as estimated time of arrival (ETA) reporting for the route, time-based restrictions, and driving window scheduling for trip planning. This involves specifying a trip start time with the ITripPlanSettings::TripStart property. When this property is set, and the ITripPlanSettings::TripStartEnable property is set to True, time awareness is enabled and ETAs will be reported for each turn in the output driving directions. If time domain information is available in the street data, time-based turn restrictions are also enabled when the TripStart property is set. The ITripPlanSettings interface can only be accessed through the IRouterSetup::TripPlanSettings property. The example below shows how to set the TripStart property.

When time awareness is configured, driving windows can also be defined; this is useful for trip planning, multiple day routes, delivery scheduling, and so on. A driving window represents a range of time when travel takes place. Multiple driving windows can be specified and added to the driving window collection, which is implemented by the ITripPlanSettings::DrivingWindows property.

U-turn policy

The degree to which the router allows U-turns can be configured with the IRouterSetup::BacktrackPolicy property. This property implements the esriSMBacktrackPolicy enumeration, for which there are three possible values: esriSMBTPDisable, which prohibits U-turns unconditionally; esriSMBTPAllow, which allows U-turns at all times unless there is a turn restriction in the data (note that turn restrictions can be disabled using IRouterSetup::Restrictions); and esriSMBTPDeadend allows U-turns at dead ends only. The default is esriSMBTPAllow. See the following example that illustrates how to disable U-turns for the router.

Length units

The length units used for calculating distance in the output driving directions can be configured with the IRouterSetup::DirectionsLengthUnits property, which implements the esriSMDirectionsLengthUnits enumeration. The allowable values are esriSMDLUMiles (miles), esriSMDLUKilometers (kilometers), esriSMDLUMeters (meters), esriSMDLUFeet (feet), and esriSMDLUYards (yards). Miles are the default units.

Output route format

The final parameter that can be configured for the router is the information that is output by the route calculation. The IDirections object output by the route calculation can contain any or all of the following information: the route summary (total driving time and distance), route geometry, and driving direction text. The IRouterSetup::DirectionsContentType property allows the output format to be set by specifying an esriSMDirectionsContentType constant. The allowable values are All, GeometryOnly, SummaryOnly, GeometryAndSummary, and SummaryAndTexts. The default value for the property is esriSMDCTAll.

Driving directions

When a route is calculated, the output consists of textual driving directions, information about the route properties, and the geometry corresponding to each segment of the route. The IRouter::Solve and ITrackingRouter::ReSolve methods, which are used to calculate a route, output an IDirections object, which provides access to detailed information about the route.

Both general and detailed information about the route can be accessed through the IDirections interface. The IDirections::Summary property returns the IDirectionsSummary interface, which provides general information about the entire route, including the total driving distance, driving time, and the extent of the route. Note that there are two different route times output by IDirectionsSummary, represented by the TotalTime and the TotalDrivingTime properties. If trip planning is enabled and multiple driving windows are configured, the TotalDrivingTime value equals the actual time on the road, while the TotalTime value includes non-driving time as well (that is, time between driving windows). For example, in a scenario where driving begins at 8:00 a.m., stops for lunch at 12:00 p.m., begins again at 1:00 p.m., and ends at 6:00 p.m., the TotalTime is 10 hours, while the TotalDrivingTime is nine hours.

The IDirections::Items property returns the IDirectionCollection object, which provides access to each segment of the route through the IDirectionCollection::Item property. The Item property returns the IDirection object, which represents an individual route part and provides access to detailed information about the route part through the IDirection interface. A route part in this context is a portion of a route beginning at a turn and continuing until the next turn. The route part information provided by IDirection includes the textual driving directions, the geometry (represented by an IPointCollection object), the street name, the turn angle, the azimuth of travel, the drive time, the maneuver type (that is, turn right, highway merge, exit, fork, roundabout, and so on), and the extent of the route part. The information provided by IDirection can be used to display a list of driving directions and draw a graphical representation of the route in a mapping application.

Route tracking

An essential component of a navigation system is the ability to track the location of a client along a route and reroute them if they stray from the route.

If a GPS connection is available, progression along the route can be tracked, which allows route recalculation if an off-route condition is detected. Once a GPS connection is successfully made using the mobile GPS namespace, the current location, velocity, and bearing can be determined. These values can then be passed to StopClass to define the properties of a route stop. The idea is to set the current GPS location as the start location for the route. The information passed to StopClass will also be used to snap the current location of the client to the closest and most appropriate road segment that adheres to the stop properties. Consider, for example, a situation where the current speed of travel is 65 miles per hour, and there are two road segments that are equidistant from the location and parallel to each other; one of the segments is a freeway and one is an alley. The stop snaps to the freeway segment because the current speed more closely matches the network attribute speed of the freeway than that of the alley. You can further narrow the road choice for snapping by specifying the IStop::BearingTolerance property, which limits the roads that can be snapped to based on their bearing. The maximum distance that is searched for a road segment to snap to can be specified using the IStop::SearchTolerance property.

After defining the initial route stop (the start location), any number of intermediate stops can be specified as well; at least one other stop representing the end location must be specified. See the Creating stops section for more information. Pass the IStopCollection object to the IRouter::Solve method, which calculates the route and generates an IDirections object. Define a new IRouteTracker object, by calling the IRouteTrackerFactory::CreateRouteTracker method. Initialize route tracking by calling the IRouteTracker::SetRoute and SetStopIndex methods (in that order). Pass the IDirections object that was output by the original route calculation, to SetRoute. The SetStopIndex method is used to specify the stop from which to begin tracking by its index in the original stop collection (beginning with 0).

IRouteTracker provides several properties and methods for tracking progress along the route. IRouteTracker is responsible for snapping to the route, differentiating it from IStop, which is used to snap to the street network. Set the IRouteTracker::OffRouteDistanceThreshold property to define the maximum distance that the point can deviate from the route before it is considered to be off-route. The IRouteTracker::Status property returns the tracking status, which implements the esriSMTrackingStatus enumeration. A value of esriSMTSOffRoute indicates an off-route condition. The IRouteTracker::UpdateLocation method moves the point along the route, and it requires the current position and bearing as input parameters. These values must be passed to the UpdateLocation method from the GPS at regular intervals, to provide useful tracking information.

As long as the point remains on the route, detailed information about the route's progress can be passed to them each time UpdateLocation is run. This information is obtained through the IRouteTracker::TrackingDirection property, which returns the ITrackingDirection object. This object provides the following information: access to the current driving direction item and the percentage of it that has been completed; the next direction item; distance and time to the next maneuver, and the maneuver type that is forthcoming; the geometry of the portion of the route segment that has been completed, and the geometry of the portion of the route segment that remains until the next maneuver. This is all standard information that needs to be provided by any effective navigation system.

If the point triggers the off-route flag, the IRouter::ReSolve method should be used to recalculate the route. A stop collection consisting of the current location and the remaining stops, as well as the original driving directions (the IDirections object, which can be obtained from the IRouteTracker::Route property), must be passed to the method. The ReSolve method returns the new driving directions in the IDirections object. Tracking can then be reinitialized by passing the IDirections object output by the ReSolve method to the IRouteTracker::SetRoute method.

Basic tracking workflow steps

The basic workflow looks like this:

  1. Get the initial GPS location/bearing/speed/latency.
  2. Pass them to IStop to create a stop.
  3. Add one or more additional stops and calculate a route with IRouter::Solve.
  4. Initialize tracking with the IRouteTracker::SetRoute method, passing the IDirections from IRouter::Solve to it, and with IRouteTracker::SetStopIndex.
  5. Set the IRouteTracker::OffRouteDistanceThreshold property.
  6. Track the route using IRouteTracker::UpdateLocation, passing the current GPS location and bearing to it at a regular interval.
  7. Return information about the route progress with ITrackingDirection.
  8. If the tracking status is off-route, recalculate the route with the IRouter::Resolve method.

Repeat steps 6-8.

1/7/2015