GML in Wikipedia

How does a programmer get on the GML train? I was asked this question yesterday, and didn't have a satisfactory answer. The specification is not the place to start, a book takes a few days to arrive in your hands, and articles on the web are mainly aimed at managers. Today I was clued in to Ron Lake's brand new Wikipedia GML pages. This is where to begin.

Django and MapServer

One problem that new Python MapScript users immediately run into is the choice of web framework; Python is blessed (or afflicted) with a multitude. I think these users owe it to themselves to check out what Adrian Holovaty has been doing on chicagocrime.org using Django.

I'm still up to my ears in Zope 2 projects through the end of this summer, but will be trying out Django as soon as possible.

Image Server and GDAL?

An All Points Blog post from the ESRI UC blurted (no less than four exclaimation marks) that the new Image Server is using GDAL.

accepts many formats (1 to 32 bits per channel) tif, geotif jpg, lzw packbit flat, scanline, tiled (optimal)

bil, bsq, bip jp2000, mrsid, ecw nitf, hda img(GDAL) (USES GDAL [open source library for imagery - Ed.] INTERNALLY TO DO THE TRANSLATIONS!!!!) sde raster oracle georaster

This is not something than can be confirmed by Googling for Image (or Prompt) Server and GDAL. Is it rumor or truth? As a GDAL user, I sincerely hope for the latter; the more use GDAL gets from the bigs, the better it will become.

What, no Lisp?

Rosso is drawing the line with Python. Ruby and Javascript examples will probably appear somewhere soon, if they haven't already. I appreciate Rosso's explanation of the need for a new account to use the public services, and am amused to find that our particular producer/consumer roles extend into the wine world as well, though I must say that my tastes run more towards the Rhone than to Napa.

GIS in the Rockies

Next month I'll be at GIS in the Rockies, conducting a presentation/workshop entitled Data Processing and Mapping with Python: Open Source and Open Standards in the conference's Emerging Standards track. I'm pleased to have been invited to talk about the projects that we're working on in the Open Source GIS community, and show off some specific Python applications. Contents include:

  • Overview of open source GIS projects.

  • Vector and raster processing with GDAL, GEOS, and Python.

  • Introduction to PostGIS and the Python DB API.

  • Providing and consuming web map and feature services using MapServer and the Python mapscript module.

This won't be hands-on like the workshop Hobu and I ran at OSG05, but will be similarly aimed at programmer/analysts and their managers, with many scripting examples that can be brought back for immediate use in the shop.

While not strictly open, ArcWeb services are technology that some attendees will want to see covered, and so I'll work my previous ZSI and ArcWeb exercise into the mix. Using Python for ArcGIS geoprocessing is, however, outside the scope of this presentation.

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:

/files/GDT_ArcWeb_US_2_pimap257553707.png

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.

Cheapo WFS and uDig

/files/wfs_and_udig_tn.png

It's been a while, but I have finally made the time to upgrade my Cheapo WFS so that it can feed [screenshot] uDig, Refractions' new desktop GIS app.

I found the oXygen XML editor to be a handy program for finding bugs in my capabilities document. I'm only demo-ing oXygen now but might spring for it if it's equally useful with WMS and SLD. Getting my data into uDig was mostly a matter of tweaking the WFS response and schema into a form that GeoTools would accept. Evidentally, members is not a good typename no matter the namespace.

The service root is

http://sgillies.net:9001/mapserver/members/

and the online resource URL for capabilities, which you may enter in uDig's WFS data source wizard, is

http://sgillies.net:9001/mapserver/members/capabilities.rpy?request=GetCapabilities

MapServer users will need to adjust to the change in the typename, using the following layer definition:

LAYER
   NAME "members"
   TYPE POINT
   STATUS DEFAULT
   CONNECTIONTYPE WFS
   CONNECTION "http://sgillies.net:9001/mapserver/members/features.rpy?"
   METADATA
     "wfs_service" "WFS"
     "wfs_typename" "users"
     "wfs_version" "1.0.0"
   END
   LABELITEM "zco:fullname"
   PROJECTION "+init=epsg:4326" END
END

Back to the Future

David Maguire has a preview of ESRI's "new" type of image server. Raw imagery in the filesystem rather than RDBMS, on-the-fly image processing: these are great features that MapServer users have enjoyed for 5+ years. Storing massive raster datasets in an RDBMS was always a bit of a boondoggle.