Poking at ESRI's Public ArcWeb Services
In the wake of Google's mapping API release, ESRI has opened up some of its SOAP-based web services for limited public use to see if they can lure in the map hackers. I played around with a trial subscription to ArcWeb services two years ago, and this seemed a good opportunity to dust off the old code and try again with the public services.
As before I'm using ZSI, the Zolera SOAP Infrastructure for Python. Happily, it's improved, and now features generation of service stubs and types from WSDL. Two years ago I was faced with implementing my own ArcWeb types. Now I can use ZSI's wsdl2py.py script to generate type and client stub modules from the ESRI authentication and map image WSDL URLs, which allows me to abandon my earlier code and start fresh:
$ wsdl2py.py -u https://arcweb.esri.com/services/v2/Authentication.wsdl $ wsdl2py.py -u https://arcweb.esri.com/services/v2/MapImage.wsdl
resulting in the creation of three files:
$ ls *.py Authentication_services.py MapImage_services.py MapImage_services_types.py
Following the example, I quickly coded up a request for an authenticated token using my existing ESRI global account:
import sys # modules generated by wsdl2py from Authentication_services import * opts = {'tracefile': sys.stdout} # Auth service auth_loc = AuthenticationLocator() auth_serv = auth_loc.getIAuthentication(**opts) # Get a token tok_req = getToken1InWrapper() tok_req._username = '******' tok_req._password = '******' tok_resp = auth_serv.getToken(tok_req) token_ustr = tok_resp._Result
and was informed that I could not use the public services with this account because I had an expired non-public subscription. Annoying, this was, and seems to support James Fee's contention that the public service release caught ESRI itself off-guard. So I marched through the ESRI account drill again, and continued on. The following code gets a token and uses it to make the simplest possible request for a map image and print the resulting map image URL:
## awmap.py import sys # modules generated by wsdl2py from Authentication_services import * from MapImage_services import * opts = {'tracefile': sys.stdout} def set_map_extent(o, e): o.Set_minx(e['minx']) o.Set_miny(e['miny']) o.Set_maxx(e['maxx']) o.Set_maxy(e['maxy']) def set_map_size(o, s): o.Set_width(s[0]) o.Set_height(s[1]) # extent and datasource extent = {'minx': -105.14, 'miny': 40.53, 'maxx': -105.04, 'maxy': 40.63} size = [400, 400] datasource = 'GDT.Streets.US' def main(): # Auth service auth_loc = AuthenticationLocator() auth_serv = auth_loc.getIAuthentication() # get a token tok_req = getToken1InWrapper() tok_req._username = '******' tok_req._password = '******' tok_resp = auth_serv.getToken(tok_req) token_ustr = tok_resp._Result # map service implementation map_loc = MapImageLocator() map_serv = map_loc.getIMapImage() # get map image url map_req = getMap0InWrapper() map_req._token = token_ustr map_req._mapExtent = ns4.Envelope_Def() set_map_extent(map_req._mapExtent, extent) map_req._mapImageOptions = ns5.MapImageOptions_Def() map_req._mapImageOptions._dataSource = datasource map_resp = map_serv.getMap(map_req) print map_resp._Result._mapUrl if __name__ == '__main__': main()
Running the script:
$ [sean@lenny arcweb]$ python awmap.py http://redlandsarcweb.esri.com/out/maps/GDT_ArcWeb_US_2_blackmap2248241332.png
Produced the following image at the URL:
In my opinion, ESRI needs to make some cosmetic improvements to its default map if it is going to catch on with web designers and programmers. I know for a fact that the software behind the service allows for great looking maps, so let's see some fine cartography in this default map. This is the first look that many people will have of the public ESRI maps, so it must look sharp.
This exercise increases my fondness for SOAP very little, but ZSI makes using services such as these a fairly painless task for an intermediate Python programmer.