Thursday, October 27, 2005

Adding Selection tool to MapViewer template

Although the selection tool is provided in ArcGIS Server MapViewer template, it can't be used as-is unlike other tools (zoomin, identify etc.) That is because it is necessary to set the selected layer to the AGSSelection object before this tool can be used.

AGSSelection selection = (AGSSelection)
agsContext.getAttribute(
AGSSelection.WEB_CONTEXT_ATTRIBUTE_NAME);
selection.setSelectedLayerId(layerId);

Here are the steps to implement the selection tool in the MapViewer template:

1. Use arcgisant tool to create a web application named SelectionTest using the MapViewer template.

2. Create a new project as discussed here and copy over the newly created webapplication from ArcGIS build directory to this directory. Be sure to update the build file with the new app name.


3. Under the src folder, create a folder named test.

4. Create a file named AGSSelectionLayer.java in the test folder with this content:


package test;

import com.esri.arcgis.webcontrols.faces.event.*;

import com.esri.arcgis.webcontrols.data.*;

import com.esri.arcgis.webcontrols.ags.data.*;

import java.util.*;

import javax.faces.component.UIData;

import javax.faces.model.SelectItem;

import java.util.logging.*;

import com.esri.arcgis.geodatabase.*;

import com.esri.arcgis.carto.ILayerDescriptions;



public class AGSSelectionLayer implements

WebContextInitialize, WebContextObserver{

private static Logger logger =

Logger.getLogger(AGSSelectionLayer.class.getName());

private AGSWebContext agsContext;

private String mapName;

private int layerId = 0;

public void init(WebContext agsContext) {

if(agsContext == null ||
!(agsContext instanceof AGSWebContext))

throw new IllegalArgumentException

("WebContext null.");

this.agsContext = (AGSWebContext)agsContext;

setLayerId(((Integer)((SelectItem)

((AGSWebMap)agsContext.
getWebMap()).getFeatureLayers()
.get(0)).getValue()).intValue());

}



public void update(WebContext context, Object arg) {

if(arg == null ||
arg != AGSRefreshId.DATA_FRAME_CHANGED)
return;

AGSWebMap agsMap = ((AGSWebMap)
agsContext.getWebMap());

this.mapName = agsMap.getFocusMapName();

setLayerId(((Integer)((SelectItem)

agsMap.getFeatureLayers()
.get(0)).getValue()).intValue());

}



public int getLayerId() {

return layerId;

}



public void setLayerId(int layerId) {

this.layerId = layerId;

AGSSelection selection = (AGSSelection)agsContext

.getAttribute(
AGSSelection.WEB_CONTEXT_ATTRIBUTE_NAME
);

selection.setSelectedLayerId(layerId);

}



public void clearResults() {

try {

ILayerDescriptions layerDescs =

((AGSWebMap)agsContext.getWebMap()).

getFocusMapDescription().getLayerDescriptions();

for(int i = 0; i < layerDescs.getCount(); ++i)

layerDescs.getElement(i).setSelectionFeatures(null);

} catch(Exception _) {

logger.log(Level.WARNING,
"Unable to deselect features.",
_);

}

agsContext.refresh(AGSRefreshId.MAP_OPERATION);

}

}

Notice that on init method, we are calling setLayerId method and passing the first featurelayer from the collection in the wemap. setLayerId method sets the selection layer to the AGSSelection object. clearResults method clears out selection from all layers.

5. Go to webapp_name/WEB-INF/classes folder and open managed_context_attributes.xml file in a text editor. Add a new managed-context-attribute as shown below:


<managed-context-attribute>

<name>esriAGSSelectionLayer</name>

<attribute-class>test.AGSSelectionLayer</attribute-class>

<description>Selection Layer</description>

</managed-context-attribute>


6. Open mapviewer.jsp file from webapp folder and find the IMG tag for identify tool. Add the following code right after it to add a dropdown list of all FeatureLayers, a Selection tool and a button to clear selection.


<td>

Select From:

</td>

<td>

lt;jsfh:selectOneMenu onchange="this.form.submit();"

value="#{sessionScope['mapContext'].
attributes['esriAGSSelectionLayer'].
layerId}">

<jsfc:selectItems value="#{sessionScope['mapContext'].
webMap.featureLayers}
"/>

</jsfh:selectOneMenu>

</td>

<td>

<IMG id="imgSelection"
name="imgSelection"
src="images/polygon.gif"
alt="select"
title="Select"
onmouseover="this.src='images/polygonU.gif'"
onmousedown="this.src='images/polygonD.gif';
MapDragRectangle('Map0', 'Selection');
HighlightTool('Selection');"
onmouseout="ButtonOut('imgSelection', 'Map0',
'Selection', 'images/polygon.gif',
'images/polygonD.gif')">

</td>

<td>

<jsfh:commandButton id="cmdClear"
image="images/cancel.gif"
onmousedown="this.src='images/cancelD.gif'"
onmouseover="this.src='images/cancelU.gif'"
onmouseout="this.src='images/cancel.gif'"
title="Clear Selection"
alt="Clear Selection"
action="#{sessionScope['mapContext'].
attributes['esriAGSSelectionLayer'].clearResults}" />

</td>



7. Open templates.js file in a text editor from js folder and find HighlightTool function. Modify this function as shown below to include the Selection tool.





function HighlightTool(tool)

{

if ((tool!=null) && (tool!=""))

{

document.images["imgZoomIn"].src = "images/zoomin.gif";

document.images["imgZoomOut"].src = "images/zoomout.gif";

document.images["imgPan"].src = "images/pan.gif";

document.images["imgIdentify"].src = "images/identify.gif";

document.images["imgSelection"].src = "images/polygon.gif";

switch (tool)

{

case "ZoomIn":

document.images["imgZoomIn"].src = "images/zoominD.gif";

break;

case "ZoomOut":

document.images["imgZoomOut"].src = "images/zoomoutD.gif";

break;

case "Pan":

document.images["imgPan"].src = "images/panD.gif";

break;

case "Identify":

document.images["imgIdentify"].src = "images/identifyD.gif";

break;

case "Selection":

document.images["imgSelection"].src = "images/polygonD.gif";

break;

default:

}

}

}



8. Open command prompt and CD to ant folder. Run this command: arcgisant build

9. Verify that the SelectionTest.war file is created in build folder. Copy this file back to the ArcGIS Installation Directory\DeveloperKit\Templates\Java\build directory.

10. Copy the webapp folder back to the ArcGIS Installation Directory\DeveloperKit\Templates\Java\build directory.

11. Use arcgisant tool to deploy the web application.

Thursday, October 20, 2005

ANT tool for customizing ArcGIS Server application

IDE projects introduce unnecessary complication and overhead. So I typically limit the use of IDE for Java development to build classes. This way I can keep my project simple and easily managable. Ant tool can instead be used for project development and deployment. ArcGIS Server uses ant for configuration and deployment of template application. It can also be used for extending the template web applications. I use the following approach to customize the ArcGIS Server java template web applications:

1. Create a workspace folder in a convenient place in your local directory. For example: C:/Temp/AGSProjects

2. Inside the workspace folder, create the project folder. For example: C:/Temp/AGSProjects/MapProject1

3. Inside the project folder, create this folder structure:
MapProject1
   |-ant
   |-build
   |-src

4. Use arcgisant tool to create an ArcGIS Server java template web application. Refer to ArcGIS Server Administration and Development Guide for more information.

5. Copy the web application folder built in ArcGIS\DeveloperKit\Templates\Java\build folder to the projectfolder. (MapProject1 folder in the above example.)

6. Create a file named build.xml with the following content:


<project default="build" basedir="../" name="ags" >
<!-- load environment variables -->
<property environment="env"/>
<property name="devkit.home" value="${env.AGSDEVKITHOME}" />
<property name="arcgisant.home" value="${devkit.home}/tools/ant"/>
<!-- library dependency settings -->
<property name="arcgis.dir"
location="${devkit.home}/Templates/Java/WEB-INF/lib"/>
<!-- jar file mappings -->
<property name="jintegra.jar" location="${arcgis.dir}/jintegra.jar"/>
<property name="arcobjects.jar"
location="${arcgis.dir}/arcobjects.jar"/>
<property name="arcgis_webcatalog.jar"
location="${arcgis.dir}/arcgis_webcatalog.jar"/>
<!-- Project settings -->
<property name="project.distname" value="MapViewer1"/>
<!-- current project paths -->
<property file="${basedir}/ant/build.properties"/>
<property name="webroot.dir" value="${basedir}/${project.distname}"/>
<property name="webinf.dir" value="${webroot.dir}/WEB-INF"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="build.dir" value="build"/>
<path id="arcgis.classpath">
<fileset dir="${arcgis.dir}">
<include name="*.jar" />
</fileset>
</path>
<!-- Check timestamp on files -->
<target name="prepare">
<tstamp/>
</target>
<!-- Copy any resource or configuration files -->
<target name="resources"
description="Copy any resource or configuration files">
<copy todir="${webinf.dir}/classes" includeEmptyDirs="no">
<fileset dir="${src.dir}">
<patternset>
<include name="**/*.conf"/>
<include name="**/*.properties"/>
<include name="**/*.xml"/>
</patternset>
</fileset>
</copy>
</target>
<!-- compile-->
<target name="compile" depends="prepare,resources"
description="Compile the project classes">
<javac srcdir="${src.dir}" destdir="${webinf.dir}/classes">
<classpath refid="arcgis.classpath"/>
</javac>
</target>
<!-- Remove existing compiled classes -->
<target name="clean"
description="Remove classes directory for clean build">
<delete dir="${webinf.dir}/classes"/>
<mkdir dir="${webinf.dir}/classes"/>
</target>
<!-- Build the project -->
<target name="build1" description="Build the project"
depends="prepare,compile"/>
<target name="rebuild" description="Rebuild the project"
depends="clean,prepare,compile"/>
<!-- Create war file -->
<target name="build" depends="build1"
description="Create the war file for deployment">
<mkdir dir="${build.dir}"/>
<war basedir="${webroot.dir}"
warfile="${build.dir}/${project.distname}.war"
webxml="${webinf.dir}/web.xml">
<exclude name="WEB-INF/${build.dir}/**"/>
<exclude name="WEB-INF/src/**"/>
<exclude name="WEB-INF/web.xml"/>
</war>
</target>
</project>



7. Change the value in this line in the build.xml file to the name of the web application you create above.

<property name="project.distname" value="MapViewer1"/>

8. Customize the web application as necessary.

9. Add any java source code to src folder.

10. Open command prompt and CD to ant directory in your project. Type this command to build the project:
arcgisant build

11. Verify that a war file is built in the build folder. Deploy this war file directly or copy the web application folder and the war file back to ArcGIS\DeveloperKit\Templates\Java\build folder and use arcgisant to deploy it.

You can repeat the same steps to build any other web applications. You can use the same build file but make sure to update it with the new project name as mentioned above in step 7.