Wednesday, October 24, 2007

Flickr Images as Markers

You can create BubbleMarkers that when expanded will display a Flickr image. In the below example, I'm creating a map, and when the user clicks on the search button, I'm searching any public image in the map extent.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:framework="com.esri.aws.osgi.framework.*"
xmlns:map="com.esri.aws.awx.map.*"
layout="absolute"
>
<mx:Script>
<![CDATA[
import mx.controls.Image;
import com.esri.aws.awx.geom.PointShape;
import com.esri.aws.awx.map.layers.overlays.BubbleMarker;
import mx.controls.Alert;
import com.esri.flickr.Photo;
import mx.collections.ItemResponder;
import mx.rpc.AsyncToken;
import mx.rpc.http.HTTPService;
import com.esri.aws.awx.geom.Extent;

private function searchPhotos() : void
{
map.markerLayer.removeAllOverlays();

var extent : Extent = map.extent;
var httpService : HTTPService = new HTTPService();
var urlVar : URLVariables = new URLVariables();
urlVar.api_key = "19640523";
urlVar.method="flickr.photos.search";
urlVar.extras = "geo";
urlVar.bbox = extent.minX+","+extent.minY+","+extent.maxX+","+extent.maxY;
httpService.request = urlVar;
httpService.resultFormat = HTTPService.RESULT_FORMAT_E4X;
httpService.url = "http://api.flickr.com/services/rest/";
var async : AsyncToken = httpService.send();
async.addResponder( new ItemResponder(
function( data : Object, token : Object = null) : void {
var rsp : XML = data.result as XML;
if( rsp.@stat == "ok")
{
for each ( var photos : XMLList in rsp.photos)
{
for each ( var photoXML : XML in photos.photo)
{
var photo : Photo = new Photo();
photo.id = photoXML.@id;
photo.owner = photoXML.@owner;
photo.secret = photoXML.@secret;
photo.server = photoXML.@server;
photo.farm = photoXML.@farm;
photo.title = photoXML.@title;
photo.isPublic = photoXML.@ispublic;
photo.isFriend = photoXML.@isfriend;
photo.isFamily = photoXML.@isfamily == "1";
photo.latitude = photoXML.@latitude;
photo.longitude = photoXML.@longitude;
photo.accuracy = photoXML.@accuracy;

addPhotoMarker( photo );
}
}
}
},
function( info : Object, token : Object = null) : void
{
Alert.show( info.toString());
}
));
}

private function addPhotoMarker( photo : Photo ) : void
{
var pointShape : PointShape = new PointShape( photo.longitude, photo.latitude);
var bubbleMarker : BubbleMarker = new BubbleMarker( pointShape );
bubbleMarker.label = photo.title;
map.markerLayer.addOverlay( bubbleMarker );
var image : Image = new Image();
// http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg
image.source = "http://farm" + photo.farm +
".static.flickr.com/" + photo.server + "/" + photo.id + "_" + photo.secret + "_t.jpg";
bubbleMarker.element = image;
}
]]>
</mx:Script>
<framework:Framework apiKey="19640523"/>
<mx:Panel width="100%" height="100%">
<map:Map id="map"/>
<mx:ControlBar>
<mx:Button label="Search Photos" click="searchPhotos()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

And here is the Photo class

package com.esri.flickr
{
public class Photo
{
public var id : String;
public var owner : String;
public var secret : String;
public var server : String;
public var farm : String;
public var title : String;
public var isPublic : Boolean;
public var isFriend : Boolean;
public var isFamily : Boolean;
public var latitude : Number;
public var longitude : Number;
public var accuracy : int;
}
}

2 comments:

Jay Wood said...

I just tried the example, and got an error where Photo is used -- seems the com.esri.flickr.Photo class is not defined in the esri library version I am using. Is this one of the new features coming out in the Beta 2 release? I look forward to seeing it in action! Thanks for all the great examples.

thunderhead said...

Updated the code to not use the flikr swc and added the Photo class :-)