Atompub and KML Demo

Update (2009-05-20): Hammock has been retired, replaced since December 2007 by Knowhere.

I have repurposed my Hammock application into a demonstration of the Atompub, KML, and Google Earth integration. Now, from an Atom perspective there is a service document and one collection at:

http://sgillies.net/hammock/index.atom

http://sgillies.net/hammock/places/

Subscribe to that second URL, it's an Atom feed. Any newsreader should be able to use it to monitor changes to the collection. Next, start Google Earth and in your temporary places container create a new network link to this URL:

http://sgillies.net/hammock/places.kml

The same (very simplistic) data model supports both the Atom feed and the KML document.

Ready to publish data to the Web, Atompub-style? All you need is a terminal, curl or another moderately sophisticated HTTP client, and a little make-believe. Imagine that Google Earth or another future geo-browser is doing all the POST and PUT dirty work for you.

In the temporary places container, create a new point placemark anywhere. Give it a name and a plain text description. Save it to your filesystem as hammock.kml. To create a new, publicly-shared place within the collection based on your new placemark you send the contents of that file in the body of a request to the collection URI. I showed that URI above, but the sure place to find it is in the atom:link element of the KML file. View the source on that file and verify that there's a link to http://sgillies.net/hammock/places/. Now send a request like:

POST /hammock/places/ HTTP/1.1
Host: sgillies.net
Content-type: application/vnd.google-earth.kml+xml

<kml>
...
</kml>

You can use curl to do it like this:

$ cat hammock.kml | curl -d @- --header
Content-type:application/vnd.google-earth.kml+xml
http://sgillies.net/hammock/places/

It's very important to specify the proper content type. If you've typed carefully, you will get response with a Location header containing the URL of the newly created resource. If you refresh the Atom feed and network link, you'll see the new resource reflected in each. You've seen this before in other apps like FeatureServer. What's new is that the KML document itself carries a link to the collection URI, the factory for new placemark resources. That's Atompub in action.

Furthermore, any placemark resource represented in http://sgillies.net/hammock/places.kml can be edited via its "edit" or "edit-media" (they are equivalent in this demo) atom:links using the HTTP PUT method. View the source to find the edit link for your newly created resource, and copy it (remember, one day Google Earth should do all this for you). Now, move the placemark in Google Earth or create a new one, and save it to the filesystem. Finally, PUT the saved placemark to the edit URI you copied using curl like:

$ cat edit.kml | curl -X PUT -d @- --header
Content-type:application/vnd.google-earth.kml+xml
http://sgillies.net/hammock/places/3

In this case, I've edited the third place. Note the use of the PUT method. If you typed carefully, the changes you made will be reflected in your newsreader and in the Google Earth network link.

It almost seems too simple to work: serve KML to users that provides the very links by which users can add to, or modify, the web resources represented in the document. I'd be surprised if there is a tidier solution. I hope this simple demo can convince a few people to take a closer look at using Atompub for geospatial services.

Comments

Re: Atompub and KML Demo

Author: Christopher Schmidt

The KML doesn't use the Atom namespace at all, so far as I can tell. Is that intentional? Seems odd to me...

Re: Atompub and KML Demo

Author: Sean

Fixed.

Re: Atompub and KML Demo

Author: Christopher Schmidt

So, I'm confused on one thing: you say '... can be edited via its "edit" or "edit-media" (they are equivalent in this demo) atom:links ...' What is the difference? It seems like in general, the edit-media URLs allow you to edit the different representations of the same resource. For FeatureServer, it seems like this means that there could (theoretically) be edit-media URLs for each of the supported input services (Atom, KML, JSON, etc.). Is that right? Is there a reason these URLs have to be different, or is differentiation between 'Content-Type' on the PUT, as defined by the 'type' attribute on the <atom:link> sufficient?

Re: Atompub and KML Demo

Author: Christopher Schmidt

For the record, I've added a 'atom:link rel="self"' and rel='edit-media' to featureserver's KML output. I suppose I should add the same to the atom feeds? Is there any atom-pub supporting client I could test out?

Re: Atompub and KML Demo

Author: Sean

Christopher, I think that anything we made would be the first truly geospatial Atompub client. I can see myself contributing to one to for OpenLayers. Pete Lacey's appfs is a really intriguing client that might support geo use cases. Seems like a lightweight WebDAV. The canonical example for media resources and edit-media links is an image collection (ala Flickr). Posting a new image to the collection creates both an image (media) resource and a media link resource. That media link resource contains metadata for the image resource. The resources in the canonical example are completely normalized; there's no overlap between the media and metadata (media link). You update the image by a PUT to the collection entry's "edit-media" URI, and update the metadata by a PUT to the entry's "edit" URI. What's the rationale for explicit "edit-media" links? Here's one case: completely separate backends for images and metadata/annotations. On the other hand, a KML placemark and Atom entry overlap significantly, and I've limited the scope of my demo to the point where the overlap is complete. You can PUT KML to the "edit-media" URI, or an Atom entry to the "edit" URI, but the effect is the same. That's just a detail of my demo's implementation, not a recommendation. Andrew Turner's work on factoring KML into modules could tie into Atompub very well. An Atompub + KML client could PUT the metadata module's elements (as Atom) to an "edit" URI, and PUT everything else (as KML) to the "edit-media" URI.