RESTful

Update 17-7-2008 : “Formal” demo server now runs on apache2-mod-python

API

Not much has changed on the outside, but a lot has changed on the inside. Most importantly you can now get the altitude profile through a RESTful API. My mentor Artem Dudarev built a nice Google Maps demo that uses this API. A more formal demonstration can be found here (source code).

There is currently one way to send the route to my server, but there will be three ways. There are currently two types of output available for the profile, but there will be four. The wiki explains everything in detail, but here is a summary. It uses a short drive through Heidelberg as an example. Have a quick look in Google Maps.

Let’s start with the easiest input and output (which is not working yet by the way).

http://altitude.sprovoost.nl/profile/gchart?lats=49.407810,49.407770,49.408950,49.407040,49.406880,49.407620,49.413360,49.414800,49.414730&lons=8.681080,8.684210,8.692368,8.692670,8.693919,8.694270,8.692300,8.692110,8.693110

This simply sends a list of latitudes and longitudes via an HTTP/GET request and returns an image. You could use that in an <img> tag.

A more standards compliant way is to send some XML, an OpenLS RouteGeometry object, through an HTTP POST request to: http://altitude.sprovoost.nl/profile/gchart_url/xml/ . Check out the wiki to see what that XML should look like. To be fair, OpenLS goes a little over my head, so don’t expect a very proper implementation at this point; consider it a gesture.

A more hip way, and probably also the most data efficient and easiest to program way, is to use the recently released Protocol Buffers from Google. Encoding in Python is a simple as this:

route_pb = altitudeprofile_pb2.Route()
for p in route:  point = route_pb.point.add()  point.lat = p['lat']  point.lon = p['lon']
route_pb_string = route_pb.SerializeToString()

Here route is an array of dictionaries like {‘lat’ : 49.407810, ‘lon’ : 8.681080}. More details in wiki.

The protocol buffer string is only 108 bytes in this case, whereas the xml document was 793 bytes and the GET string uses 180 bytes.

The examples here return a Google Chart image. The server will fetch this image and then send it to the client. This is easy to use, but uses more resources on my end than strictly necessary. Therefore it is also possible to fetch the URL to the image in stead of the image itself. In stead of:

http://altitude.sprovoost.nl/profile/gchart?lats=...&lons=....

you use:

http://altitude.sprovoost.nl/profile/gchart_url?lats=....&lons=....

It is also possible to retrieve and XML document:

http://altitude.sprovoost.nl/profile/xml?lats=....&lons=....

And finally I will also support protocol buffers as an output format.

Any combination of input and output will be possible.

App Engine continued

The current version of altitude.sprovoost.nl runs on the Google App Engine. There are however a number of issues with the app engine that prevent full scale, planet wide, deployment at this stage.

The first problem is limited storage space (500 MB) during the test phase.

The second problem lies in the way the data is stored, which currently takes about 100 bytes per record. Since I store each altitude as one record that adds up. It is currently unclear whether this 100 bytes includes the key or not. Eventually Google will not count these keys towards data usage, because they prefer us to optimize for performance in stead of cost. In theory I only require 2 bytes (a smallint) per record, so the whole planet would only require about 40 GB. There is a discussion on the mailing list about this.

The third problem is uploading data. I already explained in my previous post that uploading the planet with the current tools would take 16 years. I opened a ticket for it.

The fourth problem is that the app engine can’t deal with Google’s own shiny new Protocol Buffers yet. I mentioned it on the mailing list and I’m sure that will be fixed soon.

In the mean time, I am working on getting my PostGIS version back up and running. It uses mostly the same code. I am also considering supporting MySQL, since I am not using any GIS functionality anyway.

The competition / colleges

I am not the only one on this planet who is working on altitude profiles.

The most impressive one is probably Hey What’s That. If you ever enjoyed the view from a mountain or high-rise building and wondered what you were looking at in the distance, you’ll love this. They also provide an altitude profile with a HTTP/GET API. They even take the roundness of the earth into account and they are contemplating refraction.

That reminds me of the Wikipedia article about the horizon: I drew the diagram on that page years ago because I  needed it for a paper on Islamic prayer times and refraction; as I understood it, you are not supposed to pray when the sun is exactly on the horizon, because pagans do that.  Refraction makes that issue a bit more complicated and I spent some time with a fellow student trying to figure out how Islamic scientist looked at that issue in the past. Contact Jan Hogendijk if you find this fascinating. The figure is still there, albeit with some improvements.

The Google Maps Mania blog lists even more examples of altitude profiles.

This makes it ever more important for me to focus. My focus is:

  • open source (obviously since it’s a Google Summer of Code project)
  • short distances (so I can pretend the world is ‘flat’ and hopefully don’t have to worry about sudden spikes in elevation between sampled points)
  • different methods to access the service
  • KISS (Keep It Simple Stupid)
  • prioritize quality of data over quality of graphics

Git

Git-svn has some issues with branches. I found a solution here (also read the follow ups). This is what I had to synchronize my master branch with subversion after I merged another branch into it:

Start with the svn head. I use a trunk/tags/branches structure in subversion. If you don’t, you may have to replace “trunk” with “git-svn”.

git checkout -b tempbranch trunk
# bring in all the changes from your branch
git merge --squash master
# commit with whatever message you want
git commit -m "Whatever, this message will self destruct anyway"
# and ship it to svn land
git svn dcommit
# Go back to your master branch
git checkout master
# Clean up
git branch -D tempbranch

I usually update svn less frequently than git. But if you to use a more recent version of my code and can’t use git, just drop me an email.