Welcome to ESRI Blogs

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.

Steps

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 {
    dojox.off.files.cache(url);
    dojox.off.sync.synchronize();
    handler(url);
    }
    catch(e){handler(url);}
    };
    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);
    }

    dojox.off.files.slurp();
    dojo.forEach(filesToCapture, function(item) {
    dojox.off.files.cache(item);
    dojox.off.sync.synchronize();
    });

    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);
}

Example

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.

Limitations

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

    dojox.off.files.remove(url);

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

Published Friday, October 10, 2008 12:28 PM by sterlingdq
Filed under: , , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Using Gears in a .NET Web ADF application

Can something similar be done using Silverlight?
Wednesday, October 29, 2008 11:35 AM by Colin Blair

Leave a Comment

(required) 
required 
(required)