<?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:services="com.esri.aws.services.*"
layout="absolute"
>
<mx:Script>
<![CDATA[
import com.esri.aws.services.FindOptions;
import com.esri.aws.services.FindResultSet;
import com.esri.aws.services.GeocodeInfo;
import mx.controls.Alert;
import mx.collections.ItemResponder;
import com.esri.aws.services.IFind;
import flash.utils.getQualifiedClassName;
import com.esri.aws.osgi.framework.IServiceReference;
import com.esri.aws.osgi.framework.IBundleContext;
private function doFind() : void
{
var context : IBundleContext = framework.systemContext;
var ref : IServiceReference = context.getServiceReference(getQualifiedClassName(IFind));
if( ref == null)
{
Alert.show( "No service reference !");
return;
}
var find : IFind = context.getService( ref ) as IFind;
find.findLocation( textInput.text, null, new ItemResponder(
function( data : Object, token : Object = null) : void
{
var findResultSet : FindResultSet = FindResultSet(data);
arrayCollection = new ArrayCollection( findResultSet.findResults );
},
function( info : Object, token : Object = null) : void
{
Alert.show( info.toString());
}
));
}
]]>
</mx:Script>
<framework:Framework id="framework"
apiKey="XXXXX">
<services:FindActivator/>
</framework:Framework>
<mx:ArrayCollection id="arrayCollection"/>
<mx:Panel width="100%" height="100%">
<mx:DataGrid width="100%" height="100%" dataProvider="{arrayCollection}"/>
<mx:ControlBar>
<mx:TextInput id="textInput" enter="doFind()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>
Thursday, October 25, 2007
How to find locations ?
So...if you want to find "380 new york st, redlands, ca" or "www.esri.com" or "909 793 285", you can use the IFind service.
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.
And here is the Photo class
<?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;
}
}
Wednesday, October 17, 2007
Flex and OSGi
The AWX framework is based on a simplified OSGi implementation in AS3. The advent of flex modules made this implementation possible. The following is a simple walk-through that showcases how to use this solution. The idea is to define an interface whose implementation can be defined and discovered at runtime. Using FlexBuilder as a project manager makes things a bit easier.
Create a flex library project named "FooAPI" to define the following interface. A SWC "FooAPI.swc" is generated upon the build in the "bin" directory.
Create the main application as a flex project.
The
The
The
The
Create a flex library project named "FooAPI" to define the following interface. A SWC "FooAPI.swc" is generated upon the build in the "bin" directory.
package com.esri.awxCreate a flex actionscript project named "FooBundle" - make sure to add the AWX swc as a project library and the "FooAPI" project. Modify the FooBundle.as class as follows:
{
public interface IFoo
{
function doFoo( text : String ) : String;
}
}
package {Here we are creating a flex module that implements the
import com.esri.aws.osgi.framework.IBundleActivator;
import com.esri.aws.osgi.framework.IBundleContext;
import com.esri.awx.FooImpl;
import com.esri.awx.IFoo;
import flash.utils.getQualifiedClassName;
import mx.modules.ModuleBase;
public class FooBundle extends ModuleBase implements IBundleActivator
{
public function start( context : IBundleContext ) : void
{
context.registerService( getQualifiedClassName(IFoo), new FooImpl());
}
public function stop( context : IBundleContext ) : void
{
}
}
}
IBundleActivator
interface that defines the start
and stop
functions. In the start
fnction implementation, we register a FooImpl instance with the framework. The value of getQualifiedClassName(IFoo) (Notice, we are using the IFoo interface) is acting as a key, that we can use in other bundles to get a reference to the IFoo implementation.package com.esri.awxThe compilation of this project will output a FooBundle.swf file. This is the bundle (in OSGi parlant) that we will load dynamically at runtime. Make sure that you set the output of the project to a web application. This will facilitate the following step.
{
public class FooImpl implements IFoo
{
public function doFoo( text : String ) : String
{
return "foo::"+text;
}
}
}
Create the main application as a flex project.
<?xml version="1.0" encoding="utf-8"?>Here in the main application, we create an instance of the
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:awx="http://www.arcwebservices.com/2007/awx"
layout="horizontal"
>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import com.esri.awx.IFoo;
import flash.utils.getQualifiedClassName;
import com.esri.aws.osgi.framework.IServiceReference;
import com.esri.aws.osgi.framework.IBundle;
import com.esri.aws.osgi.framework.IBundleContext;
private function listBundles() : void
{
trace( "---Bundles---");
var context : IBundleContext = framework.systemContext;
for each ( var bundle : IBundle in context.getBundles())
{
trace( bundle.getBundleID()+" "+bundle.getSymbolicName());
}
}
private function loadFoo() : void
{
framework.installBundle("http://host/webapp/FooBundle.swf");
}
private function doFoo() : void
{
var context : IBundleContext = framework.systemContext;
var ref:IServiceReference = context.getServiceReference(getQualifiedClassName(IFoo));
if( ref == null)
{
Alert.show( "No reference to service IFoo");
}
else
{
var foo : IFoo = context.getService( ref ) as IFoo;
trace( foo.doFoo( "Hello"));
}
}
private function uploadFoo() : void
{
var bundleID : int = -1;
var context : IBundleContext = framework.systemContext;
for each ( var bundle : IBundle in context.getBundles())
{
if( bundle.getLocation() == "http://host/webapp/FooBundle.swf")
{
bundleID = bundle.getBundleID();
break;
}
}
if( bundleID != -1)
{
context.getBundle(bundleID).uninstall();
}
}
]]>
</mx:Script>
<mx:TraceTarget/>
<awx:Framework id="framework" apiKey="xxxxxxx"/>
<mx:Button label="List Bundles" click="listBundles()"/>
<mx:Button label="Load Foo" click="loadFoo()"/>
<mx:Button label="Do Foo" click="doFoo()"/>
<mx:Button label="Upload Foo" click="uploadFoo()"/>
</mx:Application>
Framework
.The
listBundles
function lists all the available bundles. By default, the framework installs the system bundle and an authentication bundle.The
loadFoo
function installs the foo bundle from a url.The
unloadFoo
function unloads the bundle from the framework, which automagically unregisters any registered services.The
doFoo
function demonstrates how to get a reference to an IFoo implementation. If the reference is null
then the service was not loaded or was unloaded. if we have a non-null reference value, then we use it to get a service reference, that we can safely cast to IFoo and act upon it.Tuesday, October 16, 2007
Hey ArcGIS users
You can create an ArcGIS Server based layer using the AWX Flex API. In the below sample, I'm loading a layer from a specified endpoint and then when I click click on the button, I'm turning off the "water" layer in the ArcGIS group layer.
<?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.*"
xmlns:layers="com.esri.aws.awx.map.layers.*"
layout="absolute"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.ItemResponder;
import com.esri.aws.awx.map.layers.LayerVisibility;
private function turnWaterOff() : void
{
ags.getLayerVisibilities( new ItemResponder(
function(data : Object, token : Object = null) : void {
var arrCol : ArrayCollection = data as ArrayCollection;
for each ( var layerVisibility : LayerVisibility in arrCol)
{
if( layerVisibility.name == "Water")
{
layerVisibility.visible = false;
}
}
},
function(info : Object, token : Object = null) : void {
trace( info );
}
));
}
]]>
</mx:Script>
<framework:Framework apiKey="196405023"/>
<mx:Panel width="100%" height="100%">
<map:Map>
<map:basemaps>
<layers:ArcGISMapServerGroupLayer id="ags"
endpointURI="http://host/arcgis/services/MapService/MapServer"
/>
</map:basemaps>
</map:Map>
<mx:ControlBar>
<mx:Button label="Turn Water Off" click="turnWaterOff()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>
Monday, October 15, 2007
Wednesday, October 10, 2007
Tuesday, October 2, 2007
My MAX 2007 Presentation
Thanks all for attending, it was a packed room. You can download a zipped ppt version of my presentation from here.
Subscribe to:
Posts (Atom)