Monthly Archives: May 2008

ArcGIS Server 9.3 First Looks, Part 2: Virtual Earth Adapter

We are using the Virtual Earth Tile Server that Dave Bouwman created which publishes tiles from ArcGIS Server services to Virtual Earth. It is a danged neato peace of software, and combined with the ArcDeveloper REST API, gives us a great option for exposing ArcGIS Server services. In fact, it’s such a great option that ESRI has made it a core offering, providing adapters for Google Maps and Virtual Earth along with the new REST API at 9.3. This post focuses on the Virtual Earth adapter, although I am guessing it is not functionally different from the Google Maps adapter.

When I heard about the javascript and REST APIs coming in 9.3, I was very excited. I proclaimed the end of all pain in the GIS nerd world, just knowing that these new offerings would not only make my applications better, but they would make me a better person. They would help me easily query my GIS data and teach my kids right from wrong.

My expectations may have been a bit too high.

Here are some things that I didn’t know about the VE Adapter. They may be obvious to some, but I was mildly surprised to hear them:

  • You HAVE to use a tile cache to use the VE adapter. Yes, I know it isn’t that surprising, but I had some hope that we could display live services. Yes, I know it would be slow, but sometimes hope blinds a man…
  • You HAVE to use the WGS84 Web Mercator GCS, which is not a requirement of Dave B’s tile server (score one for Dave, open source, and little people everywhere)
  • The ArcGIS Server REST API supports JSONP out-of-the-box. All you have to do is add a ‘callback’ parameter to your querystring and it’ll return the JSON all nicely wrapped in the javascript function you specify. That is very, very nice.

You can use the ‘cache-on-demand’ feature, which is a godsend to those of us who have watched cache generation processes leak into 3 weeks.

So, real quick like, I’ll crank out some code that shows you to query the REST API to get all the available map services, add them to your page. Then, just because I am freaking crazy, we’ll add the ability to toggle the tile layers on/off on your VE map.

Setup

First, get ArcGIS Server 9.3. Then, publish a couple of map services per the requirements of using the VE adapter. I mention most of it above, but here it is from the horse’s mouth. Oh, and it’ll help if the map services have data from the same area.

Make a VE Map

Create an HTML file (doesn’t even have to be served by a web server, since we’re all in javascript) and put in the base structure for a map. Something like:


<html>
<head>
<!-- Virtual Earth API -->
<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6" type="text/javascript"></script>
<!-- ESRI VE ADapter -->
<script src="http://serverapi.arcgisonline.com/jsapi/ve/?v=1" type="text/javascript"><!--mce:1--></script>
<!-- DOJO from AOL CDN -->
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js"></script>

<script language="javascript" type="text/javascript" >
 var map = null;
 var layerFactory;
 function OnPageLoad() {
            var centerat = new VELatLong(45.5852, -122.5951); //Replace this with your center
            map = new VEMap('mymap');
            map.LoadMap(centerat,12,VEMapStyle.Aerial ,false);
	    layerFactory= new ESRI.ArcGIS.VE.ArcGISLayerFactory();
 }
 dojo.addOnLoad(OnPageLoad);
</script>

<body>
  <div id='mymap' style="position:relative;height:400px;width:600px;float:left;"></div>
  <ul id="services"></ul></body>
</html>

So, a couple of quick comments about this “base” VE map. I have added the script tags to pull in the ESRI VE adapter, as well as Dojo. I am gonna use Dojo for this example because it makes querying a cross-domain REST service easy as 1,2,3. It is likely that your AGS installation will not be on the same server or in the same domain as your web server, so it is nice that AGS 9.3 has JSONP baked right in. Also, in the above code, I create a ESRI layer factory, which is an object that creates tile specifications for Virtual Earth. Finally, I add an unordered list (ul) that will eventually hold my services.

Ideally, we’d like to boogie out and get the list of services that are currently being published by AGS when the page loads. So, lets add a getServices() method and call it from our OnPageLoad…shall we?


var AGS_SERVER="http://yourserver/arcgis/rest/services";

function getServices(){
        dojo.io.script.get({
                url:AGS_SERVER,
                content:{
                    f:'json'
                },
                load:function(resp){
                    services=resp.services; // Automatically deserialized by dojo.  Thanks!
                    var ulServ=dojo.byId('services');
                    dojo.forEach(services,function(s){

                            if (s.type=="MapServer"){
                                var li = document.createElement("ul");
                                li.innerHTML=s.name;
                                ulServ.appendChild(li);
                                dojo.connect(li,"onclick",dojo.hitch(li,serviceClick));
                            }
                    }
                    );

                },
                callbackParamName:'callback'

        });

    }

Here is where using Dojo (or any javascript framework that will handle JSONP requests easily) really pays off. The getServices method is simply issuing an AJAX request to our AGS REST Service Catalog. The response is automatically deserialized into JSON and fed to our ‘load’ function. The load function then loops over each service (the response has folders in it too, but we are ignoring those today) and adds a list item to our services list for each MapServer. A click handler is added to each list item to call our serviceClick function (we haven’t added that yet). Side note: Using dojo.hitch here forces the serviceClick method to be called in the context of the list item that is clicked. In other words, when serviceClick is called, the ‘this’ keyword will refer to the list item. A whole lotta stuff happening on one line of code, which is one place where I think Dojo shines.

So, let’s quickly add the serviceClick (and some other) function:


function serviceClick(){
        var lyr= map.GetTileLayerByID(this.innerHTML);
        if (lyr==null)
        {
            addLayer(this.innerHTML);
        }
        else
        {
            toggleLayer(this.innerHTML);
        }

    }
    function addLayer(lyrName){

        layerFactory.CreateLayer(AGS_SERVER+"/"+lyrName+"/MapServer", lyrName,GetMap);

    }
    function toggleLayer(lyrName){

        var lyr=map.GetTileLayerByID(lyrName);
        if (lyr.IsVisible)
            map.HideTileLayer(lyrName);
        else
            map.ShowTileLayer(lyrName);

    }
    function GetMap(tileSourceSpec, resourceInfo) {

        map.AddTileLayer(tileSourceSpec,true);

    }

So, the serviceClick function gets the innerHTML from the list item clicked, which in this case is the name of the AGS service. It then checks our Virtual Earth map to see if that layer has been added. If the layer has not been added, we use the layer factory created on page load to create a tile specification for that service. The layer factory actually issues an AJAX request, which is why we have to specify a callback method (GetMap). GetMap adds the created tile spec to the map, and our layer is visible. Clicking on the service name in the list again will toggle that layer off. So, with very little code, we’ve created a pretty functional map with a nice VE interface and a poor man’s table-of-contents. Not bad for a few minutes work.

As usual, this post has gone on longer than I’d hoped.  If you want the not-split-up-by-the-blog-post HTML file, just drop me a comment.  Also, drop a comment if you have a question or think I am wrong/high/crazy.

Advertisements

ArcGIS Server 9.3 REST API First Looks, Part 1

Esri-logoImage via Wikipedia

You may (or may not) know that I am one of the authors of the ArcDeveloper REST API, which is an open source REST API for ArcGIS Server that can be used against ArcGIS Server (AGS) 9.2, right now, free to all comers, no waiting, etc.  If you know that, you probably know that ESRI is releasing it’s own REST API for AGS at 9.3, due out later this year.  So, I thought I’d take a few posts to show you how the REST API (in beta) is looking.  For the impatient, it looks great.  For others that may not have the beta, read on.

So, first off, we are just gonna check out the very basics of the REST API.  When you install 9.3, there is no real indication of anything all that different.  The AGS Service Properties dialogs look (basically) the same, except for some (hugely exciting, but beyond the scope of this article) changes to the Caching tab.  The real excitement comes when you start messing around with URLs against your map server.  BTW, I am using Fiddler2 with the JSON Viewer plug-in to send requests to the server and look at the results.

AGS 9.0 and later have always exposed a SOAP endpoint for each service it publishes as well as service catalog.  There is a whole SOAP API, which is my preferred method to interact with AGS services, and the URL to the SOAP service catalog looks like:

http://server/arcgis/services

Following this pattern, the REST API brings along a similar service catalog endpoint:

http://server/arcgis/rest/services

The new-kid-on-the-block REST URL is even cooler, though, as it formats the results into a cool “ArcGIS Service Explorer” that looks like:

ArcGIS Services Explorer at 9.3

Which allows you to look at metadata about your services, view them in Google Earth (how cool is that?), ArcMap, ArcGIS Explorer, or the new ArcGIS Javascript API (a subject of posts to come).  Also, you can drill-down into your service and get layer info, spatial reference, unit info, and tiling information.  In fact, on the tiling information, you can actually LOOK at some of the tiles.  Other information includes supported operations that you can execute within the Explorer, like Export Map or Identify.  Here’s a picture of the service page:

Tons of info right out of the box.

Another item the Service page has is a “Supported Interfaces” section, which I would call supported formats.   The ones listed out of the box are REST and SOAP.  Clicking on the REST link will give you all (well, most of) the information just mentioned, but in JSON format .   Here, lemme show you:

Fiddler (w/JSON Viewer) display of REST GET Request of AGS

The only difference between the URL to get to the cool HTML Services Explorer page and the URL that spits out JSON is the addition of a ‘f’ (for ‘format’) querystring parameter, like so:

http://server/arcgis/rest/services/ServiceName/MapServer?f=json

MMMMM….now, THAT’s some good REST.

There is similar love for supported operations, allowing you to crank out a quick image or perform a Find and look at the results.   Also, the (impressively comprehensive) API reference is linked on the Services Explorer pages, which, oh by-the-way, takes you here.

Finally, the last thing I want to cover in this post is the REST admin inteface.  If you go to the following URL in your browser:

http://server/arcgis/rest/admin

you’ll be hit with a login screen for the ArcGIS REST API Admin application.  It’s pretty sparse right now, not even meriting a screen shot.  Currently, you can use the admin site to tell AGS when to recycle the cached service responses and to turn on the REST Services Catalog.  Now, that second option was nowhere to be found in my admin app, but the docs assure me it’s there.

So far, the only disappointment I have had is that ESRI has chosen not to use GeoJSON as their format to return features in (or, for that matter, even as an option).  I don’t profess to know why, but I’ll try to float that to one of my contacts on the mother ship soon.

Summing up, the AGS REST API looks great before you even show a map on a site.  I am hoping to go that in future posts.


Got (Remember the) Milk?

Remember the Milk syncs with WM5Image by digitalsean via Flickr

I am, how you say, not very organized. I have tried billions of approaches of keeping task lists and to-dos that range from simply using Outlook to writing everything down on paper everyday. I have used Backpack (which is very nice, and I still use it for other things) but the reminders were too general. In all cases, the problem is never the system, but always the user. If I kept my tasks in Outlook, then I couldn’t get to them when I was reading my GMail account or if I use Backpack reminders, I had to have a window to Backpack open while doing other things. As it turns out, if it was even remotely awkward or required me to put forth any more effort than simply recording the task, then i didn’t do it.

My latest approach is Remember The Milk. RTM is an online task list service that focuses ONLY on managing your tasks. Being very Web 2.0y, it has an API, which means third party apps already abound. For example, RTM has a Mac OSX dashboard widget, a Quicksliver plugin, Twitter integration (supremely cool), GMail integration (finally, tasks with my GMail done right), and a Firefox extension. The pro version (a very reasonable $25/year) offers up integration with Windows Mobile, Blackberry, and iPhone/iPod Touch. You can also expose your tasks as an ICS feed and pull them into any calendar that supports it. For me, what this means is that wherever I am working, I am looking at the same task list. If I enter a task in Outlook while at work, I can mark it completed from the iPod Touch during my kid’s swim practice.  Also, RTM works with Google Gears, so offline access is already there (Gears doesn’t support Safari yet, but that is coming…)

The tasks can be tagged (duh), arranged in lists, given a URL, duration, priority, due date, and (most righteously) a location. Now, I can look at a Google Map with my tasks on it. For example, some of my locations are Home, Harris Teeter (a grocery store), and Costco (a bulk grocery), allowing me to make Smart Lists where I split the list by location. You can publish lists to the world, email lists to your Inbox (or any other list) so my wife can give me my HoneyDo list is a way that makes my Nerd Muscle twitch with delight.

All in all, I am very encouraged by RTM and its offerings. I highly recommend that anyone who is as task-tarded as I am check it out.

Other RTM Resources