7.2. Calculating a RouteA valid route consists of a starting point and an ending point; sometimes a route can also have one or more stops between its starting and stopping points. To calculate a route, you need to have at least two waypoints expressed in terms of LatLong objects. Depending on how much control you need in calculating a route, MapPoint Web Service offers two methods: RouteServiceSoap.CalculateSimpleRoute and RouteServiceSoap.CalculateRoute. 7.2.1. Calculating a Route Using the CalculateSimpleRoute MethodThe RoutServiceSoap.CalculateSimpleRoute method calculates a route using latitude/longitude coordinates. This method uses an array of latitude/longitude coordinates, a map data source name (such as MapPoint.NA), and a SegmentPreference enumeration to indicate whether the route should be calculated using the SegmentPreference.Quickest option (yielding the route with minimal travel time) or the SegmentPreference.Shortest option (yielding the route with minimal travel distance). The following example shows how to use the RouteServiceSoap.CalculateSimpleRoute method with latitude/longitude pairs: //Define waypoints LatLong[] latLongs = new LatLong[2]; //Seattle, WA latLongs[0] = new LatLong(); latLongs[0].Latitude = 47.6034; latLongs[0].Longitude = -122.3295; //Redmond, WA latLongs[1] = new LatLong(); latLongs[1].Latitude = 47.6785; latLongs[1].Longitude = -122.1308; //Now create a route service proxy RouteServiceSoap routeService = new RouteServiceSoap(); //Assign credentials routeService.Credentials = new System.Net.NetworkCredential(userid, password); //Calcuate Route Route route = routeService.CalculateSimpleRoute(latLongs, "MapPoint.NA", SegmentPreference.Quickest); Keep in mind that if your route exceeds 50,000 kilometers, an error is thrown, but you can pass a maximum of 50 latitude/longitude pairs to this method. Despite this apparent flexibility, it does not offer much control over the route service behavior, such as setting the driving starting time and ending time, requesting only route itinerary without a calculated route representation cache, and so on. This method tends to be inefficient when you just want to calculate route itinerary without returning a calculated route representation; however, that's exactly the level of control that the RouteServiceSoap.CalculateRoute method offers. 7.2.2. Calculating a Route Using the CalculateRoute MethodThe RouteServiceSoap.CalculateRoute method takes a valid RouteSpecification object as an input parameter and returns a Route object. The RouteSpecification object allows you to specify your route using Waypoint objects and Segment objects. One of the advantages of this approach is better control over the route calculation process; using a RouteSpecification object, you can control the segment level routing settings, such as shortest versus quickest and driving times. A Waypoint object is a wrapper around a location that is part of a route. To define a Waypoint object, you need to have an associated latitude/longitude pair (or a LatLong object). Once you have the Waypoints outlined for a route, you can assign them to Segment objects to create an array of route segment specification. This route segment specification array is used in calculating the route when the RouteServiceSoap.CalculateRoute method is called. The following example shows how to call this method using a RouteSpecification object: //Now create a route service proxy RouteServiceSoap routeService = new RouteServiceSoap(); //Assign credentials routeService.Credentials = new System.Net.NetworkCredential(userid, password); //Now define RouteSpecifications //Define segments SegmentSpecification[] routeSegmentsSpec = new SegmentSpecification[3]; //Define start segment routeSegmentsSpec[0] = new SegmentSpecification(); routeSegmentsSpec[0].Waypoint = new Waypoint(); routeSegmentsSpec[0].Waypoint.Name = "Start"; //Seattle, WA routeSegmentsSpec[0].Waypoint.Location = new Location(); routeSegmentsSpec[0].Waypoint.Location.LatLong = new LatLong(); routeSegmentsSpec[0].Waypoint.Location.LatLong.Latitude = 47.6034; routeSegmentsSpec[0].Waypoint.Location.LatLong.Longitude = -122.3295; //Set this segment to be the quickest routeSegmentsSpec[0].Options = new SegmentOptions(); routeSegmentsSpec[0].Options.Preference = SegmentPreference.Quickest; //Define stop segment routeSegmentsSpec[1] = new SegmentSpecification(); routeSegmentsSpec[1].Waypoint = new Waypoint(); routeSegmentsSpec[1].Waypoint.Name = "Stop"; //Redmond, WA routeSegmentsSpec[1].Waypoint.Location = new Location(); routeSegmentsSpec[1].Waypoint.Location.LatLong = new LatLong(); routeSegmentsSpec[1].Waypoint.Location.LatLong.Latitude = 47.6785; routeSegmentsSpec[1].Waypoint.Location.LatLong.Longitude = -122.1308; //Set this segment to be the shortest routeSegmentsSpec[1].Options = new SegmentOptions(); routeSegmentsSpec[1].Options.Preference = SegmentPreference.Shortest; //Define to segment routeSegmentsSpec[2] = new SegmentSpecification(); routeSegmentsSpec[2].Waypoint = new Waypoint(); routeSegmentsSpec[2].Waypoint.Name = "Finish"; //Portland, OR routeSegmentsSpec[2].Waypoint.Location = new Location(); routeSegmentsSpec[2].Waypoint.Location.LatLong = new LatLong(); routeSegmentsSpec[2].Waypoint.Location.LatLong.Latitude = 45.5118; routeSegmentsSpec[2].Waypoint.Location.LatLong.Longitude = -122.6755; //Now create a Route Specification and assign segments //and data source to be used RouteSpecification routeSpec = new RouteSpecification(); routeSpec.DataSourceName = "MapPoint.NA"; routeSpec.Segments = routeSegmentsSpec; //Set the itinerary only mask routeSpec.ResultMask = RouteResultMask.Itinerary; //Calculate Route Route route = routeService.CalculateRoute(routeSpec); In this example, I define three segments from Seattle, WA to Portland, OR with a stop at Redmond, WA. The real advantage to using the CalculateRoute method can be seen in how I set the segment preferences; I have set the first segment of my route from Seattle to Redmond as the quickest segment: //Set this segment to be the quickest routeSegmentsSpec[0].Options = new SegmentOptions(); routeSegmentsSpec[0].Options.Preference = SegmentPreference.Quickest; This guarantees that when my route is calculated, I get the directions that can take me from Seattle to Redmond in the minimal amount of time; then, I set the second segment as the shortest segment: //Set this segment to be the shortest routeSegmentsSpec[1].Options = new SegmentOptions(); routeSegmentsSpec[1].Options.Preference = SegmentPreference.Shortest; This setting guarantees that the route contains the directions that travel the minimal distance to go from Redmond, WA to Portland, OR. Finally, you can also reduce the SOAP payload by requesting the "itinerary only" route object by setting the following RouteResultMask to the RouteSpecification object: //Set the itinerary only mask routeSpec.ResultMask = RouteResultMask.Itinerary; The CalculateRoute method provides considerably more control than the CalculateSimpleRoute method; however, keep in mind that only 50 waypoints are allowed with this method. Finally, as with the CalculateSimpleRoute method, if your route exceeds 50,000 kilometers, an error is thrown. 7.2.2.1. Controlling the driving timesBefore we get into the details of getting the route object information returned by the previously discussed methods, there is one more setting you can set to the RouteSpecification object to control the driving times, the DriverProfile object. By default, MapPoint Web Service considers the valid driving times in a day to be from 9:00 a.m. to 5:00 p.m. When you calculate a route without setting any specific driver profile settings, routes are calculated using these default times. However, if you want to drive from 10:00 a.m. to 3:00 p.m., use the DriverProfile object. To set specific starting and ending driving times in a day, use the DriverProfile object; this object has two fields, DayStartTime and DayEndTime, using which you can set the starting time and ending time in a day. These two values are always expressed in minutes elapsed since the day has started at 12:00 a.m. (except for the default values of -1 and -1). To set a DayStartTime at 10:00 a.m., use the following code: //Create a driver profile object DriverProfile driverProfile = new DriverProfile(); //Start driving every day at 10 AM in the morning driverProfile.DayStartTime = 10 * 60; Similarly, you can set the DayEndTime at 3:00 p.m. as follows: //End driving every day at 3 PM in the evening //3 PM = 12 + 3 = 15 hours since 12:00 AM driverProfile.DayEndTime = 15 * 60; To set this DriverProfile object to the RouteSpecification object to put the new driving day start and end times into effect while calculating your route, use the following code: //Assign Driver's profile routeSpec.DriverProfile = driverProfile; Keep in mind that setting the driver's profile with custom driving start and end times changes the total trip time as well as the driving directions accordingly. 7.2.2.2. Setting default distance unitsDepending on where you are actually driving, sometimes it makes sense to see the driving directions and distances in the units that are used locally; for example in the United States, the distance is measured in miles, while in the United Kingdom, the distance is measured in kilometers. MapPoint Web Service allows you to set your distance preference for route calculations via the UserInfoRouteHeader object. This object is set to the RouteServiceSoap instance before calling the CalculateRoute or CalculateSimpleRoute methods: //Create an instance of user info route header UserInfoRouteHeader routeHeader = new UserInfoRouteHeader(); //Set distance unit to Miles routeHeader.DefaultDistanceUnit = DistanceUnit.Mile; //Assign it to Route Service instance routeService.UserInfoRouteHeaderValue = routeHeader; //Calculate Route route = routeService.CalculateRoute(routeSpec); Depending on what the default distance unit is set to, the route object contains the information about the total route distance and segment distance accordingly. The default distance unit always starts out as kilometers, and you need to change that if you want miles. 7.2.2.3. Setting the default cultureYou can also use the UserInfoRouteHeader object to obtain the driving directions in any of the supported languages; to get driving directions in French, use the following code: //Create an instance of user info route header UserInfoRouteHeader routeHeader = new UserInfoRouteHeader(); //Create Culture Info routeHeader.Culture = new CultureInfo(); //And set it to French routeHeader.Culture.Name = "FR"; //Assign it to Route Service instance routeService.UserInfoRouteHeaderValue = routeHeader; //Calculate Route route = routeService.CalculateRoute(routeSpec); This code results in driving directions in French. For a full list of languages supported by MapPoint Web Service, refer to Chapter 5. Now that we have seen how to calculate a route with different options, it's time to look at the itinerary details contained within a route. |