In this tutorial, I’ll show you how to get started with the Yahoo! Maps API in Flash. We’ll load a couple of RSS feeds and plot some natural disaster warnings using their longitudes and latitudes.
Step 1: Get an App ID
Go to http://developer.yahoo.com/flash/maps/ and sign up for an App ID.

Step 2: Download the Component
On the Yahoo Map AS3 Component page, download the newest version of the component.

Step 3: Install the Component
When the file is done downloading, extract the zip file. Navigate to the Flash folder and install the MXP file.

Step 4: Move to Flash
Start Flash and open a new ActionScript 3.0 file, then save it in a new folder as "yahoo_map.fla".

Step 5: Set Up the Document
Change the stage size to 640×480. Navigate to the components tab and drag a copy of the YahooMaps component to the stage. Once it’s on the stage, delete it. That will put a copy in the library so we can access it from there.

Step 6: The Text Area
Drag a copy of the TextArea from the components tab. In the properties panel, change the size of the TextArea to a width of 640px and a height of 100px. Give it an X position of 0 and a Y position of 330. Finally, give it an instance name of "textArea".

Step 7: The Radio Buttons
Next, drag a copy of the the RadioButton from the components tab. Copy and paste it three times, so that there are four instances of the RadioButton component on the stage. Align them to the top and evenly space them out, so that they’re in a straight line right next to one another. Next, drag them below the TextArea component.

Step 8: The Radio Button Parameters
Select the first radio button. Give it an instance name of "radioAll". With the button still selected, switch over to the parameters panel. Give it a group name of "Disasters". Change the label property to "All" and the selected property to "true".
Select the next radio button. Give it an instance name of "radioEarth", the same group name of "Disasters", a label of "Earthquakes" and leave the selected property as "false".
Select the third radio button. Its instance name is "radioTsu", the group name is "Disasters", the label is "Tsunamis", and the selected property is "false".
Finally, select the fourth radio button. It has an instance name of "radioVolcano", its group name is "Disasters", it has a label of "Volcanoes", and selected is "false". Since we want to be able to toggle between the buttons, we gave them the same group name. Space them accordingly, so that they’re evenly spaced.

Step 9: The Empty MovieClip
Create a separate layer. Place the layer below the layer with TextArea and RadioButton components. In the library panel, at the bottom, select the new symbol icon. Create a new empty movieclip. Drag an instance onto the stage in the newly created layer, then give it an instance name of "empty". This movie clip will hold our map when it’s loaded. Give the empty movie clip an X and Y position of 0. That way it’s lined up with the top left corner of the stage.

Step 10: Setting Up the Document Class
Go to file > new and select a new ActionScript File. Save the file in the same directory as your "yahoo_map" FLA file with the name "yahoo_map.as". In your yahoo_map FLA document, in the properties panel, type "yahoo_map" in the Document class field. This will make your actionscript file the Document class for your yahoo_map FLA.

Step 11: The Document Class Skeleton
This is the basic setup for our document class:
package {
import flash.display.Sprite;
public class yahoo_map extends Sprite
{
public function yahoo_map()
{
}
}
}
Step 12: The Yahoo Maps Import Statements
These are the statements that will drive the YahooMap API
package {
import com.yahoo.maps.api.YahooMap;
import com.yahoo.maps.api.YahooMapEvent;
import com.yahoo.maps.api.core.location.LatLon;
import com.yahoo.maps.api.markers.Marker;
import flash.display.Sprite;
public class yahoo_map extends Sprite
{
public function yahoo_map()
{
}
}
}
Step 13: The Rest of the Import Statements
Simply add these below the YahooMaps import statement. Make sure that they are above the class declaration.
package {
import com.yahoo.maps.api.YahooMap;
import com.yahoo.maps.api.YahooMapEvent;
import com.yahoo.maps.api.core.location.LatLon;
import com.yahoo.maps.api.markers.Marker;
import fl.controls.RadioButtonGroup;
import fl.controls.RadioButton;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.ColorTransform;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.text.AntiAliasType;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
public class yahoo_map extends Sprite
{
public function yahoo_map()
{
}
}
}
Step 14: Declaring the Variables
Here we’re going to delcare the global variables. We’ll need the app id that you got from the YahooMaps page and we’re going to need to use some php later to make the feeds load into Flash. That is why we have the CURL constant. Make sure that these are placed below the class declaration but above the main public function.
public class yahoo_map extends Sprite
{
private static const APPID:String = "YOUR APP ID";
private static const CURL:String = "curl.php";
private var map:YahooMap;
private var ds:DropShadowFilter;
private var geo:Namespace;
private var tsuArray:Array;
private var tsuCounter:int = 0;
private var color:ColorTransform;
private var group:RadioButtonGroup;
public function yahoo_map()
Step 15: Setting up our Init Function
Here we’ll instantiate all of our variables. After searching Google, I found four RSS feeds for tsunami warnings from weather.gov. I loaded those into the tsuArray variable, so that I can load them one at a time. The geo namespace is going to help with getting to the latitude and longitude of all the RSS feeds. Also, there is a new RadioButtonGroup that will handle the toggling of the RadioButton components on the stage. Finally, I call the handleMap function. That will start the map loading process.
public function yahoo_map()
{
init();
}
private function init():void
{
tsuArray = new Array("http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_pacific.xml", "http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_hawaii.xml", "http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_indian.xml", "http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_caribe.xml");
geo = new Namespace("http://www.georss.org/georss");
ds = new DropShadowFilter(2,90,0x00000,0.75,2,2,1,3);
color = new ColorTransform();
group = new RadioButtonGroup("Disasters");
handleMap();
}
Step 16: Setting up our Map
This is where we start working with the map basics and where we’ll use our app id. Also, when we call the map.init() method, we dictate the size we want the map to be. The map will be the width of the stage and have a height that touches the top of the TextArea component. We also listen for the MAP_INITALIZE event.
private function handleMap():void
{
map = new YahooMap();
map.addEventListener(YahooMapEvent.MAP_INITIALIZE, onInit);
map.init(APPID, stage.stageWidth, 330);
}
Step 17: The Map is Ready
When the map is initialized, it will fire the onInit function. Here is where we’ll add the map to the empty movie clip that was placed on the stage. That way the map will load underneath the TextArea and RadioButton components — just in case. We then add the zoom, pan, and type widgets. These control the type of map, add the ability to pan the map and add the zoom controls. We’ll center the map to 0,0.
The map is looking for a new LatLon variable to which you plug in two numbers. I used 0,0 to set the map at where the Equator and Prime Meridian meet. After, maps zoom level is set. This is set to the highest altitude possible. That way we can see all the natural disaster warnings across the globe. Next we call the function to start loading our RSS feeds.

private function onInit(event:YahooMapEvent):void
{
empty.addChild(map);
map.addZoomWidget();
map.addPanControl();
map.addTypeWidget();
map.zoomLevel = 17;
map.centerLatLon = new LatLon(0,0);
volcanoes();
}
Step 18: cURLing the Feeds
We have to step out of Flash for a second and do a little PHP. When I started doing this project, I realized that the feeds wouldn’t load on my website. A quick and easy way that I by-passed it was be using cURL. I found a useful sample code from Google. I’m not too sure where exactly it came from, but I’ve been using the same script for some time now. Open a new PHP file, paste in the following code and save it as "curl.php"
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $_POST['earl']); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); ?>
Step 19: Back to Flash
Now that we’ve called the function to start loading our volcano feed, we can take a look at what’s going on inside the function. Simply put, we are loading our curl.php page which is loading the RSS feed. We then add a listener for when the page is done loading.
private function volcanoes():void
{
var url:URLLoader = new URLLoader();
url.addEventListener(Event.COMPLETE, onVolcano);
var vars:URLVariables = new URLVariables();
var req:URLRequest = new URLRequest(CURL);
req.method = URLRequestMethod.POST;
vars.earl = "http://volcanoes.usgs.gov/rss/vhpcaprss.xml"
req.data = vars;
url.load(req);
}
Step 20: The First Feed is Loaded
In the first feed, there are a few interesting features. The most important one is the geo:point. This is the latitude and longitude of the warning. Also, in this feed, there is a color code to show the alert level of the activity. With the feed loaded, there are two xml lists that are going to be loaded. One is for the latitude and longitude. The other is for the color code.
The lists are looped through and the new markers are created on the map. Custom movie clips are added to the markers, these are made using functions I will describe soon. The color of the nested movie clips is controlled by using the "colorTransform" property. After the feed is loaded and the markers are placed, the next RSS feed is set to load. I also pass the description text to the newly created movie clip, so that I can get to it later using the name that was given to the movie clip.

private function onVolcano(event:Event):void
{
var vol:Namespace = new Namespace("http://volcano.wr.usgs.gov/rss/volcanons/1.0");
var xml:XML = new XML(event.target.data);
var pointList:XMLList = xml..geo::point.text();
var colorList:XMLList = xml..vol::colorcode.text();
var string:String;
for(var i:uint; i
Step 21: Loading the Second Feed
Now it’s time to load the earthquakes RSS feed. The functions work pretty much the same way as before.
private function earthQuakes():void
{
var url:URLLoader = new URLLoader();
var vars:URLVariables = new URLVariables();
var req:URLRequest = new URLRequest(CURL);
req.method = URLRequestMethod.POST;
vars.earl = "http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml"
req.data = vars;
url.addEventListener(Event.COMPLETE, onEarthQuake);
url.load(req);
}
The differences are that there is no color code for this feed. Instead I just change the color manually to brown. Also, the description of the alert has some html inside it. I used a regular expression that I came across from Google a while back to strip all the HTML out of it. Without doing that, the TextArea component will load an image, which I didn’t want.
One more thing to note is that this is a different type of RSS feed. For some reason (in my experience) Atom feeds don’t like to parse properly. The way around this was to climb down the child tree to the first item. Also, the item node doesn’t always have the same number of children. I added a simple if statement to account for it. Finally, we call the function to load the last of the RSS feeds.

private function onEarthQuake(event:Event):void
{
var xml:XML = new XML(event.target.data);
var list:XMLList = xml..geo::point.text();
var string:String
for(var i:uint; i<\/?\w+((\s+(\w|\w[\w-]*\w)(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;
string = string.replace(pattern, "");
earth.desc = string;
}
tsunamis();
}
Step 22: The Final Set of Feeds
This is where we start to load the tsunami feeds. We created a tsuCounter so that we can increase the number each time a feed is loaded. When the counter reaches the end of the tsuArray, we’ll add the change listeners to the RadioButtonGroup that was created. Since I want to be able to access every marker created in every array, I added tsuCounter to the beginning of the name of the movie clip. That way I’ll be able to access the description from 0Tsunami1 and 1Tsunami1.
Finally, when all the feeds have been loaded, we add the event listener to the RadioButtonGroup

private function tsunamis():void
{
var url:URLLoader = new URLLoader();
var vars:URLVariables = new URLVariables();
var req:URLRequest = new URLRequest(CURL);
req.method = URLRequestMethod.POST;
vars.earl = tsuArray[tsuCounter]
req.data = vars;
url.addEventListener(Event.COMPLETE, onTsu);
url.load(req);
}
private function onTsu(event:Event):void
{
tsuCounter++;
if(tsuCounter == tsuArray.length)
{
group.addEventListener(Event.CHANGE, onChange);
} else
{
tsunamis();
}
var xml:XML = new XML(event.target.data);
var list:XMLList = xml..geo::point.text();
var string:String;
for(var i:uint; i
Step 23: Other Functions
These are the functions that are adding the markers, controlling the look of the markers, setting the longitude and latitude of the markers and creating the movie clips in the markers. The drawMarker function creates a new marker, adds a drop shadow, then adds the movie clip to it, passes the same name as the movieclip to it, gets the latitude and longitude from the loaded RSS feed and finally adds the event listeners. The marker is added the the markerManager of the map. The drawCircle function just draws a circle 10 pixels wide. The getLatlon function takes the string that is passed to it, breaks it apart and returns the LatLon. The last function, theColor, handles the different colors passed to it through the volcano feed.
private function drawMarker(mc:MovieClip, string:String, name:String):void
{
var marker:Marker = new Marker();
marker.filters = [ds];
marker.addChild(mc);
marker.latlon = getLatlon(string);
marker.name = name;
map.markerManager.addMarker(marker);
marker.addEventListener(MouseEvent.ROLL_OVER, onOver);
marker.addEventListener(MouseEvent.CLICK, onClick);
}
private function drawCircle():MovieClip
{
var mc:MovieClip = new MovieClip();
mc.graphics.beginFill(0xFF0000, 1);
mc.graphics.drawCircle(5,5,5);
mc.graphics.endFill();
return mc;
}
private function getLatlon(string:String):LatLon
{
var array:Array = string.split(/[\s]/);
var latlon:LatLon = new LatLon(array[0], array[1]);
return latlon;
}
private function theColor(string:String):ColorTransform
{
var int:uint;
switch (string)
{
case "ORANGE" :
int = 0xFD8000;
break;
case "GREEN" :
int = 0x225E33;
break;
default :
int = 0xFF0000;
}
var ct:ColorTransform = new ColorTransform();
ct.color = int;
return ct;
}
Step 24: Event Handling
When the user rolls over the marker, the description of the alert is displayed in the TextArea component. This is handled through the onOver function. The target is cast as a marker using the name that was passed it. Then we receive the description text that was passed to the movieclip nested inside the marker and send it to the TextArea component. The onClick event pans the map to whichever marker was clicked. This is done by using the map.panToLatLon() method.
private function onOver(event:MouseEvent):void
{
var marker:Marker = Marker(map.markerContainer.getChildByName(event.target.name))
var mc:MovieClip = MovieClip(marker.getChildByName(event.target.name));
textArea.htmlText = mc.desc;
}
private function onClick(event:MouseEvent):void
{
var marker:Marker = Marker(map.markerContainer.getChildByName(event.target.name))
map.panToLatLon(marker.latlon);
}
The final event is the onChange event. This event turns off all the movie clips except the selected buttons. It also pans the map to the most recent alert that was received in the RSS feed.
private function onChange(event:Event):void
{
var g:RadioButtonGroup = RadioButtonGroup(event.target);
var i:uint;
var marker:Marker;
var panTo:Marker;
switch(g.selection.name)
{
case "radioVolcano" :
for(i = 0; i
The Final Code
Here is what the final code looks like.
package {
import com.yahoo.maps.api.YahooMap;
import com.yahoo.maps.api.YahooMapEvent;
import com.yahoo.maps.api.core.location.LatLon;
import com.yahoo.maps.api.markers.Marker;
import fl.controls.RadioButtonGroup;
import fl.controls.RadioButton;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.ColorTransform;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.text.AntiAliasType;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
public class yahoo_map extends Sprite
{
private static const APPID:String = "YOUR APP ID";
private static const CURL:String = "curl.php";
private var map:YahooMap;
private var ds:DropShadowFilter;
private var geo:Namespace;
private var tsuArray:Array;
private var tsuCounter:int = 0;
private var color:ColorTransform;
private var group:RadioButtonGroup;
public function yahoo_map()
{
init();
}
private function init():void
{
color = new ColorTransform();
tsuArray = new Array("http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_pacific.xml", "http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_hawaii.xml", "http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_indian.xml", "http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_caribe.xml");
geo = new Namespace("http://www.georss.org/georss");
ds = new DropShadowFilter(2,90,0x00000,0.75,2,2,1,3);
group = new RadioButtonGroup("Disasters");
handleMap();
}
private function handleMap():void
{
map = new YahooMap();
map.addEventListener(YahooMapEvent.MAP_INITIALIZE, onInit);
map.init(APPID, stage.stageWidth, 330);
}
private function onInit(event:YahooMapEvent):void
{
empty.addChild(map);
map.addZoomWidget();
map.addPanControl();
map.addTypeWidget();
map.zoomLevel = 17;
map.centerLatLon = new LatLon(0,0);
volcanoes();
}
private function volcanoes():void
{
var url:URLLoader = new URLLoader();
url.addEventListener(Event.COMPLETE, onVolcano);
var vars:URLVariables = new URLVariables();
var req:URLRequest = new URLRequest(CURL);
req.method = URLRequestMethod.POST;
vars.earl = "http://volcanoes.usgs.gov/rss/vhpcaprss.xml"
req.data = vars;
url.load(req);
}
private function onVolcano(event:Event):void
{
var vol:Namespace = new Namespace("http://volcano.wr.usgs.gov/rss/volcanons/1.0");
var xml:XML = new XML(event.target.data);
var pointList:XMLList = xml..geo::point.text();
var colorList:XMLList = xml..vol::colorcode.text();
var string:String;
for(var i:uint; i<\/?\w+((\s+(\w|\w[\w-]*\w)(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;
string = string.replace(pattern, "");
earth.desc = string;
}
tsunamis();
}
private function tsunamis():void
{
var url:URLLoader = new URLLoader();
var vars:URLVariables = new URLVariables();
var req:URLRequest = new URLRequest(CURL);
req.method = URLRequestMethod.POST;
vars.earl = tsuArray[tsuCounter]
req.data = vars;
url.addEventListener(Event.COMPLETE, onTsu);
url.load(req);
}
private function onTsu(event:Event):void
{
tsuCounter++;
if(tsuCounter == tsuArray.length)
{
group.addEventListener(Event.CHANGE, onChange);
} else
{
tsunamis();
}
var xml:XML = new XML(event.target.data);
var list:XMLList = xml..geo::point.text();
var string:String;
for(var i:uint; i
Conclusion
I’ve barely scratched the surface for what YahooMaps has under the hood. Read the documentation and go nuts!



Pingback: Special Blog to All » Plotting Points Using Yahoo! Maps and RSS - Flashtuts+
Pingback: Plotting Points Using Yahoo! Maps and RSS - Flashtuts+ « RSS
Pingback: Down the Foxhole – Last Week on Flashtuts+
Pingback: Plotting Points Using Yahoo! Maps and RSS | Alias 3d Media
Pingback: 45+ Advanced Tutorials of Adobe Flash ActionScript « CSS Tips
Pingback: 45+ Advanced Tutorials of Adobe Flash ActionScript | JS Tips