When I recently started Geocaching I found that I wanted to have some kind of log that helped me keep track of what caches I had found and which I was still looking for. There are several of these on the market, but I saw this as an opportunity to build something cross-platform and with a rich mapping interface. So I started working on GeoLog, and application that uses the GPX files I download from Geocaching.com to display their location on a map. Thats about as far as I am with the application but I think this could be a great tool for all geocachers when I get done.

The core functionality of the application right now is the map interface. Since I am building this in AIR I saw no reason not to take this opportunity to use the Yahoo AS3 Map component. This is my first mapping application and I can not imagine yahoo having made this any easier. There are a whole bunch of examples and demos with code for how to do most tasks.

The map from yahoo is an AS3 component which I don’t think has any ties to the Flex framework. So when using it you must instantiate it and then add it as a child to a UIComponent in your appliaction. While this approach is fine, I wanted to encapsulate it a bit for my application. So I created a new Actionscript class and extended UIComponent. I then overrode the createChildren and updateDisplayList methods to implement the adding and manipulating of the yahoo map. I am posting the code for YahooMapViewer.as below in case anyone is interested.


package view
{
import com.yahoo.maps.api.YahooMap;
import com.yahoo.maps.api.YahooMapEvent;
import com.yahoo.maps.api.core.location.Address;
import com.yahoo.maps.api.markers.Marker;
import com.yahoo.maps.webservices.geocoder.GeocoderResult;
import com.yahoo.maps.webservices.geocoder.events.GeocoderEvent;
import mx.core.UIComponent;

public class YahooMapViewer extends UIComponent
{

public var api_key:String = "";
public var startAddress:String = "";

private var yahooMap:YahooMap;

public function YahooMapViewer()
{
super();
}

protected override function createChildren():void
{
super.createChildren();
yahooMap = new YahooMap();
yahooMap.init(api_key, DEFAULT_MEASURED_WIDTH, DEFAULT_MEASURED_HEIGHT);
yahooMap.addEventListener(YahooMapEvent.MAP_INITIALIZE, handleMapInitialize);
addChild(yahooMap);

yahooMap.addPanControl();
yahooMap.addZoomWidget();
yahooMap.addTypeWidget();
}

protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
yahooMap.setSize(unscaledWidth, unscaledHeight);
}

private function handleMapInitialize(event:YahooMapEvent):void
{
var address:Address = new Address(startAddress);
address.addEventListener(GeocoderEvent.GEOCODER_SUCCESS, handleGeocodeSuccess);
address.geocode();
}
private function handleGeocodeSuccess(event:GeocoderEvent):void
{
var result:GeocoderResult = (event.target as Address).geocoderResultSet.firstResult;
yahooMap.zoomLevel = result.zoomLevel;
yahooMap.centerLatLon = result.latlon;
}

public function addMarker(marker:Marker):void{
yahooMap.markerManager.addMarker(marker);
}

}
}

With this class its now trivial to use the Yahoo Map in your mxml application.


<view :YahooMapViewer id="ym" api_key="Your-Yahoo-Application-API-Key" startAddress="97223" width="100%" height="100%" />