Oct
4
Using Yahoo ASTRA Map API with Flex 2


Posted: 4th October 2007
Tags: , , ,
Posted in Flex and Air
Comments: 12 Comments »

Yahoo recently released a new Flash framework for use with it’s Search, Weather, Mapping, Upcoming and Answers APIs called ASTRA (ActionScript Toolkit for Rich Applications). As the documentation is still a little sketchy in places I thought I would write a quick getting started tutorial on using the ASTRA framework with Flex 2 and Flex Builder.

 

Getting Started

Note: I also recomment you read Yahoo’s own tutorial on getting started as well as this

This article assumes you are using the most current version of Flex Builder 2 (2.0.1). You can download a trial version directly from Adobe

Once you have Flex Builder installed, you will need to download the latest version of the ASTRA framework from Yahoo Developer Network’s new Flash Developer Center , unzip the files into a suitable folder, this could be your Flex Builder workspace but could be anywhere that Flex Builder has access to.

Yahoo suggests adding the ASTRA sources as a Source Path (under Project > Properties > Flex Build Path > Source Path) which can be useful if you want to look at the source code. If you do, click ‘Add Folder’ and navigate to your unzipped ASTRA framework, then browse to and select the following subfolder (Source/Actionscript 3). If you are not bothered about viewing or changing the sources, Yahoo have bundled a pre-packaged .swc library file in the Build folder of ASTRA. Add this file, by adding it to your Flex Build Path (Project > Properties > Flex Build Path > Library Path > Add SWC)

Once this is created there is one more important step… You need to copy the file named as2map.swf from the build folder, to the root path of your project, however, at the time of writing this particular as2map.swf file seems a little buggy and one important feature that missing is the ability to add an event handler to handle the event that is raised when a user searches for a location and there is more than one possible location. If you are only going to be positioning the map using Lat and Lon, you don’t need to worry, but if you want the user to enter an address string you will need to use the older as2map.swf file that is located under Examples/Maps/traffic.

Once you have the as2map.swf located in your project root, you can now add the map directly into your MXML page.

Adding the map

To add the map to a container, you first need to add the XML namespace to your application (or component if adding to a custom component). If you are adding it directly to your main application MXML file you would add the following attribute to your tag:

  1. <mx:Application xmlns:mx=http://www.adobe.com/2006/mxml
  2. xmlns:yahoo=com.yahoo.webapis.maps.*
  3. layout=absolute creationComplete=init();>

With the XML namespace defined, you can now go ahead and add the Yahoo Map to your application using the following:

  1. <yahoo:YahooMapService id=myMap UUID={UNIQUEID}
  2. swfDomId={SWFDOMID} apiId={YAHOOAPIKEY} mapURL = {MAPSWF}
  3. horizontalCenter=0 verticalCenter=0 width=600 height=400 />

In the above code I have bound UNIQUEID, swfDomId, apiId and mapURL to constants, however you could simply enter the relevant parameter values here.

UNIQUEID is literally a unique int value, Yahoo suggest using getTimer() to generate a psuedorandom number.

swfDomId is a string that needs to be set to the name of the Project (or in particular, must match the name assigned to the embed tag in the generated html file, by default the name of your project) and I belive is case sensitive. This is used so that the external as2map.swf file can access your application.

apiId is your Yahoo API key, if you don’t have one you need to register with Yahoo

mapURL is the path to the as2map.swf, if you put this in the root of your project, as advised above, this is literally “as2map.swf”

Test your application and your map should be shown.

Scaling the map

If you would like to scale your map beyond the default 600×400 width and height, you need to set scaleContent=”false on the YahooMapService tag. i.e.

  1. <yahooYahooMapService .. scaleContent=false>

Failing to set this attribute causes the map to distort and not scale as expected.

Adding controls

Once the map is on the page, we can start to add controls to allow users to interact with the map. We can choose which controls we want to add, and we add these programmatically. If you do not already have an block on the page, add one, then add the following code.

  1. private function onLoad():void
  2. {
  3. // myMap is the id I gave the YahooMapService earlier
  4. myMap.addEventListener(onMapLoad, onMapLoaded)
  5. }
  6. private function onMapLoaded(ev:Object):void
  7. {
  8. // Allow the user to drag the map to pan around
  9. var panTool:PanTool = new PanTool(this);
  10. panTool.setPanTool(true);
  11. var widgets:Widgets = new Widgets(this);
  12. // Adds the zoom control and window control that can be opened to help pan
  13. widgets.showNavigatorWidget(true);
  14. // Adds buttons to allow users to switch from Arial, Satellite or Hybrid
  15. widgets.showSatelliteControlWidget(true);
  16. }

We now need to get the application to call our onLoad function once the application is loaded using the creationComplete event, which inturns adds our onMapLoaded function as a listener for _onMap_load. We add this to our tag as follows:

  1. <yahooYahooMapService .. creationComplete=onLoad()>

Using the Controllers

Yahoo have provided us with two main controllers to allow us to programmatically interact with the map. Firstly the MapController which allows us to vaigate to locations using an address string, which is automatically Geo Coded for us, or the LatLonController which allows us to manipulate the map using Latitude and Longitude co-ordinates. In addition to these two controllers there are also Overlays class that allows Yahoo or custom overlays to be added and a Distance tool to calculate distences (these go beyond the scope of this tutorial but more info can be found in the API documentation).

To add the main two controllers we create them as follows in the onMapLoaded function:

  1. //Map controller, we pass our map to the constructor
  2. var mapController:MapController = new MapController(myMap)
  3. //LatLonController, again passing our map instance
  4. var latLonController:LatLonController = new LatLonController(myMap)

Once these are created we can call methods on these objects as follows:

  1. //Go to address and zoom to 6 (0..16 scale, 0 nearest)
  2. mapController.goToAddressAndZoom(London, 6);

If the address is found, we are navigated to the location and the map is zoomed to the specified level. However if the location is not found ASTRA fires a mapGeoCodeError event which we need to capture as shown below:

Note: At the time of writing the newest as2map.swf file (which is 164kb is size) does not fire this event. If you need to catch this event then use the older as2map file (155kb) located with the traffic example (see above). If you need to use the latest as2map.swf you will either have to wait for Yahoo to fix this, or use an external GeoCoding service, such as the free GeoNames Service. (Note however: have personally experienced performance issues with this service)

Handling Events

In order to handle events with ASTRA (and unfortunately this is not clearly documented) you need to create an instance of the MapEventsDispatcher class as follows (again once the map is loaded, so put this in your onMapLoaded function).

  1. //Create the MapEventDispatcher, passing the map instance to it’s contructor
  2. var mapEvents:MapEventDispatcher = new MapEventDispatcher(myMap);
  3. //Then add event listeners as follows
  4. mapEvents.addEventListener(mapGeocodeError, suggestedAddresses)

All Map events fire an event of type MapEvent which is a standard event, however data passed back from the as2map.swf is stored in a parameter named lastResult, the structure of lastResult varies and does not always match the documentation.

Tip: Finding Out the Structure of Data Stored in MapEvent.lastResult

While developing you can query the structure of the event using a useful technique that I found on Scott Morgan’s Blog

  1. private function suggestedAddresses(ev:MapEvent):void
  2. {
  3. for (var i in ev.lastResult)
  4. {
  5. trace(i + : + ev.lastResult[i])
  6. }
  7. }

Adding a Custom Marker

 

Finally another feature that is not well documented is how to add a Point of Interest marker, in particular a customPOIMarker to a specific Latitude or Longitude. It is easy to add one to an address such as “London, UK” using the MapConroller.addCustomPOIMarker method, however with the LatLonController you need to do the following:

  1. var latLonContoller:LatLonController = new LatLonController(myMap)
  2. // addMarkerByLatLon(markerType:String,latitude:Number,longitude:Number, settings:Object) i.e.
  3. latLonController.addMarkerByLatLon(CustomPOIMarker, 50.1024, -5.0417, {index: ClockObj, title: Location, description: Jon Milet Baker’s Location, markerColor: 0xda001d, strokeColor: 0xda001d});

Useful Resources

Comments below..

Advertisement

 




Comments

Note: You can leave a response, or trackback from your own site.

 
Comment:

hi this is a good introduction, give us more on this please. meanwhile let me add that when create a custom marker using latloncontroller.addmarkerByLatLon, if you don’t know the value of latitude and longitude you can use the click event that returns on the object this: ev.lastResult.latlonObj.y for latitude and ev.lastResult.latlonObj.x for longitude, s oyou can put it like this: latlon.addMarkerByLatLon(”CustomPOIMarker”,ev.lastResult.latlonObj.y,ev.lastResult.latlonObj.x,{index:’,myindex’,title:’mytitle ‘,description:’mydescription’,markerColor:’0×336699′ });

 
 
Comment:

Cool stuff….may ASTRA grow fast!! Eager to see it happening.

 
 


Kaushal Shah
5/11/2007
1:27 pm

Comment:

HI, ASTRA works really good. I have easily attached this tool in my site, but i found one problem, in some IE6 this doesn’t work even not giving onMapErro(), while in other IE6 its work perfactly. What to do in this case?

 
 
Comment:

Hi, This could be due to Javascript settings, I believe that the AS3 ASTRA framework uses the ExternalInterface API to communicate with the AS2 a2map.swf via Javascript calls. Don’t quote me on that as I am not on the Yahoo development team and have not gobe through thier code in great detail.

 
 


Kaushal Shah
6/11/2007
9:07 am

Comment:

Thanks for quick response.
And you r correct that its not going ahead from Draw() method of YahooMapService.as. This method uses ExternalInterface.addCallback to know us when the map is loaded or if there was an error loading it.

Now from where I can get some solution?

 
 
Comment:

Hi,

I have followed your instructions and when I run the example (your first two code blocks) I am being shown the default flex background with a small 5*5 grey image. When I run the as2map.swf it is also very small. I think it is nearly working but i’m having some difficulty working out what the problem is :(

Thank youfor your time,

Adam

The code is as folows:

 
 
Comment:

Hi Adam,

Make sure the swfDomId=“{SWFDOMID}“ in your yahooYahooMapService tag matches the name of the embed tag in the generated html, by default it is set to the project name.

Regards

Jon

 
 
Comment:

Thank you so much, if its any use because of the support I get from people like you I now do it when I can on my blog and i’m glad to say I have helped at least one guy out.

Adam

 
 
Comment:

Hi,

I’ve had a read through the astra library docs and am having difficulty adding the two extra options which you have example code for (pan and widget). The error i’m getting is

“1067: Implicit coercion of a value of type MapExample to an unrelated type com.yahoo.webapis.maps:YahooMapService”

Its odd because when I use the code hint thing I can see the widgets and the pan class.

 
 
Comment:

Harry, change your code to :

var panTool:PanTool = new PanTool(yahooMapID);
var widgets:Widgets = new Widgets(yahooMapID);

Hope that helps.
Thx for the tutorial !

 
 
Comment:

Hey thanks for Astra,it was really helpful for . iCould get the map into my flex page. But
mapController.goToAddressAndZoom(“London“, 6);

This doesnt seem to work
.Any pointers on how to have user search for a particular loacation.
Is there any other function that can be used to acheive this.
Thanks

 
 
Comment:

Can you give full source code? still green in Flex

 
Add a comment:

 



    My Web Apps..

    Stubmatic.com
    Stubmatic is an online box office service for venues, promoters, bands, theatres and anyone with tickets to sell. Our members sell tickets online without incurring any booking fees and we provide all the tools to promote, sell and track sales.

    View Jon Baker's profile on LinkedIn


    View blog authority