Moxi Media Inc.
Custom Tools Discussion Forum

IMF Developer's Guide » Custom Tools  

This document describes how to create a custom tool in the IMF. A custom tool is one that can be developed to provide a new map-related function, where the user chooses the tool to become 'active', then clicks on the map to execute the tool's function. It is important to note the distinction between a button and a tool. A button causes something to happen right away when the user clicks the icon, where a tool sets a 'state' which defines what happens when the user clicks a map. Tools are defined with the <tool> element.

Although some programming is involved, custom tools are easy to add to the IMF interface, and provide the developer with a powerful capability to add new interactive mapping functions to an IMF site.

Important: The format of the coordinate parameters has changed at v4.0.6 due to problems with the ServletExec servlet engine. Formerly, the coordinates were passed with commas separating the x and y values, and semicolons separating the coordinate pairs. The coordinates are now passed using commas between the values and the pairs. A new constructor for AimsPoints has been created that accepts this string to easily transform existing custom tool scripts.

Custom tools are defined in the site configuration file just like the other tools. The IMF application considers any tool that it doesn't already know about to be a custom tool automatically. The name of the tool is used to figure out whether the tool is a standard tool. The reserved names for internal tools are:

To create a custom tool, simply define a tool in the site configuration XML that doesn't have one of these names. Obviously, you will need to create a routine that is associated with the custom tool, but the good news is that there is no additional work involved in connecting your routine to the tool in the IMF GUI.

How a custom tool works

A custom tool is defined in the site configuration XML file similar to the following tool included with IMF. Note that the main difference between built-in tools and the custom tools that you create is that custom tools need to have a handler document defined in the tool element. The handler is the routine that you create to support your tool. Built-in tools and buttons do not use the handler attribute. The following is an example of a custom tool that is included in the IMF distribution.

<tool name="Text Markup"
      handler="$FRAMEWORK/imfTextMarkupForm.jsp"
      hint="Text Markup"
      status="Adds user-defined text to the map."
      graphic="$FRAMEWORK/tools/text_1.gif"
      active-graphic="$FRAMEWORK/tools/text_2.gif"
      width="16" height="16" />

The way a custom tool works is that when the tool is active the script or document that is defined as the handler is called in the dataFrame window. The name of the tool and the coordinates of the user click point are passed to the script or document as arguments. In the above example, a form is displayed in the data frame for the user to enter some text to add to the map at the location clicked.

The above example assumes that the shape type is "point", which is the default shape type for a tool. The shape type can also be set to a "box", "line", or "polygon". If the shape type is "box", the script will be called with a pair of coordinates when the user draws the box, or only one coordinate if the user clicks the map once without dragging the mouse to define a box. If the shape type is "line" or "polygon", the script will be called EACH TIME THE USER CLICKS THE MAP, with the list of coordinates that make up the line or the polygon. Although not a custom tool, the measure tools are an example of how to handle a custom tool that accepts more than one coordinate value, showing the location and distance between the coordinates.

To review what a custom tool handler script gets passed, an example may help. We will use a script called imfArgs.jsp as the handler for our examples. imfArgs.jsp is a handy script that is included in IMF to help developers to understand the the arguments passed when creating reporting and custom tool handlers. It simply displays a list of the arguments passed to the script. Try the following to see what imfArgs.jsp does:

http://www.moximedia.com/imf/imfArgs.jsp?msg=hello&recipient=world

Now, set up the following custom tool definitions using imfArgs.jsp as the handler. This will add a custom tool to your application for each of the shape types.

<tool name="Point Test"
      shape="point"
      handler="$FRAMEWORK/imfArgs.jsp"
      hint="Point Test"
      status="Custom tool test - point."
      graphic="$FRAMEWORK/tools/markup_point1.gif"
      active-graphic="$FRAMEWORK/tools/markup_point2.gif"
      width="16" height="16" />

<tool name="Box Test"
      shape="box"
      handler="$FRAMEWORK/imfArgs.jsp"
      hint="Box Test"
      status="Custom tool test - box."
      graphic="$FRAMEWORK/tools/markup_rect1.gif"
      active-graphic="$FRAMEWORK/tools/markup_rect2.gif"
      width="16" height="16" />

<tool name="Line Test"
      shape="line"
      handler="$FRAMEWORK/imfArgs.jsp"
      hint="Line Test"
      status="Custom tool test - line."
      graphic="$FRAMEWORK/tools/markup_line1.gif"
      active-graphic="$FRAMEWORK/tools/markup_line2.gif"
      width="16" height="16" />

<tool name="Polygon Test"
      shape="polygon"
      handler="$FRAMEWORK/imfArgs.jsp"
      hint="Polygon Test"
      status="Custom tool test - polygon."
      graphic="$FRAMEWORK/tools/markup_polygon1.gif"
      active-graphic="$FRAMEWORK/tools/markup_polygon2.gif"
      width="16" height="16" />

Try out your new tools. It will help you to understand clearly what is happening when the user clicks the map. All that is left to do is to create a real handler that does what you need your tool to do. You can create custom tools to do hyperlinks, create combination spatial / attribute query forms, or anything where you need some spatial user input. For example, you can create a parcel drill down identify tool, where you select a parcel and use it as a filter to display records from other layers that intersect the parcel. The possibilities are endless. The editing tools extension is simply a set of custom tools created to perform editing tasks.

An example

Let's use what we know to build an example. Before we do, there is a distinction between what can be done by developers that will be installing scripts inside the IMF distribution directory and what can be done by developers that don't have direct access to the IMF (site developers that install their code in remote directories or in other directories on the same server). The scripts installed in the IMF directory can access the map object in the user's session, and those in other places cannot. Some API scripts have been developed to allow remote scripts to perform some actions that would otherwise require in-directory access, but handlers that need to access and modify the map settings are much easier to develop if they will be installed in the IMF directory tree. The recommended location for custom scripts that are installed in the IMF directory is in the ext directory or a subdirectory of that.

This example is for an in-directory installation to add a user-drawn line to the acetate layer of the map. We will actually develop two JSP scripts, one that displays each time the user clicks, and the script that adds the line to the map when the user is done. The definition of our tool will be:

<tool name="Line Markup"
      shape="line"
      handler="$FRAMEWORK/ext/lineMarkupHandler1.jsp"
      hint="Line Markup"
      status="Adds a line that you draw to the map."
      graphic="$FRAMEWORK/tools/markup_line1.gif"
      active-graphic="$FRAMEWORK/tools/markup_line2.gif"
      width="16" height="16" />

The following is a simple document that displays the status as the user clicks. Note that it doesn't really do much except count the points and put the argument string (the coordinates of the line) into a form that it will be passed to the "final" handler script when the user clicks the submit button.


<%@ page import="com.moximedia.aims.*" %>
<%@ page import="java.util.StringTokenizer" %>
<% 
  // Program: $FRAMEWORK/ext/lineMarkupHandler1.jsp
  // Purpose: Example handler script for custom tool.
  // Notes:   For example purposes, to keep this file as readable as 
  //          possible, a simple HTML format is presented.

  // The points are contained in the "pts" parameter as a string of 
  // x,y coordinates, with the x and y separated by commas and the 
  // coordinates separated by commas too. The AimsPoints class has
  // a constructor that uses this string format to create a points
  // list easily from the pts argument.

  AimsPoints pts = new AimsPoints(request.getParameter("pts"));

%>
<html>
<head>
</head>
<body>
<form name="frm" method="post" action="imfLineMarkupHandler2.jsp">
<p>
<%= pts.getCount() %>
<% if (pts.getCount() <= 1) { %>
point recorded. Click more points to define the line.
<% } else { %>
points recorded. Click more points to define the line, or click
Submit when you are finished drawing your line.
</p> 
<input type="hidden" name="pts" value="<%= ptsArg %>">
<input type="submit" name="Submit" value="Submit">
<% } %>
<form>
</body>
</html>