Vishful thinking…

A better jQuery scale slider

Posted in Uncategorized by viswaug on November 10, 2008

I was looking to make the jQuery slider I had posted about earlier a little better. After a little bit of work and ‘leveraging‘ some code from this extension to the jQuery slider, I came up with the following.

Click here for the demo.

NewJQuerySlider

Advertisements

Form validation and processing with jQuery

Posted in Uncategorized by viswaug on November 10, 2008

Developing web mapping applications is uniquely different from most other web sites in the sense that the entire web application is just a single web page. The user never really leaves the map page and all the form validations and submissions happen through ajax. The map page will contain multiple forms that on submission do not post back their contents back to the server but just perform certain actions on the map. These actions could happen after performing an ajax request to the ArcGIS Server REST API or an ajax submission of the form contents.

jQuery and some of its plug-ins prove to be quite useful for performing some of these repetitive form validation and processing tasks. The two jQuery plug-ins that I use as a part of my toolkit are

jQuery Validation Plug-in

jQuery Form Plug-in

With help of jQuery, the above mentioned plug-ins and some CSS, I had built a small helper JavaScript class that helps me tackle the form scenarios on a map page rather effortlessly. There is plenty of documentation for jQuery and its validation and form plug-ins all around the Internet. But this FormHelper.js class just encapsulates some more of the repetitive tasks around them. The class takes in the following five possible parameters.

1) formID  (REQUIRED) – The ID of the HTML form element on the page

2) rules (REQUIRED) – NULL if no rules needs to be specified else pass the rules in the format accepted by the jQuery validation plug-in. More details on the format of the rules can be found here.

3) submitHandler (REQUIRED) – A callback function that will be called when the user clicks submit and the input values PASS the validations specified.

4) validationFailedHandler (OPTIONAL) –  A callback function that will be called when the user clicks submit and the input values FAIL validations specified.

5) ajaxFormOptions (OPTIONAL) – form options in the format accepted by the jQuery form plug-in. More details on the options for the jQuery form plug-in can be found here.

Here is the FormHelper in action. Obviously, the interface in the demo may not satisfy or work for all your requirements but it will get you started or might give you something to tweak around and achieve your desired interface.

FormValidation

Replacing the Dojo scale slider with the jQuery slider for the ESRI JS API

Posted in Uncategorized by viswaug on October 10, 2008

The Dojo slider widget that is used by the ESRI JS API gets rendered to the web page as table element. It is surprising that the Dojo would use the table element for layout purposes when rendering the scale slider. JQuery’s slider on the other hand uses DIVs and generates much cleaner HTML for it’s rendering purposes. The HTML page provided below replaces the Dojo Slider with jQuery’s slider.

Click here to see demo.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <title>jQuery Slider for the ESRI JS APIs</title>
        <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.1/js/dojo/dijit/themes/tundra/tundra.css" />
        <link rel="stylesheet" href="http://dev.jquery.com/view/tags/ui/latest/themes/flora/flora.all.css" type="text/css" media="screen" title="Flora (Default)" />
        <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.1"></script>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.2/jquery-ui.min.js"></script>
        <script type="text/javascript">
          dojo.require("esri.map");
          var map;
          var setupSlider = function(mapLoaded) {
              if (mapLoaded._baseLayer.tileInfo) {
                var lods = mapLoaded._baseLayer.tileInfo.lods;
                //initialize the scale slider
                $("#scaleSlider").slider({
                    min:0,
                    max:lods.length - 1,
                    slide: function(e, ui) { //the function that handles the event when the user uses the slider and changes the map extent
                        map.setLevel(ui.value);
                    }
                    });
                //hook up the listener to listen to the scale changes on the map and updates the slider accordingly
                dojo.connect(mapLoaded, "onExtentChange", function(extent, delta, levelChange, lod){
                    if(levelChange) {
                        $("#scaleSlider").slider("moveTo", mapLoaded.getLevel(), 0)
                    }
                });
                $("#scaleSlider").slider("moveTo", mapLoaded.getLevel(), 0);
            }
            else {
                $("#scaleSlider").hide();
            }
          };
          var init = function() {
            map = new esri.Map("map", {slider:false});
            var tiledMapServiceLayer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer");
            map.addLayer(tiledMapServiceLayer);
            dojo.connect(map, "onLoad", setupSlider)
          };
          dojo.addOnLoad(init);
        </script>
    </head>
    <body class="tundra">
        <div id="map" style="position:relative; width:900px; height:600px; border:1px solid #000;">
            <div id='scaleSlider' class='ui-slider-1' style="position:absolute; right:5px; bottom:5px; color:#fff; z-index:50;">
                <div id="scaleSliderHandle" class='ui-slider-handle'></div>
            </div>
        </div>
    </body>
</html>

And that’s it. The jQuery slider works seamlessly with the ESRI JS API map. The slider currently positioned at the bottom right of the map. But it can be positioned as desired and also can be used with a vertical orientation like with the default slider.

A handy tool for OpenLayers enthusiasts – OpenLayers Architect

Posted in Uncategorized by viswaug on September 22, 2008

I stumbled upon this cool tool called “OpenLayers Architect” that lets you build your map page by letting you add and manage the layers that will be displayed in the map. A real handy tool for ‘visual’ people like me. Lets you manage the layer settings through a dialog like below and lets you do a whole bunch other stuff. I don’t think it is robust yet but I think it is a cool concept. A step closer towards ArcMAP for the web…

LayerSettings

Hopefully, ESRI can build such a tool for their JS APIs in the future…

A better way to read ArcGIS Server logs…and some weird errors being logged

Posted in Uncategorized by viswaug on September 14, 2008

The logs generated by ArcGIS Server come in real handy sometimes when trying to troubleshoot some problems with the server. Also, if you are developer creating custom “Sever Object Extensions (SOE)“, the “ILogSupport” interface provides the facility to add your own custom messages to the ArcGIS Server logs. Since, there is no way to debug the Server Object Extensions (at least I don’t know of any), logging messages from inside the SOE is crucial to be able to debug and troubleshoot the Server Object Extensions both during its development and also after deployment. Viewing the ArcGIS Server log file always used to be a pain in the ‘you know where’ since it was just a huge and constantly growing text file. I used to be using my favorite text editor Notepad++ to read the log file which notified me when the log file changes and updates it automatically. But still that only went so far to take the pain out of viewing the logs. Here is some information that will enable you understand the ArcGIS Server logs better.

Log Codes Overview

Core Server Log Codes

Map Service Log Codes

The ArcGIS Server log file can be found under the “C:\program files\arcgis\server\user\log” directory. A new log file is created whenever the ArcSOM service is restarted.

Recently, I came across an utility called “BareTail” (yeah, I know what you are thinking…snap out of it) that made reading the ArcGIS Server log files a lot less painful. They do have a free version of the software that can be downloaded from here. The utility can open large text files (> 2GB) and tracks the end of the file constantly thus eliminating the need to constantly scroll all the time. The utility also has a really cool feature where it highlights lines containing specific words with a specified color. This is a great feature for the ArcGIS Server log files since every log file entry contains a string representing the TYPE of the log message. The different types of ArcGIS Server log messages are:

ERROR
WARNING
INFO
DETAILED
DEBUG

This TYPE string in the log message, allows us to highlight the lines in the log file with different colors are shown below. This lets the ArcGIS Server logs to be read so much easier.

CropperCapture[18]

CropperCapture[21]

I have saved the color scheme shown above into a configuration file. The configuration file can be downloaded from here. You can import the color scheme directly into your BareTail install and set it to be the default.

Being able to read the log files this clearly allowed me to notice errors being logged that I would have never noticed before. For instance, I noticed that every time I previewed a non-cached MapService in ArcCatalog, a “Method Failed.” ERROR (See Below) was being logged when the “MapServer.GetTileCacheInfo” was called. I don’t think calling the “MapServer.GetTileCacheInfo”method for a non-cached MapService should fail and be logged as an ERROR. Not quite sure why this happens on my server but it doesn’t make me feel good about it.

<Msg time=’2008-09-13T17:38:37′ type=’ERROR’ code=’100005′ target=’TalonMap.MapServer’ methodName=’MapServer.GetTileCacheInfo’ machine=’Talon’ process=’2832′ thread=’2908′ elapsed=’0.00019′>Method failed.HRESULT = 0x80004005 : Unspecified error  .</Msg>

BareTail is also a great tool for viewing other log files. If you are using Log4NET to create logs in your applications, BareTail will come in real handy for viewing those log files also. I will actually be using Log4NET to log messages from my Server Object Extensions instead of using the ArcGIS Server log files which will allow me to concentrate only on the messages logged by my component.

Tagged with: , ,

System.Drawing.Imaging Namespace

Posted in Uncategorized by viswaug on September 11, 2008

I was really taken aback today when I read that Microsoft does not support the use of the “System.Drawing.Imaging” Namespace within a windows or ASP.NET service. I have never had a problem with it when I have used it before and don’t expect to have a problem with it. But it is surprising that Microsoft doesn’t support it. Just thought some others might have the same reaction to it as I did…

Why is it important to follow RESTful principles when developing a REST API

Posted in Uncategorized by viswaug on September 8, 2008

When developing a RESTful API, it is important to follow the REST principles as much as possible. Sometimes it may not be apparent as to why, hopefully the following will illustrate the importance of following the REST principles. The web by itself is RESTful, REST treats everything as a resource and it has set of verbs or HTTP methods mapped to the operations that can be performed on resources.

Fetch the resource – HTTP GET
Insert a new resource – HTTP POST
Update a resource – HTTP PUT
Delete a resource – HTTP DELETE

And when you are writing your own REST API to perform one of the above operations on a resource, it is good practice to always to use the corresponding HTTP method to do so. Why is this important and when will you run into problems following the above principle? Well, let’s say that you have a HTTP GET URL endpoint that takes an identifier for a resources and actually deletes the resource instead of just fetching it. I can’t remember which one but one of the wiki implementations out there had beed doing the same where they were deleting web pages in the wiki when a HTTP GET request was made to an URL. And one fine night, the “GoogleBot” (Google’s web spider or crawler) came along and started making HTTP GET requests to that URL hoping to index the resource at that URL. This resulted in most of the web pages in the wiki being deleted and in a huge loss of information. So, your REST API will also be susceptible to such disasters if the REST principles are not followed strictly.

Following the REST principle, might be a problem when you need to send in a lot of information in the query string of the HTTP GET URL. For example, if you want to be able to fetch all the parcels inside a polygon, a representation of the polygon needs to be passed into the HTTP URL GET endpoint to be able to perform the query. In these cases, the length of the URL could become a problem. Normally, it is not a good idea to let the length of your URL exceed 1024. A lot of organizations might restrict the length of the URLs by using tools like UrlScan (this feature is built right into IIS 7.0). In these cases, you might have to end up POSTing the information to the URL, or in other words using a HTTP POST instead of HTTP GET. Actually, this is exactly what the ESRI REST API does. The JS API actually examines the length of the URL and if the length is larger than a certain number (the default is 2000), they POST the information to REST server instead of using GET(via a proxy, which i will write about soon). The ArcGIS REST server actually accepts both GETs and POSTs at the same URL endpoint since they are implemented as HTTPHandlers. Currently, the REST support in WCF does not allow the developer to accept both GETs and POSTs at the same URL endpoint.

When a different HTTP method is being used instead of the correct method, it is a good practice to do so while also adding the “X-HTTP-Method-Override" header to the HTTP request. Here is how Google uses this technique to get past some restrictive firewalls.

Why is a HTTP GET better than a HTTP POST? Well, your browser only caches the outputs from HTTP GET requests and never from a HTTP POST request. And the developer can gain control over how long the browser cache will be valid by setting the “Cache-Control” and the “Expires” headers in the HTTP response.

Updated post with the correct HTTP method operation after Sean Gillies pointed it out.

Tagged with: ,

Missing features in the ESRI JS API v1.1

Posted in Uncategorized by viswaug on September 7, 2008

As I am in the process of building my current project using the ESRI JS API v1.1, I am beginning to come across some of the currently missing features in JS API and the REST API that in my opinion are required to build any enterprise GIS web mapping application. We are currently in the process of filling in those holes by building the missing functionality ourselves. So, if you are just considering the JS API for your projects, take the following into consideration.

1) The REST API currently does not provide the MIN and MAX extent information for scale dependent layer visibility. This will be needed to build a Table of Contents for the map where the layers that are not visible at the current scale can be greyed out.

2) The REST API currently also does not provide the swatch image information that will be required to build the Table of Contents. Both the MIN & MAX extent information and the swatch images are available in the SOAP API, so building a REST service to provide these missing information shouldn’t be difficult. The fact that the missing information in available in the SOAP API is important because it will allow the Table of Contents to be populated even when the user adds a map service from an external URL dynamically.

3) The JS API currently does not allow the user to zoom or pan when the user is in the process of drawing a point, polyline or polygon feature.

4) The JS API currently does not allow the user to add or edit vertices in an existing feature. This feature might be available in the future versions of the JS API.

5) The JS API currently does not document how to build custom layer types to add to the map like ArcIMS or WMS layers etc. But I think the documentation and samples to do this is coming in the future versions. Hopefully v1.2…

6) I am not quite sure about the client-side graphics layers performance yet. If you are using the client-side graphics layer for displaying the selection set, then having 10 polygons each with a 1000 vertices selected could significantly affect the drawing performance of the graphics layer. Leveraging the server-side graphics layer for this circumstance would be ideal, but this is currently not possible with the JS API. But with some work, leveraging the server-side graphics layer in the JS API is possible.

Disabling REST and SOAP services in ArcGIS Server 9.3

Posted in Uncategorized by viswaug on August 28, 2008

The REST (Representational State Transfer) interface to ArcGIS Server was something that was added new in 9.3. But the SOAP interface to ArcGIS Server was available in the 9.2 versions and helped developers avoid the pitfalls of the Web ADF in 9.2. The WSDL for the SOAP services could be accessed at

http://MachineName/arcgis/services/MapServiceName/MapServer?wsdl

And the REST services could be accessed at

http://MachineName/arcgis/services/MapServiceName/MapServer (html)

or

http://MachineName/arcgis/services/MapServiceName/MapServer?f=json&pretty=true (json)

The SOAP access to services hosted by ArcGIS Server can be disabled through ArcCatalog. The following screenshots show how that can be done.

CropperCapture[14]

or

CropperCapture[11]

The REST service keeps chugging along even when the SOAP service is disabled. The “Services Directory” (available at http://MachineName/arcgis/services/MapServiceName/MapServers) entry for the map service still displays a link to the SOAP interface as shown below. But the link will be broken and you will receive an HTTP 404 error if you try to access the WSDL with the SOAP services disabled. The link displayed here seems to be constructed from the “SoapUrl” element value in the “C:\inetpub\wwwroot\ArcGIS\rest\rest.config” file.

CropperCapture[15]

The URL to the SOAP endpoint is not available in the JSON output from http://MachineName/arcgis/services/MapServiceName/MapServer?f=json&pretty=true. That would have been handy.

I haven’t come across any documented way of turning off the REST web services. But this can be done pretty easily by taking advantage of one of the lesser known ASP.NET 2.0 features and creating an empty file called “App_Offline.htm” file in the “C:\inetpub\wwwroot\ArcGIS\rest” directory. Creating the empty in that directory should disable the REST services while still having ArcGIS and the SOAP interfaces running.

ESRI REST URLs – Gotcha

Posted in Uncategorized by viswaug on August 27, 2008

We noticed this behavior with the ESRI REST API URLs today during one of our discussions in the office today. Normally the ESRI REST URLs look this way

 http://MachineName/ArcGIS/rest/services/MapServiceName/MapServer

In the above URL, the mapserver name is not case-sensitive. That is, the URLs below will work just fine.

 http://MachineName/ArcGIS/rest/services/MapServicename/MapServer

http://MachineName/ArcGIS/rest/services/mapservicename/MapServer

But note that in ArcGIS server, you can organize your MapServices in folders. Although, you cannot have folders inside folders. For the MapServices in the folders, the REST URL look like below. Where the URL includes the folder name before the MapService name.

 http://MachineName/ArcGIS/rest/services/FolderName/MapServiceName/MapServer

But the weird part is that the name of the folder in the above URL IS case-sensitive. That is, the URLs below will not work.

 http://MachineName/ArcGIS/rest/services/Foldername/MapServiceName/MapServer

http://MachineName/ArcGIS/rest/services/foldername/MapServiceName/MapServer

Hopefully, this inconsistent behavior is an oversight and ESRI would get around to fixing it in the coming versions.