Chameleon JavaScript API - version 2.0

Abstract

This document details how to develop Chameleon-based, JavaScript client applications.

Last Updated: 2005/01/11

Revision History


Table of Contents

Introduction
Getting Started
Developing Using the JSAPI
Developing Using JSAPI Events
Handling Errors
Other Considerations
Object Model Details
CWCApplication
CWCMapObject
CWCLayer
CWCRectangle
CWCPoint
CWCMLTObject
CWCErrorManagerObject
Event Details
For More Information
About this Document
Revision History
Copyright/Licensing Information
Feedback

This document is intended to help you use the JavaScript API (JSAPI) for Chameleon 2.0. If, after thoroughly reading this document and trying out its instructions, you have further JSAPI questions, please refer to the For More Information section.

The Chameleon JavaScript API is a programming interface for creating client applications in JavaScript that utilize the capabilities of Chameleon. Client applications can use the JSAPI to customize navigation and display of maps in several ways.

Chameleon provides the capability to create very complex applications using only HTML-based templates and existing widgets. As well, it is possible to modify existing widgets or create entirely new widgets to perform additional functions. However, this customization requires knowledge of the internal architecture of Chameleon, knowledge of the PHP programming language, and administrative access to a Chameleon instance.

In general, Chameleon application developers will not meet all these requirements. The Chameleon JSAPI object model is an abstraction of the internal architecture of Chameleon that provides a way for application developers to extend the built-in behavior of Chameleon and its widgets.

Note: JavaScript is not an "object oriented" language (as is Java). The language does not contain the ability to declare classes and methods in those classes. It does provide a pseudo-object mechanism through the this identifier and the prototype property. The end result is that JavaScript developers can create pseudo-objects that contain methods and properties. It is assumed that developers using the JSAPI are experienced JavaScript developers that are familiar with these concepts.

In order to use the JSAPI in a Chameleon application, two additional tags need to be added to a Chameleon application template. The first is a SharedResource tag named CWCJSAPI that identifies to all other widgets that the JSAPI is to be used. In general, SharedResource tags should be defined at the beginning of a template, although this is not required. The CWCJSAPISharedResource tag is declared as follows:

<CWC2 TYPE="SharedResource" NAME="CWCJSAPI"/>
    

The second is a widget tag that includes the Chameleon JSAPI code. Its purpose is to include the cwcjsapi.js file into the template and ensure that the JSAPI is properly initialized when the page is loaded. It has no visible user interface and can be declared anywhere in the template. Normally, it would be good practice to declare the CWCJSAPI tag with the associated CWCJSAPISharedResource. The CWCJSAPI tag is declared as follows:

<CWC2 TYPE="CWCJSAPI" DEBUG="false"/>
    

With the addition of the above two tags in a Chameleon application template, the application operates in "JavaScript" mode. This means that, whenever possible, user actions do not result in the application page being submitted. Instead, the JSAPI communicates with the server and updates the application interface directly by modifying text box contents and changing images. In some cases, especially on servers with high loads, this results in a more responsive application that puts less load on the server. For this reason, it may be desirable to incorporate the JSAPI even when no custom development is done.

In order to use the JSAPI for more than making Chameleon applications run primarily on the client side, the application developer typically adds code that allows the user to take some action or that responds to the user taking some action. In the first case, the developer can insert HTML elements and attach JavaScript functions to them to perform actions. For example, the developer may wish to provide a button that the user can click to set the extents of the view to some previously recorded or predefined value. To do this, the developer could add

<INPUT TYPE="BUTTON" OnClick="MySetExtents()"  value="Reset View">
    

inside the form tag on the page. Clicking this button would cause the following function to be executed:

/* Zoom the map to x1, y1, x2, y2, previously recorded extents */
function MySetExtents()
{
  goCWCJSAPI.oMap.SetExtents(x1, y1, x2, y2);
}
    

The developer could also provide a function to capture the current extents for later use in MySetExtents by adding

<INPUT TYPE="BUTTON"  OnClick="MyCaptureExtents()" value="Capture">
    

and the following function:

/* Capture the current extents for later processing */
function MyCaptureExtents()
{
  x1 = goCWCJSAPI.oMap.minx;
  x2 = goCWCJSAPI.oMap.maxx;
  y1 = goCWCJSAPI.oMap.miny;
  y2 = goCWCJSAPI.oMap.maxy;
}
    

In addition to directly accessing or modifying the state of the application, the developer may also need the application to be notified when the user takes some action. The Chameleon JSAPI provides an event framework that allows the developer to register JavaScript functions that are called when an event happens. The Chameleon JSAPI provides several different event types that can be used when registering for events. They are listed at the end of this document. In order to register for events, the developer must provide code that registers function names with the JSAPI after the JSAPI has been initialized. This requires that the developer provide a custom OnLoad function for the BODY element and call the Chameleon onload function at the beginning of the function. The following code demonstrates how this is accomplished. The example provides a "zoom to last extents" capability that tracks the previous extents as the user navigates. To access this functionality, the developer would add an

<INPUT  TYPE="BUTTON" OnClick="MyPreviousExtents()" value="Previous Extents">
    

to the template.

<script language="JavaScript">
//state variables for capturing current extents as the user zooms
var cx1, cx2, cy1, cy2;
//state variables for remembering previous extents
var px1, px2, py1, py2;

function MyOnLoad()
{
  // make sure to initialize Chameleon first
  CWC2OnLoadFunction();
  goCWCJSAPI.RegisterEvent( MAP_EXTENTS_CHANGED, "MyExtentsChanged" );
  //initialize the extents
  cx1 = goCWCJSAPI.oMap.minx;
  cx2 = goCWCJSAPI.oMap.maxx;
  cy1 = goCWCJSAPI.oMap.miny;
  cy2 = goCWCJSAPI.oMap.maxy;
  px1 = cx1;
  px2 = cx2;
  py1 = cy1;
  py2 = cy2;
}


/* this function is called whenever the map extents change,
 * capture the current extents and previous extents */
function MyExtentsChanged()
{
  px1 = cx1;
  px2 = cx2;
  py1 = cy1;
  py2 = cy2;
  cx1 = goCWCJSAPI.oMap.minx;
  cx2 = goCWCJSAPI.oMap.maxx;
  cy1 = goCWCJSAPI.oMap.miny;
  cy2 = goCWCJSAPI.oMap.maxy;
}

/* called when the user wants to go back to the previous extents */
function MyPreviousExtents()
{
  goCWCJSAPI.oMap.SetExtents( px1, py1, px2, py2 );
}

</script>
</head>
<body onload="MyOnLoad()">

<form>
<input type="button" onclick="MyPreviousExtents()" value="Previous Extents">
...
    

During processing, the JSAPI may encounter error conditions. The Chameleon JSAPI provides an error management framework that enables developers to create robust applications that handle various error conditions in a consistent and reliable manner. The CWCErrorManager object is contained in the global CWCApplication object and can be accessed through the oErrorManager property.

Error conditions can happen under two separate circumstances and developers need to be aware of both:

In general, the JSAPI attempts to handle all actions without submitting the current page, thus preserving application state and reducing load on the server. Unfortunately, under the following circumstances it is necessary to cause the page to be submitted :

If you allow any of these actions to be taken, then you are also responsible for providing a mechanism for preserving state between page submits. The Chameleon JSAPI manages its own state, but it does not preserve any other state. The Chameleon JSAPI preserves state through the use of hidden form variables (i.e., input type="hidden"), and this is also the suggested solution for preserving custom application state.

Also note that this use of JavaScript, while conforming to the standard, is not compatible with some browsers that have an immature javascript implementation. Most notably, Konqueror-based browsers (such as Safari on Mac OSX) are known to not work well with this code (although this is improving as the browser gets more mature). The code is known to work with IE 4+ and most versions of Netscape/Mozilla after 4.79. Other browsers are not directly supported but may work.

As previously discussed, the Chameleon JSAPI is composed of several JavaScript "objects" working together in a framework that allows an application developer to access data and make changes to an application's state. The remainder of this document describes the properties and methods of these objects in more detail. Following the description of each of the objects is a list of all the relevant events provided by the Chameleon JSAPI event manager.

The CWCApplication object provides the execution context for a Chameleon application. A single global CWCApplication object is created when the page is loaded. The CWCApplication contains a CWCMapObject that defines the view and layers in the map image. The CWCApplication provides the framework for event and error handling.

The CWCMapObject object represents a set of layers that are rendered to create the composite map image and contains properties and methods that affect the map image and view.

  • GetLayer( nIndex )

    Return a reference to a CWCLayer object for a given index. If the index is not valid, this method returns false.

    Parameters

    nIndex - The index of the layer to get.

    Returns

    An instance of CWCLayer or false if an error occurs.

  • GetLayerByName( szName )

    Return a reference to a CWCLayer object based on the layer's name. If the name is not valid, this method returns false.

    szName - The name of the layer to get.

    Returns

    An instance of CWCLayer or false if an error occurs.

  • AddWMSLayer( szName, szTitle, szSRS, szConnection, szVersion, szFormat )

    Create a new CWCLayer object with the given name, title, SRS string, connection string, WMS version number, and image format.

    Parameters

    szName - [string] - The name of the layer.

    szTitle - [string] - The title of the layer.

    szSRS - [string] - The projection of the layer.

    szConnection - [string] - The URL to the WMS server.

    szVersion - [string] - The version resource of the WMS server.

    szFormat - [string] - The image format to retrieve the image in.

    Returns

    [boolean] - true if the layer was added successfully, false if something went wrong.

  • AddGridLayer( szName, szProjection, szColor, szLabelFont, szLabelColor, szLabelSize,szLabelFormat, nMinSubdivide, nMaxSubdivide, fMinInterval, fMaxInterval, fMinArcs, fMaxArcs )

    Add a Grid reference layer to the map image.

    Parameters

    szName - [string] - The name of the layer, defaults to grid.

    szProjection - [string] - The EPSG projection in which to display the grid layer.

    szColor - [string] - An RGB color to draw the grid in, specified as a comma-separated set of RGB values between 0 and 255. 0,0,0 is black and 255,255,255 is white.

    szLabelFont - [string] - The font to display grid labels in, either a TrueType font supported by the Service Instance or BITMAP for a built-in font. Note: At this time, only BITMAP is supported. All font names are transparently changed to BITMAP and the label size is always interpreted as a string value.

    szLabelColor - [string] - An RGB color to draw the labels in, specified as a comma separated set of RGB values between 0 and 255. 0,0,0 is black and 255,255,255 is white.

    szLabelSize - [string]/[integer] - If font is set to BITMAP, then this parameter is a string value - one of TINY, SMALL, MEDIUM, LARGE, or GIANT. If font is set to some other font name, then the font is a TrueType font and this parameter is interpreted as an integer value and used as the point size of the font.

    szLabelFormat - [string] - A format specifier for labels. Use DDMMSS for DMS or DDMM for DM format. See http://mapserver.gis.umn.edu/cgi-bin/wiki.pl?MapServerGrid for more information on formatting grid labels and grids in general.

    nMinSubdivide - [integer] - The minimum number of subdivisions per arc.

    nMaxSubdivide - [integer] - The maximum number of subdivisions per arc.

    fMinInterval - [float] - The minimum interval for grid spacing (in map units). Depends on the current projection.

    fMaxInterval - [float] - The maximum interval for grid spacing (in map units). Depends on the current projection.

    fMinArcs - [float] - A hint to the subdividing engine to try to produce at least this many subdivisions, if possible.

    fMaxArcs - [float] - A hint to the subdividing engine to try to produce no more that this many subdivisions, if possible.

    Returns

    [boolean] - Always returns true.

  • CreateNewLayer( szName, szType, bDisplay )

    Add a new layer to a map of a given name and type. This method is used to create "feature" layers. When points and rectangles are added to a map, they are added to a default point or line layer unless this function has been called, in which case they can be added to a named layer of the appropriate type.

    Parameters

    szName - [string] - The name to give to the newly created layer.

    szType - [string] - The type of layer to add. One of POINT or LINE.

    bDisplay - [integer] - Optional. Value can be 0 or 1. It is set to 0 by default. If set to 0, the new layer will have a metadata called CWC_TMP_LAYER which will be used in the Legend in order to not display the layer.

    Returns

    [boolean] - true if the layer was created successfully, false otherwise.

  • GetProjection( )

    Return the projection of a Map as an EPSG code.

    Parameters

    None.

    Returns

    [string] - The EPSG code in the form EPSG:xxxxx.

  • ChangeProjection( szProjection )

    Set the projection of a Map to an EPSG code, if supported.

    Parameters

    szProjection - [string] - The new projection as an ESPG code in the form EPSG:xxxx.

    Returns

    [boolean] - true if the projection was changed, false if an error occurred.

  • ReprojectPoint( szCallback, fX, fY, szProjectionFrom, szProjectionTo )

    Convert a geographic location from one projection to another. This function is asynchronous. The result of the projection is passed to the provided callback function.

    Parameters

    szCallback - [string] - The name of a JavaScript function to call when the reprojected point is ready. This function declares two parameters to receive the X and Y values. X is passed as the first parameter and Y is passed as the second parameter.

    fX - [float] - The X coordinate to convert.

    fY - [float] - The Y coordinate to convert.

    szProjectionFrom - [string] - The projection of the input point as an ESPG code in the form EPSG:xxxx.

    szProjectionTo - [string] - The output projection as an ESPG code in the form EPSG:xxxx.

    Returns

    [boolean] - true if the input parameters were valid, false otherwise.

  • SetExtents( fX1, fY1, fX2, fY2 )

    Set the map extents to (X1, Y1) and (X2, Y2). All values are in geographic coordinates in the current projection.

    Parameters

    fX1 - [float] - The minimum X value for the new extents.

    fY1 - [float] - The minimum Y value for the new extents.

    fX2 - [float] - The maximum X value for the new extents.

    fY2 - [float] - The maximum Y value for the new extents.

    Returns

    [boolean] - Always returns true.

  • SetZoomFactor( nFactor )

    Set the zoom factor to a new value.

    Parameters

    nFactor - [integer] - The new zoom factor. Must be greater than or equal to 2.

    Returns

    [boolean] - Always returns true.

  • ZoomIn( )

    Zoom in by the current zoom factor at the center of the view.

    Parameters

    None.

    Returns

    [boolean] - Always returns true.

  • ZoomOut( )

    Zoom out by the current zoom factor at the center of the view.

    Parameters

    None.

    Returns

    [boolean] - Always returns true

  • ZoomInPos( nX, nY )

    Zoom in by the current zoom factor at a specified location. nX and nY are specified (in pixels) from the top, left corner of the map image. nX must be between 0 and the width of the view. nY must be between 0 and the height of the view.

    Parameters

    nX - [integer] - The X coordinate (in pixels) to zoom at.

    nY - [integer] - The Y coordinate (in pixels) to zoom at.

    Returns

    [boolean] - Returns true if nX and nY are within the map size, false if not.

  • ZoomOutPos( nX, nY )

    Zoom out by the current zoom factor from the specified location. nX and nY are specified (in pixels) from the top, left corner of the map image. nX must be between 0 and the width of the view. nY must be between 0 and the height of the view.

    Parameters

    nX - [integer] - The X coordinate (in pixels) to zoom out at.

    nY - [integer] - The Y coordinate (in pixels) to zoom out at.

    Returns

    [boolean] - Returns true if nX and nY are within the map size, false if not.

  • ZoomRect( nMinX, nMinY, nMaxX, nMaxY )

    Zoom to a rectangle defined in pixel coordinates. The top, left corner of the zoom rectangle is (nMinX, nMinY) and the bottom, right corner is (nMaxX, nMaxY). nMinX must be less that nMaxX and both must be between 0 and the width of the view. nMinY must be less than nMaxY and both must be between 0 and the height of the view.

    Parameters

    nMinX - [integer] - The left edge of the zoom rectangle (in pixels).

    nMinY - [integer] - The top edge of the zoom rectangle (in pixels).

    nMaxX - [integer] - The right edge of the zoom rectangle (in pixels).

    nMaxY - [integer] - The bottom edge of the zoom rectangle (in pixels).

    Returns

    [boolean] - Returns true if all parameters are within the extents of the map, false if one or more are not.

  • ZoomFull( )

    Zoom to the full extents of the current map. The full extents are defined by the extents specified in the Context when it was first loaded.

    Parameters

    None.

    Returns

    [boolean] - Always returns true.

  • ZoomScale( fScale )

    Zoom to a floating-point scale value at the center of the map.

    Parameters

    fScale - [float] - The new scale value to use. Must be greater than 0.

    Returns

    [boolean] - Returns true if fScale is greater than 0, false otherwise.

  • Recenter( nX, nY )

    Recenter the map at the pixel coordinates specified. nX and nY are specified (in pixels) from the top, left of the map image. nX must be between 0 and the width of the view. nY must be between 0 and the height of the view.

    Parameters

    nX - [integer] - The X coordinate (in pixels) to center the view at.

    nY - [integer] - The Y coordinate (in pixels) to center the view at.

    Returns

    [boolean] - Returns true if the parameters are within the size of the map, false otherwise.

  • Refresh( )

    Refresh the map image. Any outstanding changes to the map or layer objects are actioned at this point. Events may be triggered from calling this method, depending on what changes were outstanding.

    Parameters

    None.

    Returns

    [boolean] - Always returns true.

  • SetLayerDrawingOrder( aOrder )

    Modify the layer drawing order.

    Parameters

    aOrder - [array] - An array of layer indexes. Layers are re-ordered as they appear in the array with the layer at index 0 being drawn first (beneath all other layers) and the layer at the last index being drawn on top of all layers. For a map with four layers, the following array will reverse the drawing order of the layers: Array( 3, 2, 1, 0 ). Note: After setting the layer drawing orders, the layers appear at the new indexes. In the previous example, the layer previously at index 3 is now be at index 0.

    Returns

    [boolean] - Returns true if the array is the same size as the number of layers in the map and if each layer index is valid, otherwise returns false.

  • Geo2Pix( fX, fY )

    Convert geographic coordinates into a pixel location and return the value as an array of two values with X in the first element and Y in the second. fX and fY must lie within the current geographic extents of the map view.

    Parameters

    fX - [float] - The X coordinate to convert to pixel coordinates.

    fY - [float] - The Y coordinate to convert to pixel coordinates.

    Returns

    [array] - An array containing the converted coordinates with the X coordinate at index 0 and the Y coordinate at index 1. This method returns false if the geographic extents lie outside the currently visible extents.

  • Pix2Geo( nX, nY )

    Convert pixel coordinates into a geographic location based on the current map units and projection. The return value is two floating-point numbers in an array with the X coordinate in the first element and the Y value in the second. nX and nY must lie within the current view size.

    Parameters

    nX - [integer] - The X coordinate to convert from pixel to geographic units.

    nY - [integer] - The Y coordinate to convert from pixel to geographic units.

    Returns

    [array] - An array containing the converted coordinates with the X coordinate at index 0 and the Y coordinate at index 1. This method will return false if the pixel values lie outside the current map size.

  • GetDistance( fX1, fY1, fX2, fY2 )

    Return the distance between two pixel locations as a floating-point number. The value is calculated as a Pythagorean distance.

    Parameters

    fX1 - [float] - The X coordinate of the first point.

    fY1 - [float] - The Y coordinate of the first point.

    fX2 - [float] - The X coordinate of the second point.

    fY2 - [float] - The Y coordinate of the second point.

    Returns

    [float] - The distance between the two points, in the same units as the values passed in.

  • ConvertUnit( szUnitIn, szUnitOut, value )

    Convert a value from szUnitIn to szUnitOut. szUnitIn and szUnitOut are two valid unit specifications. Valid specifications are INCHES, FEET, MILES, METERS, KILOMETERS, DEGREES and PIXELS. If one of the units is not valid or an error occurs, the return value is false.

    Parameters

    szUnitIn - [string] - The units to convert the value from. One of INCHES, FEET, MILES, METERS, KILOMETERS, DEGREES and PIXELS.

    szUnitOut - [string] - The units to convert the value to. One of INCHES, FEET, MILES, METERS, KILOMETERS, DEGREES and PIXELS.

    value - [float] - The value to convert.

    Returns

    [float] - The converted value, or false if one of the units is not valid.

  • SetViewSize( nWidth, nHeight )

    Set the view size to nWidth pixels wide by nHeight pixels high if allowed by the template. Check bAllowResize in the map object to see if resizing is allowed. If resizing is not allowed, this function returns false.

    Parameters

    nWidth - [integer] - The width of the new view (in pixels).

    nHeight - [integer] - The height of the new view (in pixels).

    Returns

    [boolean] - Returns true if nWidth and nHeight are greater than 0.

  • AddPoint( szLayerName, oPoint )

    Add a point to the map on the named layer. If the layer name is not provided or is not valid, an error is generated. oPoint is an instance of CWCPoint that represents the point to be added to the layer.

    Parameters

    szLayerName - [string] - The name of the layer to add the point to.

    oPoint - [CWCPoint] - A CWCPoint instance to add.

    Returns

    [boolean] - Returns true if the point was added, false if the layer name was not valid or the point object was not valid.

  • AddRectangle( szLayerName, oRectangle )

    Add a rectangle to the map on the named layer. If the layer name is not provided or is not valid, an error will be generated. oRectangle is an instance of CWCRectangle that represents the rectangle to be added to the layer.

    Parameters

    szLayerName - [string] - The name of the layer to add the rectangle to.

    oRectangle - [CWCRectangle] - A CWCRectangle instance to add.

    Returns

    [boolean] - Returns true if the rectangle was added, false if the layer name was not valid or the rectangle object was not valid.

The CWCLayer object represents a single layer of information in a composite map view. Instances of CWCLayer always belong to a CWCMap. The position of the layer in the map is determined by the layer index.

The CWCPoint object defines a geographic point and associates rendering styles with the point. The CWCPoint object is used with the AddPoint method on a CWCLayer object to create a point on a layer. CWCPoint has no methods, only properties.

The CWCErrorManagerObject is used to manage errors reported by the JSAPI and Chameleon. An instance of the Error Manager is always created in the CWCApplication global instance. When an error occurs in the JSAPI or Chameleon, a new error is pushed onto the error manager's stack and the function returns false. The application can then check to see if an error was reported by calling PopLastError( ), which returns an array containing one error condition or false if no errors are available. The array consists of an error code (index 0) and a text message associated with the error (index 1).

There are several error codes defined by the JSAPI, as follows:

Error codes are defined as JavaScript variables, so it is valid to call:

oErrorManager.Error( ERR_NOTICE, "hey, something happened");
      

Applications can define there own error codes for specific purposes, and use the JSAPI error manager to mange them. Because the JSAPI is an evolving work, application-defined error codes should start at ERR_NEXT, which is the next available error code, and should increment the value of ERR_NEXT as follows:

var MyErrorCode = ERR_NEXT ++;
      

The Chameleon JavaScript API provides an event handling mechanism that informs your application of changes in the application, map, or a layer object as they happen. The Chameleon event mechanism uses a registration system that links JavaScript function names to event ids. When a change happens, it triggers events by calling all the function names that were registered for the appropriate event ids. To register a function to be called when an event happens, pass the event id and a string containing the JavaScript function name to the RegisterEvent method of the global CWCApplication object.

Functions that are called in response to events happening are "callback" functions. Callback functions should define no parameters.

Event ids are actually JavaScript variables created by the Chameleon JavaScript API that contain the event id of the associated event. When calling the RegisterEvent function, pass one of these variables as the first parameter. The following Event ids are defined:

If you were unable to answer all the questions you had about the subject of this document, other possible methods of obtaining information include:

The numbering is in parallel with the revision control system. Missing numbers indicate minor maintenance revision updates.

Revision History
Revision 1.002003/06/29Paul Spencer
original HTML version
Revision 1.012003/09/10Darren Redfern
initial translation from HTML to DocBook
Revision 1.022004/09/25Darren Redfern
Updated for Chameleon 2.0
Revision 1.12004/11/12Darren Redfern
finished initial draft
Revision 1.22005/01/11Jeff McKenna
added latest comments from PS