Sunday, November 23, 2008

Sunday, November 16, 2008

Polygon and Geodetic Circle Draw Tool

In this sample, I'm demonstrating how to roll you own draw tool using the Flex API for ArcGISServer. I'm attaching mouse listeners to the map and based on the selected tool, I'm drawing a polyline, a circle or a geodetic circle. For the latter, I'm using the undocumented (subject to changes) ProjUtils class to enable me to calculate the distance in meters between two lat/lon values. In addition, this class has the capability to calculate a lat/lon value for a given lat/lon origin, radius and azimuth. When using this sample, watch out for boundary condition (too close to the poles or crossing the date line) as this is a very simple implementation. How to handle these conditions will be another post :-) as usual, you can download the source from here. Have fun, and hope to see some of you at MAX next week.

Tuesday, November 11, 2008

Serializing Geometries To BlazeDS

Was asked if there is a way to serialize the geometries of a Flex client application using for example BlazeDS. And the answer is 'yes'. All geometries are tagged with a [RemoteClass] metadata. Here is the break down (BTW - this is subject to change in the next version):

SpatialReference com.esri.ags.ASSpatialReference
MapPoint com.esri.ags.geometry.ASPoint
Polyline com.esri.ags.geometry.ASPolyline
Polygon com.esri.ags.geometry.ASPolygon

Here is for example the Java side of MapPoint:

package com.esri.ags.geometry;

import com.esri.ags.ASSpatialReference;

public class ASPoint implements IASGeometry
{
public double x;
public double y;
public ASSpatialReference spatialReference;
}

The following is a very simple client application that calls a RemoteObject to save a MapPoint instance:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
>
<mx:Script>
<![CDATA[
import com.esri.ags.geometry.MapPoint;
private function clickHandler() : void
{
mapPointRO.save( new MapPoint( 45, 45 ));
}
]]>
</mx:Script>
<mx:RemoteObject id="mapPointRO" destination="mapPoint"/>
<mx:Button label="Save" click="clickHandler()"/>
</mx:Application>

The RemoteObject destination is defined in remoting-config.xml:

<destination id="mapPoint">
<properties>
<source>com.esri.remoteobject.MapPointRO</source>
<scope>application</scope>
</properties>
</destination>

And here is the POJO under BlazeDS:

package com.esri.remoteobject;

import com.esri.ags.geometry.ASPoint;

public class MapPointRO
{
public void save(final ASPoint asPoint)
{
System.out.println("asPoint.x = " + asPoint.x);
System.out.println("asPoint.y = " + asPoint.y);
}
}

You can download all the Java implementations from here.

Friday, November 7, 2008

Speaking At MAX 2008

This year, I will be a speaker at MAX 2008. The session title is 'Delivery of a Mission-Critical RIA for NATO' and is held on Tuesday at 4:30. Hope to see you all there.

Saving Map Snapshot

This week, while in Redlands for a holistic lab session on the Flex API for ArcGIS Server, a user showed me the following gem. Using the new Flash Player 10 FileReference class, you can create an image snapshot of a map component and save it locally to a file, without a server side service. To compile the application using FlexBuilder, you need to adjust your compiler SDK to version 3.2.

<?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"
layout="vertical"
>
<mx:Script>
<![CDATA[
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.JPEGEncoder;

private function clickHandler() : void
{
const decoder: JPEGEncoder = new JPEGEncoder();
map.logoVisible=false;
map.scaleBarVisible=false;
map.zoomSliderVisible = false;
const imageSnapshot:ImageSnapshot = ImageSnapshot.captureImage(map,96,decoder,true);
map.logoVisible=true;
map.scaleBarVisible=true;
map.zoomSliderVisible = true;
const fileReference:FileReference = new FileReference();
fileReference.save(imageSnapshot.data,"map.jpg");
}
]]>
</mx:Script>
<esri:Map id="map">
<esri:ArcGISTiledMapServiceLayer
url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
</esri:Map>
<mx:Button label="Snapshot" click="clickHandler()"/>
</mx:Application>

Thanks Ofir :-)

Monday, November 3, 2008

Find Nearby Place

So... if you are given a latitude and a longitude values and you want to find a nearby place, then you have to check out GeoNames. They have a web API that you can access for free (as in beer :-) Here is a simple usage of the API using the Flex API for AGS:

<?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"
layout="absolute"
>
<mx:Script>
<![CDATA[
import com.esri.ags.geometry.MapPoint;
import com.esri.ags.Graphic;
import com.esri.ags.events.MapMouseEvent;
import mx.rpc.events.ResultEvent;

private function mapClickHandler( event : MapMouseEvent ) : void
{
const urlVar : URLVariables = new URLVariables();
urlVar.lat = event.mapPoint.y.toFixed( 6 );
urlVar.lng = event.mapPoint.x.toFixed( 6 );
httpService.send( urlVar );
}

private function resultHandler( event : ResultEvent ) : void
{
const geonames : XML = event.result as XML;
const geoname : XML = geonames.geoname[0];
const name : String = geoname.name;
const lat : Number = geoname.lat;
const lng : Number = geoname.lng;
const graphic : Graphic = new Graphic( new MapPoint( lng, lat));
graphic.toolTip = name;
gl.add( graphic );
}
]]>
</mx:Script>
<mx:HTTPService id="httpService"
useProxy="false"
resultFormat="e4x"
url="http://ws.geonames.org/findNearbyPlaceName"
result="resultHandler(event)"/>
<esri:Map
openHandCursorVisible="false"
mapClick="mapClickHandler(event)">
<esri:ArcGISTiledMapServiceLayer
url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
<esri:GraphicsLayer id="gl">
<esri:symbol>
<esri:SimpleMarkerSymbol color="0xFF0000"/>
</esri:symbol>
</esri:GraphicsLayer>
</esri:Map>
</mx:Application>