Creating and Optimizing a Route |
A Route is a collection of RouteStop objects. Each route has two stops that are designated as the Start and End stops and any other number of stops in between.
At the end of this topic our application will be capable of the following:
Tip |
---|
Remember that a Route is an ordered set of locations that must be traveled to, while the actual path between those locations is represented by a corresponding Directions object. |
We will add a right-click context menu to our application that will allow the user to create route stops by clicking on the map.
In the Designer view add a ContextMenuStrip to mapMain (ContextMenuStrip can be found in the Toolbox). Edit the menu (by clicking on it in the Form view) and add the following options to the menu:
We need to add code to our previously written MouseUp event to deal with the context menu right-click.
private void mapMain_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (!mapMini.Contains(mapMain.Center)) { mapMini.Center = mapMain.Center; mapMini.Invalidate(); } } if (e.Button == MouseButtons.Right) { contextMenuStrip.Show(MousePosition.X,MousePosition.Y); } }
Recall from the first topic (Creating the Basic Project) that we have already created a Route property named route and added it to mapMain's renderList. This means that we can quickly add stops, however these new stops will not be drawn until the map is updated. We can force the map to update by calling mapMain.Invalidate().
In the Designer View, edit the context menu and select the "Set as Start" option. Create a Click event for this option, and switch to the Code view. Add the following code to the new event:
private void setAsStartToolStripMenuItem_Click(object sender, EventArgs e) { try { route.Start = new RouteStop(currentMouseLocation); mapMain.Invalidate(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Tip |
---|
It's possible that the user will try to add a stop in an invalid location (such as in the ocean). If this happens an exception will be generated when creating the Directions object. |
Setting the ending point of a route is identical in method to the above, except that route.Start should be changed to route.End:
private void setAsEndToolStripMenuItem_Click(object sender, EventArgs e) { try { route.End = new RouteStop(currentMouseLocation); mapMain.Invalidate(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Stops are added in a similar way to the start and the end:
private void addStopToolStripMenuItem_Click(object sender, EventArgs e) { try { route.AddStop(new RouteStop(currentMouseLocation)); mapMain.Invalidate(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Note |
---|
Start and End stops are colored differently from regular stops. When adding stops you may notice that the order changes, this is because GeoBase performs some basic sorting on the stop order when a new stop is added. You can override this sorting behavior by using the AddStop(RouteStop, Int32) method. |
The following code clears all the stops from an existing Route. Add an appropriate click event and modify the code to match the snippet below.
Note |
---|
A route with no stops will not be displayed on the map. |
private void clearRouteToolStripMenuItem_Click(object sender, EventArgs e) { route.Clear(); // remove the old directions from display if (directions != null) renderList.Remove(directions); mapMain.Invalidate(); }
When a route is optimized the order of the stops on the route will be arranged to satisfy the chosen Routing Strategy. The default RoutingStrategy looks for the fastest travel time. Strategies are also applied when a route is calculated.
In the Designer, add a Click event to the "Optimize Stops" item on the context menu. Switch to the Code View and add the following code to the new event.
private void optimizeStopsToolStripMenuItem_Click(object sender, EventArgs e) { try { //Indicate that optimization can take some time -- for long routes this.Cursor = Cursors.WaitCursor; route.OptimizeStops(); this.Cursor = Cursors.Default; mapMain.Invalidate(); } catch (Exception ex) { this.Cursor = Cursors.Default; MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.Cursor = Cursors.Default; }
Note |
---|
Optimization time may be significant enough to warrant changing the mouse cursor, as above. |
In the next tutorial we will generate driving directions for the user's chosen route.