<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0YNSXs_fSp7ImA9WhRUEk4.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522</id><updated>2012-01-22T07:26:38.545-05:00</updated><category term="ArcIMS" /><category term="FlashPlayer" /><category term="line style arrow" /><category term="quantile thematic" /><category term="heat map" /><category term="mailto" /><category term="polynomial" /><category term="QueryTask DataBinding" /><category term="ANTLR" /><category term="LCDS" /><category term="flare symbol" /><category term="quadtree" /><category term="InfoWindow" /><category term="transcoding" /><category term="PixelBender" /><category term="Flex" /><category term="maps awx2" /><category term="screen cleaner" /><category term="Sumposium" /><category term="compc" /><category term="SpringSource" /><category term="heatmap papervision3d shapefile" /><category term="geonames" /><category term="shapefile" /><category term="MAX 2008" /><category term="VOs" /><category term="java" /><category term="fluint" /><category term="AIR" /><category term="AppEngine BlazeDS" /><category term="StreetView" /><category term="degrafa" /><category term="cocomo" /><category term="findservice" /><category term="EXIF" /><category term="fabridge" /><category term="isometric" /><category term="noaa" /><category term="iPhone" /><category term="ArcWebServices Flex2 Precipitation" /><category term="HTML" /><category term="SpatialQuery" /><category term="parcels" /><category term="360|Flex" /><category term="Cairngorm AWX OSGi" /><category term="FlexBuilder" /><category term="3D routing papervision" /><category term="legend" /><category term="label" /><category term="Flex OSGi" /><category term="StringTemplate" /><category term="geocode reverse-geocode" /><category term="Flex ArcGIS" /><category term="XP" /><category term="cluster" /><category term="flexcode coverage" /><category term="map" /><category term="Navigation" /><category term="IDE" /><category term="AWX4.0" /><category term="Platform" /><category term="grid" /><category term="georss" /><category term="MAX2007" /><category term="BlazeDS" /><category term="mouse handler" /><category term="graticule" /><category term="clustering map points" /><category term="Spring" /><category term="callout infosymbol" /><category term="JSON" /><category term="A* pathfinind" /><category term="titlewindow" /><category term="polygon" /><category term="Minn" /><category term="flare" /><category term="junit flex ant" /><category term="OSGi" /><category term="Kinect" /><category term="draw tool" /><category term="ajax" /><category term="ArcGIS" /><category term="geodesic circle" /><category term="DefaultProperty" /><category term="modules" /><category term="flexunit" /><category term="S3" /><category term="granite" /><category term="resizable" /><category term="mxml" /><category term="mgrs" /><category term="contour" /><category term="Ground Overlay" /><category term="IntelliJ" /><category term="awxbridge" /><category term="RTree" /><category term="layer visibility" /><category term="graphics dash line" /><category term="Adobe MAX2007" /><category term="J2AS3" /><category term="metadata" /><category term="AMF" /><category term="geolocation gears geode" /><title>Thunderhead Explorer</title><subtitle type="html">Tips and Tricks using ArcGIS API for Flex and other fun stuff :-)</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://thunderheadxpler.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>128</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ThunderheadExplorer" /><feedburner:info uri="thunderheadexplorer" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DUYNQnY7fCp7ImA9WhdbFkQ.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-3854689069224651435</id><published>2011-10-11T23:25:00.001-04:00</published><updated>2011-10-15T12:46:33.804-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-15T12:46:33.804-04:00</app:edited><title>Yet Another Micro Architecture for Flex RIA and RMA</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
The Holistic micro-architecture framework for building RIAs and RMAs (Rich Mobile Applications) "borrows" from &lt;a href="http://www.robotlegs.org/"&gt;Robotlegs&lt;/a&gt;, &lt;a href="http://puremvc.org/"&gt;PureMVC&lt;/a&gt;, &lt;a href="http://sourceforge.net/adobe/cairngorm/home/Home/"&gt;Cairngorm&lt;/a&gt;, &lt;a href="http://swizframework.org/"&gt;SWIZ&lt;/a&gt;,&amp;nbsp;&lt;a href="https://github.com/robertpenner/as3-signals"&gt;AS3Signals&lt;/a&gt; and the &lt;a href="http://www.springsource.org/about"&gt;SpringFramework&lt;/a&gt;.  Each has one or two things that I really like about it, but what I wanted is to bring all these things into one simple, very lightweight framework that enables me to quickly and more importantly methodically build mobile, web and desktop applications. This Holistic API is designed to work on top of either the &lt;a href="http://www.adobe.com/products/flex.html"&gt;Flex&lt;/a&gt; web or mobile framework and takes advantage of the Flex compiler, environment and lifecycle. Several "design patterns" are utilized in the API, such as &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;Model-View-Controller&lt;/a&gt;, Loose Coupling, &lt;a href="http://en.wikipedia.org/wiki/Service_locator_pattern"&gt;Locator&lt;/a&gt;, Usage of Interface, &lt;a href="http://en.wikipedia.org/wiki/Delegation_pattern"&gt;Delegation&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;Separation of Concerns&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Inversion_of_control"&gt;Inversion Of Control&lt;/a&gt;,&amp;nbsp;not sure if some of latter are pure design patterns per &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns"&gt;GoF&lt;/a&gt;, but bear with me :-) One thing that is heavily relied on, is programming to convention versus programming to configuration.
&lt;br/&gt;
&lt;br/&gt;
&lt;img src="http://dl.dropbox.com/u/2193160/MVC.png" alt="MVC"/&gt;
&lt;br/&gt;
&lt;br/&gt;
Looking at the above diagram, the state of an application resides in the Model. The model is a set of non visual properties, where some properties are annotated using the [Bindable] metadata, in such that a change event will be dispatched whenever that property is mutated. This [Bindable] metadata is an indication that this property is represented by a view.
&lt;br/&gt;
&lt;pre&gt;
public class Model {
    [Bindable]
    public var text:String;
}
&lt;/pre&gt;
Views are subclasses of UIComponents and are bound using curly braces (I call them 'magic' braces) to the Model to represent the state of the application based on the view capabilities.
&lt;br/&gt;
&lt;pre&gt;
&amp;lt;s:label text="{model.text}"/&amp;gt;
&lt;/pre&gt;
In the above example, this Label instance is representing the model 'text' property and any changes to the 'text' value will be auto-magically shown in the label location on the screen.
For a more complex example; a property that is a list of features can be bound to a map view and the features will be drawn as points on the map. At the same time, that same list can be bound to a data grid where each feature will be represented as a row in that grid. A model can have multiple view representations in an application.&lt;br/&gt;
Now, if a view wants to modify the model, it does so using a controller. A view is not, I repeat, is not allowed to mutate the model. Only a controller is allowed to mutate the model.  This is very important as a convention.  All the logic to mutate the model should reside in a controller even if it means that the logic is a single line implementation. Trust me on this, when developing the application, in the beginning this might be a single line. But... along the application development process, this will get more elaborated per the application requirements.  You will be tempted by the programming devils to "touch" the model from the view and you will come to regret it later on. So be resilient and do the right thing !&lt;br/&gt;
Enough preaching. So how does a view tell a controller to mutate the model ? Simple, using signals.  A signal is a glorified event with integrated event dispatching enabling a loose coupling between the view and the controller.
&lt;br/&gt;
The following is the signature of the static 'send' function in the Signal class:
&lt;br/&gt;
&lt;pre&gt;
public static function send(type:String,...args):void
&lt;/pre&gt;
The first required string argument is the signal type. This string is very important in our convention over configuration design as we will see later on. A signal can optionally carry additional information such as in the following example:
&lt;br/&gt;
&lt;pre&gt;
&amp;lt;s:textinput id="ti"/&amp;gt;
&amp;lt;s:button click="Signal.send('submit',ti.text)" label="{model.text}"/&amp;gt;
&lt;/pre&gt;
When the user clicks on the Button instance, a signal of type 'submit' is sent along with the text that was entered in the TextInput instance.&lt;br/&gt;
Now, I need 'something' to receive that signal and act on it. This something is a controller. Again, relying on convention over configuration, I will create a controller named 'SubmitController'. Note the prefix 'Submit', it is the same as the signal type.  Again this is the convention over configuration that is working in my favor where by writing pseudo-self documenting code. I can look at my list of controllers in my IDE and can tell immediately from the names what signal is handled by what class. Yes, I will have a lot of controllers, but this divide and conquer approach enables me to do one thing and one thing very well and separate my concerns.&lt;br/&gt;
In the controller class implementation, to handle the 'submit' signal, I should and must have a function named 'submit' that accepts one argument of type String like the following:
&lt;br/&gt;
&lt;pre&gt;
[Signal]
public function submit(text:String):void
{
  ...
}
&lt;/pre&gt;
Note the [Signal] metadata on the function declaration. See, as a Flex developer, you are already familiar with and using the built-in annotations such as [Bindable]. But Flex enables a developer to create his/her own metadata that will be attached to the class in question for introspection, cool, eh ?
Back to signals, one more example to solidify the association of signals to controllers - if you send a signal of the form:
&lt;br/&gt;
&lt;pre&gt;
Signal.send('foo', 123, 'text', new Date());
&lt;/pre&gt;
To handle that signal, you should have the following controller declaration:
&lt;br/&gt;
&lt;pre&gt;
public class FooController {
    [Signal]
    public function foo( nume:Number, text:String, now:Date):void {
      ...
    }
}
&lt;/pre&gt;
Note that the order of the handler function arguments should match the order and type of the signal arguments. 123 -&gt; nume, 'text' -&gt; text, new Date() -&gt; now.
What makes this pretty neat is the independence of the hardwiring signal dispatching mechanism and the handler is just a function that can be unit tested, more on that later.
&lt;br/&gt;
Applications need to communicate with the outside world, say for example you want to locate an address using an in-the-cloud-locator service. Controllers do not communicate with the outside world, they delegate that external communication to a service. That service will use the correct protocol and payload format to talk to the external service be SOAP, REST, RemoteService in XML, JSON or AMF or whatever. To enable different implementations of these protocols, an interface is declared and is injected into the controller for usage like as follows:
&lt;br/&gt;
&lt;pre&gt;
public class LocateController {

    [Inject]
    public var locateService:ILocateService;

    [Signal]
    public function locate(address:String):void
    {
        locateService.locate(address,
            new AsyncResponder(resultHandler, faultHandler));
    }
}
&lt;/pre&gt;
The locateService variable is assigned at runtime using inversion of control and when the 'locate' signal is sent, it is handled by the 'locate' function who delegates it to the ILocateService implementation.

The [Inject] metadata is for more than injecting service implementations. Here is another usage to overcome AS3 language constraints and make your code more testable.

Say you start a project and Signal A is sent, you go and you write Controller A to handle the signal. Now you have to write another controller B to handle signal B (remember SoC :-) but you find that Controller A and B will share some code. Since you are a good OO developer, you create a super class S that has the common code and make Controller A and Controller B subclass S. You feeling pretty good, onto Controller C to handle signal C. But wait a minute, some code from Controller B can be shared with Controller C. Ok, you create a super class D and subclass. But wait a minute..., AS3 is a single inheritance model, than means Controller B cannot subclass super class S and D at the same time. This is where composition is better that inheritance where now I can move the common code to class S and class D and inject those classes into controller A,B and C.
&lt;br/&gt;
&lt;pre&gt;
public class AController {
    [Inject]
    public var refS:ClassS;

    [Signal]
    public function doA(val:*):void {
        refS.doS(val);
    }
}

public class BController {
    [Inject]
    public var refD:ClassD;
    
    [Inject]
    public var refS:ClassS;

    [Signal]
    public function doB(val:*):void {
        refS.doS(val);
        refD.doD(val);
    }
}

public class CController {
    [Inject]
    public var refD:ClassD;

    [Signal]
    public function doC(val:*):void {
        refD.doD(val);
    }
}
&lt;/pre&gt;
Cool ? Onward, something _has_ to wire all these pieces together and that something is a Registry instance that is declared in the main application mxml as follows:
&lt;pre&gt;
&amp;lt;fx:Declarations&amp;gt;
    &amp;lt;h:Registry id="registry"&amp;gt;
        ...
   &amp;lt;/h:Registry&amp;gt;
&amp;lt;/fx:Declarations&amp;gt;
&lt;/pre&gt;
The children of the Registry are all the application controllers and all injectable delegates and services. So using the above example:
&lt;pre&gt;
&amp;lt;h:Registry id="registry"&amp;gt;
   &amp;lt;m:Model/&amp;gt;
    &amp;lt;c:ClassS/&amp;gt;
    &amp;lt;c:ClassD/&amp;gt;
    &amp;lt;s:AController/&amp;gt;
    &amp;lt;s:BController/&amp;gt;
    &amp;lt;s:CController/&amp;gt;
&amp;lt;/h:Registry&amp;gt;
&lt;/pre&gt;
Taking advantage of the declarative nature of Flex, I declare the registry children that gets translated into ActionScript instantiation, whereupon creation completion, the registry will introspect each child for [Inject] metadata and invokes the setter with the appropriate type instances. Next, the [Signal] metadata are located and a proxy object is created wrapping the annotated function as event listener to the Signals (remember, signals are nothing more than glorified events). All this introspection by the Registry is perform using the as3-commons-reflect library (url).
Going back to programing to interfaces and having multiple implementation of an interface in the Registry, how is the injection resolved ? Well, by default the first implementation is injected.
But what if I want a specific implementation ? here is the solution:
&lt;pre&gt;

&amp;lt;h:Registry&amp;gt;
    &amp;lt;c:RestService/&amp;gt;
    &amp;lt;c:SoapService id="soapService"/&amp;gt;
    &amp;lt;c:FooController/&amp;gt;
    &amp;lt;c:BarController/&amp;gt;
&amp;lt;/h:Registry&amp;gt;

[Register(name="restService")]
public class RestService Implements IService {
  ...
}

public class FooController {
  [Inject]
  public var restService:IService;
  ...
}

public class BarController {
  [Inject(name="soapService")]
  public var service:IService;
  ...
}

&lt;/pre&gt;
There is a lot packed in this example and there is a lot of conventions, so stay with me. The registry is declared with a couple of services and controllers. Note that the SoapController is registered with the "soapController" id. This enables the BarController to be injected with that specific implementation of the IService interface via the name attribute in the inject metadata. Next, the RestService is registered with the Registry with the name "restService" as declared in the class metadata. Now (magic time), the FooController is injected with the RestService instance despite the absence of the name attribute in the inject metadata because the _variable_ name is same as the class registration. Pretty powerful, I know, mind blowing!
&lt;br/&gt;
&lt;br/&gt;
Ok, last but not least, unit testing. Actually, if you do &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt;, that should be first. The holistic framework looks for simple interfaces, classes and functions, and with the built-in capabilities of unit testing and &lt;a href="http://www.adobe.com/devnet/flash-builder/articles/ascode-coverage.html"&gt;code coverage&lt;/a&gt; add-on to FlashBuilder, there is no excuse not to test your code. Whole books and articles have been written about Flex unit testing so google them.
&lt;br/&gt;
&lt;br/&gt;
Like usual all the source code is available &lt;a href="http://dl.dropbox.com/u/2193160/HolisticLib2Test.fxp"&gt;here&lt;/a&gt;. I drink my own champagne, what you will find is the Flex unit test project that includes the holistic library.
&lt;br/&gt;
&lt;br/&gt;
Have fun.
&lt;br/&gt;
&lt;br/&gt;
Update: I created a &lt;a href="http://dl.dropbox.com/u/2193160/MVCApp.zip"&gt;very simple project&lt;/a&gt; that demonstrated the usage of the Holistic framework. As I said it is a simple application that displays a data grid that is bound to a list property in the model. Below the grid is a form that enables you to enter a first name and last name. When you click on the submit button, a signal is sent with the entered info. A handler will received the info and will delegate it to a service that uppercases the values and adds them to the list.
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-3854689069224651435?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cGW5lh3HZFdrooNaIcVsxnWy768/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cGW5lh3HZFdrooNaIcVsxnWy768/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cGW5lh3HZFdrooNaIcVsxnWy768/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cGW5lh3HZFdrooNaIcVsxnWy768/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/r-SK2sFZa00" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/3854689069224651435/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=3854689069224651435" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3854689069224651435?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3854689069224651435?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/r-SK2sFZa00/micro-architecture-for-flex-ria-and-rma.html" title="Yet Another Micro Architecture for Flex RIA and RMA" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>13</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2011/10/micro-architecture-for-flex-ria-and-rma.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUBRn0_cCp7ImA9WhdbGU4.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-1060063438450626096</id><published>2011-10-11T11:18:00.000-04:00</published><updated>2011-10-18T07:10:57.348-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-18T07:10:57.348-04:00</app:edited><title>Map Tiles For Offline Usage Using ArcGIS API for Flex</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
So… Google introduced an offline feature to their mobile mapping application, enabling you to view map tiles when you are disconnected from the network. This is pretty neat and very useful now that local storage is so “abundant” on mobile devices.  In this post, I would like to show you how to use the mobile device local storage for offline tile retrieval using the &lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;ArcGIS API for Flex&lt;/a&gt;. When we built the API, we always had the vision of extensibility to enable people to do things that we did not think about. One of then was to enable the control of the URL from where the tiles will be retrieved.  A while back, I did such an implementation using &lt;a href="http://thunderheadxpler.blogspot.com/2008/09/arcgis-tiles-on-amazon-s3.html"&gt;Amazon S3&lt;/a&gt;. So, I rehashed that code using Adobe AIR File capabilities. The demo application that I am featuring here operates in two modes; an online mode and an offline mode.  In the online mode, I keep a set all downloaded tiles for a particular viewing session. Before I go offline, I download the map server metadata and all the visited tiles to my device local storage. The AIR runtime can notify an application when the network connectivity changes.  This enables me to put the application in offline mode and when I start panning and zooming, rather than retrieving the tiles from the cloud, I retrieve the tiles from my local storage. Pretty neat, eh ? So here is the code:
&lt;br /&gt;
&lt;pre&gt;public class OfflineTiledMapServiceLayer extends ArcGISTiledMapServiceLayer
{
  override protected function getTileURL(
     level:Number,
     row:Number,
     col:Number
  ):URLRequest
  {
    var urlRequest:URLRequest;

    if (Model.instance.isOffline)
    {
      urlRequest = new URLRequest(
        "app-storage:/l" + level + "r" + row + "c" + col);
    }
    else
    {
      urlRequest = super.getTileURL(level, row, col);
      if (urlRequest.url in Model.instance.cacheItemDict === false)
      {
        const item:CacheItem = new CacheItem();
        item.urlRequest = urlRequest;
        item.level = level;
        item.row = row;
        item.col = col;
        Model.instance.cacheItemDict[urlRequest.url] = item;
      }
   }

   return urlRequest;
 }
}
&lt;/pre&gt;
The OfflineTiledMapServiceLayer extends the ArcGISTiledMapServiceLayer class and overrides the &lt;i&gt;getTileURL&lt;/i&gt; function. This function is invoked to get the tile URL for a particular map level, row and column.  If the application mode is offline, then the “app-storage” url scheme is used and the path is in the form of “l”+level+”r”+row+”c”+column. If the application mode is online, then the super.getTileURL is invoked and we keep a set of visited URLs. Using the application settings view, the application has the option to download the map server metadata and iterate over the visited tiles and save the bitmap images to the local storage as defined by File.applicationStorageDirectory.
The AIR runtime has the capability to notify the application of a network change.  When this occurs, I ping a URL (www.google.com) using the HTTPService to determine if this is a connect or a disconnect change thus putting the application in an online or offline state.
&lt;br&gt;
The application can be written in such a way that any visited tile can automatically be saved to the local storage, I leave that as an exercise  for the reader :-)
&lt;br&gt;
Like usual, all the source code is available &lt;a href="http://dl.dropbox.com/u/2193160/OfflineApp.zip"&gt;here&lt;/a&gt;.
&lt;br&gt;
&lt;b&gt;NOTE&lt;/b&gt;: This sample application is for demonstration purposes &lt;b&gt;ONLY&lt;/b&gt; and is intended to be used with your own legally cacheable tiles - I am not a lawyer, but I am pretty sure that it is not legal to save locally the ArcGIS.com accessible tiles.
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-1060063438450626096?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pbed5PmYQGmJ55mTq6M8hw8wZkY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pbed5PmYQGmJ55mTq6M8hw8wZkY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pbed5PmYQGmJ55mTq6M8hw8wZkY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pbed5PmYQGmJ55mTq6M8hw8wZkY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/1KBza7ltD_Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/1060063438450626096/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=1060063438450626096" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/1060063438450626096?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/1060063438450626096?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/1KBza7ltD_Q/map-tiles-for-offline-usage-using.html" title="Map Tiles For Offline Usage Using ArcGIS API for Flex" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2011/10/map-tiles-for-offline-usage-using.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcCR38-eyp7ImA9WhdWGUk.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-9201458991560181904</id><published>2011-09-12T17:40:00.000-04:00</published><updated>2011-09-13T15:27:46.153-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-13T15:27:46.153-04:00</app:edited><title>Introspective Event Handling For Flex SkinnableComponents</title><content type="html">So the &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Flex+4"&gt;Flex Spark&lt;/a&gt; architecture promotes the separation of a component model/controller from its view, or in Flex lingo, its skin. Here is the PITA process that I go throughout when creating a skinnable component manually:
&lt;ol&gt;
&lt;li&gt;I create an ActionScript class (the host component) that subclasses SkinnableComponent.&lt;/li&gt;
&lt;li&gt;I define and annotate the skin parts. I try to define the skin part types to be as high as possible in the class hierarchy.  What I mean by that is instead of defining a part to be of type Button, I make it of type ButtonBase.&lt;/li&gt;
&lt;li&gt;I override the partAdded function and add all the event listeners for each part, as event handling should be done in the host component not in the skin.&lt;/li&gt;
&lt;li&gt;I override the partRemoved function and remove all the added event listeners, as I want to be a “good citizen”.&lt;/li&gt;
&lt;li&gt;I create a subclass of Skin and associate it with the host component.&lt;/li&gt;
&lt;li&gt;I add the skin parts and any graphic elements to make it “pretty”.&lt;/li&gt;
&lt;li&gt;I “ClassReference” the skin to its host component as the default skin in the main application stylesheet.&lt;/li&gt;
&lt;li&gt;I Implement the content of the event listeners.&lt;/li&gt;
&lt;li&gt;Done, to the next skinnable component.&lt;/li&gt;
&lt;/ol&gt;
Told you was PITA!

So here is what a very simple skinnable component looks like:

&lt;pre&gt;
package com.esri.views {
import flash.events.MouseEvent;
import mx.controls.Alert;
import spark.components.supportClasses.ButtonBase;

public class MySkinnableComponent extends SkinnableComponent{
    [SkinPart]
    public var myPart:ButtonBase;

    public function MySkinnableComponent(){
    }

    override protected function partAdded(partName:String, instance:Object):void {
      super.partAdded(partName, instance);
      if( instance === myPart) {
        myPart.addEventListener(MouseEvent.CLICK,myPart_clickHandler);
      }
    }

    override protected function partRemove(partName:String, instance:Object):void {
      super.partAdded(partName, instance);
      if( instance === myPart) {
        myPart.removeEventListener(MouseEvent.CLICK,myPart_clickHandler);
      }
    }

    public function myPart_clickHandler(event:MouseEvent):void {
      Alert.show('myPart_clickHandler');
    }
}
}
&lt;/pre&gt;

Pretty Eh ? When programming, I do believe in &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY&lt;/a&gt; and if something is “boilerplate”, then it should be "templated". In the above, what is really the PITA, is the monkey-coding of adding and removing event listeners for each added and removed part. Talk about repeating yourself ! What if we could automate that process with convention and very minimal configuration. This will enable me to focus on the fun part which is the skinning and styling, and on the money making part which is the logic.

Now, please note my event handlers:
&lt;pre&gt;
	public function myPart_clickHandler(event:MouseEvent):void
&lt;/pre&gt;
This naming convention says a lot; this is an event handler for a part named “myPart” and it is handling the “click” event whenever it is dispatched. Cool eh ? See, using this convention, a colleague can look at this “self-documented” function and figure out what is going on at that line of code.
So how to make this set of functions with this convention be automagically “hooked” and discovered by the running application ? Enter metadata! So with minimal configuration, I can now have:
&lt;pre&gt;
	[SkinPartEventHandler]
	public function myPart_clickHandler(event:MouseEvent):void
&lt;/pre&gt;
The discovery and handling of these functions can now be done for any skinnable component in a templated way by overriding the partAdded function using the amazing &lt;a href="http://www.as3commons.org/as3-commons-reflect/"&gt;as3-commons-reflect&lt;/a&gt; reflection library:
&lt;pre&gt;
override protected function partAdded(
  partName:String,
  instance:Object
  ):void
{
  super.partAdded(partName, instance);
  for each (var method:Method in m_type.methods){
    const metadataArray:Array = method.getMetadat("SkinPartEventHandler");
    if (metadataArray &amp;&amp; metadataArray.length){
      const metadata:Metadata = metadataArray[0];
      const tokens:Array = method.name.split("_");
      const localName:String = tokens[0];
      if (localName === partName){
        const eventHandler:String = tokens[1];
        const eventType:String = eventHandler.substr(0,
             eventHandler.indexOf("Handler"));
        instance.addEventListener(eventType, this[method.name]);
      }
    }
  }
}
&lt;/pre&gt;
So what is happening here ? As each skin part is added, we look for all the method in this class that are annotated with SkinPartEventHandler. Based on the agreed convention, the name of each matching method can be split into two tokens using the underscore character as a separator.  If first split token matches the added part name, then we can get the event type from the second token which is the string that is prefixing the ‘Handler’ text. So now, we can add the matching method as a listener to that added instance for that event type. Cool ? I think so too ! Come to think about it, All event handling in Flash/Flex should be done with metadata and convention. Oh well!

Here is a &lt;a href="http://dl.dropbox.com/u/2193160/IntroSkinApp.fxp"&gt;FlashBuilder project&lt;/a&gt; that you can download and see how this is implement and for you to DRY.
&lt;p&gt;
I am leaving the &lt;b&gt;MOST&lt;/b&gt; important part for last, make sure to add "-keep-as3-metadata+=SkinPartEventHandler" to your "Additional compiler arguments" in the "Flex Compiler" under your project properties, or else this special metadata will not be compiled into the class definition by default.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-9201458991560181904?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BMrcnvDwNr6iUaFPJsb_5A0I2Qk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BMrcnvDwNr6iUaFPJsb_5A0I2Qk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BMrcnvDwNr6iUaFPJsb_5A0I2Qk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BMrcnvDwNr6iUaFPJsb_5A0I2Qk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/CnzlmfJngH0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/9201458991560181904/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=9201458991560181904" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/9201458991560181904?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/9201458991560181904?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/CnzlmfJngH0/introspective-event-handling-for-flex.html" title="Introspective Event Handling For Flex SkinnableComponents" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2011/09/introspective-event-handling-for-flex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIHQXc_fCp7ImA9WhdWFU8.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-8971241039284958353</id><published>2011-08-19T17:49:00.002-04:00</published><updated>2011-09-08T18:55:30.944-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-08T18:55:30.944-04:00</app:edited><title>ArcGIS Lite API for Flex</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;The ArcGIS API for Flex&lt;/a&gt; is pretty amazing and very powerful, but it is very GIS centric. Flex Programmers have to know for example the difference between &lt;a href="http://en.wikipedia.org/wiki/Mercator_projection"&gt;mercator&lt;/a&gt; and geographical coordinates systems and have to understand the concepts of map layers, etc….&lt;br /&gt;
Programmers just want to put dots on maps at a specific latitude and longitude. This is very easy to do say for example using the google map API and folks have been asking for something like that for a while.  So, I am please to tell you about an &lt;a href="https://github.com/ArcGIS/ArcGISAPILiteforFlex"&gt;open source project&lt;/a&gt; that we have launched on github that is exactly that. A simple mapping API that is based on the core API to enable Flex developers to build mapping applications.  The idea to open source the project is to let you see how some high level functions are implemented using the low level API.  Here is a quick sample:&lt;br /&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:views="com.esri.views.*"&amp;gt;
    &amp;lt;fx:Script&amp;gt;
        &amp;lt;![CDATA[
            import com.esri.ags.events.MapEvent;

            private function map_loadHandler(event:MapEvent):void
            {
                map.setCenter([ 40.736072, -73.992062 ])
            }
        ]]&amp;gt;
    &amp;lt;/fx:Script&amp;gt;
    &amp;lt;views:ESRIMap id="map" load="map_loadHandler(event)"/&amp;gt;
&amp;lt;/s:Application&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
In addition, the API is mobile friendly. You can build Android and iOS mapping applications using the Flex API.  Here is a mobile sample:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:views="com.esri.views.*"&amp;gt;
    &amp;lt;fx:Style source="stylesheet.css"/&amp;gt;
    &amp;lt;fx:Script&amp;gt;
        &amp;lt;![CDATA[
            import com.esri.ags.events.MapEvent;
            import com.esri.events.GeolocationUpdateEvent;

            private function map_geolocationUpdateHandler(event:GeolocationUpdateEvent):void
            {
                map.locationToAddress(event.mapPoint, 50.0);
            }

            private function map_loadHandler(event:MapEvent):void
            {
                map.whereAmI();
            }
        ]]&amp;gt;
    &amp;lt;/fx:Script&amp;gt;
    &amp;lt;views:ESRIMobileMap id="map"
                         geolocationUpdate="map_geolocationUpdateHandler(event)"
                         load="map_loadHandler(event)"/&amp;gt;
&amp;lt;/s:Application&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
As mentioned earlier, the project is on &lt;a href="https://github.com/ArcGIS/ArcGISAPILiteforFlex"&gt;github&lt;/a&gt;. So you can clone it, compile it with the &lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;core API swc&lt;/a&gt; and learn how geocoding or routing is implemented.&lt;br /&gt;
&lt;br /&gt;
The project can use more documentation as, I do write self documenting code! LOL - Sorry, that was not funny since this is supposed to be a stepping stone to the core API that _is_ very well documented. So, I will have to spend more time on this and add more high level functions like “driveTimePolygon”.&lt;br /&gt;
&lt;br /&gt;
Anyway, “git clone” the project and tell me what you think.&lt;br /&gt;
&lt;br /&gt;
Want to give credit where credit is due - &lt;a href="http://twitter.com/#!/agup"&gt;Andy Gup&lt;/a&gt; started this initiative with his great &lt;a href="http://www.arcgis.com/home/item.html?id=726c6bbb2ebb4a87b2d3b360d547eeec"&gt;Starter Project Template&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Just to clarify an important point. This API is for very simple mapping purposes and is NOT maintained by the core team.&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-8971241039284958353?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gh52M1saCIXl4O2jTw0SkKD0dHQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gh52M1saCIXl4O2jTw0SkKD0dHQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gh52M1saCIXl4O2jTw0SkKD0dHQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gh52M1saCIXl4O2jTw0SkKD0dHQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/948OlljQ47g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/8971241039284958353/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=8971241039284958353" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8971241039284958353?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8971241039284958353?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/948OlljQ47g/arcgis-lite-api-for-flex.html" title="ArcGIS Lite API for Flex" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>13</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2011/08/arcgis-lite-api-for-flex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4NRn0ycCp7ImA9WhZWGE8.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-3975619320763247688</id><published>2011-03-29T09:02:00.010-04:00</published><updated>2011-05-19T12:53:17.398-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-19T12:53:17.398-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Kinect" /><title>Hacking the Kinect with Flash in a Mapping Application</title><content type="html">At this year's &lt;a href="http://www.esri.com/events/devsummit/index.html"&gt;DevSummit&lt;/a&gt;, I did a couple of demo theater presentations.  One of them was about hacking the Microsoft Kinect using the Flash platform in a mapping application. &lt;a href="http://www.youtube.com/watch?v=2e0b5X4eAQ0&amp;feature=channel_video_title"&gt;Here&lt;/a&gt; is a video.&lt;br /&gt;
&lt;a href="http://www.xbox.com/en-US/kinect"&gt;Kinect&lt;/a&gt; is a very successful and important product for Microsoft. And if you ever played with it using an XBox, you will understand why it is a very neat piece of technology.&lt;br /&gt;
Now, have you see the movie "&lt;a href="http://en.wikipedia.org/wiki/Minority_Report_(film)"&gt;Minority Report&lt;/a&gt;" ? Remember in the beginning of the movie when Tom Cruise step up to a console and started waving his hands to manipulate images (&lt;a href="http://www.youtube.com/watch?v=NwVBzx0LMNQ"&gt;video&lt;/a&gt;)? One of the gestures that most fascinated me was the one where he twisted his wrist while his fingers were pretending to grab a baseball size object. That twisting gesture moved a sequence of images through time. Twist to the right and the sequence moves forward in time. Twist to the left and the sequence moves back in time. In the movie, he went back and forth to detect a pattern in that time sequence. Now, wouldn't be cool if we can do the same with Flash and a Kinect?&lt;br /&gt;
A couple of months back, I was working on a project that visualized levels of flash flood data from hurricane &lt;a href="http://impactnews.com/central-austin/293-recent-news/9678-tropical-storm-hermine-drenches-austin"&gt;Hermine&lt;/a&gt; over Austin, TX. The data is temporal and is localized to nodes of a virtual grid on top of Austin with a cell size of about one and half kilometers. Using a &lt;a href="http://www.adobe.com/products/flex/"&gt;Flex&lt;/a&gt; interface to Kinect, I want to detect rotation gestures that my hands will be performing to animate back and forth the flash flood levels over a time period.&lt;br /&gt;
My flood data was stored in a DBF file. Using the most excellent DBF library from &lt;a href="http://www.vanrijkom.org"&gt;Edwin van Rijkom&lt;/a&gt;, I was able to parse and load the data into memory. This data is about 71 Megabytes, as it spans an area of about 25 by 25 kilometers for about 4 days worth of hourly information. All that data is loaded into memory and bucketed by space and time in such that for each hour, I can know instantly what is the flood level value at any location.&lt;br /&gt;
Next, to make this spatial data morph itself over time visually and efficiently using the &lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;ArcGIS API for Flex&lt;/a&gt;, I created my own custom temporal layer. This custom layer, relies heavily on the bitmap capabilities of the Flash Player. At the application startup time, I create a base bitmap that is proportional to the map pixel width and height. Then, at each frame refresh during the life cycle of the application, I advance or retard an hour index value. For an hour index value, I can lookup all the nodes and their values and convert them to small rectangular bitmaps whose pixel width and height values are adjusted proportionally to the map scale based on about 1.5 square Km area. Each bitmap is filled with a color picked from a color ramp proportional to the range of the loaded flood level values. Blue on the lower end. Red on the upper end. Each bitmap is &lt;a href="http://en.wikipedia.org/wiki/Bit_blit"&gt;bit-blit'ed&lt;/a&gt; on the base bitmap who is then bit-blit'ed onto the flash player display. By repeating this process over time, each location varies its color, giving the illusion of motion as a color traverses from one node to another. Cool, eh?&lt;br /&gt;
In my MVC implementation of the application, my hour index was a bindable property in my model and my temporal layer was bound to this property in such a way that whenever that property changes, the layer reflected that change by bit-blitting the node data stored in the model.&lt;br /&gt;
Now, that was the easy part of the implementation. The difficult part is how to hook the Kinect to my Mac and consume Kinect depth frames using Flex to detect gestures that will be translated into positive or negative changes to my model hour index property (Remember, I modify that value and the layer reflects that change). Googling around, I came across the &lt;a href="http://openkinect.org/wiki/Main_Page"&gt;OpenKinect&lt;/a&gt; project. In the Wrappers section, I was delighted to find that somebody has already developed an &lt;a href="http://www.as3kinect.org/"&gt;ActionScript implementation&lt;/a&gt; and from the looks of it, I thought I was almost there. The AS3Kinect client implementation opens a persistent socket connection from flash to a daemon process written in C that was linked at compile time with the &lt;a href="https://github.com/OpenKinect/libfreenect"&gt;libfreenect&lt;/a&gt; library. This daemon process reads the Kinect depth frames as a byte stream from the USB port and forwards that stream of bytes through the open socket to the Flash application. Once on the client side and again taking advantage of the bitmap capabilities, blobs can be detected. A blob is a small region on the bitmap with the same color. See, the Kinect sends depth information as bitmap frames. If you extend your hands in front of you and make your palms face the Kinect, your palms and your body are at a different depth relatively to the Kinect device. By creating a virtual front and back plane, depth data can be filtered and converted to either white or black color encoded bytes on a bitmap. White for the front bytes and black for the back bytes. A continuous patch of white bytes (your palms) can be converted to a blob.  A blob movement (single palm) can be translated to gestures like a swipe up, down, left and right. And multiple blob movements (your two palms moving)  can be translated to for example a rotation when the blobs are swirling around a point or a scale up or down when the blobs are separated from each other diagonally or brought together diagonally. I wrote a simple program to test the transfer of the Kinect bytes through that daemon proxy to my flex application and it was sluggish and non-responsive despite that the supplied test program rgbdemo (written in pure C and utilizing OpenGL) worked flawless. Now, the AS3Kinet forum said that all should be fine when they tested it on their PC's. It was that last word that prompted me to test it on my Windows machine and on that machine, it worked !!! I did a little bit of investigation and that led me to write this &lt;a href="http://thunderheadxpler.blogspot.com/2010/12/as3-socket-issues-with-large-data-on.html"&gt;blog&lt;/a&gt; post. Summarizing the post; the problem is that there exists a 64K chunking limit on sockets in the Flash player on Mac OS, and I needed to process 2 MBytes chunks (the size of a Kinect depth frame). And that 64K limit, throttled way back the data stream resulting in a slow to respond application :-( BTW, in the post, I did not want to give out too much of what I was working on, as I was preparing a surprise demo for &lt;a href="http://www.gisworx.ae/"&gt;GISWORX'11&lt;/a&gt; plenary session.&lt;br /&gt;
I tried to circumvent the chunking problem by using &lt;a href="http://labs.adobe.com/technologies/alchemy/"&gt;Alchemy&lt;/a&gt; and &lt;a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/LocalConnection.html"&gt;LocalConnection&lt;/a&gt;, but that too had it chunking limits, and came to the realization that blob detection and gesture recognition has to occur down in the proxy and passed along as small packets of information to the client. The AS3Kinect had yet another project based on the &lt;a href="http://www.openni.org/"&gt;OpenNI&lt;/a&gt; specification that did exactly what I needed, but that implementation was based on the Windows API and I have a Mac. I was very disappointed and started to panic with GISWORX'11 looming so closely. More googling around, I came across another natural interface specification, TUIO. The &lt;a href="http://www.tuio.org/"&gt;TUIO home page&lt;/a&gt; mentioned a Kinect implementation that runs on Mac OS. In addition, somebody implemented an &lt;a href="http://bubblebird.at/tuioflash/tuio-as3-library/"&gt;AS3 interface&lt;/a&gt; to the TUIO protocol. The process is the same as with the AS3Kinect, where a TUIO server (&lt;a href="https://code.google.com/p/tuiokinect/"&gt;TUIOKinect.app&lt;/a&gt;) is started. It reads the USB data stream and converts the chunks into frames where each frame is analyzed to detect blobs. All that is happening on the server. The detected blobs and their trajectories are converted into gestures.  The gestures are encoded into byte arrays per the TUIO specification and broadcasted as UDP packets. The AS3 TUIO protocol implementation can read the UDP packet, decodes it and dispatch it as AS3 event. To test the implementation, a simple sample application was provided to rotate and translate any display object whose mouseenabled property is set to true. The sample application worked beautifully. Now, it was time to hook the TUIO AS3 implementation into my mapping application.&lt;br /&gt;
UDP packets can only be consumed by an AIR application, so first, I had to convert my web application to an AIR application. I used the &lt;a href="http://labs.adobe.com/technologies/airlaunchpad/"&gt;AIRLanchpad&lt;/a&gt; application to generate the base template, and because my web application was based on MVC, the port of the model, the controls and some of the views was simple.  The main application had to change from an Application subclass to a WindowedApplication subclass. At the application creation complete event handling, a TUIOClient is instantiated with a UDP connector so is a gesture manager with a stage reference and a rotation gesture listener. The gesture manager having a reference to the stage watches for any added display object with mouse enabled property.  These display objects can become gesture listeners. The custom layer being mouse enabled and a child of the stage is a candidate for a listener to gesture rotate events.  Now, Kinect is very responsive and TUIOKinect will blast the application with rotation events.  To smooth this fast sequence of rotation value that could have pikes in the stream, I implemented a digital &lt;a href="http://en.wikipedia.org/wiki/Low-pass_filter"&gt;low pass filter&lt;/a&gt; giving me smooth rotation values as my extended palms are performing rotation gestures. A rotation to the right gives me a positive angle which translated to incrementing my hour index value in my model which through binding automagically refreshed the layer to show the flood level values at each node at that time instance. A rotation to the left, does the opposite. Works like a charm, and this was a &lt;span style="font-weight:bold;"&gt;huge&lt;/span&gt; success at the GISWORX'11 plenary. Modest, ain't I ?&lt;br /&gt;
If you have a Kinect and want to try it on your mac, download the AIR application from &lt;a href="http://dl.dropbox.com/u/2193160/NEXRADApp.air"&gt;here&lt;/a&gt;. Like usual, the source is available for you to check out what I have done. Just hold the right key on the date label of the running application and it will give you the option to view and download the source code.&lt;br /&gt;
Happy Kinecting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-3975619320763247688?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wCxDCW3CmK6CmB9i1ZGBNtAWfsg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wCxDCW3CmK6CmB9i1ZGBNtAWfsg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wCxDCW3CmK6CmB9i1ZGBNtAWfsg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wCxDCW3CmK6CmB9i1ZGBNtAWfsg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/CaHsFkCY-yU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/3975619320763247688/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=3975619320763247688" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3975619320763247688?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3975619320763247688?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/CaHsFkCY-yU/hacking-kinect-with-flash-in-mapping.html" title="Hacking the Kinect with Flash in a Mapping Application" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>7</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2011/03/hacking-kinect-with-flash-in-mapping.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AGSXs5eCp7ImA9Wx9XF0k.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-4709617067790681902</id><published>2010-12-28T20:44:00.003-05:00</published><updated>2011-01-11T07:42:08.520-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-11T07:42:08.520-05:00</app:edited><title>AS3 Socket Issues With Large Data on MacOS</title><content type="html">So... I was writing an MXML/AS3 application that uses a &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/Socket.html"&gt;Socket&lt;/a&gt; class instance to consume large amounts of data from a Java socket server program.  The server is supposed to write very rapidly 1MB data chucks to a connected AS3 client. Now the funny part is that when the packet size is less that 64K, the server would write these packets very quickly, but when it was writing 1MB chucks, it would "stall" between writes while the client was reading the data in 64KB chuncks. So, I start pulling my old TCP tuning trick back from my 'C' days to tune the socket server. But no difference. I can only tune the server side as the client AS3 socket class does not offer any tuning properties and I'm assuming that the folks at Adobe would implement sockets correctly.  It is this last statement that kept nagging me. "How often have I said to you that when you have eliminated the impossible, whatever remains, however improbable, must be the truth?" (Sherlock Holmes). So I wrote a simple Java socket client to test my server and guess what...no stall, A-Ha ! So there _is_ an issue with AS3 Sockets...but still...could not believe it, I mean...my MacBook Pro is used for development, God knows how many libraries I've installed and I have two VPN clients and again, God only knows what they setup in the kernel to make the tunnel. So, I took my Java server jar and my AS3 AIR application and installed them on a "clean" MacBook. Started the server and then the AIR application, and guess what....same result.  The server stalls between writes as the AS3 Socket client is reading in 64K chucks the data. Now this is messed up.   Dusted my old Dell with XP, installed the latest updates (that took forever) and then dropped the java server jar and AIR application. Started the server and then the AIR application, and guess what ? NO STALL. No way....my trusty Flash Player implementation on MacOS has issues. Just to make sure, started the server on XP and AIR on MacOS; stall. Started the server on MacOS and AIR on XP; No Stall.&lt;br /&gt;I'm writing this to share my experience, the binaries and the source code hoping that somebody out there tells me that I've done wrong or if there is indeed an issue.&lt;br /&gt;Please test it yourself. You need to have &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"&gt;Java&lt;/a&gt; and &lt;a href="http://get.adobe.com/air/"&gt;AIR&lt;/a&gt; installed.  The AIR package is &lt;a href="http://dl.dropbox.com/u/2193160/SocketTest.air"&gt;here&lt;/a&gt; and the server jar is &lt;a href="http://dl.dropbox.com/u/2193160/SocketServer.jar"&gt;here&lt;/a&gt;. The java source code is &lt;a href="http://dl.dropbox.com/u/2193160/SocketServer.zip"&gt;here&lt;/a&gt; and the FlashBuilder project is &lt;a href="http://dl.dropbox.com/u/2193160/SocketTest.fxp"&gt;here&lt;/a&gt;.&lt;br /&gt;From a command line, start the java server as follows:&lt;br /&gt;$ java -jar SocketServer.jar&lt;br /&gt;As to the client, just double click on the installed application. I'm printing to the console the number on packets that have been sent. On my Mac, I see a print statement every one second. On my XP, all is done in one second.&lt;br /&gt;Thanks Y'all - in the meantime will do my development off my XP. Happy New Year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-4709617067790681902?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gW3SOoF5UywQqpEcQnKn5Jb_mOY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gW3SOoF5UywQqpEcQnKn5Jb_mOY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gW3SOoF5UywQqpEcQnKn5Jb_mOY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gW3SOoF5UywQqpEcQnKn5Jb_mOY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/zhNdTV3iKQI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/4709617067790681902/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=4709617067790681902" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/4709617067790681902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/4709617067790681902?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/zhNdTV3iKQI/as3-socket-issues-with-large-data-on.html" title="AS3 Socket Issues With Large Data on MacOS" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/12/as3-socket-issues-with-large-data-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4GQHo7fSp7ImA9WhZaEEU.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-2235274520703269005</id><published>2010-11-04T16:16:00.004-04:00</published><updated>2011-06-26T07:15:21.405-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-26T07:15:21.405-04:00</app:edited><title>How to use Esri Flex API on Android and iPhone</title><content type="html">Update (Jun 2011) : For more updated info, check out my &lt;a href="http://www.adobe.com/devnet/flash-builder/articles/mobile-mapping-app-arcgis.html"&gt;ADC article here&lt;/a&gt;.&lt;br /&gt;
At &lt;a href="http://2010.max.adobe.com/"&gt;MAX2010&lt;/a&gt; (Awesome BTW) Adobe introduced &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Hero"&gt;Flex SDK Hero&lt;/a&gt; and &lt;a href="http://labs.adobe.com/technologies/flashbuilder_burrito/"&gt;Flash Builder Burrito&lt;/a&gt; which enables you to build and deploy Flex mobile applications on Android by default. In addition, using the revitalized &lt;a href="http://labs.adobe.com/technologies/packagerforiphone/"&gt;Packager for iPhone&lt;/a&gt;, you can postprocess the swf into an ipa that you can deploy on an iPhone using iTunes.&lt;br /&gt;
&lt;br /&gt;
In this post, I will share with you the steps that I took to use the &lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;Flex API for ArcGIS&lt;/a&gt; to build a mobile mapping application.&lt;br /&gt;
&lt;br /&gt;
First and foremost - RTFM - here are some links that u _need_ to read specially for iPhone provisioning:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Hero"&gt;http://opensource.adobe.com/wiki/display/flexsdk/Hero&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://labs.adobe.com/technologies/flashbuilder_burrito/"&gt;http://labs.adobe.com/technologies/flashbuilder_burrito/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://labs.adobe.com/technologies/packagerforiphone/"&gt;http://labs.adobe.com/technologies/packagerforiphone/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The cool part of this whole process is now you have one code base to build upon and deploy on Android and iPhone and in the future whatever mobile platform Adobe decides to support.&lt;br /&gt;
You can download the source code of the sample application from &lt;a href="http://thunderhead.esri.com/readonlyurl/MyMobileApp.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;
This simple application queries the states demographic layer in arcgis.com and displays the result as a list. By taking advantage of the new state syntax in Flex 4, if the user rotates the phone to view the info in landscape mode, the list is replaced with a map showing the selected states. Cool ?&lt;br /&gt;
There is no new Flex API for ArcGIS to learn. I'm using the same old Query, QueryTask, Map, ArcGISTiledLayer, GraphicLayer and SimpleFillSymbol classes from the released Flex API.&lt;br /&gt;
Now, to compile the application using Flash Builder Burrito, make sure to include in the libs project folder the flexapi swc and make sure to copy from the Flex sdks folder (under the burrito application folder) the mx.swc and the sparkskins.swc files. For the next release of our swc will not require the last two swc, just add them for now. Your package explorer in Flash Builder should look like this:&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_mTRp79uRCDU/TNMW_MYitCI/AAAAAAAAADs/cYYD-91nIkE/s1600/PackageExplorer.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 164px; height: 200px;" src="http://4.bp.blogspot.com/_mTRp79uRCDU/TNMW_MYitCI/AAAAAAAAADs/cYYD-91nIkE/s200/PackageExplorer.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5535793641880204322" /&gt;&lt;/a&gt;&lt;br /&gt;
Now you can compile, deploy and run your swf on the USB attached Android. Make sure that you have the latest AIR runtime on your phone. If not, then delete AIR using the Settings view and redeploy the application, the latest runtime engine will be automagically installed.&lt;br /&gt;
&lt;br /&gt;
Now to the iPhone. Currently, Burrito does not have a built-in wizard to postprocess the swf into and an ipa. This must be done via command line tools. So, download and install the latest iphone packager for your platform (windows or mac). In my case, I had to re-compile the source code to reproduce the swf.  Here is the content of my bash shell script:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;pre&gt;FLEX_HOME="/Applications/Adobe Flash Builder Burrito/sdks/4.5.0"
"${FLEX_HOME}/bin/mxmlc"\
-load-config "${FLEX_HOME}/frameworks/airmobile-config.xml"\
-compiler.include-libraries+=libs\
-sp src\
-o bin-debug/MyMobileApp.swf src/MyMobileApp.mxml
&lt;/pre&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Next is to convert the swf to an ipa.  Here is the content of my shell script:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;pre&gt;~/packagerforiphone_v2_mac_101110/bin/pfi\
-package\
-target ipa-test\
-provisioning-profile ~/YourProfile.mobileprovision\
-storetype pkcs12\
-keystore ~/YourFile.p12\
-storepass YourPassword\
MyMobileApp.ipa\
bin-debug/MyMobileApp-ios.xml\
bin-debug/MyMobileApp.swf\
bin-debug/assets/Default.png\
bin-debug/assets/Icon29.png\
bin-debug/assets/Icon57.png\
bin-debug/assets/Icon512.png
&lt;/pre&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Here is the content of MyMobileApp-ios.xml:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;application xmlns="http://ns.adobe.com/air/application/2.0"&amp;gt;
&amp;lt;id&amp;gt;ThunderHead&amp;lt;/id&amp;gt;
&amp;lt;filename&amp;gt;MyMobileApp&amp;lt;/filename&amp;gt;
&amp;lt;name&amp;gt;MyMobileApp&amp;lt;/name&amp;gt;
&amp;lt;version&amp;gt;v1&amp;lt;/version&amp;gt;
&amp;lt;initialWindow&amp;gt;
&amp;lt;renderMode&amp;gt;gpu&amp;lt;/renderMode&amp;gt;
&amp;lt;content&amp;gt;bin-debug/MyMobileApp.swf&amp;lt;/content&amp;gt;
&amp;lt;fullScreen&amp;gt;true&amp;lt;/fullScreen&amp;gt;
&amp;lt;aspectRatio&amp;gt;portrait&amp;lt;/aspectRatio&amp;gt;
&amp;lt;autoOrients&amp;gt;true&amp;lt;/autoOrients&amp;gt;
&amp;lt;/initialWindow&amp;gt;
&amp;lt;supportedProfiles&amp;gt;mobileDevice&amp;lt;/supportedProfiles&amp;gt;
&amp;lt;icon&amp;gt;
&amp;lt;image29x29&amp;gt;bin-debug/assets/Icon29.png&amp;lt;/image29x29&amp;gt;
&amp;lt;image57x57&amp;gt;bin-debug/assets/Icon57.png&amp;lt;/image57x57&amp;gt;
&amp;lt;image512x512&amp;gt;bin-debug/assets/Icon512.png&amp;lt;/image512x512&amp;gt;
&amp;lt;/icon&amp;gt;
&amp;lt;iPhone&amp;gt;
&amp;lt;InfoAdditions&amp;gt;&amp;lt;![CDATA[
&amp;lt;key&amp;gt;UIStatusBarStyle&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;UIStatusBarStyleBlackOpaque&amp;lt;/string&amp;gt;
&amp;lt;key&amp;gt;UIRequiresPersistentWiFi&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;NO&amp;lt;/string&amp;gt;
]]&amp;gt;&amp;lt;/InfoAdditions&amp;gt;
&amp;lt;/iPhone&amp;gt;
&amp;lt;/application&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;&lt;br /&gt;
Again - if you want to know what all the above options mean - you _must_ read the packager documentation. The pfi command will run for a long time - do not worry - it will eventually finish - again, this is still in its early stages, and I hope that Adobe will make this easier and faster in the future.&lt;br /&gt;
Now drag the ipa file onto iTunes and sync your iPhone. you should in theory have the app on your iPhone.&lt;br /&gt;
I hope this works for you and tell me what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-2235274520703269005?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7gIyJYHwZzbSiutV8orO-UMi1kY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7gIyJYHwZzbSiutV8orO-UMi1kY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7gIyJYHwZzbSiutV8orO-UMi1kY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7gIyJYHwZzbSiutV8orO-UMi1kY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/qqQomb-6JD8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/2235274520703269005/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=2235274520703269005" title="29 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/2235274520703269005?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/2235274520703269005?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/qqQomb-6JD8/how-to-use-esri-flex-api-on-android-and.html" title="How to use Esri Flex API on Android and iPhone" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_mTRp79uRCDU/TNMW_MYitCI/AAAAAAAAADs/cYYD-91nIkE/s72-c/PackageExplorer.png" height="72" width="72" /><thr:total>29</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/11/how-to-use-esri-flex-api-on-android-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8DR3o9eSp7ImA9Wx5WFUw.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-2767984881623574342</id><published>2010-09-24T14:35:00.003-04:00</published><updated>2010-09-26T10:21:16.461-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-26T10:21:16.461-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="legend" /><category scheme="http://www.blogger.com/atom/ns#" term="noaa" /><title>Dynamic Legend Generation From An Image Map Services</title><content type="html">You can see the national weather warnings that NOAA publishes &lt;a href="http://www.weather.gov/view/nationalwarnings.php?map=on"&gt;here&lt;/a&gt;. If you look at the page, you will notice that _all_ the legend swatches and text are presented under the map and you are left to your own means of locating the associated colors between the map and the legend grid to figure out what is on the map.&lt;br /&gt;It would be nice if the legend grid could be dynamically generated to list only the swatch colors and their descriptions based on what is on the map. This is what this post tries to solve.&lt;br /&gt;So NOAA publishes the national weather service maps as Esri ArcGIS REST &lt;a href="http://rmgsc.cr.usgs.gov/ArcGIS/rest/services"&gt;endpoints&lt;/a&gt;. Using an instance of an ArcGISDynamicMapServiceLayer subclass, I can intercept the reponse image. Once I have the image bitmap data, I can get a histogram of the color distribution. Now using NOAA color &lt;a href="http://www.weather.gov/wwamap-prd/faq.php"&gt;map&lt;/a&gt;, I can associate a color with a description and populate a legend UI component. Check out the application in action &lt;a href="http://thunderhead.esri.com/readonlyurl/WeatherApp/WeatherApp.html"&gt;here&lt;/a&gt;. The legend located on the top right corner is not fully transparent, roll the mouse over it to make it fully opaque. And like usual, you can download the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/WeatherApp/srcview"&gt;here&lt;/a&gt;.&lt;br /&gt;Update: Looks like my usage and processing of the histogram does not lead me to a unique set of colors. So I reverted back to good old fashion looping through the pixels and creating a unique bucket of colors. Works pretty fast and more importantly correctly :-)  A colleague at Esri was wondering if you can click on the map and popup an info window containing the label of the weather at that location, so I updated the code to handle this request - Thanks Mehul.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-2767984881623574342?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f1krxUtySN9o3vH2dsC1vtrUfr0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f1krxUtySN9o3vH2dsC1vtrUfr0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f1krxUtySN9o3vH2dsC1vtrUfr0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f1krxUtySN9o3vH2dsC1vtrUfr0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/8XN8xOTGlgQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/2767984881623574342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=2767984881623574342" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/2767984881623574342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/2767984881623574342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/8XN8xOTGlgQ/dynamic-legend-generation-from-image.html" title="Dynamic Legend Generation From An Image Map Services" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/09/dynamic-legend-generation-from-image.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IMQ3g4fyp7ImA9Wx9RFEQ.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-6148406329793178510</id><published>2010-08-16T20:48:00.003-04:00</published><updated>2010-12-16T04:26:22.637-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-16T04:26:22.637-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cluster" /><category scheme="http://www.blogger.com/atom/ns#" term="flare" /><title>Image Flare Symbol For Clustered Graphics</title><content type="html">This is a long overdue post following the clustering &lt;a href="http://thunderheadxpler.blogspot.com/2010/08/weighted-clustering-with-attributes.html"&gt;post&lt;/a&gt; where I wanted each flare element in a cluster symbol to flare to a different image symbol when the flare expands out.  In addition, the default flare symbol expands upon a rollover mouse event, by me giving you the source code, you can customize it to expand on click, double click, shift click, whatever you want - you have the source code. The same applies to the flare elements. The ImageFlareSymbol has the same properties as the basic FlareSymbol but has two additional properties (backgroundWeights, backgroundColors) to color code the clusters based on their weight value. Each cluster is composed of one or more Graphic instance. In this implementation, each graphic must be symbolized with an instance of ImageFlareElementSymbol. The latter has a property ‘href’ that reference a bitmap url that will be displayed as a flare element. &lt;a href="http://thunderhead.esri.com/readonlyurl/FlareApp/FlareApp.html"&gt;Here&lt;/a&gt; is a sample application to show the image flare in action. And like usual, &lt;a href="http://thunderhead.esri.com/readonlyurl/FlareApp/srcview/FlareApp.zip"&gt;here&lt;/a&gt; is the source code.&lt;br /&gt;&lt;a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="mraad"&gt;Tweet&lt;/a&gt;&lt;script type="text/javascript" src="http://platform.twitter.com/widgets.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-6148406329793178510?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C7XDuEFDNPC8CRnVnqqo66t_SJI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C7XDuEFDNPC8CRnVnqqo66t_SJI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C7XDuEFDNPC8CRnVnqqo66t_SJI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C7XDuEFDNPC8CRnVnqqo66t_SJI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/eCFImhXPbDM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/6148406329793178510/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=6148406329793178510" title="30 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/6148406329793178510?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/6148406329793178510?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/eCFImhXPbDM/image-flare-symbol-for-clustered.html" title="Image Flare Symbol For Clustered Graphics" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>30</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/08/image-flare-symbol-for-clustered.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIDSX88eyp7ImA9Wx5SEEg.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-9059781803000701442</id><published>2010-08-05T16:43:00.004-04:00</published><updated>2010-08-05T20:29:38.173-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-05T20:29:38.173-04:00</app:edited><title>Weighted Map Feature Clustering With Attributes</title><content type="html">&lt;div&gt;Was asked if the WeightedClusterer can cluster features not just by proximity but by proximity and attribute property value.  The idea is that there should be at least one cluster per unique attribute property value. Let me explain further:&lt;/div&gt;&lt;div&gt;￼&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://dl.dropbox.com/u/2193160/cluster.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 276px; height: 266px;" src="http://dl.dropbox.com/u/2193160/cluster.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The above snapshot is a clustering of cities based on proximity and country - note that despite the proximity of Belgium and The Netherlands, two distinct clusters have been created one for BE and the other for NL - now for France - there is a cluster containing one feature over Paris, however due to the distance from Paris (at that scale) a cluster was created based on 3 cities in the south of France. Make sense ?&lt;/div&gt;&lt;div&gt;In the implementation of the AttrClusterer class that extends the ESRIClusterer class, we override the clusterGraphics function.  This function is invoked indirectly by the Flex framework during the update of the display list. In this function, we overlay a virtual grid on the map.  This grid acts as a spatial index.  Features that are in the same cell will be initially clustered together. Next a process of searching and merging will be executed till no cluster overlaps another cluster. Let me explain this process; for each cluster, search the immediately adjacent cell for any overlapping cluster (that is why we need that spatial index grid :-).  If a neighboring cluster is found, then the two cluster merge into one cluster and the location of the new cluster is based on the weight of each original cluster. the new cluster is spatially indexed and the original two clusters are removed.  BTW, this process is guaranteed to converge to a steady state solution, so there is no need for a terminal condition like a counter.  Now something of importance here is the index used to locate neighbors. The spatial index is implemented as a hash map, the cluster  key is a combination of the cluster position relative to the center of the map and the cluster attribute - remember - that what started this whole implementation. You can see the application in action &lt;a href="http://thunderhead.esri.com/readonlyurl/ClusterApp/ClusterApp.html"&gt;here&lt;/a&gt;.  I’ve loaded the top 1000 cities by population from &lt;a href="http://www.geonames.org/"&gt;geonames&lt;/a&gt;. And like usual, you can find the source code &lt;a href="http://thunderhead.esri.com/readonlyurl/ClusterApp/srcview/"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-9059781803000701442?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ML_wnFwsc0b4WKt1CO70Em_0LeY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ML_wnFwsc0b4WKt1CO70Em_0LeY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ML_wnFwsc0b4WKt1CO70Em_0LeY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ML_wnFwsc0b4WKt1CO70Em_0LeY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/DvwTg78AEE0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/9059781803000701442/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=9059781803000701442" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/9059781803000701442?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/9059781803000701442?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/DvwTg78AEE0/weighted-clustering-with-attributes.html" title="Weighted Map Feature Clustering With Attributes" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>11</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/08/weighted-clustering-with-attributes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04FQXo7fyp7ImA9Wx5TFE0.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-8679527402986452332</id><published>2010-07-26T07:20:00.004-04:00</published><updated>2010-07-29T07:11:50.407-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-29T07:11:50.407-04:00</app:edited><title>Merging Table Of Content and Legend Info</title><content type="html">Initially, while working on &lt;a href="http://www.gulfofmexicoresponsemap.com/dwhi/"&gt;Gulf Of Mexico Response Map&lt;/a&gt;, the legend and table-of-content were two separate windows. That took too much real-estate, and a TOC layer was hard to correlate with the legend swatch by name only.  So I set upon merging the legend window and the table-of-content into one window. There is plenty of TOC code as a visual tree component, but it is the legend UI that causes us trouble as there is no &lt;a href="http://resources.esri.com/help/9.3/arcgisserver/apis/rest/gettingstarted.html"&gt;REST&lt;/a&gt; endpoint to get the layer swatch information.  Well with the advent of &lt;a href="http://help.arcgis.com/en/webapi/flex/apiref/com/esri/ags/layers/FeatureLayer.html"&gt;FeatureLayer&lt;/a&gt; somebody can argue that this could be done. But you still have to go back and forth for each layer and get the rendering information.  BTW, this will be remedied in 10.1, as a new REST endpoint will be introduced to get _all_ rendering information of a map service.  In the meantime, I had to do something. As you can imagine the project map services were very dynamic and the layer content was changing constantly, so having a static legend is out of the question. There were attempts to create an ArcObject proxy, where the client application connects to that proxy who issues a SOAP request to an ArcGIS server for the legend info.  The SOAP result is converted to JSON and forwarded back to the client for decoding and rendering. The code was written in .Net and have a Java based server. I wanted to be platform independent and have a two tier architecture (at least from a 10,000 feet perspective) and the introduction of a proxy was out of the question. So....I have to issue SOAP calls directly from the client to ArcGIS server. This is where the advent of FlashBuilder with its data connectivity option was a blessing. FlashBuilder can generate correctly stub code for ArcGIS SOAP methods based on a map service WSDL. This was impossible in FlexBuilder. Yes, it does bloat the code base a bit, but it is a small price to pay for such a dynamic system. The TOC code is based on the &lt;a href="http://help.arcgis.com/en/webapps/flexviewer/"&gt;FlexViewer&lt;/a&gt; TOC code. I modified the item renderer to be of variable height to accommodate the renderer swatches as child elements. You can see the application in action &lt;a href="http://thunderhead.esri.com/readonlyurl/LegendApp/LegendApp.html"&gt;here&lt;/a&gt;. And like usual, you can download the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/LegendApp/srcview/"&gt;here&lt;/a&gt;. Small note: First time through, it take a few seconds to get the swatches, so if you open the tree, it will look “plain” and somehow AGS returns blank swatches for tiled map services. not sure why ! have to ask the core team about that. Oh one more thing, in addition to adding the &lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;Flex API for AGS&lt;/a&gt; swc, make sure to include the Adobe provided fiber swcs. Until 10.1 (hopefully soon) hope this can help.&lt;div&gt;PS: If you have a 10 server - there is a &lt;a href="http://sampleserver3.arcgisonline.com/ArcGIS/SDK/REST/layers.html"&gt;REST&lt;/a&gt; way to get all the layers published in a map server that could be used to create swatches from the rendering information.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-8679527402986452332?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VvLfcCfBCM74CiHedwdlMZR1E_Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VvLfcCfBCM74CiHedwdlMZR1E_Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VvLfcCfBCM74CiHedwdlMZR1E_Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VvLfcCfBCM74CiHedwdlMZR1E_Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/xmmasF4wd9U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/8679527402986452332/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=8679527402986452332" title="28 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8679527402986452332?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8679527402986452332?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/xmmasF4wd9U/merging-table-of-content-and-legend.html" title="Merging Table Of Content and Legend Info" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>28</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/07/merging-table-of-content-and-legend.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEINRHc6cCp7ImA9WxFaGE4.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-5573152150970238950</id><published>2010-07-22T17:51:00.004-04:00</published><updated>2010-07-22T18:09:55.918-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-22T18:09:55.918-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PixelBender" /><category scheme="http://www.blogger.com/atom/ns#" term="Flex" /><title>Pixel Bender For Map Projection</title><content type="html">A customer came up to me at the &lt;a href="http://www.esri.com/events/user-conference/index.html"&gt;User Conference&lt;/a&gt; and asked me if I can apply the same overlay method that I used in my &lt;a href="http://thunderheadxpler.blogspot.com/2009/02/ground-overlays-on-maps.html"&gt;OverlaySymbol&lt;/a&gt; application to position a geographic referenced image on a &lt;a href="http://www.fmepedia.com/index.php/Web_Mercator"&gt;web mercator&lt;/a&gt; tiled base map; since esri is migrating most of its published maps on &lt;a href="http://www.arcgis.com/home/"&gt;arcgis.com&lt;/a&gt; to web mercator. After talking it over with my friend Kerry (who is the final authority when it comes to map projections), he recommended that this should be a pixel by pixel operation due to the exponential latitude elongation nature of web mercator. So basically the algorithm is; for each output mercator pixel, convert it back to geographic, find out in the geographic image source what is the pixel color at that geographic location and assign that color to the output mercator pixel. Straight forward, I mean the web mercator transform is well known. I just have to do it a million time, and... that is when I started panicking. A million time loop in AS3 - that will take forever (well actually half a second) in user space. Then I remembered &lt;a href="http://labs.adobe.com/technologies/pixelbender/"&gt;PixelBender&lt;/a&gt;. That is what it does for living very well - massively process pixels at the GPU level. So I downloaded the &lt;a href="http://www.adobe.com/devnet/pixelbender/"&gt;toolkit&lt;/a&gt;, went over the tutorials (all awesome) and I started writing my own filter. PixelBender can operate in a filter, blender or filler mode. It is the last mode that I'm interested in, as it enables me to fill any region in a display object based on a set of parameters. So I approached this overlay method differently than my previous experiment. I created a layer rather than an symbol to overlay the geographic image. The source of the image will be a property of the layer. The layer will load the compiled PixelBender filter code and on an extent change, PixelBender will be invoked to fill the layer graphics context based on the image source and extent as parameters. And it is fast :-). The following is a snippet of the mercator filter source code:&lt;pre&gt;void evaluatePixel()&lt;br /&gt;{&lt;br /&gt;float2 pt = outCoord();&lt;br /&gt;pt.x = pt.x * targetWidthFact + targetXMin;&lt;br /&gt;pt.y = (targetPixelHeight - pt.y) * targetHeightFact + targetYMin;&lt;br /&gt;&lt;br /&gt;pt.x = degrees(pt.x / 6378137.0);&lt;br /&gt;pt.y = degrees(2.0*atan(1.0) - (2.0 * atan(exp(-1.0 * pt.y / 6378137.0))));&lt;br /&gt;if( pt.x &lt; -180.0 || pt.x &gt; 180.0 || pt.y &lt; -90.0 || pt.y &gt; 90.0)&lt;br /&gt;{&lt;br /&gt;  dst = float4(0.0,0.0,0.0,0.0);&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;  pt.x = (pt.x - sourceXMin) * sourceWidthFact;&lt;br /&gt;  pt.y = (sourceYMax - pt.y) * sourceHeightFact;&lt;br /&gt;  dst = sampleNearest(src,pt);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So the evaluatePixel() function is invoked by Pixel Bender on each pixel in the target image. the built-in outCoord() function return the coordinated in the target image that is currently being processed. In the next two lines, I convert the pixel values into mercator values - this is a linear transformation. Then I convert the mercator values into geographic value. If the values are 'outside' the geographic boundaries are return a fully transparent pixel value. Otherwise I linearly convert it to a pixel coordinate based on the image source width and height and I invoke the built-in sampleNearest() function to get me the pixel color value and return that value to pixel bender who will paint the target pixel location with that value. Cool, eh ?&lt;br /&gt;You can see the application in action &lt;a href="http://thunderhead.esri.com/readonlyurl/OverlayApp/OverlayApp.html"&gt;here&lt;/a&gt;.  It shows precipitation image data from &lt;a href="http://origin.cpc.ncep.noaa.gov/products/GIS/map_viewer/png/GLB_DLY_PREC/"&gt;NOAA&lt;/a&gt;. And like usual you can download the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/OverlayApp/srcview/"&gt;here&lt;/a&gt;. BTW, this requires the new &lt;a href="http://help.arcgis.com/en/webapi/flex/"&gt;Flex API&lt;/a&gt; for ArcGIS Server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-5573152150970238950?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yDbi66JUHMRm9xc0Z_t4FuvON5s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yDbi66JUHMRm9xc0Z_t4FuvON5s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yDbi66JUHMRm9xc0Z_t4FuvON5s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yDbi66JUHMRm9xc0Z_t4FuvON5s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/vi9WqapajGw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/5573152150970238950/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=5573152150970238950" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/5573152150970238950?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/5573152150970238950?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/vi9WqapajGw/pixel-bender-for-map-projection.html" title="Pixel Bender For Map Projection" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/07/pixel-bender-for-map-projection.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYERXo-cSp7ImA9WxBbEUk.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-1877105998484525610</id><published>2010-03-09T07:55:00.012-05:00</published><updated>2010-03-09T08:58:24.459-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-09T08:58:24.459-05:00</app:edited><title>Augmented Reality, iPhone and ArcGIS Server</title><content type="html">&lt;div&gt;I am a HUGE fan of &lt;a href="http://en.wikipedia.org/wiki/Augmented_reality"&gt;Augmented Reality&lt;/a&gt;, and one of my favorite applications on the iPhone is &lt;a href="http://layar.com/"&gt;Layar&lt;/a&gt;. In this post, I will "walk you" through how to setup a simple &lt;a href="http://www.esri.com/software/arcgis/arcgisserver/index.html"&gt;ArcGIS&lt;/a&gt; Layar Point Of Interests (POI) layer and how to expose it through the &lt;a href="http://layar.com/layar-is-in-the-iphone-app-store/"&gt;iPhone&lt;/a&gt; application. In addition, I created a small &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/"&gt;Flex&lt;/a&gt; application that will enable you to add POIs to that feature class through a python geo-processor task.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;BTW - this is heavily geared to using &lt;a href="http://www.esri.com/"&gt;ESRI&lt;/a&gt; desktop and server tools and I'm assuming that you are familiar with these tools.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, request a developer key from &lt;a href="http://dev.layar.com/"&gt;http://dev.layar.com/&lt;/a&gt;.  This might take a couple of hours to get to you.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, in the meantime, let's get started. Using ArcCatalog, create a new point feature class called 'Layar' in a geodatabase with the following fields: Title (text), Line2 (Text), Line3 (Text), Line4 (Text), Attribution (Text), Type (Integer), ImageUrl (Text:512).&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_mTRp79uRCDU/S5ZHYtwsSqI/AAAAAAAAADM/LFFP4x8ub0A/s1600-h/FeatureClass.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 162px; height: 200px;" src="http://3.bp.blogspot.com/_mTRp79uRCDU/S5ZHYtwsSqI/AAAAAAAAADM/LFFP4x8ub0A/s200/FeatureClass.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5446619289277450914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;Import that layer into a map document using ArcMap. Save and publish the MXD as a Map Service. Just to be on the safe side, clear your REST endpoint service directory cache and list the available services. You should now see the new map service and you can now query using REST the newly created 'Layar' layer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, we need to populate this 'Layar' layer. With the Advent of ArcGIS 10, this could easily be achieved using the new FeatureTask endpoint. However, I'm still using a 9.3.X server and I will have to rely on a geoprocessing task to add point features to the Layar feature class. For the sake of simplicity and quick deployment, I decided to implement this GP task using python. So, using ArcCatalog, create a new GP Toolbox and add to the toolbox a new python script.  You can download the script from &lt;a href="http://thunderhead.esri.com/readonlyurl/LayarCreate.py"&gt;here&lt;/a&gt;. Again, I'm assuming that you are familiar with all these tools.  This script will have two parameters. The first input parameter should be named 'featureSet' of type 'FeatureSet' and its schema should reference the Layar feature class. The second parameter should be named 'objectID'.  It has an output direction and is of type LONG. Basically what the script does; it expects a feature set with one feature.  That feature is read using a cursor and placed in memory. Next an insert cursor is created on the Layar feature class and populated with the in memory information and executed. Upon a successful execution, the OBJECTID of the last inserted feature is retrieved and returned back as a parameter. The whole script is surrounded by a try: except: in case of an exception, where a -1 as an OBJECTID value is returned back. Simple but not simplistic :-) Publish this Toolbox, clear the cache and now you should have new GPService task.&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_mTRp79uRCDU/S5ZJPyUpTyI/AAAAAAAAADU/6hjfIH-Pvp8/s1600-h/LayarApp.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 200px; height: 140px;" src="http://1.bp.blogspot.com/_mTRp79uRCDU/S5ZJPyUpTyI/AAAAAAAAADU/6hjfIH-Pvp8/s200/LayarApp.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5446621334906425122" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To use this GP task interactively, I created a &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/"&gt;Flex&lt;/a&gt; based web application.&lt;/div&gt;&lt;div&gt;This application consists of a side-by-side map and form component enabling the user by zooming and panning to click and define POI coordinates and to populate that POI attributes. By clicking the Save button, the above publish GP task is invoked and upon a successful completion, the map is refreshed to show the newly added POI. The Flex  application source code can be downloaded from &lt;a href="http://thunderhead.esri.com/readonlyurl/LayarApp.zip"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that we have created and authored this Layar information, we need to publish and consume it on the iPhone Layar application. The Layar folks have described in detail the JSON publishing format - &lt;a href="http://layar.pbworks.com/GetPointsOfInterest"&gt;http://layar.pbworks.com/GetPointsOfInterest&lt;/a&gt;. So what we need now, is a middleware that accepts an HTTP request from an iPhone, convert the input parameters to an ArcGIS REST query, invoke a query task whose URL is the Layar layer URL in the above publish map service, read the ArcGIS JSON response and convert to a Layar JSON response. Easy, eh ? That is why we have computers :-) I accomplished all this using Java Web Application - you can download the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/LayarWeb.zip"&gt;here&lt;/a&gt;. This web application is basically a servlet that relies on the &lt;a href="http://hc.apache.org/httpclient-3.x/"&gt;Apache HTTPClient&lt;/a&gt; library for http communication and the J&lt;a href="http://jackson.codehaus.org/"&gt;ackson JSON processor&lt;/a&gt; library for fast consumption and JSON production.  You might wonder why I decided to write this in Java versus say python. well...First, I'm a Java nut.  Two, I can whip this up fairly quickly, Three, wanted to experiment with &lt;a href="http://code.google.com/appengine/"&gt;Google Java App Engine&lt;/a&gt; so I can be "in the cloud man !" - LOL, last one is just an artifact of the first two - but it is cool ! When the iPhone Layar application requests POI, it does so on a predefined URL (more on this later) with the following HTTP GET parameters, lat: your current latitude location, lon: your current longitude location, radius: the search radius in meters plus other parameters. In this application I'm just decoding lat, lon and radius.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that you have an in-the-cloud POI Layar endpoint and assuming that you have gotten your Layar developer key, you can sign in to &lt;a href="http://dev.layar.com/"&gt;http://dev.layar.com/&lt;/a&gt; and create your own layer. The form will request a POI URL, enter your in-the-cloud poi servlet endpoint. All of the above was leading this point. I highly recommend that you test your layer using the Layar test page &lt;a href="http://dev.layar.com/api20test/layarTestPage/"&gt;http://dev.layar.com/api20test/layarTestPage/&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To test this on your iPhone, go to "Settings" add add your developer ID and key to the Layar application settings. Launch the Layar application, and you should see your newly published layer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_mTRp79uRCDU/S5ZLk2q7RuI/AAAAAAAAADc/Y04zmFj3zD8/s1600-h/LayarView.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 134px; height: 200px;" src="http://3.bp.blogspot.com/_mTRp79uRCDU/S5ZLk2q7RuI/AAAAAAAAADc/Y04zmFj3zD8/s200/LayarView.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5446623895874127586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is just the tip of the iceberg. There is so much more that you can do, adjust and customize. I just wanted to share this "little" experience with you. Hope you found it useful and tell me what you think.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-1877105998484525610?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1DGRLc19th2-R88yBm0ExaVUVyw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1DGRLc19th2-R88yBm0ExaVUVyw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1DGRLc19th2-R88yBm0ExaVUVyw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1DGRLc19th2-R88yBm0ExaVUVyw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/GQAlj0VV48k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/1877105998484525610/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=1877105998484525610" title="25 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/1877105998484525610?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/1877105998484525610?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/GQAlj0VV48k/augmented-reality-iphone-and-arcgis.html" title="Augmented Reality, iPhone and ArcGIS Server" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_mTRp79uRCDU/S5ZHYtwsSqI/AAAAAAAAADM/LFFP4x8ub0A/s72-c/FeatureClass.png" height="72" width="72" /><thr:total>25</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/03/augmented-reality-iphone-and-arcgis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08AQH89eSp7ImA9WxBUEk0.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-8026176993495274617</id><published>2010-02-26T12:17:00.004-05:00</published><updated>2010-02-26T12:37:21.161-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-26T12:37:21.161-05:00</app:edited><title>Heat Map Layer Revisited</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_mTRp79uRCDU/S4gGttMYVKI/AAAAAAAAADE/AyMG2YgLffE/s1600-h/HeapMapNew.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://1.bp.blogspot.com/_mTRp79uRCDU/S4gGttMYVKI/AAAAAAAAADE/AyMG2YgLffE/s320/HeapMapNew.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5442607531972646050" /&gt;&lt;/a&gt;Following &lt;a href="http://thunderheadxpler.blogspot.com/2009/11/spatial-temporal-mbta-heatmap.html"&gt;this&lt;/a&gt; post, Glenn G. found an "issue" when panning the map. I revisited the project and indeed there was a bug.  Thanks Glenn. I updated the project and &lt;a href="http://thunderhead.esri.com/readonlyurl/HeatMapNew/HeatMapNew.html"&gt;here&lt;/a&gt; is the result. In this project, I downloaded from &lt;a href="http://download.geonames.org/export/dump/"&gt;geonames&lt;/a&gt; all cities with population over 15000 and plotted them on the map. The clustering of the cities (over 21,000) generated a cool heat map. Check it out and tell me what you think. And like usual, you can download the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/HeatMapNew/srcview/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-8026176993495274617?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gHFv7h7_YYnxMci5dEWPytjfnDg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gHFv7h7_YYnxMci5dEWPytjfnDg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gHFv7h7_YYnxMci5dEWPytjfnDg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gHFv7h7_YYnxMci5dEWPytjfnDg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/eNB-0YhNaQQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/8026176993495274617/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=8026176993495274617" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8026176993495274617?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8026176993495274617?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/eNB-0YhNaQQ/heat-map-layer-revisited.html" title="Heat Map Layer Revisited" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_mTRp79uRCDU/S4gGttMYVKI/AAAAAAAAADE/AyMG2YgLffE/s72-c/HeapMapNew.png" height="72" width="72" /><thr:total>14</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/02/heat-map-layer-revisited.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQNSXk4cSp7ImA9WxBWF0Q.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-8086410443072978527</id><published>2010-02-10T05:16:00.005-05:00</published><updated>2010-02-10T05:39:58.739-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-10T05:39:58.739-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><title>How Oracle Can Improve Java</title><content type="html">Found &lt;a href="http://www.eweek.com/c/a/Application-Development/15-Ways-Oracle-Can-Make-Java-Better-and-Improve-Its-Stance-with-Developers-271933/?kc=rss"&gt;this&lt;/a&gt; great article "15 Ways Oracle Can Make Java Better (and Improve Its Stance with Developers)" - here is my "in the weed" take:&lt;div&gt;&lt;ol&gt;&lt;li&gt;Keep &lt;a href="http://java.sun.com/javaone/index.jsp"&gt;JavaONE&lt;/a&gt; - with heavy focus on developers.&lt;/li&gt;&lt;li&gt; Embrace &lt;a href="http://www.osgi.org/Main/HomePage"&gt;OSGi&lt;/a&gt; down in the core VM.&lt;/li&gt;&lt;li&gt;Kill &lt;a href="http://javafx.com/"&gt;JavaFx&lt;/a&gt; - Work closer with &lt;a href="http://www.adobe.com/"&gt;Adobe&lt;/a&gt; on &lt;a href="http://www.adobe.com/products/flex/"&gt;Flex&lt;/a&gt; / &lt;a href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/"&gt;BlazeDS&lt;/a&gt; / &lt;a href="http://www.adobe.com/products/livecycle/dataservices/"&gt;LCDS&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Improve Dynamic Language Support - &lt;a href="http://groovy.codehaus.org/"&gt;groovy&lt;/a&gt; / &lt;a href="http://www.scala-lang.org/"&gt;scala&lt;/a&gt; / JRuby / Jython /etc...&lt;/li&gt;&lt;li&gt;Talk to Google about ME (seriously?) / &lt;a href="http://www.android.com"&gt;Android&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Kill NetBeans - &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; may be King, but &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ&lt;/a&gt; is God !&lt;/li&gt;&lt;li&gt;Introduce new language primitives XML / Function / JSON.&lt;/li&gt;&lt;li&gt;Improve language - set/get bean, native String ( switch myString {case "foo": ...}) as for casting.&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx"&gt;LINQ&lt;/a&gt; for Java - LCDS can help here.&lt;/li&gt;&lt;li&gt;Talk to the &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt; folks - there-is-only-one-framework-zuul :-)&lt;/li&gt;&lt;li&gt;No "Effing" store !&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;So....what do you think ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-8086410443072978527?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Np9rUAndUn-Rh_B60y1QO-5fi3U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Np9rUAndUn-Rh_B60y1QO-5fi3U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Np9rUAndUn-Rh_B60y1QO-5fi3U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Np9rUAndUn-Rh_B60y1QO-5fi3U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/0vyp3RsGwlI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/8086410443072978527/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=8086410443072978527" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8086410443072978527?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8086410443072978527?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/0vyp3RsGwlI/how-oracle-can-improve-java.html" title="How Oracle Can Improve Java" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2010/02/how-oracle-can-improve-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMFR3w6eSp7ImA9WxBSE0g.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-3935542362456708959</id><published>2009-12-20T17:44:00.004-05:00</published><updated>2009-12-20T18:06:56.211-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-20T18:06:56.211-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="StreetView" /><title>Street View Within Flex API for AGS</title><content type="html">There is &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/index.cfm?fa=codeGalleryDetails&amp;amp;scriptID=16070"&gt;this&lt;/a&gt; great sample in our code gallery where a Google Streetview is integrated with a map based on the Flex API for AGS. However, what I wanted is to have the street view to be part of the map, not an HTML sibling element. Found &lt;a href="http://code.google.com/p/flex-iframe/"&gt;this&lt;/a&gt; project (flex-iframe) on google code, where you can display an HTML page inside a flex application. So I went ahead and merged the two projects. One of the requirements is to modify the template html file that is generated by Flex Builder with additional javascript code that enables the bridging between the flash and javascript world. I was not thrilled with fooling around with generated code, then I remembered the JavaScript flex tag by &lt;a href="http://www.abdulqabiz.com/blog/archives/2006/06/16/a-mxml-component-that-embeds-javascript-in-html/"&gt;Abdul Qabiz&lt;/a&gt;. This flex element enables you to put javascript code _in_ a flex application, and on initialization it will be "evaled" and injected into the parent document DOM. So I merged all three projects together and &lt;a href="http://thunderhead.esri.com/readonlyurl/StreetView/StreetViewApp.html"&gt;this&lt;/a&gt; is you get. &lt;a href="http://thunderhead.esri.com/readonlyurl/StreetView/StreetViewApp.html"&gt;Check out it&lt;/a&gt; and tell me what you think. And like usual, the source code is &lt;a href="http://thunderhead.esri.com/readonlyurl/StreetView/srcview/"&gt;here&lt;/a&gt;. There are some gems in there, like a custom symbol and I've adjusted the JavaScript flex tag. I've tried the app on my mac using safari, firefox and chrome, and it worked fine. However, I had issues with firefox on vista. IE worked for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-3935542362456708959?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gwGz8RbsAR_8V1GgvvqHgCOGifI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gwGz8RbsAR_8V1GgvvqHgCOGifI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gwGz8RbsAR_8V1GgvvqHgCOGifI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gwGz8RbsAR_8V1GgvvqHgCOGifI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/UR2L4lNnQ1Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/3935542362456708959/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=3935542362456708959" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3935542362456708959?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3935542362456708959?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/UR2L4lNnQ1Y/street-view-within-flex-api-for-ags.html" title="Street View Within Flex API for AGS" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>11</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/12/street-view-within-flex-api-for-ags.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUNQXo8eSp7ImA9WxNbGEU.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-1823796544244766063</id><published>2009-11-22T05:17:00.003-05:00</published><updated>2009-11-22T05:38:10.471-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-22T05:38:10.471-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="titlewindow" /><category scheme="http://www.blogger.com/atom/ns#" term="resizable" /><title>Yet Another Resizable TitleWindow</title><content type="html">Was kinda ticked that &lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_12.html"&gt;TitleWindow&lt;/a&gt; did not have a resizable property :-( Found &lt;a href="http://nisheet.wordpress.com/2007/04/28/resizable-title-window/"&gt;this&lt;/a&gt; reference when I googled "ResizableTitleWindow" - but was way too heavy. I just needed a _simple_ resizable title window, where I can grab the lower right corner and drag it to resize the window. Then I remembered that &lt;a href="http://code.google.com/p/flexlib/"&gt;flexlib&lt;/a&gt; has a &lt;a href="http://en.wikipedia.org/wiki/Multiple_document_interface"&gt;MDI&lt;/a&gt; package and I was always impressed with the code quality :-) Found the most excellent code for the MDIWindow component with resizable behaviour and additional features that I did not need.  &lt;a href="http://thunderhead.esri.com/readonlyurl/ResizableTitleWindowApp/ResizableTitleWindowApp.html"&gt;Here&lt;/a&gt; is my yet simplified derived version. And like usual, you can down the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/ResizableTitleWindowApp/srcview/"&gt;here&lt;/a&gt;. BTW, I leave it as an "exercise" to the reader to add a visual element to the title window to indicate that it is resizable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-1823796544244766063?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/z4NXKA65netFPa4qSXak2CKJq2g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z4NXKA65netFPa4qSXak2CKJq2g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/z4NXKA65netFPa4qSXak2CKJq2g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z4NXKA65netFPa4qSXak2CKJq2g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/GpHLa2FQkR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/1823796544244766063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=1823796544244766063" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/1823796544244766063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/1823796544244766063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/GpHLa2FQkR4/yet-another-resizable-titlewindow.html" title="Yet Another Resizable TitleWindow" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/11/yet-another-resizable-titlewindow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AGRXsyfCp7ImA9WxNbEUQ.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-3951038651742920782</id><published>2009-11-14T06:24:00.003-05:00</published><updated>2009-11-14T06:55:24.594-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-14T06:55:24.594-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="heat map" /><title>Spatial / Temporal MBTA HeatMap</title><content type="html">MassDOT issued a &lt;a href="http://www.eot.state.ma.us/default.asp?pgid=content/developer_VizChallenge&amp;sid=about"&gt;visualization challenge&lt;/a&gt;, where it is calling on developers to use released CharlieCard data to visualize "A Day in the Life of the MBTA". The following three applications use the &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/"&gt;Flex API for ArcGIS&lt;/a&gt; as a response to this challenge. The first application (click &lt;a href="http://thunderhead.esri.com/readonlyurl/MBTA/MBTA1.html"&gt;here&lt;/a&gt; to view it) consists of two maps. The first map contains a dynamically generated heat layer that morphs based on the selected hour. The second map is an isometric projection, but the T lines are represented in a schematic layout rather than a geographical layout. A schematic layout is what you see when you step up to a metro map at the station. You, the user, can rotate the schematic map by holding down the left mouse and dragging it left or right (no zoom in, sorry). At the bottom of the application is a horizontal slider. As you drag the slider, you are changing the "current" hour and minutes of the day. On the geographic map, the heat layer will reflect the CharlieCard counts per station. As to the isometric map, bars will extrude from every station, where the height of the bar is proportional to the CharlieCard count. There is a PLAY button, to play the hours of the day for you to step back and watch. The second application (click &lt;a href="http://thunderhead.esri.com/readonlyurl/MBTA/MBTA2.html"&gt;here&lt;/a&gt; to view it) is a  simplified version of the first, where I embedded the clock in the map and removed the isometric map. This was nice and uncluttered, perfect for a dashboard on a large screen, say at the MBTA headquarters (hint, hint :-).  The third application (click &lt;a href="http://thunderhead.esri.com/readonlyurl/MBTA/MBTA3.html"&gt;here&lt;/a&gt; to view it), is the same as the second one, but I added a table that lists all the active stations in descending count order.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;Now, let me tell you how I built these applications. As I mentioned earlier, These are all based on the &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/"&gt;Flex API for ArcGIS&lt;/a&gt;. The base map image tiles are retrieved from &lt;a href="http://resources.esri.com/arcgisonlineservices/"&gt;ArcGIS Online&lt;/a&gt;. The geographical and isometric lines and stops are read from embedded shapefiles.  The hour statistics are post-processed using ye-good-olde Excel from the MBTA released data. The result is a tab separated fields file, where each line in the file has the station name, the hour, and the sum of CharlieCards for that hour at that station. Again, that file is embedded in the application. Might take a bit of time to load the application, but all the spatial and temporal information is now on the client for local manipulation, after all this _is_ an Rich Internet Application.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;What enabled me to quickly create three views of the same application is what I would like to talk to you next and is the guiding principles that I use to develop most of my "simple" applications. Three letters: M, V, C. You are now saying to yourself "yes, yes, Mansour...so what framework did you use ?" Actually....none! I can hear now. "Oh no, the (nasty word)... created _yet_ another framework". Actually I did not. I do have to admit that I did look at the usual suspects (Cairngorm, PureMVC, Swiz, Mate) but really did not need the extra swcs and the weight. What I _do_ need, is the MVC philosophy. But, can I do it with just the Flash and Flex provided classes? Yes, so here is the micro architecture and thought process. The Model is a singleton (O' oh, Singletonitis... hold on, hear me out) that holds the application state. It contains [Bindable] properties. Views (subclasses of UIComponent) are bound to the Model using "{}" in MXML (one of the beauties of Flex) or through ChangeWatcher instance in AS3. If a view or a non-view element wants to change the Model, it dispatches an event encapsulating all the values to change the Model. A controller instance will be listening for that event type and in its event handler code will process the encapsulated values and modifies the Model. As the view is bound to the Model, then the view will reflect any changes in the matter that it desires such as a set of map graphics or rows in a data grid. And the process (create an event, dispatch the event, controller listens for the event, processes the event and modifies the Model, view is bound to the Model and changes) repeats itself, over and over.  You _will_ be temped to modify the Model directly from the view, but that will be an instant gratification solution. As the application development progresses, you _will_ find yourself needing to encapsulate that Model modification, thus the introduction of a controller. So, my advise is do it right from the beginning. Now, to enable that central event dispatching, we take advantage of the Application being an instance of EventDispatcher. To not confuse the Flex events with my events, all my event types are suffix with "$" such as "complete$". Last but not least, is the instantiation of the controllers and making them event listeners. As a matter of convention, all controllers names are prefixed with the event type, such as "CompleteController", and are declared as immediate children tag to the mx:Application tag in the MXML. For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;mx:Application&amp;gt;&lt;br /&gt;  &amp;lt;controller:CompleteController/&amp;gt;&lt;br /&gt;  &amp;lt;controller:LoadDataController/&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;esri:Map/&amp;gt;&lt;br /&gt;  &amp;lt;view:MyView/&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What does this mean? This tells the runtime engine to create anonymous instances of these controller classes. Each controller should have an empty constructor that registers it as a listener to the event to process and modify the Model.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class CompleteController&lt;br /&gt;{&lt;br /&gt;  public function CompleteController&lt;br /&gt;  {&lt;br /&gt;     Application.application.addEventListener( "complete$", handler ); &lt;br /&gt;  }&lt;br /&gt;  private function handler( event : Event ) : void&lt;br /&gt;  {&lt;br /&gt;     // Process, process....modify Model.&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this process in mind, you now are structured to take every application feature and break it down into these three pieces which makes you focus on the task at hand. In addition, with unit testing (another blog topic) feature closure will emerge enabling you to move on to the next task. Yes, you do become what I call a "code monkey", but this is where the usage of for example &lt;a href="http://www.smileonmymac.com/TextExpander/"&gt;TextExpander&lt;/a&gt; on my mac can automagically generate code based on a template. Side Note - One of these days, gotta write an eclipse plug-in :-)&lt;br /&gt;Finally, have to give credit where credit is due, as I would have not been able to put this application together so quickly without "borrowing" code from:&lt;br /&gt;&lt;br/&gt;&lt;a href="http://vanrijkom.org/wordpress/"&gt;Edwin van Rijkom&lt;/a&gt; for the shapefile library.&lt;br /&gt;&lt;br/&gt;&lt;a href="http://www.degrafa.org/"&gt;Juan Sanchez&lt;/a&gt; for the clock.&lt;br /&gt;&lt;br/&gt;&lt;a href="http://code.google.com/p/michaelvandaniker/"&gt;Michael VanDaniker&lt;/a&gt; for the heat map.&lt;br /&gt;&lt;br/&gt;&lt;a href="http://www.bit-101.com/blog/"&gt;Keith Peters&lt;/a&gt; for the isometric code.&lt;br /&gt;&lt;br/&gt;&lt;a href="http://www.scalenine.com/gallery/"&gt;Nahuel Foronda&lt;/a&gt; for the Brownie skins&lt;br /&gt;&lt;br/&gt;If I missed any person - it was not intentional. And like usual, you can download the source code from &lt;a href="http://thunderhead.esri.com/readonlyurl/MBTA/srcview/"&gt;here&lt;/a&gt;. Hope you enjoyed this and tell me what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-3951038651742920782?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0iQc2vR1gqTcTnoIcNYsdOnR4VE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0iQc2vR1gqTcTnoIcNYsdOnR4VE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0iQc2vR1gqTcTnoIcNYsdOnR4VE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0iQc2vR1gqTcTnoIcNYsdOnR4VE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/qbXR7TaURKQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/3951038651742920782/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=3951038651742920782" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3951038651742920782?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3951038651742920782?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/qbXR7TaURKQ/spatial-temporal-mbta-heatmap.html" title="Spatial / Temporal MBTA HeatMap" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>14</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/11/spatial-temporal-mbta-heatmap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8EQX4zfyp7ImA9WxNXFU0.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-9172814622903970994</id><published>2009-09-23T18:35:00.003-04:00</published><updated>2009-10-02T14:23:20.087-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T14:23:20.087-04:00</app:edited><title>Open Letter to Delta Airlines</title><content type="html">Dear Delta,&lt;br /&gt;&lt;br /&gt;First, have to prefix this letter with the following; being a million miler, I love flying with you and the little perks I get; like my wife being upgraded to first class on a 14 hour flight, while I hanged in the back with the kids - MAJOR POINTS for me _and_ you :-)&lt;br /&gt;However (and here is the rub), I'm ticked at your ticketing system (kinda funny this play on word :-) about how it interacts, or most likely does not interact with our corporate travel department. See, I have an upcoming opportunity to travel coast to coast one week after another. When I submitted my two travel requests to fly Delta, Corporate kicked it back saying that Delta is more expensive ($200 and $300 more) than Virgin on one and AA on the other. Grrr, you don't fight Travel in these economic times. And...well I kinda wanted to try Virgin as I heard so much about it, but AA, no way! Had to admit defeat and take what was given to me, and then I started thinking. I do travel on one of these submitted trips very often and Delta _must_ know this. They _should_ have "bent" a little on the price for my business. I've been reading "&lt;a href="http://www.amazon.com/Free-Future-Radical-Chris-Anderson/dp/1401322905"&gt;Free: The Future of a Radical Price&lt;/a&gt;" by Chris Anderson (BTW, you can get his book for free) and I'm not saying I have to fly for free, but hear me out.  What if you offered a free system that allows corporate travel departments to enter my frequent flier number, my upcoming trips, and (here is the important part) a form of a bid for these trips. In my case, $200 and $300 dollar less that the "list" price.&lt;br /&gt;You, given my history and preferences, can look at me "holistically" and can accept that bid. Propose something that is close, say within $40, the "bend" which Travel will accept the difference, after all they _are_ trying to accommodate me. Or you can totally reject the bid. What I mean by holistically, is that in today's world of data mining from me (you have over 10 years worth of travel info on me), my fellow travelers and other external information, you _should_ be able to determine a price point (even at a _small_ loss today) that is acceptable to both parties, as you _will_ make it up and be profitable later.  I'm sure somewhere in the bowels of your IT department you are brewing something like that. If not, then you should look at these recommendation engines (like what Amazon and Netflix has) for your frequent fliers. Anyway, this advise is free on the hope that such a holistic system will exist. Looking forward to traveling with you when the price is right to Corporate.&lt;br /&gt;&lt;br /&gt;Regards,&lt;br /&gt;Mansour&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-9172814622903970994?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/UhgMeutWBuHMS3VmoFxgYnqM_S4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UhgMeutWBuHMS3VmoFxgYnqM_S4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/UhgMeutWBuHMS3VmoFxgYnqM_S4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UhgMeutWBuHMS3VmoFxgYnqM_S4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/m-Rkj5FBZR8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/9172814622903970994/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=9172814622903970994" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/9172814622903970994?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/9172814622903970994?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/m-Rkj5FBZR8/open-letter-to-delta-airlines.html" title="Open Letter to Delta Airlines" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/09/open-letter-to-delta-airlines.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08ERXc_cSp7ImA9WxNUGEk.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-4390750728140241650</id><published>2009-09-18T03:40:00.006-04:00</published><updated>2009-11-10T03:30:04.949-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-10T03:30:04.949-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="shapefile" /><title>Map Layer From Local Shapefile</title><content type="html">In this post, I will demo how to load a local &lt;a href="http://en.wikipedia.org/wiki/Shapefile"&gt;shapefile&lt;/a&gt; from your hard drive, and overlay it on an map whose base layer is derived from a remote &lt;a href="http://www.esri.com/software/arcgis/arcgisserver/index.html"&gt;ArcGIS&lt;/a&gt; server. Using the &lt;a href="http://www.adobe.com/products/flashplayer/"&gt;Flash Player 10&lt;/a&gt; FileReference API, this task is fairly easy. However, I did not want the user to be prompted for each imported file as a shapefile is composed of a .shp file holding the geometry and a .dbf file holding the attributes. So, the idea is to zip the shp and dbf and load the zip, and then let the application unzip the content and parse the shp and dbf entries. The application is using the &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/"&gt;Flex API for AGS&lt;/a&gt; and makes use of two wonderful as3 library; the shp library from &lt;a href="http://vanrijkom.org/wordpress/"&gt;Edwin van Rijkom&lt;/a&gt;, and a zip library from &lt;a href="http://nochump.com/blog/?index.html"&gt;David Chang&lt;/a&gt;. In this application, I created a custom geometry to take advantage of the coordinate array format in the shapefile reducing the impedance and taking advantage of the "compression". Well, this not truly compressed - this an array of x,y,x,y,etc... rather than an array of MapPoint instances :-) and since this a custom geometry, well then you need a custom symbol to render that geometry. In this demo, I wanted to load and display the output of a plume model/process, and here is the result:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_mTRp79uRCDU/SrNFHMcQKUI/AAAAAAAAAC0/8_YeSTHtw58/s1600-h/Plume.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 310px; height: 224px;" src="http://2.bp.blogspot.com/_mTRp79uRCDU/SrNFHMcQKUI/AAAAAAAAAC0/8_YeSTHtw58/s320/Plume.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382721969539000642" /&gt;&lt;/a&gt;&lt;br /&gt;You can download the zip file from &lt;a href="http://thunderhead.esri.com/readonlyurl/Plume.zip"&gt;here&lt;/a&gt;, and you can see the application in action &lt;a href="http://thunderhead.esri.com/readonlyurl/ShpOverlay/ShpOverlay.html"&gt;here&lt;/a&gt;. And like usual, the source code is &lt;a href="http://thunderhead.esri.com/readonlyurl/ShpOverlay/srcview"&gt;here&lt;/a&gt;.&lt;br /&gt;10/10/09 - I've updated the source to be a bit more robust - BTW, this only handles polygon shapes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-4390750728140241650?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9Ksy_vxsft8HauwrpVXpBL9Xc9w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9Ksy_vxsft8HauwrpVXpBL9Xc9w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9Ksy_vxsft8HauwrpVXpBL9Xc9w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9Ksy_vxsft8HauwrpVXpBL9Xc9w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/5A7gqvHdELY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/4390750728140241650/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=4390750728140241650" title="23 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/4390750728140241650?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/4390750728140241650?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/5A7gqvHdELY/map-layer-from-local-shapefile.html" title="Map Layer From Local Shapefile" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_mTRp79uRCDU/SrNFHMcQKUI/AAAAAAAAAC0/8_YeSTHtw58/s72-c/Plume.png" height="72" width="72" /><thr:total>23</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/09/map-layer-from-local-shapefile.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCQHg8fyp7ImA9WxNRE08.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-3282299990731663034</id><published>2009-09-07T08:16:00.002-04:00</published><updated>2009-09-07T08:44:21.677-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-07T08:44:21.677-04:00</app:edited><title>Horizontal Map Slider</title><content type="html">A customer emailed me asking me how to create a horizontal map slider using the &lt;a href="http://www.esri.com/flex"&gt;Flex API for AGS&lt;/a&gt;. The &lt;code&gt;Map&lt;/code&gt; component has a property &lt;code&gt;navigationClass&lt;/code&gt; to enable users to define a custom navigation class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    &amp;lt;esri:Map navigationClass="com.esri.sample.MyNavigation"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this sample, I defined a reference to the class &lt;code&gt;com.esri.sample.MyNavigation&lt;/code&gt;  which is a subclass of the &lt;code&gt;Navigation&lt;/code&gt; class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public class MyNavigation extends Navigation&lt;br /&gt;    {&lt;br /&gt;        public function MyNavigation()&lt;br /&gt;        {&lt;br /&gt;            mx_internal::layoutObject.direction = BoxDirection.HORIZONTAL;&lt;br /&gt;            navigationSliderClass = MyNavigationSlider;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /**&lt;br /&gt;         * Override the order of the components.&lt;br /&gt;         */&lt;br /&gt;        override protected function addZoomInZoomOutComponents(zoomInButton:UIComponent, zoomOutButton:UIComponent):void&lt;br /&gt;        {&lt;br /&gt;            addChild(new Spacer());&lt;br /&gt;            addChild(zoomOutButton);&lt;br /&gt;            addChild(zoomInButton);&lt;br /&gt;            addChild(new Spacer());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the constructor, I defined the box direction (note the mx_internal :-) and my own custom slider.  In addition, I've overwritten the &lt;code&gt;addZoomInZoomOutComponents&lt;/code&gt; function to specify the order of the in/out buttons. Lastly, I defined a custom navigation slider to ensure the &lt;code&gt;direction&lt;/code&gt; is horizontal.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public class MyNavigationSlider extends NavigationSlider&lt;br /&gt;    {&lt;br /&gt;        public function MyNavigationSlider()&lt;br /&gt;        {&lt;br /&gt;            direction = SliderDirection.HORIZONTAL;&lt;br /&gt;            maxHeight = 25;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://thunderhead.esri.com/readonlyurl/NavSample3/NavSample3.html"&gt;Here&lt;/a&gt; is the final result, and like usual the source code is &lt;a href="http://thunderhead.esri.com/readonlyurl/NavSample3/srcview"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-3282299990731663034?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PneDaSG43HvK1_l96XEbZvpE8tE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PneDaSG43HvK1_l96XEbZvpE8tE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PneDaSG43HvK1_l96XEbZvpE8tE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PneDaSG43HvK1_l96XEbZvpE8tE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/1X1tOZD--84" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/3282299990731663034/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=3282299990731663034" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3282299990731663034?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/3282299990731663034?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/1X1tOZD--84/horizontal-map-slider.html" title="Horizontal Map Slider" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/09/horizontal-map-slider.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04ASHc5cSp7ImA9WxJaGE8.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-5471741106088321215</id><published>2009-08-09T08:32:00.003-04:00</published><updated>2009-08-09T08:45:49.929-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-09T08:45:49.929-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="isometric" /><category scheme="http://www.blogger.com/atom/ns#" term="iPhone" /><title>iPhone Isometric Shapefile Viewer</title><content type="html">Not sure if some of you have see the &lt;a href="http://uc2009.esri.com/sdcc3d/"&gt;3D in-door routing application&lt;/a&gt; that I did for the ESRI 2009 User Conference. I used &lt;a href="http://blog.papervision3d.org/"&gt;Papervision3D&lt;/a&gt; for this app, and was a lot of fun to develop. A couple of weeks before the conference, I decided to implement the same app on an iPhone using Obj-C.  Being a newbie in the latter, I ramped up quickly on the language (got quickly over my hang ups on bracket, and kinda like the language :-). I started to look at the 3D built-in engine that uses a derivative of OpenGL and thought that I will not have the time to get this up and running.  So I started to look for simpler alternatives.  I read Keith Peters' most excellent &lt;a href="http://www.amazon.com/gp/product/B001W0Z8U4/ref=pd_lpo_k2_dp_sr_2?pf_rd_p=304485901&amp;pf_rd_s=lpo-top-stripe-1&amp;pf_rd_t=201&amp;pf_rd_i=1590597915&amp;pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_r=168FDA00EH9HJBX3Y3KK"&gt;AdvancED ActionScript 3.0 Animation&lt;/a&gt; book and used his A* implementation for client side routing application with barriers. check it out &lt;a href="http://thunderheadxpler.blogspot.com/2009/05/street-path-finding-in-as3.html"&gt;here&lt;/a&gt;. The next chapter in the book is all about isometric projection.  This is exactly what I needed, an isometric view of the CDCC floors and rooms with a small twist, where the user can rotate the view.&lt;br /&gt;So before doing a full Obj-C dive, I prototyped my application in Flex/AS3.  The idea was to read a 3D shapefile (thanks &lt;a href="http://shp.riaforge.org/"&gt;Edwin&lt;/a&gt;), apply a rotation matrix on the original coordinates and then pass them through Peters isometric utility class. Once debugged and got it up and running (check out the app &lt;a href="http://thunderhead.esri.com/readonlyurl/IsoApp/IsoApp.html"&gt;here&lt;/a&gt;, hold and drag the mouse to rotate the view), I ported the code to Obj-C. Check out &lt;a href="http://thunderheadxpler.blogspot.com/2009/07/indoor-routing-for-uc2009-on-iphone.html"&gt;this&lt;/a&gt; post to see some iPhone app snapshots.  Like usual, &lt;a href="http://thunderhead.esri.com/readonlyurl/IsoApp/srcview"&gt;here&lt;/a&gt; is the source code of the flex app.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-5471741106088321215?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9oS2Bzi4-Wd1mZ5SSV9col0EvT4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9oS2Bzi4-Wd1mZ5SSV9col0EvT4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9oS2Bzi4-Wd1mZ5SSV9col0EvT4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9oS2Bzi4-Wd1mZ5SSV9col0EvT4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/cQlRppG00rA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/5471741106088321215/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=5471741106088321215" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/5471741106088321215?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/5471741106088321215?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/cQlRppG00rA/iphone-isometric-shapefile-viewer.html" title="iPhone Isometric Shapefile Viewer" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>12</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/08/iphone-isometric-shapefile-viewer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYNQX45eCp7ImA9WxJaEEs.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-8796955752130655789</id><published>2009-07-31T14:35:00.002-04:00</published><updated>2009-07-31T15:06:30.020-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-31T15:06:30.020-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mgrs" /><category scheme="http://www.blogger.com/atom/ns#" term="polynomial" /><category scheme="http://www.blogger.com/atom/ns#" term="quadtree" /><category scheme="http://www.blogger.com/atom/ns#" term="contour" /><category scheme="http://www.blogger.com/atom/ns#" term="graticule" /><category scheme="http://www.blogger.com/atom/ns#" term="grid" /><title>Cool Flex API for AGS Samples</title><content type="html">My friend and colleague _extraordinaire_ Kerry Coffin been working with the &lt;a href="http://resources.esri.com/arcgisserver/apis/flex/"&gt;Flex API for AGS&lt;/a&gt;, and send me the following list of samples:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/MapGrid/MapGrid.html"&gt;Linear Grid&lt;/a&gt;: This app shows a linear grid distance (miles, km etc) on a geographic map. Zoom In; pan north and south;change the number of grids;etc. Notice the grid width displayed.  Also change the units.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/SimpleGraticule/WebMercatorGraticule.html"&gt;Graticule&lt;/a&gt;: This app shows a Lat/Lon graticule in a web Mercator map. Zoom in continually.  Notice how the graticule adjusts.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/SimpleGraticule/SimpleGraticule.html"&gt;SimpleGraticule&lt;/a&gt;: This app shows a Lat/Lon graticule in a Geographic map. Zoom in continually. Notice how the graticule adjusts.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/QuadTree/QTreeApp.html"&gt;Quad Tree&lt;/a&gt;: This app shows a quad tree component that can index and search points in a client app. Add a bunch of points (Pick add 10K points).  Drag the mouse to search. Try adding 10K more.  Search again.  The app shows you how the indexing is done.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/conflation/ConflationTool.html"&gt;Polynomial transformation&lt;/a&gt;: This app shows how to warp any image and overlay it on a map. (polynomial transformation) Press show resulting image.  Change the order to 2.  The user selects common points from both left and right. I’ve preloaded the app with a bunch of common points.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/Contours/Contours.html"&gt;Normal Contours&lt;/a&gt;: Click to add elevation points.  Pick a few points with elevation 100.  Change the elevation to 105  pick a few more. Etc. Turn off the triangles to see only contours.  (similar to the 3d app…except just contours)&lt;br /&gt;&lt;br /&gt;And last &lt;a href="http://esri-flexapp.s3.amazonaws.com/Contours/contour3d.html"&gt;my 3D app&lt;/a&gt;.  It’s similar to using the contouring app.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://esri-flexapp.s3.amazonaws.com/MGRS/MGRS.html"&gt;MGRS&lt;/a&gt;: For the MGRS app, pan around the map by dragging your mouse.  Of particular interest is the north pole, as most people  leave off these zones, and they don’t draw curves.&lt;br /&gt;If you zoom out, the scale dependency of the MGRS Layer turns off the finer grids.  (MGRSLayer is implemented by extending Layer and implementing updateLayer()). The curves are drawn by doing the following algorithm:  I don’t brute force it and add a trillion points  and then project.  To draw a line I project the 2 endpoints to pixel locations, and then project the mid point to its pixel location. I then compare the mid point’s projected pixel location to its pixel location by averaging the two endpoints. If the locations differ by more then one pixel…I do this to both halfs.  This algorithm is done “logically” recursively…but I set a limit as to how many midpoints I add.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-8796955752130655789?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f0POXlxgOkC-2SnKi4U9jbIfpCM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f0POXlxgOkC-2SnKi4U9jbIfpCM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f0POXlxgOkC-2SnKi4U9jbIfpCM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f0POXlxgOkC-2SnKi4U9jbIfpCM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/UHeHE0X57fU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/8796955752130655789/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=8796955752130655789" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8796955752130655789?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8796955752130655789?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/UHeHE0X57fU/cool-flex-api-for-ags-samples.html" title="Cool Flex API for AGS Samples" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/07/cool-flex-api-for-ags-samples.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQDR3szcCp7ImA9WxJUFEs.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-2507683816991931167</id><published>2009-07-13T02:25:00.006-04:00</published><updated>2009-07-13T02:42:56.588-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-13T02:42:56.588-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iPhone" /><title>Indoor Routing for UC2009 on iPhone</title><content type="html">Yes - just finished a native iPhone application (not using Safari) that uses the ArcGIS Server REST endpoint to create a 3D path between rooms in the San Diego Convention Center for the 2009 User Conference - this is _not_ an officially endorsed application (Yet :-) but for me, it was a great experience to see if I can get the iPhone to connect to AGS and render the result path in 3D as vector graphics. Yes, vector graphics - this is _not_ an image - if you drag your finger across the screen, the SDCC floor will rotate to give you a different perspective of the path. Cool eh ? Will be showing up at the UC on Monday, so stop by the Flex booth if you wanna see it live and have an AR version on the browser - AR you ask ? Just stop by :-) Here are some screenshots of the app - looking forward to seeing a lot of u there.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_mTRp79uRCDU/SlrWUUmSBuI/AAAAAAAAACU/h3-tn_nEhBQ/s1600-h/fromroom.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 166px; height: 320px;" src="http://4.bp.blogspot.com/_mTRp79uRCDU/SlrWUUmSBuI/AAAAAAAAACU/h3-tn_nEhBQ/s320/fromroom.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5357830351325628130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_mTRp79uRCDU/SlrXPLKtMAI/AAAAAAAAACs/uCiOFVrvD50/s1600-h/toroom.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 166px; height: 320px;" src="http://2.bp.blogspot.com/_mTRp79uRCDU/SlrXPLKtMAI/AAAAAAAAACs/uCiOFVrvD50/s320/toroom.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5357831362406330370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_mTRp79uRCDU/SlrW2iUHCNI/AAAAAAAAACk/PQqbBsNrMgY/s1600-h/route1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 166px; height: 320px;" src="http://2.bp.blogspot.com/_mTRp79uRCDU/SlrW2iUHCNI/AAAAAAAAACk/PQqbBsNrMgY/s320/route1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5357830939123058898" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-2507683816991931167?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dgL2Z-oWl6EVZSRyUaDc5DJ2ZCY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dgL2Z-oWl6EVZSRyUaDc5DJ2ZCY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dgL2Z-oWl6EVZSRyUaDc5DJ2ZCY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dgL2Z-oWl6EVZSRyUaDc5DJ2ZCY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/yPj9TQfvpg8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/2507683816991931167/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=2507683816991931167" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/2507683816991931167?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/2507683816991931167?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/yPj9TQfvpg8/indoor-routing-for-uc2009-on-iphone.html" title="Indoor Routing for UC2009 on iPhone" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_mTRp79uRCDU/SlrWUUmSBuI/AAAAAAAAACU/h3-tn_nEhBQ/s72-c/fromroom.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/07/indoor-routing-for-uc2009-on-iphone.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQCQXg-fyp7ImA9WxJQFkg.&quot;"><id>tag:blogger.com,1999:blog-4442573390356643522.post-8067974355165829229</id><published>2009-05-28T18:24:00.004-04:00</published><updated>2009-05-29T22:59:20.657-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-29T22:59:20.657-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EXIF" /><title>Mapping EXIF Images With GPS Info</title><content type="html">Was tasked to load an &lt;a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format"&gt;EXIF&lt;/a&gt; image with GPS info onto a map using the &lt;a href="http://www.esri.com/flex"&gt;Flex API for AGS&lt;/a&gt;.  So I first looked around for existing AS3 libraries and found &lt;a href="http://code.shichiseki.jp/as3/ExifInfo/"&gt;ExifInfo&lt;/a&gt;. Downloaded it and tried it, but somehow it failed loading some EXIF images. Then I remembered a JavaScript &lt;a href="http://www.nihilogic.dk/labs/gps_exif_google_maps/"&gt;library&lt;/a&gt; that a colleague pointed it out to me. So I ported the code to AS3 (optimization will come later) and &lt;a href="http://thunderhead.esri.com/readonlyurl/EXIFApp/EXIFApp.html"&gt;here&lt;/a&gt; is the result. I used &lt;a href="http://picasa.google.com"&gt;picasa&lt;/a&gt; to load some images and geo-tagged them using Google Earth (that is from the Tools menu BTW) and it worked pretty well.  I borrowed some ideas and code from the author of ExifInfo and made my own EXIF mxml enabled class. Like usual &lt;a href="http://thunderhead.esri.com/readonlyurl/EXIFApp/srcview/index.html"&gt;here&lt;/a&gt; is the source code. BTW - There is a TextInput field at the bottom of the application, enter the url of your image (make sure that you have a crossdomain.xml at the base of your url) and if the image has EXIF GPS info, the map will display it.  Try "assets/sample1.jpg" and hit enter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4442573390356643522-8067974355165829229?l=thunderheadxpler.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nbemR6bCJ7o_fmc_-_rerzqTGtU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nbemR6bCJ7o_fmc_-_rerzqTGtU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nbemR6bCJ7o_fmc_-_rerzqTGtU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nbemR6bCJ7o_fmc_-_rerzqTGtU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThunderheadExplorer/~4/Y5ET6r1-vtw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thunderheadxpler.blogspot.com/feeds/8067974355165829229/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4442573390356643522&amp;postID=8067974355165829229" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8067974355165829229?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4442573390356643522/posts/default/8067974355165829229?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThunderheadExplorer/~3/Y5ET6r1-vtw/mapping-exif-images-with-gps-info.html" title="Mapping EXIF Images With GPS Info" /><author><name>Mansour Raad</name><uri>https://profiles.google.com/101070656256923022280</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-6l0QzW_BYQo/AAAAAAAAAAI/AAAAAAAAAFU/74OVSseINFo/s512-c/photo.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://thunderheadxpler.blogspot.com/2009/05/mapping-exif-images-with-gps-info.html</feedburner:origLink></entry></feed>

