Combining MapPoint Web Service Driving Directions

 

IMPORTANT: MapPoint Web Service was retired on November 18, 2011. Please see Bing Maps for a list of current Bing Maps APIs.

Joe Como
Microsoft Corporation

May 2005

Applies to:

Microsoft MapPoint Web Service

Summary: Learn how to combine individual turn-by-turn steps in MapPoint Web Service driving directions to reduce the number of map views that you request and to simplify driving directions for users. (7 printed pages)

Contents

Introduction
Installing and Running the CombineTurnMaps Sample
Creating a Class for Consolidated Directions
Consolidating StepsSteps That Should Not Be Combined
Conclusion

Introduction

When you use the MapPoint Web Service SOAP API to calculate a route between two or more points, MapPoint Web Service returns a set of map views in the Route object. Each map view corresponds to a specific text instruction, providing the user with a visual representation of the maneuver that is being explained, as shown in Figure 1.

ms980192.mwscombine1(en-us,MSDN.10).gif

Figure 1. Map views and individual text instructions

However, every map that you render in your application requires a separate MapPoint Web Service transaction, which can add up quickly if a route has many steps. This article describes techniques that you can use to consolidate driving-direction steps and maps into more efficient clusters, as shown in Figure 2.

ms980192.mwscombine2(en-us,MSDN.10).gif

Figure 2. Map views with combined text instructions

First, the article describes how to create a class to hold the combined steps, and then demonstrates how to determine which steps to combine and how to store the combined steps in an instance of the class. To illustrate these techniques, a sample application accompanies this article. The CombineTurnMaps sample is a simple ASP.NET application in which a user can specify a start point and an end point and display a map and driving directions between the two points. You can download the sample from this page in the Microsoft Download Center.

This article assumes that you are already familiar with the MapPoint Web Service SOAP API and MapPoint Web Service in general. For more information about MapPoint Web Service or to sign up for a free evaluation account, visit the MapPoint Web Service Web site. For more information about programming with MapPoint Web Service, see the MapPoint Web Service SDK.

Installing and Running the CombineTurnMaps Sample

To run this sample in Microsoft Visual Studio .NET, your Visual Studio .NET installation must be configured to run and debug ASP.NET applications, and Internet Information Services (IIS) must be running.

To install and run the sample

  1. In the IIS virtual root directory, create a new folder called CombineTurnMaps. The default path to the virtual root directory is C:\Inetpub\Wwwroot\.
  2. Download the files from this page in the Microsoft Download Center and copy them into the new CombineTurnMaps folder.
  3. Navigate to the new folder, and then double-click the CombineTurnMaps.csproj file to open it.
  4. In Solution Explorer, right-click the Web Reference MapPointService, and then click Update Web Reference.
  5. In Solution Explorer, double-click the file Web.config to open it, and then set the values of the MPUser and MPPass keys to your customer ID and password, respectively.
  6. On the File menu, click Save to save the Web.config file.
  7. In Solution Explorer, right-click the Default.aspx file, and then click Set as Start Page.
  8. Compile the project and then run it.

Creating a Class for Consolidated Directions

As mentioned earlier, MapPoint Web Service returns directions in the form of a Route object. Within this Route object, the Itinerary property contains an array of Direction objects, each of which contains detailed information about a step in the route that is being returned. For the purpose of combining steps, you use the following properties of the Direction class:

  • Instruction—Contains a text representation of a step (Direction also has a FormattedInstruction property, which adds HTML formatting to the instruction string).
  • View—A MapViewRepresentations object that contains a visual representation of the step in map form.
  • LatLong—A LatLong object that indicates where the beginning of the step is located on the MapViewRepresentations object. (Later, you can use the LatLong object to create a Pushpin object that marks the step on the map.)

In your application, you may want to expose the values of other Direction properties to users, such as DirectionType, Distance, and Duration. For more information, see Direction Class in the MapPoint Web Service SDK.

Because you are combining multiple steps, you need a structure that will hold multiple Direction objects, one MapViewRepresentations object, which will contain the map view that encompasses all of the combined steps, and multiple Pushpin objects, which will represent each step on the map. Additionally, you need methods to set and retrieve the values of these members.

[C#]
public class CombinedSteps
{
   private ArrayList CombinedDirections;
   private MapViewRepresentations CombinedMap;
   private ArrayList MapPushpins;
   public CombinedSteps()
   {
      CombinedDirections = new ArrayList();
      MapPushpins = new ArrayList();
   }
   public void AddDirection(Direction directionToAdd) 
   {
      CombinedDirections.Add(directionToAdd);
   }
   public void AddMapView(ViewByBoundingRectangle viewByBoundRect) 
   {
      CombinedMap = new MapViewRepresentations();
      CombinedMap.ByBoundingRectangle = viewByBoundRect;
      return;
   }
   public void AddPushpins(Pushpin[] pushPinsToMap) 
   {
      foreach (Pushpin pin in pushPinsToMap) 
      {
         MapPushpins.Add(pin);
      }
   }
   public object[] GetDirectionsArray() 
   {
      return CombinedDirections.ToArray();
   }
   public ViewByBoundingRectangle GetMapView() 
   {
      return CombinedMap.ByBoundingRectangle;
   }
   public int GetDirectionsArraySize()
   {
      return CombinedDirections.Count;
   }
   public object[] GetMapPushpinsArray()
   {
      return MapPushpins.ToArray();
   }
   public int GetMapPushpinsArraySize()
   {
      return MapPushpins.Count;
   }
}

Consolidating Steps

To consolidate the steps in driving directions, use the following process:

  1. Retrieve the bounding rectangle (the LatLongRectangle object) that encompasses the map view for the first step.
  2. Determine whether the LatLong property for the next step is within the bounding rectangle you just retrieved by using the IsInBox method in the following code example. If it is, you should be able to combine those steps.
  3. Continue testing each successive step in the route. Each time IsInBox returns a value of true, use the AddDirection method in the previous code example to add the Direction object of the current step to the CombinedSteps object that contains the original step. In addition, add a Pushpin object to the MapPushpins ArrayList to mark the new step on the map.
  4. When you find a LatLong point that does not fit within the bounding rectangle for the original step, create a MapViewRepresentations object that includes all of the steps that you have combined by making a padded BoundingRectangle object from the LatLong values of the combined steps. Then, assign the MapViewRepresentations object to the appropriate CombinedSteps object.
  5. Repeat steps 1 through 4, starting with the first step that was not included in the previous group.

After you test all of the available steps, you will have an ArrayList object that contains CombinedSteps objects that you can iterate through to display the driving directions.

Note  To prevent your map from becoming cluttered, you may want to limit the number of steps that can be combined, although the CombineTurnMaps example project does not.

[C#]
LatLongRectangle rectangle = 
Route.Itinerary.Segments[segmentNumber].Directions[stepNumber].View.
ByBoundingRectangle.BoundingRectangle;

LatLong point = 
Route.Itinerary.Segments[segmentNumber].Directions[stepNumber + 
1].LatLong;

// Determine whether the latitude and longitude coordinates are
// within the given bounding rectangle.
public static bool IsInBox(LatLongRectangle rectangle, LatLong point)
{
   if (rectangle.Southwest.Longitude <= 
rectangle.Northeast.Longitude)
   {
      return (rectangle.Southwest.Latitude <= point.Latitude
         && rectangle.Northeast.Latitude >= point.Latitude
         && rectangle.Southwest.Longitude <= point.Longitude
         && rectangle.Northeast.Longitude >= point.Longitude);
   }
   return false;
}

Note that this method only works for a LatLongRectangle object whose boundaries do not span the prime meridian. If your application has to be able to handle such a case, you'll need to modify the method appropriately.

Steps That Should Not Be Combined

If one step is much longer or shorter than another step, you may not want to combine them. For example, if you combine a 1-mile step with a 200-mile step, the 1-mile path of the first step would be lost on a map that displays the 200-mile path of the second point. In addition, the icon for the first step would most likely be obscured by the icon for the second step. To prevent the first step from being lost or obscured, compare the distance values of the steps before you combine them. There is no set difference factor that you should use as a limit; however, limiting the steps that you combine to those with a difference factor of no more than 10 is a good starting point. For example, you would only combine a 1-mile step with steps of 9.99 miles or less.

You can also prevent steps from being combined based on the values of their DirectionType properties. In particular, if a route includes more than one waypoint (such as a route that starts in Denver, CO, proceeds to Phoenix, AZ, and ends in San Diego, CA), you may want to stop combining steps when you reach a Direction object that has a DirectionType value of Waypoint, EndOfDay, or StartOfDay. Other steps that you may not want to combine are those with a DirectionType value of Border or Warning.

One last restriction to consider is that the endpoint of any segment should probably have its own map, so that the map for the final step, which will usually be a specific street address, is zoomed in far enough so that the user can see the necessary detail for finding the destination point.

Conclusion

The best way to see the difference between combining driving directions steps and leaving them unchanged is to compare the output from the CombineTurnMaps sample application with the output from the TurnByTurnRouteMaps sample in the MapPoint Web Service SDK.

By comparing the two sets of directions side-by-side, you will see that the directions from CombineTurnMaps contain far fewer steps and maps. Incorporating this functionality into your application can save map transactions and result in a cleaner display of directions.

Joe Como is a Web Development Engineer in the Microsoft MapPoint Business Unit and is a member of the Professional Services team.