Routing
With the new version 6.0 of our Actionscript SDK, it is easier than ever to get directions and even have a draggable route on a map. In order to use the routing features you must include the Directions.swc into your project, which comes with the download of the Actionscript SDK.
NOTE: It is not required to use the Actionscript SDK to access the routing services. See the Mapquest Platform Web Services documentation for more information.
Contents
Creating a Simple Route
In order to get directions and routes, a Directions object is required. The only required parameter for the Directions object is a TileMap object or your API key, which can be found by signing into the Developer Network.
At its simplest form, a Directions object can be created using this piece of code:
var dir:Directions = new Directions(myMap);
Or this piece of code:
var dir:Directions = new Directions('YOUR KEY HERE');
Note: Using a TileMap object in the constructor will automatically place a route ribbon and the POIs of the locations on that map.
In order to get a route, locations must be specified. This is done using the locations property of the Directions object, to an array of locations:
dir.locations = ['York, PA', 'Lancaster, PA'];
This can also be set in the constructor:
var arrLocations:Array = new Array(); arrLocations = ['York, PA', 'Lancaster, PA']; var dir:Directions = new Directions(myMap, arrLocations);
One last parameter can be set as the third parameter in a Directions constructor, a DirectionsOptions object:
var dir:Directions = new Directions(myMap, arrLocations, options);
To receive the response of a route call, the Directions object must have event listeners set. There are three specific DirectionsEvent constants that can be used. One for a successful route call, one for an unsuccessful route call, and one for an ambiguous route call.
NOTE: An ambiguous route call is when one or more locations are not specific enough to know the exact location. In this case an object with a list of possible locations is returned.
This is an example of setting all three of these event listeners:
dir.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, doSuccess); dir.addEventListener(DirectionsEvent.DIRECTIONS_AMBIGUITY, doAmbiguities); dir.addEventListener(DirectionsEvent.DIRECTIONS_ERROR, doError);
The last step required is to simply make the route function call:
dir.route();
The table below explains properties of the Directions object.
| Property | Description |
|---|---|
| bestFitRouteStops Boolean |
This property sets whether the map should try and fit all the route stops on the map, or if it should just keep the map how it is, regardless of whether all the stops are visible or not. |
| key String |
The unique API key given to a user upon signing up for an account. This can be found by signing into the Developer Network. |
| locations Array |
This is an array of locations to use as stops on a route. |
| map TileMap object |
This property is to set a map for the route to be shown on.
If a map was used in the Directions constructor, then this property should already be set to that map.
Note: A map property can be null if a user doesn't intend to show a route on a map. |
| options DirectionsOptions object |
If a user intends to use options provided for the routing service, a DirectionsOptions object must be created and set to the options property. See below for details. |
| ribbonIsDraggable Boolean |
When this is true, the route ribbon and stops that are on a map are draggable. If set to false the route is not draggable. |
Route Function
The route() method is used to make a route call. To retrieve the information returned, an event listener must be assigned to the Directions object. The DirectionsEvent object will contain the route information. For more details on our routing service see Mapquest Platform Web Serivces. The sample below makes a simple route() call, puts a draggable route onto the map, and then uses the response to list the directions on a textArea.
Here is the code to the above sample:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCC()">
<mx:Script>
<![CDATA[
import com.mapquest.LatLng;
import com.mapquest.tilemap.TileMap;
import com.mapquest.services.directions.*;
import mx.core.UIComponent;
import mx.controls.TextArea;
private var myMap:TileMap;
private var dir:Directions;
private var txt:TextArea = new TextArea();
/*
* initial function to set up the map
*/
private function onCC():void {
//create a UIComponent for the map
var myUIC:UIComponent = new UIComponent();
//create the map
this.myMap = new TileMap("YOUR_KEY_HERE");
//add the map to the UIComponent
myUIC.addChild(this.myMap);
//add the UIComponent to the stage
this.addChild(myUIC);
//create a text area to display results
txt.y = 480;
txt.width = 550;
txt.height = 475;
this.addChild(txt);
}
/*
* function creates a directions object and calls route()
*/
private function getTheRoute():void {
//create an array of locations
var arrLocations:Array = new Array();
arrLocations = ['Lancaster, PA', 'York, PA'];
//create the Directions object
this.dir = new Directions(myMap, arrLocations);
//give dir event listeners
dir.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, doSuccess);
dir.addEventListener(DirectionsEvent.DIRECTIONS_AMBIGUITY, doAmbiguities);
dir.addEventListener(DirectionsEvent.DIRECTIONS_ERROR, doError);
//get the route
dir.route();
}
/*
* function to handle a successful route call
* this function displays the returned directions from the DriectionsEvent object
*/
private function doSuccess(e:DirectionsEvent):void {
//after a route call, if the route is to be placed on a map,
//the routeShape will be called to ensure the route is fitted on the map appropriately
//this if statement makes sure we don't execute the following code twice
if (e.routeType != "routeShape") {
txt.htmlText = '';
//displays the total distance and time first
if (e.xml.route.options.unit == "K") {
txt.htmlText += "Total Distance: " + Number(e.xml.route.distance).toFixed(2)
+ " Kilometers";
}
else {
txt.htmlText += "Total Distance: " + Number(e.xml.route.distance).toFixed(2) + " Miles";
}
txt.htmlText += " Time: " + e.xml.route.formattedTime + "\n\n";
//loop through each maneuver in each leg and display the narrative as well as the time and distance
for each (var leg:XML in e.xml.route.legs.leg) {
for each (var maneuver:XML in leg.maneuvers.maneuver) {
txt.htmlText += maneuver.narrative;
if (maneuver.time != 0) {
if (e.xml.route.options.unit == "K") {
txt.htmlText += "\n(Distance: "
+ Number(maneuver.distance).toFixed(2)
+ " Kilometers";
}
else {
txt.htmlText += "\n(Distance: "
+ Number(maneuver.distance).toFixed(2) + " Miles";
}
txt.htmlText += " Time: " + maneuver.formattedTime + ")";
}
txt.htmlText += "\n\n";
}
}
}
}
/*
* function to handle a route call with ambiguities in it
* this function will display a list of ambiguous locations from the DirectionsEvent object
*/
private function doAmbiguities(e:DirectionsEvent):void {
txt.text += "Ambiguities were found, please choose the correct location\n";
for each (var loc:XML in e.xml.collections.locations.location) {
txt.text += loc.adminArea5 + ", " + loc.adminArea3 + ", " + loc.adminArea4 + "\n";
}
}
/*
* function to handle an unsuccessful route call
* this function will display the error message that was given from the DirectionsEvent object
*/
private function doError(e:DirectionsEvent):void {
for each (var error:XML in e.xml.info.messages.message) {
txt.text += error + "\n";
}
}
]]>
</mx:Script>
<mx:Button x="10" y="483" label="Get the Route" click="getTheRoute()"/>
</mx:Application>
Optimized Route Function
The optimizedRoute() method is used to make an optimized route call. An optimized route does a route call, but will rearrange stops in order to route the most optimal path. The starting and ending location will remain the same, so in order to see an optimized route work there must be at least four stops in the route. For more details see Mapquest Platform Web Serivces
Here is the code to the above sample:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCC()">
<mx:Script>
<![CDATA[
import com.mapquest.LatLng;
import com.mapquest.tilemap.TileMap;
import com.mapquest.services.directions.*;
import mx.core.UIComponent;
import mx.controls.TextArea;
private var myMap:TileMap;
private var dir:Directions;
private var txt:TextArea = new TextArea();
/*
* initial function to set up the map
*/
private function onCC():void {
//create a UIComponent for the map
var myUIC:UIComponent = new UIComponent();
//create the map
this.myMap = new TileMap("YOUR_KEY_HERE");
//add the map to the UIComponent
myUIC.addChild(this.myMap);
//add the UIComponent to the stage
this.addChild(myUIC);
//create a text area to display results
txt.x = 553;
txt.width = 550;
txt.height = 475;
this.addChild(txt);
}
/*
* function creates a directions object and calls route()
*/
private function getTheRoute(type:String):void {
//create an array of locations
var arrLocations:Array = new Array();
arrLocations = ['Windsor, PA', 'Lancaster, PA', 'York, PA', 'Elizabethtown, PA'];
//clear any previous routes
if (dir) {
dir.removeRoute();
}
else {
//create directions object with our map, array of locations
dir = new Directions(myMap, arrLocations);
}
//give dir event listeners
dir.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, doSuccess);
dir.addEventListener(DirectionsEvent.DIRECTIONS_AMBIGUITY, doAmbiguities);
dir.addEventListener(DirectionsEvent.DIRECTIONS_ERROR, doError);
//make the routeRibbon draggable
dir.ribbonIsDraggable = true;
//check whether to do a regular route or an optimized route
if (type == "route") {
//get the route
dir.route();
}
else if (type == "optimized") {
//get the optimized route
dir.optimizedRoute();
}
}
/*
* function to handle a successful route call
* this function displays the returned directions from the DriectionsEvent object
*/
private function doSuccess(e:DirectionsEvent):void {
//after a route call, if the route is to be placed on a map,
//the routeShape will be called to ensure the route is fitted on the map appropriately
//this if statement makes sure we don't execute the following code twice
if (e.routeType != "routeShape") {
txt.htmlText = '';
//displays the total distance and time first
if (e.xml.route.options.unit == "K") {
txt.htmlText += "Total Distance: " + Number(e.xml.route.distance).toFixed(2)
+ " Kilometers";
}
else {
txt.htmlText += "Total Distance: " + Number(e.xml.route.distance).toFixed(2) + " Miles";
}
txt.htmlText += " Time: " + e.xml.route.formattedTime + "\n\n";
//loop through each maneuver in each leg and display the narrative as well as the time and distance
for each (var leg:XML in e.xml.route.legs.leg) {
for each (var maneuver:XML in leg.maneuvers.maneuver) {
txt.htmlText += maneuver.narrative;
if (maneuver.time != 0) {
if (e.xml.route.options.unit == "K") {
txt.htmlText += "\n(Distance: "
+ Number(maneuver.distance).toFixed(2)
+ " Kilometers";
}
else {
txt.htmlText += "\n(Distance: "
+ Number(maneuver.distance).toFixed(2) + " Miles";
}
txt.htmlText += " Time: " + maneuver.formattedTime + ")";
}
txt.htmlText += "\n\n";
}
}
}
}
/*
* function to handle a route call with ambiguities in it
* this function will display a list of ambiguous locations from the DirectionsEvent object
*/
private function doAmbiguities(e:DirectionsEvent):void {
txt.text += "Ambiguities were found, please choose the correct location\n";
for each (var loc:XML in e.xml.collections.locations.location) {
txt.text += loc.adminArea5 + ", " + loc.adminArea3 + ", " + loc.adminArea4 + "\n";
}
}
/*
* function to handle an unsuccessful route call
* this function will display the error message that was given from the DirectionsEvent object
*/
private function doError(e:DirectionsEvent):void {
for each (var error:XML in e.xml.info.messages.message) {
txt.text += error + "\n";
}
}
]]>
</mx:Script>
<mx:Button x="10" y="483" label="Route" click="getTheRoute('route')"/>
<mx:Button x="78" y="483" label="Optimized Route" click="getTheRoute('optimized')"/>
</mx:Application>
Route Matrix Function
The routeMatrix() method is used to make a route matrix call. A route matrix call will not put anything on a map. In the response you will receive distances and times from one location to any others given, or from all locations to all locations given, depending on parameters set. For more details see Mapquest Platform Web Serivces
Here is the code to the above sample:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCC()">
<mx:Script>
<![CDATA[
import com.mapquest.tilemap.pois.Poi;
import com.mapquest.LatLng;
import com.mapquest.tilemap.TileMap;
import com.mapquest.services.directions.*;
import mx.core.UIComponent;
import mx.controls.TextArea;
private var myMap:TileMap;
private var dir:Directions;
private var txt:TextArea = new TextArea();
/*
* initial function to set up the map
*/
private function onCC():void {
//create a UIComponent for the map
var myUIC:UIComponent = new UIComponent();
//create the map
this.myMap = new TileMap("YOUR_KEY_HERE");
//add the map to the UIComponent
myUIC.addChild(this.myMap);
//add the UIComponent to the stage
this.addChild(myUIC);
//create a text area to display results
txt.x = 553;
txt.width = 550;
txt.height = 475;
this.addChild(txt);
}
/*
* function creates a directions object and calls route()
*/
private function getTheRoute():void {
//create an array of locations
var arrLocations:Array = new Array();
arrLocations = ['Lancaster, PA', 'York, PA', 'Windsor, PA', 'West Chester, PA'];
//clear any previous routes
if (dir) {
dir.locations = arrLocations;
}
else {
//create directions object with our map, array of locations
dir = new Directions(myMap, arrLocations);
}
//give dir event listeners
dir.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, doSuccess);
dir.addEventListener(DirectionsEvent.DIRECTIONS_AMBIGUITY, doAmbiguities);
dir.addEventListener(DirectionsEvent.DIRECTIONS_ERROR, doError);
//get the route
dir.routeMatrix();
}
/*
* function to handle a successful route call
* this function displays the returned directions from the DriectionsEvent object
*/
private function doSuccess(e:DirectionsEvent):void {
//create some counter variables
var i:int = 0;
var j:int = 0;
//clear any text in the textArea
txt.text = "";
//go through and give the results of the matrix
//the first if is for if allToAll is false
var arr:Array = new Array();
arr = e.xml.distance.split(",");
txt.text += "Distances:\n";
for (i=0; i<arr.length; i++) {
txt.text += e.xml.locations.location[0].adminArea5
+ ", " + e.xml.locations.location[0].adminArea3;
txt.text += " to " + e.xml.locations.location[i].adminArea5
+ ", " + e.xml.locations.location[i].adminArea3;
txt.text += ": " + arr[i] + " Miles";
txt.text += "\n";
}
txt.text += "\n";
arr = new Array();
arr = e.xml.time.split(",");
txt.text += "Times:\n";
for (j=0; j<arr.length; j++) {
txt.text += e.xml.locations.location[0].adminArea5
+ ", " + e.xml.locations.location[0].adminArea3;
txt.text += " to " + e.xml.locations.location[j].adminArea5
+ ", " + e.xml.locations.location[j].adminArea3;
txt.text += ": " + arr[j] + " seconds";
txt.text += "\n";
}
//remove any pois from a previous matrix call, and make pois for the current locations
myMap.removeAllShapes();
for each (var loc:XML in e.xml.locations.location) {
var ll:LatLng = new LatLng(Number(loc.latLng.lat), Number(loc.latLng.lng));
var poi:Poi = new Poi(ll);
myMap.addShape(poi);
}
myMap.bestFit();
//remove the event listeners
dir.removeEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, doSuccess);
dir.removeEventListener(DirectionsEvent.DIRECTIONS_AMBIGUITY, doAmbiguities);
dir.removeEventListener(DirectionsEvent.DIRECTIONS_ERROR, doError);
}
/*
* function to handle a route call with ambiguities in it
* this function will display a list of ambiguous locations from the DirectionsEvent object
*/
private function doAmbiguities(e:DirectionsEvent):void {
txt.text += "Ambiguities were found, please choose the correct location\n";
for each (var loc:XML in e.xml.collections.locations.location) {
txt.text += loc.adminArea5 + ", " + loc.adminArea3 + ", " + loc.adminArea4 + "\n";
}
}
/*
* function to handle an unsuccessful route call
* this function will display the error message that was given from the DirectionsEvent object
*/
private function doError(e:DirectionsEvent):void {
for each (var error:XML in e.xml.info.messages.message) {
txt.text += error + "\n";
}
}
]]>
</mx:Script>
<mx:Button x="10" y="483" label="Get the Route Matrix" click="getTheRoute()"/>
</mx:Application>
There is also one last function the Directions object provides; removeRoute(). This function returns void and its purpose is to remove a route from a map. This function is generally used when it is possible for another route to have been on a map. The samples demonstrate how this can be used.
Routing Options
The above example is our routing for Actionscript in its simplest form. There are many ways of forming locations, options for the route request, and information that can be taken from a route response.
Specifying Locations
Locations can take many forms, not just a city and state pair like shown in the example. A location can be a single-line location like above or a LatLng object:
var arrLocations:Array = new Array(); arrLocations = ['300 granite run dr, lancaster, pa, 17601', new LatLng(39.900799,-76.606102)];
For the complete list of acceptable location formats see Mapquest Platform Web Services
A route can also have more than two locations (demonstrated in the optimized route sample above):
var arrLocations:Array = new Array(); arrLocations = ['300 granite run dr, lancaster, pa', '17356', new LatLng(39.900799,-76.606102), 'york,pa,17401'];
Specifying Options
There are a number of options that can be used when making route requests. In order to use them, a DirectionsOptions object must be created.
var dirOptions:DirectionsOptions = new DirectionsOptions();
The table below explains all the options available.
| Property | Description |
|---|---|
|
units
String |
Specifies the type of units to use when calculating distance.
Acceptable values are:
|
|
routeType
String |
Specifies the type of route wanted.
Acceptable values are:
|
|
narrativeType
String |
Specifies the type of narrative to generate.
|
|
maxLinkId
Integer Default = 0 |
The maximum number of Link Ids to return for each maneuver. If zero, no Link Id data is returned. |
|
locale
String Default = en_US |
Language to use in the narrative. Input can be any supported ISO 639-1 code |
|
avoids
String collection |
Attribute flags of roads to try to avoid.
The available attribute flags depend on the data set.
This does not guarantee roads with these attributes
will be avoided if alternate route paths are too
lengthy or not possible or roads that contain
these attributes are very short.
Available choices:
|
|
mustAvoidLinkIds
Integer Collection |
Link Ids of roads to absolutely avoid. May cause some routes to fail. Multiple link ids should be comma-separated. |
|
tryAvoidLinkIds
Integer Collection |
Link Ids of roads to try to avoid during route calculation. Does not guarantee these roads will be avoided if alternate route paths are too lengthy or not possible. Multiple link ids should be comma-separated. |
|
stateBoundaryDisplay
Boolean |
State boundary display option.
|
|
countryBoundaryDisplay
Boolean |
Country boundary display option
|
|
sideOfStreetDisplay
Boolean |
Side of street display option
|
|
destinationManeuverDisplay
Boolean |
The "End at" destination maneuver display option
|
|
shapeFormat
String |
Shape format options.
|
| generalize |
If
mapState
is provided, this option will be ignored.
If no
mapState
is provided, this parameter will be used to reduce
the number of points returned in the
shapePoints
object.
If the
generalize
parameter is
0
, then
no shape simplification will be done and all shape points will be returned.
If the
generalize
parameter is >
0
,
it will be used as the tolerance distance (in meters) in the Douglas-Peucker Algorithm
for line simplification.
Higher values of
generalize
will result in fewer points
in the final route shape.
|
|
ambiguities
String |
This property tells the service how to handle an ambiguous location. If this property is set to "ignore", the route will use the first location in a list of possible locations. If this property is set to anything else, an ambiguous location will cause the route to return a list of possible locations, rather than the route. |
|
allToAll
Boolean |
This property is used only for a route matrix call. See the route matrix section for details on a route matrix call.
|
Route Sample with Options
This is the code for the above sample:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCC()">
<mx:Script>
<![CDATA[
import com.mapquest.LatLng;
import com.mapquest.tilemap.TileMap;
import com.mapquest.services.directions.*;
import mx.core.UIComponent;
import mx.controls.TextArea;
private var myMap:TileMap;
private var dir:Directions;
private var dirOptions:DirectionsOptions = new DirectionsOptions();
private var txt:TextArea = new TextArea();
/*
* initial function to set up the map
*/
private function onCC():void {
//create a UIComponent for the map
var myUIC:UIComponent = new UIComponent();
//create the map
this.myMap = new TileMap("YOUR_KEY_HERE");
//add the map to the UIComponent
myUIC.addChild(this.myMap);
//add the UIComponent to the stage
this.addChild(myUIC);
//create a text area to display results
txt.x = 553;
txt.width = 550;
txt.height = 475;
this.addChild(txt);
}
/*
* function creates a directions object and calls route()
*/
private function getTheRoute():void {
//create an array of locations
var arrLocations:Array = new Array();
arrLocations = ['Lancaster, PA', 'York, PA'];
//clear any previous routes
if (dir) {
dir.locations = arrLocations;
}
else {
//create directions object with our map, array of locations
dir = new Directions(myMap, arrLocations);
}
//give dir event listeners
dir.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, doSuccess);
dir.addEventListener(DirectionsEvent.DIRECTIONS_AMBIGUITY, doAmbiguities);
dir.addEventListener(DirectionsEvent.DIRECTIONS_ERROR, doError);
//make the routeRibbon draggable
dir.ribbonIsDraggable = true;
//set a few options for demonstration
dirOptions.unit = "k";
dirOptions.routeType = "pedestrian";
dirOptions.narrativeType = "html";
dirOptions.avoids = ['limited access'];
//set the options to the Directions object
dir.options = dirOptions;
//get the route
dir.route();
}
/*
* function to handle a successful route call
* this function displays the returned directions from the DriectionsEvent object
*/
private function doSuccess(e:DirectionsEvent):void {
//after a route call, if the route is to be placed on a map,
//the routeShape will be called to ensure the route is fitted on the map appropriately
//this if statement makes sure we don't execute the following code twice
if (e.routeType != "routeShape") {
txt.htmlText = '';
//displays the total distance and time first
if (e.xml.route.options.unit == "K") {
txt.htmlText += "Total Distance: " + Number(e.xml.route.distance).toFixed(2)
+ " Kilometers";
}
else {
txt.htmlText += "Total Distance: " + Number(e.xml.route.distance).toFixed(2) + " Miles";
}
txt.htmlText += " Time: " + e.xml.route.formattedTime + "\n\n";
//loop through each maneuver in each leg and display the narrative as well as the time and distance
for each (var leg:XML in e.xml.route.legs.leg) {
for each (var maneuver:XML in leg.maneuvers.maneuver) {
txt.htmlText += maneuver.narrative;
if (maneuver.time != 0) {
if (e.xml.route.options.unit == "K") {
txt.htmlText += "\n(Distance: "
+ Number(maneuver.distance).toFixed(2)
+ " Kilometers";
}
else {
txt.htmlText += "\n(Distance: "
+ Number(maneuver.distance).toFixed(2) + " Miles";
}
txt.htmlText += " Time: " + maneuver.formattedTime + ")";
}
txt.htmlText += "\n\n";
}
}
}
}
/*
* function to handle a route call with ambiguities in it
* this function will display a list of ambiguous locations from the DirectionsEvent object
*/
private function doAmbiguities(e:DirectionsEvent):void {
txt.text += "Ambiguities were found, please choose the correct location\n";
for each (var loc:XML in e.xml.collections.locations.location) {
txt.text += loc.adminArea5 + ", " + loc.adminArea3 + ", " + loc.adminArea4 + "\n";
}
}
/*
* function to handle an unsuccessful route call
* this function will display the error message that was given from the DirectionsEvent object
*/
private function doError(e:DirectionsEvent):void {
for each (var error:XML in e.xml.info.messages.message) {
txt.text += error + "\n";
}
}
]]>
</mx:Script>
</mx:Application>
Route Response Object
After a route call, a DirectionsEvent object is returned to the function specified in the addEventListener() function. This object can be used to read the response of the route. The exact format of this object will change based on the success of the route and type of route. For descriptions on the information that can be retrieved see Mapquest Platform Web Services