About routing in the MapPoint object model

Routing is a powerful part of MapPoint, and you can access all of that power through automation.

MapPoint has one Route object that is in use at all times. To get directions from one place to another, or to highlight those directions on the screen, you must make modifications to that route. A route is made up of a start point, an end point, and zero or more stops along the way. Collectively, these are referred to as waypoints. Changing a route mostly consists of modifying the waypoints that make up the route. You can clear the route of all waypoints, add or remove individual waypoints, or change the order of waypoints in the route.

You can access the Route object through the ActiveRoute property of the Application object.

Modifying the waypoints in a route

Once you have the Route object, the most common way to modify the route is to change the list of waypoints that it contains. Waypoint objects are created by specifying a Location or Pushpin object that defines a start point, an end point, or stop along the route. See About locations in the MapPoint object model for more information on Pushpins and locations.

If you are creating a new route, you must clear the current route first (more than one route is not allowed in the map at a given time), using the Clear method on the Route object.

The following example creates a new route by adding waypoints:

  Sub AddWaypoints()
    Dim oMap As MapPoint.Map
    Dim oRte As MapPoint.Route
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    Set oRte = oMap.ActiveRoute
    oRte.Clear
    With oRte.Waypoints
        .Add oMap.FindAddressResults(, "New Bedford", , _
             "Mass")(1)
        .Add oMap.FindAddressResults(, "Newport", , "RI")(1)
        .Add oMap.FindAddressResults(, "Mystic", , "Conn")(1)
    End With
    oRte.Calculate
    'Zoom to the route
    oRte.Directions.Location.GoTo
End Sub

Note  The Clear method is also the easiest way to remove the route from the map. You cannot delete the Route object; you simply remove all waypoints from it so that it will not appear.

When you have finished modifying the route's waypoints, you must calculate the route in order for directions and other properties of the route to be generated. To find out whether a route is calculated, use the IsCalculated property. The Directions collection of the route is the storage of the final turn-by-turn directions and gives you useful properties and methods of the route, such as the location, which is used here to zoom to the entire route. The Directions collection and Direction objects are discussed in more detail later in "Getting driving directions."

Note  The Calculate method requires some processing time and takes a longer time depending on how complicated and long the route is. It is a good idea to optimize your code so that you do not needlessly call the Calculate method too many times. For example, you do not need to call the Calculate method after adding each waypoint. It is a good idea to finish modifying your route completely before calling the Calculate method.

Waypoints can also be created from Pushpins. The Pushpins can come from any data set, including imported and linked sets. The following example imports one of the sample files and adds a subset of the Pushpins as stops. This example uses the QueryCircle method to obtain a list of records, which is a Recordset object that can be used to add Waypoint objects to the route. Any of the query methods (QueryAllRecords, QueryCircle, and QueryShape) can be substituted here.

Note  This sample assumes that there is a MyData.mdb file with an Employees table. For this code to work properly, the table must be imported as a Pushpin map. You can modify the names and paths in this code to make it work with your data.

  Sub AddPPWaypoints()
    Dim oApp As MapPoint.Application
    Set oApp = GetObject(, "MapPoint.Application")
    oApp.PaneState = geoPaneRoutePlanner

    ' Ensure we're working in miles
    oApp.Units = geoMiles

    Dim oMap As MapPoint.Map
    Set oMap = oApp.ActiveMap

    Dim strDB As String
    strDB = App.Path & "\MyData.MDB!Employees"

    ' Add all local addresses as waypoints
    Dim dsEmps As MapPoint.DataSet
    Set dsEmps = oMap.DataSets.ImportData(strDB)

    Dim oLoc As MapPoint.Location
    Set oLoc = oMap.FindResults("Seattle, WA")(1)
    oLoc.GoTo

    ' Find all employees within 20 miles of Seattle
    Dim rsEmps As MapPoint.Recordset
    Set rsEmps = dsEmps.QueryCircle(oLoc, 20)

    ' Add those addresses as Waypoints
    Dim oWps As MapPoint.Waypoints
    Set oWps = oMap.ActiveRoute.Waypoints
    Do While Not rsEmps.EOF
        If (rsEmps.IsMatched) Then
            oWps.Add rsEmps.Pushpin
        End If
        rsEmps.MoveNext
    Loop
    oMap.ActiveRoute.Calculate

    ' How many did we get?
    MsgBox oWps.Count
End Sub

You can move Waypoint objects by setting their Anchor property, which is the Pushpin or Location object with which the Waypoint object is associated. If a Waypoint object is anchored to a Pushpin and the Pushpin is moved, then the Waypoint object moves with the Pushpin.

  Sub MoveWaypoint()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    ' Zoom in on the area
    oMap.FindResults("Rhode Island, USA")(1).GoTo

    With oMap.ActiveRoute.Waypoints
        Dim oWP As MapPoint.Waypoint
        Set oWP = .Add(oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1), "First Stop")

        MsgBox "The waypoint will be moved after this message."

        Set oWP.Anchor = oMap.FindAddressResults(,_
            "Newport", , "RI")(1)
    End With
    oMap.ActiveRoute.Calculate
End Sub

To remove a waypoint from the route, simply call the Delete method on the Waypoint object.

  Sub DeleteWaypoint()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    With oMap.ActiveRoute.Waypoints
        Dim oWP As MapPoint.Waypoint
        Set oWP = .Add(oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1), "First Stop")
        oMap.ActiveRoute.Calculate
        MsgBox "The waypoint will be deleted after this message."

        oWP.Delete
    End With
    oMap.ActiveRoute.Calculate
End Sub

You can reorder Waypoint options individually using the Reorder method or the ListPosition property:

  Sub ReorderWaypoints()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    ' Zoom in on the area
    oMap.FindResults("Massachusetts, USA")(1).GoTo

    With oMap.ActiveRoute.Waypoints
        .Add oMap.FindAddressResults(, "Boston", , "Mass")(1)
        .Add oMap.FindAddressResults(, "Newport", , "RI")(1)
        .Add oMap.FindAddressResults(, "New Bedford", , _
            "Mass")(1)
        .Add oMap.FindAddressResults(, "Mystic", , "Conn")(1)
        oMap.ActiveRoute.Calculate

        MsgBox _
            "The stops will switch position after this message."

        ' Make Newport the third stop
        .Item(2).ListPosition = 3
        oMap.ActiveRoute.Calculate

        MsgBox "The start and end points will switch after this message."

        ' Reverse the top and bottom
        .Item(4).Reorder geoMoveToTop
        .Item(2).Reorder geoMoveToBottom
        oMap.ActiveRoute.Calculate

    End With
End Sub

Note  In the preceding code, the route is calculated three times. This is unnecessary in practice but provides a useful example because you can see the route being re-created with the new waypoint order on the screen.

You can also have MapPoint automatically reorder the route to create a shorter, more efficient trip by optimizing the route. Optimizing changes the order of the stops, but does not affect the start and end points. It will not have an effect on trips with less than four waypoints. The following code sample uses the Optimize method to optimize stops:

  Sub OptimizeWaypoints()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    ' Zoom in on the area
    oMap.FindResults("Massachusetts, USA")(1).GoTo
    	
    With oMap.ActiveRoute.Waypoints
        .Add oMap.FindAddressResults(, "Boston", , "Mass")(1)
        .Add oMap.FindAddressResults(, "Newport", , "RI")(1)
        .Add oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1)
        .Add oMap.FindAddressResults(, "Mystic", , "Conn")(1)

        .Optimize
    End With
    oMap.ActiveRoute.Calculate
End Sub

Note  Optimizing can be a time-intensive process, especially as the number of stops that you are optimizing increases. It is a good idea to manage your code so that you do not have to optimize unnecessarily. For example, do not optimize after adding each waypoint. Also, notice that the route does not need to be calculated to optimize the waypoints.

Modifying the route in other ways

Changing waypoints is not the only way that you can modify a route. You can also specify arrival, wait, and departure times for each waypoint, as well as areas to avoid and general preferences for specific drivers.

The following example specifies the preferred departure time for the starting waypoint and the duration of time that will be spent at the first stop. Just as in the user interface, MapPoint will attempt to accommodate your time preferences when calculating the route, but it cannot always use these preferences. For example, if you set the departure time from the first stop at 10:00 A.M. and the arrival time for the next stop at 10:10 A.M. when there is a 30-minute drive between them, MapPoint will not be able to create the route using those preferences.

Note  Time intervals are represented in fractional days. You can use the GeoTimeConstants geoOneHour and geoOneMinute to calculate the time intervals.

  Sub WaypointTimes()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    With oMap.ActiveRoute.Waypoints
        Dim oWP As MapPoint.Waypoint
        .Add oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1)
        .Add oMap.FindAddressResults(, "Newport", , "RI")(1)
        .Add oMap.FindAddressResults(, "Mystic", , "Conn")(1)

        .Item(1).PreferredDeparture = "10:00 AM"
        .Item(2).StopTime = 3 * geoOneHour
    End With
    oMap.ActiveRoute.Calculate
End Sub

Note  You can specify the time you want to depart, arrive, or stop at a particular waypoint. You can't set the arrival time for the start waypoint or the departure time for the end waypoint.

You can create a detour around an area by creating a rectangle Shape object and setting its Avoided property to True. The following is an example of creating and using an avoided area:

  Sub AvoidArea()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    Dim locFallRiver As MapPoint.Location
    Set locFallRiver = oMap.FindAddressResults(,_
        "Fall River", , "Mass")(1)
    locFallRiver.GoTo

    ' Create an avoided area
    Dim oDetour As MapPoint.Shape
    Set oDetour = oMap.Shapes.AddShape(geoShapeRectangle, _
        locFallRiver, 4, 4)
    oDetour.Name = "Detour"
    oDetour.Avoided = True

    With oMap.ActiveRoute
        Dim oWP As MapPoint.Waypoint
        .Waypoints.Add oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1)
        .Waypoints.Add oMap.FindAddressResults(,_
            "Newport", , "RI")(1)

        .Calculate
    End With
End Sub

To remove a detour, simply call the Delete method on the Shape object or set the Avoided property to False. Removing a detour will invalidate the directions, so they will need to be recalculated.

You can also modify the way that a route is calculated by changing the driver profile. These profile settings include average driving speed, rest stop options, road preferences, how costs are calculated, size of the car's fuel tank, and other properties that may affect how the route is created. These settings can be accessed via the DriverProfile object. The following example sets the driving day from 8:00 A.M. to 7:00 P.M. with 45-minute rest breaks every four hours.

Note  Time intervals are represented in fractional days. Use the GeoTimeConstants geoOneHour and geoOneMinute to calculate the time intervals.

  Sub DefineDrivingDay()
    Dim oApp As MapPoint.Application
    Set oApp = GetObject(, "MapPoint.Application")

    Dim oDrvProf As MapPoint.DriverProfile
    Set oDrvProf = oApp.ActiveMap.ActiveRoute.DriverProfile

    oDrvProf.StartTime = "8:00 AM"
    oDrvProf.EndTime = "7:00 PM"
    oDrvProf.IncludeRestStops = True
    oDrvProf.TimeBetweenRests = 4 * geoOneHour
    oDrvProf.RestStopDuration = 45 * geoOneMinute
End Sub

Getting driving directions

Now that you can create a route that matches your set of stops and preferences, you need to create the actual driving directions. Driving directions are generated when you call the Calculate method. Driving directions include summary information, such as DrivingTime, TripTime, Distance, and Cost properties, which are accessed through the Route object. It also includes detailed driving directions, which are accessed through the Directions property. Detailed directions can be accessed for the entire route or just a route segment (the portion of a route between two consecutive waypoints). To access the directions for the entire route, use the Directions property of the Route object. To access the directions for a specific route segment of the route, use the SegmentDirections property for the Waypoint object that begins that segment.

The following code creates a route and then displays the calculated cost of the trip:

  Sub CalcRoute()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    With oMap.ActiveRoute
        .Waypoints.Add oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1)
        .Waypoints.Add oMap.FindAddressResults(,_
            "Newport", , "RI")(1)

        .Calculate
        MsgBox Format(.Cost, "$.00")
    End With
End Sub

To hide or show the Directions pane in the user interface, which includes the route directions, use the ItineraryVisible property.

  Sub ItineraryPaneToggle()
    Dim oApp As MapPoint.Application
    Set oApp = GetObject(, "MapPoint.Application")

    ' Switch the state
    oApp.ItineraryVisible = Not oApp.ItineraryVisible
End Sub

To expand or collapse directions, use the Expanded property of the Directions collection.

Direction objects and Directions collections are only valid while the itinerary that they were created with is current. Any action that changes the itinerary for a route (such as moving or adding Waypoint objects) will invalidate any Direction objects that are being accessed (such as in a variable or in a Visual Basic collection). A new Direction object must be obtained after the route is recalculated. It is therefore not advisable to cache Direction objects.

To programmatically view the directions information in automation, use the Directions collection, which contains detailed information about the calculated route. The following example shows how to access this information.

  Sub DirectionProps()
    Dim oMap As MapPoint.Map
    Set oMap = GetObject(, "MapPoint.Application").ActiveMap
    oMap.Parent.PaneState = geoPaneRoutePlanner

    With oMap.ActiveRoute
        Dim oWP As MapPoint.Waypoint
        .Waypoints.Add oMap.FindAddressResults(,_
            "New Bedford", , "Mass")(1)
        .Waypoints.Add oMap.FindAddressResults(,_
            "Newport", , "RI")(1)

        .Calculate

        MsgBox .Directions(1).StartTime & ": " & _
            .Directions(1).Instruction
    End With
End Sub

The Action property returns the action for a specified direction (such as turn left, enter roundabout, and so on), and the Type property returns the type of the direction (such as rest break, fuel stop, driving instruction, and so on).

The Directions collection and Direction object each have a Location property. This location has the "best map view" of the route, segment, or single direction that the object represents. Use this to zoom to an entire route, segment, or single direction. For more information on best map views, see Working with locations and finding places and address in the MapPoint object model.

More information

About the Microsoft MapPoint object model

What's new for Microsoft MapPoint 2004 developers

Getting started with the MapPoint object model

Getting started with the MapPoint Control

About mapping data with the MapPoint object model

About locations in the MapPoint object model

About shapes in the MapPoint object model