Tag: Rasters

ArcGIS API for JavaScript events at the 2009 ESRI User Conference

If you’re developing with the ArcGIS API for JavaScript, or you want to get started, there’s plenty to learn at the 2009 ESRI International User Conference. Here’s what you can look forward to.

Special Interest Group

Come join fellow JavaScript developers at the first ArcGIS API for JavaScript SIG. We are proud to have Dylan Schieman, CEO of SitePen and Co-founder of the Dojo Toolkit come and present to us. Dojo is a wonderful resource for building rich web applications. Dylan will talk about Dojo and what possibilities Dojo provides for you, the ESRI JavaScript developer.

Demo theaters

The demo theaters are 45-minute presentations on specialized topics, offered in a smaller setting than the technical workshops. All JavaScript-related demo theaters are offered at the ArcGIS Server showcase in Exhibit Hall C.

Enhancing ArcGIS JavaScript Applications using Dojo Dijits

Thursday, July 16th 12-1PM

Describes how you can add interactivity to your Web applications with Dojo dijits. You’ll see how the presenters built this San Diego Neighborhoods example application that uses Dojo layouts, buttons, accordion containers, and charts.

Network Analyst Server: Routing for Web Applications using ArcGIS APIs for JavaScript and Flex

Thursday July 16th 9 – 10 AM

In this demo theater you can learn about creating and publishing network analysis services using ArcGIS Server 9.3.1. You’ll then see how to use those services to add routing to JavaScript and Flex Web applications.

Technical workshops

The technical workshops take place in a larger group setting than the demo theaters. This year’s User Conference agenda offers the following ArcGIS API for JavaScript workshop:

Building Mashups Using the ArcGIS API’s for JavaScript

Wednesday, July 15th 1:30-2:45PM, Room 6E
Thursday, July 16th 10:15-11:30AM, Room 6E

This session will teach you how to build applications with the ArcGIS API for JavaScript by walking you through the online samples in the SDK and covering best practices.

GIS Design Methods

Tuesday, July 14th 8:30 – 9:45 AM, Room 30B

Applicable for ArcGIS API for JavaScript developers, this session will talk about preparing data for the Web and how to effectively expose that data from a Web application.

Posted in Services | Tagged , , , , | Leave a comment

Introducing the UserControlTask

With version 9.3.1 of the .NET Web ADF you can use the new UserControlTask to streamline the creation of your own custom tasks. Previously, you would need to create your own class that derived from FloatingPanelTask and take care of the creation and placement of your user interface controls, while paying particular attention to the page lifecycle events as they were raised. With the new UserControlTask, you can create your user interface interactively, in the design view of Visual Studio, and then simply assign a link to it using a property of the UserControlTask called TaskControl.

In Visual Studio, the first thing you’ll want to do is right-click your project and choose “Add New Item…” from the menu. When the dialog appears, choose “Web User Control”. This will create an empty template for your user control so that you can add whatever controls are necessary to your user interface. You will want to wire up any event handlers for the various user interface controls you added, and be sure to add a mechanism to start the execution of your task (typically a button).

Adding a UserControlTask to the page

In the code behind page for your control, you will need to make sure your class derives from the new ADF class called UserControlTaskPanel.

public partial class MyCustomTask : UserControlTaskPanel
    protected void btnExecute_Click(object sender, EventArgs e)
        object[] input = new object[] { TextBox1.Text, DropDownList1.SelectedValue };

    public override object ExecuteTask(object input)
        // Extract packaged parameters
        object[] parameters = (object[])input;

        string textBoxValue = (string)parameters[0];
        string selectedValue = (string)parameters[1];

        // Perform your task processing
        DateTime now = DateTime.Now;
        string heading = string.Format("The time on the server is {0}:{1:d2}:{2:d2}",
            now.Hour, now.Minute, now.Second);
        string detail = string.Format("The value in the text box is {0} and the drop down list is {1}.",
            textBoxValue, selectedValue);

        // Generate result packaged for task results control
        ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult result =
            new ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult(heading, detail);
        return result;

This will allow your code to access the Start method of the base class to begin execution of your task and supply input parameters to your task execution logic. You will need to extract applicable values from your user interface controls and package them as a single object to be used by your execution code. The final step is to implement the abstract ExecuteTask method. Here you will need to make use of the single input parameter object (which contains your packaged input values you passed into the Start method), execute your particular logic, and return a task result so that it can be displayed in a TaskResults control.

To test your task, you simply add a UserControlTask to your page (typically in a TaskManager control) and configure it appropriately. This includes assigning the TaskControl property to point to the location where your .ascx file is located, and likely assigning a value to the TaskResultsContainers property. When your application runs, your user interface should appear, collect user input, execute, and cause the task results to appear in the task results control.

For further reading, see the UserControlTask control overview in the .NET Web ADF Help.

Contributed by John Donahue of the ArcGIS Server .NET Web ADF development team.

Posted in Services | Tagged , , , | Leave a comment

ESRI User Conference will feature a Virtual Map Gallery

This year at the ESRI International User Conference, the popular Map Gallery will include a new “Virtual Map Gallery” area featuring applications made with ESRI’s Web mapping API’s. Along with the traditional multimedia applications, the Virtual Map Gallery will include interactive Web mapping applications that users have created with the ArcGIS API’s for Flex, JavaScript, .NET, Java, and Silverlight/WPF.

At the Virtual Map Gallery you can navigate Web applications by themes, including the type of API used, the base map, and category of the application. You can also vote for your favorite application as part of the Map Gallery’s People’s Choice contest.

If you are registered for the User Conference and have a web application you’d like to include, visit the Virtual Map Gallery Submissions page to submit your entry.

Contributed by Matthew Baker of ESRI Educational Services.

Posted in Services | Tagged , | Leave a comment

What's new in the 9.3.1 .NET Web ADF

Here’s a brief look at what’s new in the ArcGIS Server .NET Web ADF at 9.3.1. This information comes from the What’s new in ArcGIS 9.3.1 PDF where you can read about new features in all areas of the product. If you have questions about any of the new features, please leave a comment to this post.

Customizing the look and feel of MapTips

The Web ADF JavaScript Library has been enhanced to provide greater control over customizing the look and feel of MapTips. New examples have been added to the MapTips sample that demonstrate how to leverage this new capability. In addition, a new MapTips custom control template is also available from the ArcGIS Server Resource Center .NET code gallery that enables drag-and-drop configuration of the new customization endpoints.

User control task

A new User Control task has been added to the available Web controls in the Web ADF. This new task is based on the User Control task sample available in the software developer kit (SDK). In addition, you can configure custom User Control tasks in ArcGIS Server Manager and include them in Web mapping applications.

Print task templates

In ArcGIS 9.3.1, a new property called LayoutTemplateFile is available that allows you to define the contents of your printed maps. This file, located at your Web site’s default root directory/aspnet_client/ESRI/WebADF/PrintTaskLayoutTemplates/default.htm, is customizable.

The Print task will generate a map layout based on your template. By default, at 9.3.1, this new map template includes the map title, map, and legend information. Task results and copyright text can also be included in the printed map.

Posted in Services | Tagged , , , , | 1 Comment

Questions and answers about ArcGIS Server 9.3.1 map services

In a previous post Design patterns for Web maps, we talked about strategies and challenges for displaying different types of map layers on the Web for the best performance. Caching is the fastest way to serve Web maps, but requires an initial time investment for cache creation. Also, datasets that change often and cover a broad extent cannot be cached and require a (typically slower) dynamically drawn service. Continue reading

Posted in Services | Tagged , , , | 25 Comments

Querying points and lines on click with the ArcGIS JavaScript API

Many of the existing ArcGIS JavaScript API samples for the Query task show how to query polygon features. This post explains one way to query points and lines with a mouse click on the map.

Querying a point or a line is a little more difficult than querying a polygon because the mouse click is required to fall directly on the line or point in order for a result to be returned. To makes things easier for your users, you can build a “tolerance” envelope around the clicked point.

       var centerPoint = new esri.geometry.Point
        var mapWidth = map.extent.getWidth();

        //Divide width in map units by width in pixels
        var pixelWidth = mapWidth/map.width;

        //Calculate a 10 pixel envelope width (5 pixel tolerance on each side)
        var tolerance = 10 * pixelWidth;

        //Build tolerance envelope and set it as the query geometry
        var queryExtent = new esri.geometry.Extent
        query.geometry = queryExtent.centerAt(centerPoint);

In the above code, you figure out the width of one pixel in map units given the current scale. You then multiply this by the total tolerance width in pixels. So if you want a tolerance of 5 pixels on each side, you multiply by 10. This gives you the width of your tolerance envelope in map units.

You then use one of the esri.geometry.Extent constructors to make the square tolerance envelope. Any feature that intersects the envelope will be returned as a query result.

Building a rectangular tolerance around the clicked point

It’s worth noting that the Identify task has a built-in tolerance that you can easily modify using IdentifyParameters. However, the Identify task does not allow you the flexibility to determine which fields are returned. The Query task lets you narrow the fields.

Contributed by Sterling Quinn and Jeremy Bartley of the ArcGIS Server development team

Posted in Services | Tagged , , | 4 Comments

Geoprocessing parameter types in the ArcGIS JavaScript API

Every geoprocessing task has a set of input parameters, which represent values or datasets that the model takes in. You need to supply the parameters correctly in order to run the task. In this post we’ll look at how you find out the parameter types and supply them in your code when working with the ArcGIS JavaScript API.

One important thing to remember about geoprocessing tasks is that they have a limited set of input and output data types when compared with tools that you work with in ArcGIS Desktop. This makes it a little easier to work with parameters because you only have to learn a handful of object types.

To find out the parameter data types for any geoprocessing task, use the Services Directory. For example, take a look at the Services Directory page for this ClipAndShip task. There are two parameters here:

  • Area_To_Zip, which is of data type GPFeatureRecordSetLayer
  • Email_Zip_To, which is of data type GPString

You can tell the above parameters are both inputs since their Direction is listed as “esriGPParameterDirectionInput”.

You may be wondering how you create those parameters in your JavaScript code, especially because there’s no object in the API with a name resembling “GPFeatureRecordSetLayer”. At this point you need to use the Parameter Type table in the Supplying parameters for the Geoprocessor help topic to understand which JavaScript object corresponds to your parameter type. That table is copied in below:

Parameter type Corresponding JavaScript object
GPBoolean boolean
GPDataFile DataFile
GPDate Date
GPDouble number
GPFeatureRecordSetLayer FeatureSet
GPLinearUnit LinearUnit
GPLong number
GPRasterData RasterData
GPRasterLayer RasterData
GPRecordSet FeatureSet
GPString string

This table shows that the corresponding JavaScript object for a GPFeatureRecordSetLayer is the FeatureSet. This is an array of graphic features that can contain geometry and/or attributes.

For the GPString parameter, you just need to create a JavaScript string.

Once you have all the input parameters, you need to list them in JavaScript Object Notation (JSON) and pass them to the Geoprocessor. Your code might look like the following:

var params = { "Area_To_Zip":myFeatureSet, "Email_Zip_To":email };

If there are output parameters, you’ll have access to a ParameterValue array after the job completes. The number and types of objects in the array will vary according to the number and types of output parameters used by the task. However, the mappings between parameter types and JavaScript objects will still follow the table above.

To learn more about input and output parameters, see:

Contributed by Sterling Quinn of the ArcGIS Server software development team

Posted in Services | Tagged , , , | Leave a comment

Customizing the map progress bar in the 9.3 Web ADF (.NET)

The Web ADF includes a progress bar that displays when the map is loading map images or tiles. It makes the user aware that the site is processing the user’s request. You may wish to customize the progress bar, either to modify it or to replace it with your own progress indicator. An earlier blog post described how to do this at the 9.2 version. Things have changed for the 9.3 version, and this post gives some tips on customizing the progress bar for 9.3.

We will cover two options for customizing the progress indicator. First, you can set some of the properties of the existing progress bar. Second, you can completely replace the progress bar with your own custom progress indicator. The second option involves working with custom progress events, which we will discuss before we get to the actual replacement of the default progress indicator.

Setting progress bar properties

At the 9.3 release, two public properties are exposed that you can set for the standard progress bar. These properties are the alignment, or location, of the progress bar on the map; and whether to enable or disable the progress bar. More properties may be exposed at future service packs or versions. We will use the enable/disable property later in this article, when we replace the progress bar. Let us look now at setting the alignment property, which will introduce a client-side approach we will use throughout this article.

The alignment property may be set using the Web ADF JavaScript Library. The Web ADF contains both code that runs on the server and code that runs on the client. The server-side code uses an ASP.NET language (C# or VB). The client-side code uses JavaScript, so we use that language to customize how the client code works. You can find documentation on the Web ADF JavaScript Library in the ArcGIS Server Developer Help, available either installed on your development computer, or online at the ESRI Resource Center. See the topic Web ADF JavaScript Library under the heading Developing Web applications using the Web ADF.

The progress bar properties are on the Map, since the bar is tied to the Map. Most of the properties and methods for the Map class are actually on the MapBase class, which the Map class extends. If you look on the class properties for MapBase, you will find the progressBarAlignment property. You will notice that, like most other properties, the documentation actually shows two methods associated with this property: get_progressBarAlignment() and set_progressBarAlignment(). As you will see in the code, we use these methods rather than the property per se when setting the propery.

The set_progressBarAlignment() method takes one argument when you call it: a ContentAlignment setting. For information on this enumeration, you can click on the ContentAlignment link on the progressBarAlignment page in the help, or find it under the ESRI.ADF.System namespace in the Web ADF JavaScript Library documentation. The ContentAlignment enumeration has nine values, corresponding to nine positions on the map. They include TopLeft, MiddleCenter, and BottomRight (the default).

Now we have the information we need to set the progress bar’s alignment. To demonstrate, we will set the progress bar alignment to the MiddleCenter of the map. To do this, we add some JavaScript code into the .aspx page for our application, typically the Default.aspx page. Near the bottom of the page, just before the closing </body> tag, add a JavaScript function that will be called when the page starts up. We can do this using the ASP.NET AJAX add_init function, which guarantees our function will run after the page completely loads. We pass to add_init the name of the function (setupProgressIndicator) that will be called on startup.

In the setupProgressIndicator function, we get a reference to the JavaScript component for the map, using the ASP.NET AJAX $find function. Then we set the progress bar alignment using the ContentAlignment value we want. The resulting code would go into your .aspx page, just before the closing </body> tag.

<script language="javascript" type="text/javascript">

// Have our custom function called when the user starts the application

function setupProgressIndicator() {

// Get the JavaScript map component
var map = $find('Map1');

// Set the location of the progress bar


Custom progress events

If you want to do more than set the alignment of the built-in progress bar, you can have custom code that runs when the map is loading images or tiles. You can use this approach to supplement the standard progress bar, or completely replace it with your own indicator. The map’s onProgress event enables us to run custom code. This and other map events are discussed in the Web ADF JavaScript Library section of the Developer Help. In this section, we will use this event to display the number of pending tiles on the progress bar. Later we will replace the progress bar with a custom indicator.

To show custom content when the map is loading images or tiles, we can use the onProgress event on the map client. This event is new at 9.3, and replaces multiple events that were used at 9.2 (onRequestsPending, etc.). When a function is attached to the onProgress event, it gets called each time the number of pending tiles changes. The custom function takes two arguments: the sender of the event, which is the map component; and the number of pending tiles. You can check the second argument to determine what to display to the user.

In the code sample below, we attach to the onProgress event by calling the map’s add_onProgress method. We pass it the function to be called when the number of pending tiles changes. In this function, showProgress, we examine the number of tiles as given in the args value. If the number is greater than zero, then we display the number of tiles in the browser’s status bar. If the number of tiles is zero (i.e., the map is finished loading tiles), then we hide the status bar message.

<script language="javascript" type="text/javascript">


function setupProgressIndicator() {

// Get the JavaScript map component
var map = $find('Map1');

// Set the location of the progress bar

// Add the custom progress function

// Custom progress function
// sender = map component, args = number of pending tiles
function showProgress(sender, args) {

// If tiles pending, display number in status bar
if (args > 0) {
window.status = "Pending map tiles: " + args.toString();
} else {
// All tiles loaded - hide status bar message
window.status = "";


Custom progress indicator

Finally, we look at how to completely replace the existing progress bar with a custom indicator. The steps are: (1) turn the standard progress bar off; (2) create our custom progress indicator; and (3) turn on and off our custom indicator using the onProgress event described earlier.

The best way to turn off the standard progress bar is to use the EnableProgressBar property on the ASP.NET Web control. You can set this in Visual Studio by switching the page to Design view, selecting the Map control, and setting EnableProgressBar to False in the Properties window. Or, you can scroll up in the Source view to the Map control and add the EnableProgressBar property there, like this:

<esri:Map ID="Map1" runat="server" Height="423px"  
MapResourceManager="MapResourceManager1" Width="554px"
EnableProgressBar="False" >

Second, we’ll create our custom progress indicator. This indicator can be as simple or complex as you wish. An animated GIF image is common, but you could write a custom indicator similar to the built-in progress bar, which uses multiple divs and styles to create an animation. For our example, we will use the ajax-loader-circle.gif image, which is included with several samples in the Web ADF developer samples, such as ArcGIS_Spatial_Query_SOE. We copied this gif into our Web application folder and added it into the .aspx page within a div. We set the style position of the div so that it is approximately centered on the map control. Of course you could add code to dynamically position the progress indicator over the map, such as by getting the map’s offsetLeft/offsetTop and setting the progress indicator’s style position (see the zip file for the sample for an example of this).

<div id="progressImageDiv" style="position:absolute;left:250px;top:320px;">
<img id="progressImg" src="ajax-loader-circle.gif" alt="Loading..." />

Third, to show and hide our custom progress indicator, we use the same approach with the onProgress event as above. If tiles are pending (args > 0), then we show the progress indicator; otherwise we hide the indicator. To show/hide the indicator, we could add code to get the indicator div and set its style.display property. But the Web ADF has built-in functions to show or hide a div section, which we will use instead: showLayer and hideLayer. The complete code, with both the custom progress indicator and status bar text, is shown below.

<div id="progressImageDiv" style="position:absolute;left:250px;top:320px;">
<img id="progressImg" src="ajax-loader-circle.gif" alt="Loading..." />

<script language="javascript" type="text/javascript">


function setupProgressIndicator() {

// Get the JavaScript map component
var map = $find('Map1');

// Add the custom progress function

// Custom progress function
// sender = map component, args = number of pending tiles
function showProgress(sender, args) {

var progressImageDiv = $get("progressImageDiv");

// If tiles pending, display progress indicator and tile number in status bar
if (args > 0) {
window.status = "Pending map tiles: " + args.toString();
progressImageDiv.style.display = "block";
} else {
// All tiles loaded - hide progress indicator and status bar message
window.status = "";
progressImageDiv.style.display = "none";


The code produces something like this when the progress indicator is displaying:

Customized progress bar

The complete code for this sample is available in this zip file. The code includes a few enhancements to the code above, such as an option to recenter the custom progress indicator if the map is resized, which may occur with the Web Mapping Application template. You can also try out this sample with the link provided.


We have seen how to customize the progress indicator for the map, both by setting properties of the standard progress bar and by adding our own custom event handling to display information or even a custom progress image. The map has other events and properties that you could use for performing custom handling on the client. See the Web ADF JavaScript Library reference in the Developer Help for further information.

Try the example application

Get the code

Contributed by Bryan Baker of the ArcGIS Server .NET software development team.

Posted in Services | Tagged , , , , | 5 Comments

Creating a DHTML scale bar with the .NET Web ADF

At the 9.3 release, the .Net Web ADF’s JavaScript library exposes a lot of logic to the client side, allowing you to create a more responsive UI without the need for making calls back to the server. You can get the Web ADF JavaScript library help on the ArcGIS Server Resource Center. This post will show you how to use the JavaScript library to create a pure client-side scale bar using the Microsoft AJAX Client Library patterns.

The Web ADF’s scale bar is generated by the primary map resource using a dynamically generated image. Since the scale potentially can change on every pan, the scale bar image has to be updated frequently, adding additional overhead to the server requests for rendering and fetching these images. Furthermore, if the primary map resource doesn’t support rendering a scale bar, no scale bar is available at all. ArcIMS ArcMap Services don’t support rendering a scale bar. The approach described in this post is the recommended pattern for displaying a scale bar for ArcIMS ArcMap Services.

We can scale a standard <div> box dynamically on the client using JavaScript, and completely eliminate the extra callback, because the map control allows you to listen for and get the current extent of the map. We simply add a handler to the Map’s ‘extentChanged’ event. To do this, we first get a reference to the map object using the $find method parsing in the ClientID of the map as a parameter:

var map = $find('Map1');

Next we add the handler which will be executed every time the extent of the map has changed:


However, we need to ensure that this handler is not created until the Map has been instantiated on the client. The Microsoft AJAX framework also exposes several life-cycle events, for listening when the page has been fully loaded. So we wrap the above code in an application init event handler and place it right before the </body> tag. Notice how the pattern for adding event handlers is similar to adding handlers to the map. The full example could look something like this:

<script type="text/javascript" language="javascript" >
	function myExtentChangedHandler(sender, args) {
		   alert(sender.get_id() + ' changed extent to: ' + args.current.toString());
	Sys.Application.add_init(function() {
		   var map = $find('Map1');

Every time you pan the map, you will see a popup window like this:

Message that appears on pan

This gives us the framework for creating a simple scale bar. The next step is to place a box on the page that we can use as a scale bar by changing the width as the pixel size changes.

<div><div id="scalebar" style="background-color: #000000; width: 200px; height: 10px;"></div><span id="scalebarText">100 units</span></div>

<script type="text/javascript" language="javascript" >

function resizeScalebar(sender, args) { //resize event handler
  var pixelSize = sender.get_pixelSize(); //Gets the size on one pixel in map units
  var scalebarWidthInMapUnits = 0.001; //The initial size of the scalebar in map units
  //width in pixels of a scalebar with the current
  //scalebarWidthInMapUnits value and map's pixelsize
  var width = scalebarWidthInMapUnits / pixelSize;
  while(width<20) {
    //keep increasing scalebar size until we have a reasonable and visible size
    scalebarWidthInMapUnits *= 10;
    width = scalebarWidthInMapUnits / pixelSize;
  $get('scalebar').style.width = width + 'px';
  $get('scalebarText').innerHTML = scalebarWidthInMapUnits + ' units';
//Hook up the handlers during init
Sys.Application.add_init(function() {
  var map = $find('Map1');
  map.add_extentChanged(resizeScalebar); //fired when extent has changed
  map.add_extentChanging(resizeScalebar); //fired while map is zooming/panning
  resizeScalebar(map,null); //Force initial update of scalebar


This will generate a very simple scale bar that looks something like this:

Simple scale bar

It will automatically adjust its width between 20 and 200 px and show the corresponding width in map units next to it.

The next step is to componentize this into a real client side control that can easily be reused. The Microsoft AJAX Client Library already has a framework in place for creating controls that can inherit from each other and be extended.

A component requires a constructor, and a prototype. In the constructor you define the default properties of the control, and in the prototype you define the properties and methods, including initialize and dispose. Lastly you register the control and optionally the type you derive from, in this case Sys.UI.Control.


ADF.Samples.DhtmlScaleBar = function(element) {
  ADF.Samples.DhtmlScaleBar.initializeBase(this, [element]);
  this._map = null; //Reference to the map
  this._minWidth = 20; //minimum width of the bar before changing units
ADF.Samples.DhtmlScaleBar.prototype = {
  initialize : function () {
    ADF.Samples.DhtmlScaleBar.callBaseMethod(this, 'initialize'); //Call base initialize
    if(this._map === null) { throw Error.argumentNull('map'); }
    this._extentChangedHandler = Function.createDelegate(this,this._updateScalebar);
    //Add listener for when the map is animating its extent
    //Add listener for when the map has changed its extent
    this._createBars(); // Creates the bar and text elements
    this._updateScalebar(this._map); //Update the scalebar now
  dispose : function() {
    ADF.Samples.DhtmlScaleBar.callBaseMethod(this, 'dispose');
    if(this._extentChangedHandler && this._map) {
    if(this._scaleBar) { this.get_element().removeNode(this._scaleBar);}
    if(this._scaleBarText) { this.get_element().removeNode(this._scaleBarText); }
    this._extentChangedHandler = null;
    this._map = null;
    this._scaleBar = null;
    this._scaleBarText = null;
  _createBars : function() { //Create the bar and text
    this._scaleBar = document.createElement('div');
    this._scaleBar.style.backgroundColor = '#000000';
    this._scaleBar.style.float = 'left';
    this._scaleBarText = document.createElement('span');
    this._scaleBarText.style.float = 'left';
  _updateScalebar : function(sender,args) {
    var pixelSize = sender.get_pixelSize(); //Gets the size of one pixel in map units
    var scalebarWidthInMapUnits = 0.001; //The initial size of the scalebar in map units
    //width in pixels of a scalebar with the current
    //scalebarWidthInMapUnits value and map's pixelsize
    var width = scalebarWidthInMapUnits / pixelSize;
    while(width<this._minWidth) {
      //keep increasing scalebar size until we have a reasonable and visible size
      scalebarWidthInMapUnits *= 10;
      width = scalebarWidthInMapUnits / pixelSize;
    this._scaleBar.style.width = width + 'px';
    this._scaleBarText.innerHTML = scalebarWidthInMapUnits + ' units';
  get_map : function() { return this._map; },
  set_map : function(value) { this._map = value; },
  get_minWidth : function() { return this._minWidth; },
  set_minWidth : function(value) { this._minWidth = value; }
//Register class:
ADF.Samples.DhtmlScaleBar.registerClass('ADF.Samples.DhtmlScaleBar', Sys.UI.Control);

If we add this script to the page, we can now simply create a scale bar using the $create method. The parameters are:

  • Type
  • Object list of properties
  • Object list of event handlers (we don’t have any events here so we use null)
  • Object list of component properties. In our case the map – this ensures that the scale bar is not initialized until the map has been initialized.


<div id="bar"></div>
<script type="text/javascript" language="javascript" >
Sys.Application.add_init(function() {

At our code gallery you can download the scale bar control. It has been expanded to look a little better than just a black bar, and it also has a server-side web control that renders the above script to the page. It will analyze the primary map resource and fetch the unit of the map, and allow you to convert it to any display unit you would like on the fly. Finally, there’s some extra logic which will get the scale bar to attempt to use some nice rounded intervals. The final result will look something like below, and will even resize while the zoom animation plays or while you pan toward the poles where the scale changes. You can style the control using the web control style properties like background color, border, font-size etc.

Final scale bar

Click here to get the source code from the Code Gallery

Click here to view a demo of the scale bar

Contributed by Morten Nielsen of the ArcGIS Server .NET software development team

Posted in Services | Tagged , , , | 1 Comment

Using Gears in a .NET Web ADF application

HTML 5 introduces offline storage support which allows the browser to serve up web pages and other data locally without having to access the Internet. Some newer browser versions (Safari 3.1/Firefox 3) offer built-in support for offline storage while other browsers can use Gears to enable local storage and access of code and data without Internet access. Originally released by Google, Gears is an open-source browser plug-in that supports Internet Explorer, Firefox and Safari. A growing number of online service providers offer web applications that leverage Gears to support offline functionality using a local data store, The list of providers and applications includes Google Docs, Google Reader, Zoho, Remember The Milk, and others.

In a web mapping application, leveraging offline storage may enable you to improve application performance. In almost every case, utilizing a local client data store is faster than retrieving data from a remote server. There are, however, limitations and synchronization issues which we’ll highlight later in this post.

The 9.3 .Net Web ADF JavaScript Library provides an extensibility point for leveraging offline storage capabilities with components such as the Map control.

The content of a basic web application can be categorized into two distinct areas:

  1. Application Framework – includes the web page hosting the controls, client side code (JavaScript runtime) and supporting media such as images and style sheets
  2. Data – information passed to and from the server and the client. This includes image tiles from a cached map service that are stored on the client.

In order to use an application offline, both the framework and relevant data need to be cached and available on the client.

The remainder of this post presents an overview of the steps involved in leveraging offline capabilities with a web application that contains Web ADF controls and accesses ArcGIS Server cached services. There are two important points to consider before proceeding:

  1. The web application needs a programmatic framework on the client to utilize offline storage. The Dojo Toolkit library offers a nice abstraction layer for browsers which do and do not have built-in support for offline storage. For example, when you access a web application in Firefox 3 the toolkit will use the native storage capabilities of the browser. However, if you access the same web application using Firefox 2 the toolkit will use the Gears plug-in (if installed) or degrade gracefully.
  2. Offline access to data is limited. For example, only data provided by the host server (e.g. URL from the same source as the application) can be cached locally. In the context of a web mapping application, you would be unable to cache a local copy of image tiles from a remote cached map service, such as ArcGIS Online. In order to work around this limitation you can use a server proxy. This workaround is discussed below.


Use the following steps to leverage offline storage with Web ADF controls and ArcGIS Server map services:

  1. Add a Map and a MapResourceManager control to the web page. Add one or more cached map service resources. Optionally add buddy controls such as the ZoomLevel, Navigation, Toolbar to the web page.
  2. Add the Dojo Toolkit script library to your website and add a script reference to dojo.js in your web page.

    <script type="text/javascript" src="javascript/dojotoolkit/dojo/dojo.js"></script>
  3. The Web ADF JavaScript Library defines a set of layer types which can be used to access map images. One such layer type is AdfTileDirectAccess which enables the client browser to access pre-generated, cached map tiles via a URL. Use client-side JavaScript to override the getTileUrl method on the AdfTileDirectAccess component, to change how it accesses cached map tiles. Add the following script block at the bottom of the page, after the closing form tag (</form>):

    function getTileUrlAndCacheLocally (column,row,level,handler) {            
    var func = this.get_tileUrlGeneratorFunction();
    var serverUrl = this.get_serverUrl();
    var url = func(level, column, row, serverUrl);
    try {
    ESRI.ADF.Layers.AdfTileDirectAccess.prototype.getTileUrl = getTileUrlAndCacheLocally;

    In a nutshell, the above code intercepts a call to a function that generates a URL to a map image tile, caches the resource locally using the Dojo Toolkit’s offline API, then delegates to the handler.

  4. Capture all files of the Application Framework into local storage when the application loads. To achieve this, define a list of necessary files and add all scripts and images on the page to the list. Then use the Dojo Toolkit to store these files for offline access.

    var filesToCapture = [ location.pathname,   'images/backward_disabled.png', 'images/forward_disabled.png' ];

    var scripts = document.getElementsByTagName("script");
    for(var i=0; i < scripts.length; i++) {
    if(scripts[i].src.length > 0 && scripts[i].src != '//:') {
    Array.add(filesToCapture, scripts[i].src);
    var images = document.getElementsByTagName("img");
    for(var j=0; j < images.length; j++) {
    Array.add(filesToCapture, images[j].src);

    dojo.forEach(filesToCapture, function(item) {

    Note: Since the Dojo Toolkit uses a dynamic loader for downloading scripts on demand, scripts that may be loaded while using the web application will need to be cached locally as well. This can be achieved by adding the known paths/URL to the filesToCapture variable.

Thus far the JavaScript customizations to client-side code present an offline solution that works for caching resources (data, scripts, etc.) from the same originating server. If map image tiles reside on a remote server, a server proxy should be used. As the name suggests, the purpose of the server proxy (tileserverproxy.ashx) is to intercept requests to remote servers from the client, change the request to the same server on which the web application resides, and return map tile content.

The handler would receive a set of input request parameters (server URL, tile level, column and row) and then forms a URL for the map tile based on ArcGIS Server tiling conventions. It then issues a web request for the tile and streams it back to the browser.

A set of changes are also required in JavaScript on the client. A check is made to see if the tile URL being requested is from the originating server or not. If the URL is from a different server, the request is passed to the tileserverproxy instead. In essence, this changes how the getTileUrl method operates on an AdfTileDirectAccess component.

if(isSameOrigin(serverUrl)) {
url = func(level, column, row, serverUrl, imgFormat);
else {
url = getServerProxyUrl(level, column, row, imgFormat, serverUrl);


After connecting to the website and browsing some tiles by navigating the map (zoom/pan), set your browser to work offline. In Internet Explorer or Firefox, you do this by navigating to File > Work Offline. (Note that if you disconnect from the network, you must still explicitly set your browser to work offline.) Now try accessing the same web page. You will notice a fully functioning page and you’ll be able to navigate to tiles that are already present in your local cache.


Any time there are multiple copies of data, synchronization issues will exist. In this case, the client machine has a local copy of the application and map tiles. This makes pushing updates to the client more difficult since the browser works with its local copy and does not query the online site for updates. If the application or map tiles do not change often, this may not pose a problem. However, if you regularly update the application functionality or map tiles, you will likely need to devise an update solution.

Some options include:

  1. Periodic polling to check for updates.
  2. Notify the client to clear the cache when updates are available.
  3. Add UI elements to explicitly clear the local cache


Contributed by Nikhil Shampur of the ArcGIS Server .Net software development team

Posted in Services | Tagged , , , | Leave a comment