Routing API (turn-by-turn directions)
CalculateRoute returns turn-by-turn directions. In case you also need each leg map and a complete route map of the same route, you may set MapSize (width, height) to a value other than (0,0) in RouteOptions . When MapSize (>0, >0) then check <Map>string</Map> for route images.
|
f |
Route map |
Leg map |
Suppose we call Dispatch() method with 2 vehicles V1 and V2 and 6 stops A, B, C, D, E, F.
Now suppose Dispatch() assigns A, B to V1 and C, D, E, F to V2 vehicle.
V1---->A---->B
V2---->C--->D---->E----->F
CalculateRoute for V1 will return :
2 route.leg.maps for V1---->A, A--->B (2 legs in this route)
1 route.map V1---->A---->B
2 turn-by-turn directions for V1---->A, A--->B (2 legs in this route)
route.points for V1---->A---->B (use this to depict the route)
CalculateRoute for V2 will return :
4 route.leg.maps for V2---->C, C---->D, D---->E, E--->F (4 legs in this route)
1 route.map V2-->C--->D--->E---->F
4 turn-by-turn directions for V2---->C, C---->D, D---->E, E--->F (4 legs in this route)
route.points for V2-->C--->D--->E---->F (use this to depict the route)
Here is a button that uses web reference "ts" calling CalculateRoute method to get turn by turn directions
private void btnCalculateRoute_Click(object sender, EventArgs e)
{
btnCalculateRoute.Enabled = false;
try
{
//create request if null
if (routeRequest == null)
{
routeRequest = new TestInternal.ts.RouteSpecification();
// If maps are also desired then RouteOptions.MapSize should be added to the request:
routeRequest.RouteOptions = new ts.RouteOptions();
routeRequest.RouteOptions.DistanceUnit = ts.DistanceUnit.Mile;
routeRequest.RouteOptions.MapSize = new ts.MapSize();
routeRequest.RouteOptions.MapSize.Height = 200;
routeRequest.RouteOptions.MapSize.Width = 400;
//Let's create 10 locations for example
int count = 10;
//Create an array of locations
routeRequest.Locations = new TestInternal.ts.Location[count];
Random rnd = new Random();
for (int i = 0; i < count; i++)
{
TestInternal.ts.Location loc = new TestInternal.ts.Location();
loc.Name = string.Format("Loc_{0}", i + 1);
// in this sample we use latitude & longitude but you can use the
// Address property of location to geocode your location on-the-fly.
loc.LatLong = new TestInternal.ts.LatLong();
loc.LatLong.Latitude = 38.8 + ((i % 2 == 0) ? rnd.NextDouble() : -rnd.NextDouble()); // random locatons may not be routeable!
loc.LatLong.Longitude = -78.2 + ((i % 2 == 0) ? rnd.NextDouble() : -rnd.NextDouble());
//Add location to array.
routeRequest.Locations[i] = loc;
}
}
try
{
client.Timeout = 1000 * 60 * 30;//30 minutes
TestInternal.ts.RouteResult result = client.CalculateRoute(routeRequest);
if (result.Status == TestInternal.ts.OperationStatus.Success)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Route.RouteLegs.Length; i++)
{
sb.AppendFormat("---------------------Leg:{0}\r\n", i);
ts.RouteLeg rl = result.Route.RouteLegs[i];
for (int j = 0; j < rl.Itinerary.Items.Length; j++)
{
ts.RouteItineraryItem ri = rl.Itinerary.Items[j];
sb.AppendFormat("{0}\t [{1:f2},{2}]\r\n", ri.Text, ri.Distance, ri.Time);
}
if (rl.Map != null) // if maps are desired for each leg
{
byte[] bytes = Convert.FromBase64String(rl.Map);
using (MemoryStream ms = new MemoryStream(bytes))
{
Image mapImage = Image.FromStream(ms);
mapImage.Save(path + "\\Leg" + i + ".png");
}
}
}
if (result.Route.Map != null) // map for entire route
{
byte[] bytes = Convert.FromBase64String(result.Route.Map);
using (MemoryStream ms = new MemoryStream(bytes))
{
Image mapImage = Image.FromStream(ms);
mapImage.Save(path + "\\Route.png");
}
}
txtResult.Text = sb.ToString();
return;
}
else
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Status:{0}\r\n", result.Status);
foreach (TestInternal.ts.Error i in result.Errors)
{
sb.AppendFormat("{0}\r\n", i.Message);
}
txtResult.Text = sb.ToString();
//Show result with error. Some of locations can be skipped or may have errors.
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
finally
{
btnCalculateRoute.Enabled = true;
}
}