Tuesday, September 23, 2008

Styling, Skinning Map Navigation Control

The following is a simple sample that shows how to skin, style and reposition the map navigation control. All is done using CSS:

Navigation
{
borderSkin : ClassReference("NavBorderSkin");
showScaleInDataTip: true;
paddingLeft: 6;
paddingRight: 2;
paddingTop: 2;
paddingBottom: 2;
top: 30;
left: NaN;
right: 30;
}

NavigationMinusButton
{
disabledSkin: Embed(source="assets/globe_icon.png");
downSkin: Embed(source="assets/globe_icon.png");
overSkin: Embed(source="assets/globe_icon.png");
upSkin: Embed(source="assets/globe_icon.png");
}

NavigationPlusButton
{
disabledSkin: Embed(source="assets/home_icon.png");
downSkin: Embed(source="assets/home_icon.png");
overSkin: Embed(source="assets/home_icon.png");
upSkin: Embed(source="assets/home_icon.png");
}

Note that I have to set the value of left to NaN to override the default value. In addition, I'm using Degrafa to skin the border. Check out the sample here. And you can view the source code here.

Friday, September 12, 2008

ArcGIS Tiles on Amazon S3

Once you have generated your tiles from a map services, you can move these tiles to Amazon S3. I used the S3Fox Firefox extension to move the files from my local system to S3. In addition, make sure to copy the JSON map service metadata to a file named "MapServer" (without quotes of course :-). You can access these tiles using the Flex API for ArcGIS server as follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:esri="http://www.esri.com/2008/ags"
xmlns:s3="com.esri.s3.*"
layout="absolute"
>
<esri:Map>
<s3:S3ArcGISTiledMapServiceLayer
url="http://s3.amazonaws.com/your_map_service/MapServer"/>
</esri:Map>
</mx:Application>

And here is the implements of S3ArcGISTiledMapServiceLayer class:

package com.esri.s3
{
import com.esri.ags.layers.ArcGISTiledMapServiceLayer;

import flash.net.URLRequest;

public class S3ArcGISTiledMapServiceLayer extends ArcGISTiledMapServiceLayer
{
private var m_baseURL : String;

public function S3ArcGISTiledMapServiceLayer(url:String=null)
{
super(url);
}

override public function set url(value:String):void
{
super.url = value;
if( value )
{
var index : int = value.lastIndexOf( "/" );
m_baseURL = value.substr( 0, index );
}
else
{
m_baseURL = "";
}
}

override protected function getTileURL(
level:Number,
row:Number,
col:Number
):URLRequest
{
return new URLRequest( m_baseURL + "/l" + level + "r" + row + "c" + col + ".jpg" );
}
}
}

Note that I simplified the storage retrieval in the getTileURL function. ArcGIS places the tiles on the file system as a set of sub-directories of the form level/row/column.jpg. I decided (out of laziness :-) to keep it flat and have a set of files in the form lXrXcX.jpg.

Wednesday, September 10, 2008

Skinning InfoWindow using Degrafa

Here is an example of how to skin the border of an InfoWindow using degrafa. This can be done using CSS by defining a skinBorder to InfoWindow as follows:

InfoWindow {
padding-left : 5;
padding-right : 5;
padding-top : 5;
padding-bottom : 5;
tip-width : 3;
tip-length : 3;
border-skin : ClassReference("IWBorderSkin");
}

The IWBorderSkin is a sub-class of a degrafa GraphicBorderSkin. Like usual, you can download the source from here.

Generate AS3 VOs from Jar file

A lot of AS3 value object generators assume that you have the source code. However sometimes you are not privy to this information :-( So here is a java program that reads the content of a jar file and creates AS3 VOs. Like this post, I'm using StringTemplate to generate the files. And this other post was very helpful too. I'm using IntelliJ as my IDE and it lets me generate an executable jar. The following is the usage:

java -jar class2as3.jar jarPath packageName outputPath

You can download the source code from here.

Tuesday, September 9, 2008

Custom Symbol for Graphic using Flex API for ArcGIS

This is demonstration of a very simple custom symbol to render a graphic component on a map. Here is the application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:esri="http://www.esri.com/2008/ags"
xmlns:test="com.esri.test.*"
layout="absolute"
>
<esri:Map>
<esri:GraphicsLayer>
<esri:graphicProvider>
<mx:ArrayCollection>
<esri:Graphic>
<esri:geometry>
<esri:MapPoint x="45" y="45"/>
</esri:geometry>
<esri:symbol>
<test:CustomSymbol/>
</esri:symbol>
</esri:Graphic>
</mx:ArrayCollection>
</esri:graphicProvider>
</esri:GraphicsLayer>
</esri:Map>
</mx:Application>

And here is the CustomSymbol:

package com.esri.test
{
import com.esri.ags.Graphic;
import com.esri.ags.Map;
import com.esri.ags.esri_internal;
import com.esri.ags.geometry.MapPoint;
import com.esri.ags.symbol.Symbol;

use namespace esri_internal;

public class CustomSymbol extends Symbol
{
public function CustomSymbol()
{
super();
}

override esri_internal function drawGraphic(
map : Map,
graphic : Graphic
) : void
{
if( graphic.geometry is MapPoint )
{
drawMapPoint( map, graphic, MapPoint( graphic.geometry ));
}
}

private function drawMapPoint(
map : Map,
graphic : Graphic,
mapPoint : MapPoint
) : void
{
graphic.x = map.mapToContainerX(mapPoint.x);
graphic.y = map.mapToContainerY(mapPoint.y);

graphic.graphics.clear();
graphic.graphics.beginFill( 0xFF0000, 0.5 );
graphic.graphics.drawCircle( 0, 0, 10 );
graphic.graphics.endFill();
}

}
}

Be warned - this uses an esri_internal function that is subject to change without notice :-(