Our Blog

One of the most challenging parts of creating Home Locator was the integration with Yahoo! Maps since there was no Flex 2 version of their API (they have a Flex 1.5 version, which does not work in Flex 2).

A lot of people asked me at CFUnited and by email about how I did it. In response to that, I made this simple example that shows the details, although not all of the functions are implemented.

It is important to say before we start that I don't recommend using this technique unless you need it right away. It would be better to wait until Yahoo! releases the Flex 2 version of their API. If you can wait, it will be so much easier for you and you won't have to deal with the whole Local Connection stuff (I will explain this in a minute).

As I mentioned before, Yahoo! doesn't have a Flex 2.0 map API, so if we want to have a map, we need to use the Flash API. But having the map in Flash and the rest of the app in Flex it is not as simple as having everything written in Flex. This is because now the player has 2 virtual machines, one for Flex that runs ActionScript 3 and another for Flash that runs ActionScript 2. The problem is that the communication between both VM is not straightforward. It is not very clean and it's not as robust as I would like it to be. But we need to communicate in some way and that way is by using Local Connection. Peter Ent from Adobe made a great post explaining the details of how to communicate Flash and Flex via Local Connection so I highly recommend you to read it.

These are the steps to put the map in a Flex app:

  • You need to download and install the Yahoo! Map Flash component
  • Get a Yahoo! ID.
  • Create a .fla movie and drag the Map component from the component panel to the stage.
  • Put an instance name to your map. In my case a used "myMap".
  • Write the Yahoo! ID on the parameters of the component.
  • Write your ActionScript code and compile it. You can experiment a bit with the code, mine is very basic as you can see below (I did it on the fist frame of the movie):
// ActionScript file
import com.yahoo.maps.markers.CustomPOIMarker;
import com.yahoo.maps.tools.PanTool;
import com.yahoo.maps.widgets.NavigatorWidget;

// register as a listener to get notified when the map finishes the initialization state

myMap.addEventListener(com.yahoo.maps.api.flash.YahooMap.EVENT_INITIALIZE, onInitMap);

function onInitMap(eventData)
{
   // create tools and widgets to control the map
   myMap.addTool(new PanTool(), true);
   myMap.addWidget(new NavigatorWidget("closed"));
   // notify Flex that the map finished the initialization state
   connectedMap.send("_flexClient","mapInitialized");
}

var connectedMap:LocalConnection = new LocalConnection();
connectedMap.addMarker = function (connectionData:Object):Void
{
   //Add the marker to the map
   myMap.addMarkerByAddress(CustomPOIMarker,connectionData.address, connectionData.marker);
   myMap.setCenterByAddress(connectionData.address, 2500);
}
connectedMap.connect("_flashClient");

What I did in the Flash movie is to set a listener for the "initialize" event. This event gets fired when the map finishes its initialization. Inside this event, I added a "Tool" and a "widget" to be able to control, drag and zoom the map. I also call the Flex application to let it know that flash finished its initialization, and it's ready for use. This also helps me forcing the connection from Flash, because I found (in the beta, that is. I don't know if the bug is fixed now) that if you don't start the connection from Flash the connection sometimes doesn't work.

I also want to mention that I used an underscore in the beginning of the connection name because I found (also in the beta, but I think that is fixed now) that the connection does not work if you name it without it. For example I used "_flexClient" and "_flashClient" for my names.

I included the .fla in the source code. So you only need to open the file, include your ID following the steps described at Yahoo!, compile the swf , and you are ready to go.

Now let's look at the Flex side. There are two files. One is the mxml application (MapExample.mxml) where all the components are.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*" viewSourceURL="/assets/content/exampleFiles/flex/map/srcview/index.html">
   <local:MapConnection id="mapConnection"/>
   <mx:Panel x="10" y="10" width="392" height="336" layout="absolute">
      <mx:SWFLoader id="map" width="370" height="260" source="assets/mapExample.swf" autoLoad="true" x="1" y="1"/>
      <mx:TextInput id="address" x="63" y="268" width="229" enter="mapConnection.addMarker(address.text)"/>
      <mx:Button x="301" y="268" label="Search" click="mapConnection.addMarker(address.text)"/>
      <mx:Label x="10" y="271" text="Address:"/>
   </mx:Panel>
</mx:Application>

In this file, we have the SWFLoader tag that will be loading the map into our flex app. In this file we also have a tag that it is the instance of our local connection. MapConnection it is actually an ActionScript class that it is defined in its own file and extends from LocalConnection.

package
{
   import flash.net.LocalConnection;

   public class MapConnection extends LocalConnection
   {
      private var isInitialized:Boolean;
      private var index:uint;
      
      public function MapConnection(server:String = "_flexClient")
      {
         try {
connect(server);
}
catch (error:ArgumentError)
{
// server already created/connected
}
super();
      }
      public function mapInitialized():void
      {
         isInitialized = true;
         trace("SearchConnection init")
      }
      public function addMarker(address:String):void
      {
         var marker:Object = {index:++index, title:"title", description:"description", markerColor:0x990099, strokeColor:0xFFFF00 };
         if(isInitialized) send("_flashClient","addMarker", {address:address, marker:marker});
      }
   }
}

In this other file we have one constructor and two methods. One method is "mapInitialized()" that will be called by Flash when Flash finishes the initialization of the map. The other is "addMarker()" that is called by the button that sends the info on the text field as the "address" parameter. What the method does is take that info, create a marker object, and send that to the Flash client (the map) using the local connection method "send()" that we inherit from LocalConnection.

As you can see, this example is very straightforward. You enter an address or just a zip code (easy to type) and click search to see the address marked in the map.

View Example
Nahuel Foronda

Nahuel Foronda

47 Comments

  1. Scott
    How come there isn't a marker on the map when you look at your example? It looks like the map is in the right place (long beach) but I don't see a marker?
  2. Nahuel
    Hi Scott,
    You mean when you first load the page? You need to enter the address/zip code to see a marker. There is no marker by default.
    If you mean that the marker does not appear after you entered the location, it's a bug. I've seen that happening, but not very often. I don't know if it is a bug in Yahoo! or Flex.
  3. Yechezkal

    Yechezkal

    I am also not getting any markers. Or re-centering when putting in a location, zip, etc.

    I am not sure that the connection is initialziing. I am trying to find if I can get the console output to see if the trace on the connection is working.
  4. Yechezkal

    Yechezkal

    I did not figure out how to get the trace()'s appearing in the window. But I stuck in an mx.controls.Alert() and I can confirm that the onInitialize() is arriving at the flex side, and that they market is being sent back to the _flashClient (at least at the flex side).

    After the message arrives at the _flashClient, I have no real idea what happens, or why it is not displaying.
  5. Piatek
    I added my ApplicationID and recompiled... Now it does not work... I am using Flash MX 2004 Pro - is that to old to be using for this project? DO I need a newer version?
  6. Nahuel
    Yechezkal,
    From what you say, I think that the problem is sending the marker info from Flex to Flash. You can try adding a trace on the Flash side and see if you receive the call (to see the trace on the console you need to run the app on the flex debug mode)

    Piatek,
    I have the same version as yours, so it should work
  7. Piatek
    Hmm... THanks for the confirmation. I put the ApplicationID in the component editor and recompile not doing anything else to your sample app and it just sits there with a static map.

    Any insight would be much appreciated!!!
  8. Laura
    Piatek,
    The movie you compile in Flash must be added to the assets folder in Flex. It doesn't do anything by itself, if that is your question. (If the movie does not get copied to the bin folder in Flex, copy it there too)
  9. Piatek
    Understandable, I did do that... I'll keep playing around with it!

    BTW - Long time visitor - EXCELLENT site keep it up!!!!
  10. Yechezkal

    Yechezkal

    I got a new copy of Flex Builder in the mail today.

    It is now recentering properly.

    But the marker does not appear.

    Oddly I do not see any trace messages in the Debug Console.
  11. Chaz
    Hi to all

    I am using flex for the first time and I have a question.


    My sample app is the flexstore.

    In the template flexstore.mxml it bring in all of the mxml files in that directory and I see the viewstack tag is using some of the templates to display the content. My question is if I have a link button on the homeview.mxml and by clicking that button change the view to show the ProductsView.mxml template how can I do this?


    Thanks
  12. Yechezkal

    Yechezkal

    The problems I was having were some mistakes on my side. It is all working for me now.
  13. Joshua

    Joshua

    Works great :) thanks for the example... I hope Yahoo creates a Flex 2 version soon to make our lives easier.
  14. Chuck
    Great solution. It is obviously helping out a lot of developers in the interim. Please contact me when you get a chance. I am looking to get this solution out to more developers.
  15. Craig Newroth

    Craig Newroth

    got a question, how would I send my address to the map without the inputs so i could get the map to display my address with a marker next to it?
  16. Josh R.

    Josh R.

    I ran into an error when putting this out on the www.
    The error says I can work around this by "This may be worked around by calling Security.allowDomain." what does it mean by this and where in your example would this be placed?

    Here is the error I get.

    SecurityError: Error #2121: Security sandbox violation: BitmapData.draw: http://worksofartembroidery.com/wofa.swf cannot access http://us.maps1.yimg.com/us.tile.maps.yimg.com/tile?md=200604181524&col=1973&row=899&z=5. This may be worked around by calling Security.allowDomain.
       at flash.display::BitmapData/draw()
       at mx.effects.effectClasses::MaskEffectInstance/::getVisibleBounds()
       at mx.effects.effectClasses::MaskEffectInstance/::initMask()
       at mx.effects.effectClasses::MaskEffectInstance/startEffect()
       at mx.effects::Effect/play()
       at mx.effects::EffectManager$/::createAndPlayEffect()
       at mx.effects::EffectManager$/http://www.adobe.com/2006/flex/mx/internal::eventHandler()
       at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
       at flash.events::EventDispatcher/dispatchEvent()
       at mx.core::UIComponent/setVisible()
       at mx.containers::ViewStack/::commitSelectedIndex()
       at mx.containers::ViewStack/mx.containers:ViewStack::commitProperties()
       at mx.core::UIComponent/validateProperties()
       at mx.managers::LayoutManager/::validateProperties()
       at mx.managers::LayoutManager/::doPhasedInstantiation()
       at Function/http://adobe.com/AS3/2006/builtin::apply()
       at mx.core::UIComponent/::callLaterDispatcher2()
       at mx.core::UIComponent/::callLaterDispatcher()
  17. Curt Hall
    Hey guys,

    I've been playing around with this app, and I'm having a tough time getting the EVENT_DRAG_STOP and EVENT_DRAG_START events to work properly. I'm using Flex 2, and I'm adding the lines myMap.addEventListener(EVENT_DRAG_STOP, myFunction);
    then, function myFunction(eventData){ connectedMap.send("_flexClient", "dragStop");

    My method is flex does an Alert, but nothing shows up... I've tried several things, including stretching out the pathway to com.yahoo.maps.tools.PanTool.EVENT_DRAG_STOP, but to no luck. Any ideas? Also, would the proper way to send data to the Flex app be
    connectedMap.send("_flexClient", "dragStop", var1, var2, etc);?

    Thanks in advance!
  18. Adam Fortuna
    Great work man. Just started learning Flex last week and was looking for something like this. Implemented your example without any ease, just need to learn what I inserted. :)
  19. Darius
    Great work-around but I'm getting an error when compiling the .fla. Any ideas? I'm using Beta 3. Thanks!!

    **Error** Scene=Scene 1, layer=Layer 2, frame=1:Line 14: There is no property with the name 'addMarker'.
    connectedMap.addMarker = function (connectionData:Object):Void

    Total ActionScript Errors: 1     Reported Errors: 1
  20. Trace
    Great App!. I'm trying to construct a map for an application following your example. I would like to have it glide to the location of an address clicked on in a DataGrid, much like in your Home Locator Application. Could you please help me understand the difference between this and the example where the address is physically entered into the Map Display Panel?

    Thanks!
  21. Joris Schets

    Joris Schets

    I succeeded to get things work. However when i try this in a viewstack it doesnt work. Is there a solution? thx
  22. Hans Vansteene

    Hans Vansteene

    Hi Joris, glad you mention this! I am facing exactly the same problem as you. Many sleepless nights and no solution so far. I also tried different options like using an iFrame, but never got a result that works properly! Does anybody else have any suggestions or is there anyone who has a working example of the Yahoo Maps API in a viewstack ??
  23. Nahuel
    Hi All,
    If you trying to use this example with a viewStack or Tabs and you cannot make it work, I think it is because the creationPolicy of those components is different from the rest. They have a "deferred instantiation" by default. You can try two things:
    1. Change the creationPolicy to "ContainerCreationPolicy.ALL" 2. Create another mxml and put all the code there and add that component as a child of the viewStack.
    If that doesn't do the trick, I don't know :(
  24. Dave Meas
    Hello All,

    I am having problems with my application AND the example. I cannot get the map to center or get any tags added. I am writing a simple application to tag sales data to states/cities. Any help would be greatly appreciated.
    Thanks!

    Dave Meas
    beatport.com

    Here is my code:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       <local:MapConnection id="mapConnection" />
       <mx:Sprite id="mapDisplay"/>

       <mx:Panel x="10" y="60" width="700" height="630">
          <mx:SWFLoader id="map" width="700" height="600" source="assets/mapExample.swf" autoLoad="true" x="100" y="100"/>
       </mx:Panel>

       <mx:TextInput id="address" x="60" y="80" width="280"/>
       <mx:Button x="60" y="110" click="mapConnection.addMarker(address.text)"/>
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  25. Thomas
    Any idea when the yahoo API for flex 2 will come out? whats the word on teh street
  26. Anupam
    Hi i have used the local connection from Flex 2.0 to communicate with the flash component everything is working fine and i can call all the events in the Flex from Flash 8.0 and vice versa...
    But the problem is that i want to call an event from the Flex whenever user clicks a CustomPOIMarker on the map.
    I have tried but the event is never getting called,tried to get help from so many forums but of no use...
    Can you provide some insight in this issue
    Thanks in Advance
    Anupam
  27. Jeff Phillips

    Jeff Phillips

    How hard is it to set the map up to work in a fluid, contraint-based layout? In other words, have the maps height and width adjust to match the available browser window size as the user resizes their browser window; As is done in Adobe's Tour Tracker (very cool app btw)

    http://www.adobe.com/devnet/flex/samples/tourtracker/
  28. Rostislav Siryk
    Guys, good news for those who use the Yahoo Maps: they've released the Yahoo! AS3 API libraries and examples, including Maps! Find it here: http://developer.yahoo.com/flash/as3_api_libraries.html

    However, I'm having troubles when trying to make BitmapData.draw to loaded Yahoo Map using this API in Flex 2 app. The error is "SecurityError: Error #2121: Security sandbox violation: BitmapData.draw: http://localhost/MapsTest.swf cannot access http://us.maps1.yimg.com/us.tile.maps.yimg.com/tile?md=200702051436&col=-1&row=5&z=14&t=p. This may be worked around by calling Security.allowDomain.
       at flash.display::BitmapData/draw()
    "

    Does anyune have a clue how to overcome this annoyance?
  29. eatmorepossum

    eatmorepossum

    I too am encountering the dreaded

    *** Security Sandbox Violation ***

    error.

    specifically:

    *** Security Sandbox Violation ***
    SecurityDomain 'http://myserver:8080/cfflex/TestProject/bin/TestProject-debug.html?debug=true' tried to access incompatible context 'http://us.maps1.yimg.com/us.tile.maps.yimg.com/tile?md=200702051436&col=3&row=1&z=14&t=p'
    [SWF] /us.tile.maps.yimg.com/tile - 7,304 bytes after decompression

    I have added a crossdomain.xml policy file at the root of my server.


    *********************crossdomain.xml*******************

    <?xml version="1.0" encoding="iso-8859-1" ?>
    <!DOCTYPE cross-domain-policy
    SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd
    ">
    <cross-domain-policy>
    <allow-access-from domain="*" />
    </cross-domain-policy>

    ***************end*crossdomain*******************


    It is my understanding that there also must be a crossdomain.xml policy file at the root of yahoos server:

    http://us.maps1.yimg.com/



    I am stuck at the moment. Does anyone have any suggestions? Thanks,
    Chris
  30. eatmorepossum

    eatmorepossum

    it appears the sandbox error only occurs in debug mode. to fix the little white box (map not showing up, but a 8px x 8px white box shows up) make sure your SWFDOMID matches your mxml file name minus the ext. mine is TestProject.mxml so my constant is set as such:


    private const SWFDOMID:String = "TestProject";


    complete explanation here: http://tech.groups.yahoo.com/group/yws-maps/message/5165
  31. Matt Miraglia

    Matt Miraglia

    Hello,

    I was wondering if the Home Locator source code was available to download anywhere? This looks like a great example showing alot of different aspects of what Flex can do along with adding Yahoo maps.

    Thanks in advance,
    Matt M.
  32. Cody Snider
    This tutorial is <b>great</b>! I've been searching for these answers all day (I'm a PHP guy, 3 days into my Flex education. The code still looks a bit like Greek.) Thanks and excellent work!
  33. Nicky
    Hi, have I just begun with flex, am I creating a site web it is possible to directly load the map of small Switzerland or to put the coordinates latitude and longitude? Can you help me? Thanks Nicky
  34. Rostislav Siryk
    Guys, Adobe Apollo brings us the creat possibility to overcome all the annoyances of the crossdomain policy files to use any maps, Yahoo, Google or whatever. Of course, Apollo App will work only at the desktop, not web, but it still can be helpful for some of readers here I believe.

    To get the picture what I'm talking about, please see my Apollo 3D Google Map sample application (sources included):

    http://flash-ripper.com/en/2007/sources-for-apollo-3d-test-application/
  35. aubweb
    Hi
    I've got the same issue with the error #2121
    My map is in a viewstack but where the creationpolicy is set to 'all'.
    I saved a crossdomainpolicy file to the root of my serverm the SWFDOMID is correct ...
    I have the error but the map is correctly displayed, it's weird but annoying to have this error.
    I dunno what else to do... please help me, us to find a sollution.

    SecurityError: Error #2121: security violation Sandbox : BitmapData.draw : ...GreenTouch.swf cannot access to http://us.maps1.yimg.com/us.tile.maps.yimg.com/tile?md=200705152300&col=67111&row=21592&z=1&t=p. ....Security.allowDomain.
       at flash.display::BitmapData/draw()
       at mx.effects.effectClasses::MaskEffectInstance/::getVisibleBounds()
       at mx.effects.effectClasses::MaskEffectInstance/::initMask()
       at mx.effects.effectClasses::MaskEffectInstance/startEffect()
       at mx.effects::Effect/play()

    Thanks in advance

    Aub
  36. RobOToole
    Great Great work....the current version of the maps api for as3 doesn't have the marker class :(. So....this really is the only answer for using markers with your mashup.

    I have a very strange error....when i load my map component alone as its own application, the CustomPOIMarker opens fine but when i put it in my viewstack, the marker won't open fully(only does the mouse over open). Anyone else have this problem or an answer??
  37. JMResler
    A Thanks to eatmorepossum for the catch on the SWFDOMID... I was tearing my hair out (and I don't have any!) running the Debugger, Ethereal network traces, etc. and kept seeing the data being downloaded but couldn't make it work. Thanks!
  38. vijay
    Hi i'm new to Flex this source code help me lot to understand the Flex and yahoo map interaction i like to know how to print the map.i need sample source code to print the map which appears after the search using one print buton in ths example.
  39. vijay
    Hi i'm new to Flex this source code help me lot to understand the Flex and yahoo map interaction i like to know how to print the map.i need sample source code to print the map which appears after the search using one print buton in ths example.
  40. Omar Gonzalez
    I'm having the same issue with the Security Sandbox error. It's happening due to the lack of a crossdomain.xml on the server that is hosting the map tiles. There's a short discusson on it here:
    http://tech.groups.yahoo.com/group/ydn-flash/message/391

    I hope we can get a crossdomain.xml in place soon, I'm sure there are plenty of people trying to place the Yahoo maps in their ViewStacks or use a transition effect. Let the voices be heard! =)
  41. Diego Purgue

    Diego Purgue

    Hi,

    I need remove or open a specific Marker from the map. It's possible it??. I'm using flex 3.

    Reggards
  42. Arthurnasius Amanyire
    please i would like to know how to feed the map with new coordinates/zip/location when someone clicks on a datagrid. like in your home locator app. thanks
  43. Shaguf Mohtisham
    Thanks for the information shared here. that was an interesting and informative. I had a good experience by participating in the Adobe DevSummit in 2009 and looking forward to attend Adobe Flash Platform Summit 2010 as well. AFPS 2010 is the single largest Flash Platform conference in India which features topics like Flash, Flex, Flash Platform, AIR 2.5, Andriod, RIA, LiveCycles, PHP and more. I found the information about the conference from adobesummit.com

So, what do you think ?

Subscribe to this comment thread
Leave this field empty