Showing posts with label shapefile. Show all posts
Showing posts with label shapefile. Show all posts

Friday, September 18, 2009

Map Layer From Local Shapefile

In this post, I will demo how to load a local shapefile from your hard drive, and overlay it on an map whose base layer is derived from a remote ArcGIS server. Using the Flash Player 10 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 Flex API for AGS and makes use of two wonderful as3 library; the shp library from Edwin van Rijkom, and a zip library from David Chang. 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:

You can download the zip file from here, and you can see the application in action here. And like usual, the source code is here.
10/10/09 - I've updated the source to be a bit more robust - BTW, this only handles polygon shapes.

Monday, December 1, 2008

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.