Flash CS3 .fla file (zipped archive)
Flex 3 project, ready for import (zipped archive)
1. Installation
-
Flash CS3 Installation: Install UMap Routing API extension using Adobe Extension Manager.
Start Flash CS3, then open the "Components" window (Window->Components, or CTRL+F7). Drag and drop the
UMap Routing API component on stage.
You can then delete it from stage, or leave it: either way it will work once it is in your movie's library.
-
Flex Builder Installation: Open up Flex Builder, create new project (File->New->Flex Project).
Enter the settings for your project, click next, define the output foler, click next. Select the "Library path" tab, click "Add SWC..." button and point to the UMap_Routing_API_Flex.swc file.
Define other parameters and click "Finish". You are ready. (Note: typically you will also want to add UMap_Flex.swc file to your library path).
2. Select routing service
Before using the UMap Routing API you need to choose on of the available Routing Service Providers:
- CloudMade Routing Service (http://www.cloudmade.com/products/routing)
- MapQuest Routing Service (http://developer.mapquest.com/)

3. Route Manager
RouteManager is the main class which handles all the routing process. You shoud use to send routing requests, getting service state and obtainig the results. Here is how you can initialize the RoutingManager with one of the services:
// CloudMade Service
var rm:RouteManager = new RouteManager(RouteManager.CLOUD_MADE_SERVICE, {apikey:"My API Key here"});
// or
// MapQuest Service
// var rm:RouteManager = new RouteManager(RouteManager.MAP_QUEST_SERVICE, {clientId:"My Client ID", password:"My Password"});
// add manager to the map
map.addManager(rm);
When routing manager performs the routing, it dispatches RouteEvent.READY or RouteEvent.FAILURE event. We would certainly want to catch that, so that we can display the results or alert an error. So we add 2 listeners to the RouteManager instance.
rm.addEventListener(RouteEvent.READY, rmEvent);
rm.addEventListener(RouteEvent.FAILURE, rmEvent);
function rmEvent(event:RouteEvent):void
{
trace(event);
}
4. Perform routing
To do the routing request, construct an Array of LatLng objects which will represent the routing destinations. Then call the doRoute(Array) method of the RouteManager instance.
// construct array of destinations
var locations:Array = [];
locations.push(new LatLng(48.8, 2.3)); // Paris, France
locations.push(new LatLng(52.5, 13.4)); // Berlin, Germany
// perform routing
rm.doRoute(locations);
Once the routing is complete, and RouteManager dispatched RouteEvent.READY, we want to show the route on map, and center that in the map view, so we add some code the the rmEvent(event) function:
function rmEvent(event:RouteEvent):void
{
trace(event);
switch(event.type)
{
case RouteEvent.READY:
// show result on the default layer, and get a reference to the created polyline
var poly:Polyline = rm.showResults(event.routeResults, map.getDefaultLayer());
// set map bounds to the polyline extent
map.setBounds(poly.getBoundsLatLng());
break;
}
}
5. Advanced routing options
When you call doRoute() method, you can also specify additional routing options in the second parameter of the function call. These options differ for each routing service provider, so please read the documentation for these classes.
In our example, we can tune the type of routing request to get walking directions:
var options:Object = {};
options.routeType = CloudMadeService.ROUTE_TYPE_FOOT;
// perform routing
rm.doRoute(locations, options);
import com.afcomponents.umap.overlays.Marker;
// add start & end marker
map.addOverlay(new Marker({index:"A", position:locations[0], name:"Start"}));
map.addOverlay(new Marker({index:"B", position:locations[1], name:"End"}));

6. Understanding route results
Routing results returned by the RouteManager consist of one or more Route objects.
These objects connect the routing locations in pairs. The Routes consist of one or more Maneuver objects.
Each manuver represents a single instruction and the path polyline.
Keeping this in mind, we can write a code which will create a point for each maneuver, so that user can click on it and get the instructions.
var maneuvers:Array = rm.getAllManeuvers(results);
trace("Maneuvers total:" + maneuvers.length);
The getAllManeuvers() will return an Array of objects with label and data properties. We can use this Array to create a DataProvider object to populate a List or Combobox component. In the data property of the list item object will be stored a reference to the Maneuver object. We can access this object to, for example, open InfoWindow upon user click.
...
// set DataProvider property of the list object
list.dataProvider = new DataProvider(maneuvers);
...
// add listeners to the list
list.addEventListener(MouseEvent.CLICK, listClick);
function listClick(event:MouseEvent):void
{
// show the selected maenuver
var m:Maneuver = list.selectedItem.data;
var details:String = "" +
"Distance: " + m.distance + " metersn" +
"Time: " + m.time + "n" +
(m.turnType != "" ? "Turn type: " + m.turnType + "n" : "") +
"Heading: " + m.heading;
map.setBounds(LatLngBounds.fromLatLngArray(m.shape), null, true, 16);
map.openInfoWindow({position:m.shape[0], title:m.narrative, content:details, autoPan:true, offset:new Point(0, 0)});
}
7. The complete code (Flash)
You can download the full source .fla or create the example manually. Here are the instructions for manual creation: create new .fla file, add UMap, UMap Routing API and List components. Then add the following to the first frame:
import fl.controls.List;
import fl.data.DataProvider;
import com.afcomponents.umap.types.LatLngBounds;
import com.afcomponents.umap.display.routemanager.*;
import com.afcomponents.umap.events.RouteEvent;
import com.afcomponents.umap.core.UMap;
import com.afcomponents.umap.overlays.Polyline;
import com.afcomponents.umap.overlays.RouteLayer;
import com.afcomponents.umap.overlays.Marker;
import com.afcomponents.umap.types.RouteResults;
import com.afcomponents.umap.types.Route;
import com.afcomponents.umap.types.Maneuver;
import com.afcomponents.umap.types.LatLng;
// create UMap
var map:UMap = new UMap();
map.setSize(300,400);
map.x = map.y = 0;
addChild(map);
map.setCenter(new LatLng(47.25976 ,9.58423), 5);
// create rotue manager
var rm:RouteManager = new RouteManager(
RouteManager.CLOUD_MADE_SERVICE,
{apikey:"d128b3ae5eda571b9c8a429f53cc0f6a"}
);
map.addManager(rm);
rm.addEventListener(RouteEvent.READY, rmEvent);
rm.addEventListener(RouteEvent.FAILURE, rmEvent);
function rmEvent(event:RouteEvent):void
{
switch(event.type)
{
case RouteEvent.READY:
var results:RouteResults = event.routeResults;
// show result on the default layer,
// and get a reference to the created polyline
var poly:Polyline = rm.showResults(
results,
map.getDefaultLayer()
);
// set map bounds to the polyline extent
map.setBounds(poly.getBoundsLatLng());
// extract maneuvers
var maneuvers:Array = rm.getAllManeuvers(results);
trace("Maneuvers total:" + maneuvers.length);
populateManeuverList(maneuvers);
break;
}
}
// create list
var list:List = new List();
list.setSize(200,400);
list.x = 300;
addChild(list);
// add listeners to list
list.addEventListener(MouseEvent.CLICK, listClick);
function listClick(event:MouseEvent):void
{
// show the selected maenuver
var m:Maneuver = list.selectedItem.data;
var details:String = "" +
"Distance: " + m.distance + " metersn" +
"Time: " + m.time + "n" +
(m.turnType != "" ? "Turn type: " + m.turnType + "n" : "") +
"Heading: " + m.heading;
map.setBounds(LatLngBounds.fromLatLngArray(m.shape), null, true, 16);
map.openInfoWindow({
position:m.shape[0],
title:m.narrative,
content:details,
autoPan:true,
offset:new Point(0, 0)
});
}
// add maneuvers to the list
function populateManeuverList(maneuvers:Array):void
{
// clear ol items
list.removeAll();
// convert array to DataProvider
list.dataProvider = new DataProvider(maneuvers);
}
// define route options
var options:Object = {};
options.routeType = CloudMadeService.ROUTE_TYPE_FOOT;
// define locations
var locations:Array = [new LatLng(48.8, 2.3), new LatLng(52.5, 13.4)];
// route!
rm.doRoute(locations, options);
// add start, end marker
map.addOverlay(new Marker({index:"A", position:locations[0], name:"Start"}));
map.addOverlay(new Marker({index:"B", position:locations[1], name:"End"}));
8. The complete code (Flex)
You can download the full source Flex project or create the example manually. Here are the instructions for manual creation: create new Flex Project, add UMap, UMap Routing API SWC files. Then use the following to the Application MXML file:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
horizontalAlign="left"
verticalAlign="top"
creationComplete="init()"
>
<mx:HBox width="100%" height="100%">
<mx:Canvas width="100%" height="100%" id="mapCanvas">
</mx:Canvas>
<mx:List
height="100%"
width="200"
id="list"
enabled="false"
click="listClick()"
>
<mx:dataProvider>
Please wait...
</mx:dataProvider>
</mx:List>
</mx:HBox>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import com.afcomponents.umap.display.routemanager.*;
import com.afcomponents.umap.events.RouteEvent;
import com.afcomponents.umap.core.UMap;
import com.afcomponents.umap.overlays.Polyline;
import com.afcomponents.umap.overlays.RouteLayer;
import com.afcomponents.umap.overlays.Marker;
import com.afcomponents.umap.types.RouteResults;
import com.afcomponents.umap.types.Route;
import com.afcomponents.umap.types.Maneuver;
import com.afcomponents.umap.types.LatLng;
import com.afcomponents.umap.types.LatLngBounds;
private var map:UMap;
private var rm:RouteManager;
private function init():void
{
// create map
createMap();
// create route manager
createRouteManager();
// do routing
doRouting();
map.setCenter(new LatLng(47.25976 ,9.58423), 5);
}
private function createMap():void
{
// create map
map = new UMap();
map.setSize(mapCanvas.width, mapCanvas.height);
// add map to canvas
mapCanvas.rawChildren.addChild(map);
}
private function createRouteManager():void
{
// create rotue manager
rm = new RouteManager(
RouteManager.CLOUD_MADE_SERVICE,
{apikey:"d128b3ae5eda571b9c8a429f53cc0f6a"}
);
map.addManager(rm);
// add event listeners
rm.addEventListener(RouteEvent.READY, rmEvent);
rm.addEventListener(RouteEvent.FAILURE, rmEvent);
}
private function rmEvent(event:RouteEvent):void
{
switch(event.type)
{
case RouteEvent.READY:
var results:RouteResults = event.routeResults;
// show result on the default layer,
// and get a reference to the created polyline
var poly:Polyline = rm.showResults(
results,
map.getDefaultLayer()
);
// set map bounds to the polyline extent
map.setBounds(poly.getBoundsLatLng());
// extract maneuvers
var maneuvers:Array = rm.getAllManeuvers(results);
populateManeuverList(maneuvers);
break;
}
}
// add maneuvers to the list
private function populateManeuverList(maneuvers:Array):void
{
list.enabled = true;
// convert array to DataProvider
list.dataProvider = maneuvers;
}
private function doRouting():void
{
// define route options
var options:Object = {};
options.routeType = CloudMadeService.ROUTE_TYPE_FOOT;
// define locations
var locations:Array = [new LatLng(48.8, 2.3), new LatLng(52.5, 13.4)];
// route!
rm.doRoute(locations, options);
// add start, end marker
map.addOverlay(new Marker({index:"A", position:locations[0], name:"Start"}));
map.addOverlay(new Marker({index:"B", position:locations[1], name:"End"}));
}
private function listClick():void
{
// show the selected maenuver
var m:Maneuver = list.selectedItem.data;
var details:String = "" +
"Distance: " + m.distance + " metersn" +
"Time: " + m.time + "n" +
(m.turnType != "" ? "Turn type: " + m.turnType + "n" : "") +
"Heading: " + m.heading;
map.setBounds(LatLngBounds.fromLatLngArray(m.shape), null, true, 16);
map.openInfoWindow({
position:m.shape[0],
title:m.narrative,
content:details,
autoPan:true,
offset:new Point(0, 0)
});
}
]]>
</mx:Script>
</mx:Application>
9. Is that all?
That is all for now. But we haven't discussed all the features in the RouteManager, and there is also a special RouteLayer object. We will continue later, meanwhile we will be happy to hear your thoughts. Is the class easy to use? What features would you like to see in future releases? Thanks.
