Monday, December 22, 2008

Flaring Clustered Map Points

Following the last post, It would be nice to inspect the clustered set of map points when say the set is less than a dozen or so. In this post, I'm demonstrating something I call a FlareSymbol, which is a Symbol sub-class, where like before, the number of clustered points is shown. But, when you click on the cluster, it flares out to show the individual map points. Each flared point can react to say a mouse click to popup an info window showing its attribute values. When you click again on the cluster, it collapses the map points back to its center. Here it is in action. And like usual, you can download the source from here.

Friday, December 19, 2008

Clustering 20K+ Map Points

Was asked "what is the best way to display 20,000 markers on a map ?". Well, displaying all 20K map points does not make whole lot of sense, as you just see nothing, just a blanket of markers. A smarter approach is to cluster the points and display the clusters. Somebody pointed me to mapeed, and asked me to duplicate this using the Flex API for AGS. Here it is. I've loaded 20,000 map points from geonames and created dynamically clusters based on the scale of the map and its extent. BTW, this is all client side processing - gotta love the JIT in Flash Player :-)
[Update] Sooo many people asked me for the source code of the app - here it is. Any feedback is more than welcome.

Sunday, December 14, 2008

Editing Graphic Geometry

In this post, I'm demonstrating how to move a vertex of a polygon to modify its geometry. The application displays a graphic with a simple fill symbol. When the user clicks the Start Edit button, the symbol of the graphic is assigned to a new custom symbol instance, where the outline of the polygon is rendered as a line and the vertexes as little squares. While holding the mouse down over a square, a user can move the vertex to a new location on the map. The user can repeat this process over other vertexes until the Stop Edit button is clicked. You can see the application in action here. And like usual, the source is available from here.

Monday, December 1, 2008

Geolocation using Gears and Geode

Location based Services applications are requiring more and more that the geographical coordinates (or at least the neighborhood) of the user be automatically detected to create a more seamless and streamlined experience. Google Gears with its geolocation API and Mozilla Labs with its Geode project are making the W3C geolocation specification a reality. With such democratization of services, it would be nice to have geolocation as a native function in the flash player, so would be a JSON parser (but that is a topic of conversation for another day). Until then, we have to rely on the browser's capabilities to feed that information into the player. This can easily achieved using the ExternalInterface class. In this post, I adopted the geolocation W3C specification and implemented an ActionScript class to wrap the Gears and Geode javascript functions so they can be invoked from a Flex application. Make sure to install Gears and/or Geode to test this application. Using FlexBuilder, the index.template.html has to be adjusted to include the gears_init.js file and the geolocation.js wrapper file as follows:

...
<script type="text/javascript" src="AC_OETags.js"></script>
<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript" src="geolocation.js"></script>
<style>
...

The registration of the callback functions is done by creating an instance of the GeoLocation class:

...
<geolocation:GeoLocation id="geolocation"/>
...

The position of the web application can be determined using something of the form:

...
geolocation.getCurrentPosition( currentPositionSuccessHandler, currentPositionFaultHandler );
...

Check out the application here. And like usual, you can download the source from here.

Shapefile Viewer

Due to the ubiquitous nature of geographical data in shapefile format, I want to embed a shapefile in a flex application and display it as a layer in a map.
This work is borrowed and modified from Edwin van Rijkom. The modifications include the generation of Geometry subclasses based on the Flex API for ArcGIS Server.
So, to get started, I created a ShpLayer class that is a subclass of GraphicsLayer. I initialized this layer's symbol property with an instance of ShpSymbol which is my own custom symbol (more on this later). This way, I do not have to assign a symbol to each added Graphic instance. Internally, when a graphic is rendered, and that graphic has a null symbol property, it inherits its parent's symbol property value. This is an easy way to globally change the symbology of a graphic layer, without having to explicitly iterate through all its children :-)
The fact that I've created my own custom symbol is yet another demonstration of the extensibility of the API to render a Graphic in any which way I seem fit. This was easily done by overriding the draw public function.
In this example, I'm filling and outlining a polygon. In addition, I'm annotating the polygon with its label property and locating that annotation at its label X/Y property values.
The embedding of the shapefile (shp and dbf) in the application is accomplished by the following statement (Note the mimeType):

[Embed(source="assets/ContinentsWithLabels.shp",mimeType="application/octet-stream")]
private var m_shpClass : Class;

[Embed(source="assets/ContinentsWithLabels.dbf",mimeType="application/octet-stream")]
private var m_dbfClass : Class;

I've overridden the createChildren protected function to load into a byte array the shp and dbf content from which I created a ShpReader and a DbfHeader. I then iterated over each feature to create a Graphic instance which I pushed onto an array. At the end of the iteration, the array was converted to an ArrayCollection that became the layer's graphic provider. Here is the application in action, and like usual you can download the source from here.
One more gem. Note how I created my own subclass of Map, where I've overridden the updateDisplayList protected function to create a nice gradient filled background.