Welcome to MapForums!

When you are signed in, this message, the ads in this row, and the red-underlined link ads all go away.

## Using MapPoint in a Routing Application Part 2 - Required MapPoint Functionality

This is a discussion on Using MapPoint in a Routing Application Part 2 - Required MapPoint Functionality within the MP2K Magazine Articles forums, part of the Map Forums category; Implementation of Required MapPoint Functionality In this section we discuss the implementation of several key aspects of Route Factory functionality ...

1. ## Using MapPoint in a Routing Application Part 2 - Required MapPoint Functionality

Implementation of Required MapPoint Functionality

In this section we discuss the implementation of several key aspects of Route Factory functionality that rely upon MapPoint.

Time/Distance Evaluations

Route Factory Spreadsheet represents locations (i.e. terminals or customers) as C# objects with the underlying MapPoint.Location as an attribute. Although we only need the time and/or distance between given pairs of points, we still need to construct a MapPoint.Route object to perform the evaluation. The MapPoint.Route object is provided with the two MapPoint.Location objects as in the form of MapPoint “WayPoints” as follows:

Code:
```private static MapPoint.Route BuildMappointPair(Location locStart, Location locFinish)
{
MapPoint.Route route = RFGlobals.MyMap.ActiveRoute;
return route;
}```
We then get the data we need via:

Code:
```route.Calculate();
time = route.DrivingTime * 24;  // result returned in fractional days
distance = route.Distance;```
Alternatively, the user is allowed to specify that the algorithm use mathematically computed distances between locations. These are computed from the Location’s Latitude/Longitude coordinates using the “Great-Circle” trigonometric equations. The resulting “as the crow flies” distances are then multiplied by an empirically derived fudge factor to account for typical road circuity.

Geocoding Process

Geocoding is the process of determining a Latitude/Longitude from a Street Address and tying that to an underlying MapPoint.Location. As with any GIS System or even MapQuest, this is not a 100% reliable process. The easiest situation is when the user supplies the Latitude/Longitude coordinates, in which case we merely use:

Code:
`foundLocation = MyMap.GetLocation(loc.Latitude, loc.Longitude, 1);`
where MyMap is a MapPoint.Map object. To get the MapPoint.Location directly from the street address we use:

Code:
`MapPoint.FindResults findResults = MyMap.FindAddressResults(loc.Street, loc.City, string.Empty, region, loc.Zip, country);`
However, even if the address has been correctly specified, the function can sometimes return null or low quality (findresults.ResultsQuality > 2). Our fallback in those instances is to focus on the zip code only. We have integrated a commercial database into our application that maps the zip code to a Latitude/Longitude coordinate representing the centroid of the zip code region. (This same database maps the zip code to time zone data, which we discuss later in this article). If the zip code is also invalid, there is not much else one can do, so we trap and flag the situation for the user so they can try to get a better address.

Route Display

We use MapPoint to display the routes built by our routing algorithms. At the conclusion of the route building algorithms, the route specification is output to an Excel worksheet as a way of storing the solution between uses of the application. Each stop on the route is represented as a row on the worksheet. To display a route, the user selects a transport ID from a drop down menu and clicks on a Draw Route button. This activates the following steps for each stop (row):

1. Geocode the stop by using its Location ID to retrieve the required data from the Locations Worksheet and utilizing the geocoding process described above to obtain a MapPoint.Location
2. Add a Waypoint to a MapPoint.Route object corresponding to the MapPoint.Location.
3. Create a MapPoint.Pushpin with an identifier indicating the sequence number of the stop
4. Populate the MapPoint.Pushpin with descriptive information that will be available to the user using the “More Information” right mouse button selection.

Code:
```MapPoint.Location loc;
string waypointName;

numStops++;
loc = MyMap.GetLocation(locInfo.Latitude, locInfo.Longitude, 1);
waypointName = locInfo.ID;
pinloc.Symbol = (short)(217 + numStops);  // pushpin with stop sequence number
pinloc.Note = locInfo.Description +
"\n" + "ETA: " + i_routeData[numStops, 6].ToString() +
"\n" + "Loads: " + i_routeData[numStops, 8].ToString() +
"\n" + "UnLoads: " + i_routeData[numStops, 9].ToString();
pinloc.BalloonState = MapPoint.GeoBalloonState.geoDisplayNone;```
Note that i_RouteData is an object array with data from the Excel row for that stop.

When MapPoint displays a driving route, it also creates a set of turn-by-turn driving instructions where each stop has a listed arrival and departure time. In Route Factory Spreadsheet, we need to manually set the arrival and departure on these instructions for three reasons: 1) the duration of the stop is a function of the load/unload time at that particular stop, 2) the load/unload operation can be delayed by the stop’s time window, that is, the transport may have to wait until the stop is “open for business”, and 3) the stop may involve an “overnight” due to drive time restrictions. These considerations are handled via the following code:

Code:
```for (int i = 1; i <= numStops; i++)
{
object index = i;
waypoint = route.Waypoints.get_Item(ref index);
if (i < numStops)
{
int goodTimes = 0;
if (i_routeData[i, 6] != null)
{
arrivalTime = (DateTime)i_routeData[i, 6];
goodTimes++;
}
if (i_routeData[i, 7] != null)
{
departureTime = (DateTime)i_routeData[i, 7];
waypoint.PreferredDeparture = departureTime;
goodTimes++;
}
if (goodTimes == 2)
{
if (departureTime.Date > arrivalTime.Date)
waypoint.Overnights = (int)(departureTime.Date - arrivalTime.Date).TotalDays;
}
}
}```
Last we adjust the route.DriverProfile to be consistent with the parameter settings made by the user (details available upon request). Finally, we build and display the MapPoint route:

Code:
```route.Calculate();
route.ZoomTo();
MyApp.Visible = true;```
A sample map is shown below.

Last edited by Eric Frost; 04-18-2011 at 06:43 PM.