Using a RouteMatrix |
In this section we will use a RouteMatrix to calculate the distances and times between a number of stops.
The RouteMatrix object is an n x n matrix, R, where n is the number of stops in the relevant route. Each entry, rij (the entry at the intersection of row i and column j) is equal to the distance in meters (or time in seconds) between stops i and j.
It is important to note the following:
An employee must be dispatched to the nearest of four customers. We will use a RouteMatrix object to calculate the time and distance between the employee and each customer.
We could also use a foreach loop and manually calculate the distance/time between the employee and each customer individually, however there are significant economies-of-scale benefits in using a RouteMatrix object to perform the same task and calculate all distances and times at once.
A route matrix is constructed from a number of RouteStop objects. We will use the following stops to represent each of the five locations:
/* Employee location */ RouteStop emp = new RouteStop(new LatLon(33.84105, -117.91133)); /* Customer locations */ RouteStop cus1 = new RouteStop(new LatLon(33.84123, -117.92153)); RouteStop cus2 = new RouteStop(new LatLon(33.83373, -117.91278)); RouteStop cus3 = new RouteStop(new LatLon(33.83818, -117.90488)); RouteStop cus4 = new RouteStop(new LatLon(33.82960, -117.90041));
The locations are shown on the map below; customers in yellow and the employee in red.
The route matrix is constructed from an array of RouteStop objects and a RoutingStrategy. Two routing strategies are predefined within GeoBase: RoutingStrategyFastest and RoutingStrategyShortest. These two strategies find the fastest and shortest routes, respectively. You may also implement your own cost evaluation function to use with a RouteMatrix object. Creating and using a custom cost evaluation function will be covered in the next section: Modifying the Routing Strategy.
/* RouteMatrix */ RouteMatrix myMatrix = new RouteMatrix(new RouteStop[] { emp, cus1, cus2, cus3, cus4 }, new RoutingStrategyFastest());
Once constructed, the route matrix could be visualized as the following:
Each entry of the matrix will, of course, contain the time or distance between the respective stops as calculated by GeoBase's routing engine. We will work with a single column of the matrix (highlighted in yellow). Two methods are available to retrieve a column from a RouteMatrix object:
Caution |
---|
You cannot assume that a RouteMatrix object is symmetrical about the diagonal (meaning that any given row is the same as the corresponding column). This assumption cannot be made because elements in the road network (such as one-way streets) will introduce asymmetry to the RouteMatrix object. |
We will use the Times method to find the customer that is the shortest time away and the Distances method to find the customer that is the shortest distance away. The code is shown below.
/* Get times and distances from RouteStop 0 (emp) to all customers */ double[] myTimes = myMatrix.Times(0); // seconds double[] myDistances = myMatrix.Distances(0); // meters
The results may then be output as desired, for example to the console:
for (int i = 1; i < myTimes.Length; i++) { // the values in the distances array are measured in meters string distance = (myDistances[i]/1000).ToString(".00"); // the values in the times array are measured in seconds string time = (myTimes[i] / 60).ToString(".0"); Console.WriteLine("Distance to customer " + i + " is " + distance + "km, " + time + " minutes away"); }
For our scenario, the results are:
Distance to customer 1 is 2.36km, 3.0 minutes away Distance to customer 2 is 1.45km, 2.0 minutes away Distance to customer 3 is 11.38km, 12.5 minutes away Distance to customer 4 is 2.48km, 3.2 minutes away |
Note |
---|
The distances in this example are specified in kilometers, but can be converted to miles using the ConvertUnitsInt(Double, DistanceUnit, DistanceUnit) method. The MathUtil class contains other useful speed, distance and unit conversion methods. |
If you need to add a stop to a RouteMatrix object after it has been created use the AddStop(RouteStop) method.
Caution |
---|
Because of the performance hit associated with adding a new stop to an already calculated matrix it is recommended that the RouteMatrix object is created with all required stops, and that this method be used sparingly. |
The following code snippet demonstrates how to add a new stop:
/* Create a new stop */ RouteStop Work = new RouteStop(new LatLon(33.648720, -117.733774)); /* Add the new stop to our existing RouteMatrix */ int indexOfNewStop = myMatrix.AddStop(Work); /* We can get the distance by specifying the stop number */ myDistances = myMatrix.Distances(indexOfNewStop);
The CalculateCostMatrix method returns an n x n matrix of doubles representing the time cost (measured in arbitrary units) of traveling between each of the RouteStop objects. These cost values are calculated from the distances stored in the RouteMatrix object and are heavily dependent on the RoutingStrategy used.
The matrix's RecalculateFull method should only be called when a modification is made to the routing strategy used by the RouteMatrix object. The RecalculateFull method is automatically called when the RouteMatrix object's RoutingStrategy property is set, but not when the RoutingStrategy is modified. For example, you should call RecalculateFull when modifying the routing strategy's property AllowUTurns from True to False.