For the attention of last week

archive of

Month: September, 2009

Ever needed to know how many working days are left this year?

Well now you know:

edit: Now with a graph and twitter!


GIS on Rails

There are times we want our Rails apps to have some sort of spatial capability. Recording lat long point locations and displaying them in a google map is fine, but increasingly we want to do more with our spatial data.

We want to be able to import data from a wide range of existing spatial filetypes such as shapefile or KML. We want to store complex spatial datatypes like multiple polygons with thousands of vertices in our databases with ease. We want to be able to convert spatial data between different projections and datums. We want to be able to run spatial queries like buffers, joins and intersects. We want to RESTfully output our spatial data in a variety of formats like AMF, geoJSON, KML and shapefile. We also want to output our data to our own set of raster tiles. Finally, we want to view our data in client side flash or javascript viewers.

Well, the Python web framework GeoDjango seems to do a lot of this.

GeoDjango… ok… Er, the title says Rails…

Why was awesome

There’s currently no equivalent pre-wrapped all-in-one GIS library like GeoDjango available for Rails. In addition to this, Rails core is fairly trim, and with Rails 3 is set to get even more focussed. It’s fair to predict that GIS features will never make it into Rails core in the same way GeoDjango has integrated with Django core.

This means that if you want to do feature rich GIS web apps with Rails, you’re gonna have to assemble the pieces yourself.

As it turns out, it’s pretty easy to assemble something similar.

What we can learn from GeoDjango?

GeoDjango is actually the collective name for a suite of existing open source GIS libraries, tools and database which have been integrated into the Django core framework. OSS web GIS takes very much a “stack” style approach, making it easy to draw out discreet functionality from GeoDjango, and look for equivalents in the Ruby world.

  • GEOS – spatial predicate functions and spatial operators
  • GDAL/OGR – amongst other things specializes in reading and writing geographic data
  • Model API – Allows spatial data types to be handled in Python objects
  • Database API – Allows spatial data types to be handled in Models, and also provides for spatial querying.

Tiling and the clientside code is currently handled outside the core GeoDjango stack, and the procedure (wiring a tile generator directly to PostGIS, and writing heavy client side visualisation code) is likely to be the same for Ruby apps. See GeoServer, and Mapnik for tips on tile generation, the google maps API for flash, or openlayers API for client side Viz.

How to replicate this back in Ruby/Rails land


The good thing is that it’s all possible. I’m assuming you’re using Postgres and the amazing PostGIS extension


For the core GeoDjango functionality, I’ve used a combination of GeoRuby, postgis_adapter libraries and straight PostGIS successfully. With these 3, most of the core GeoDjango plumbing can be replicated, and there are clear extension points where more functionality is needed.

Geospatial datatypes and file IO

GeoRuby provides native Ruby representations of the OGC basic datatypes, and basic Data IO. Note that it’s almost always better to either use the shp2pgsql command or plain GDAL/OGR for data loading purposes. I had issues with Shapefile attribute reading under Ruby 1.9.1 with GeoRuby.

Analysing the data

On the spatial query layer, Postgis_adapter and raw PostGIS SQL are your best bet. Postgis_adapter provides a basic wrapper for PostGIS spatial queries and is useful for quick one off’s, but it’s *almost always* best to drop to SQL (or other) for intensive & large spatial queries. The same would be true in GeoDjango, so we’re not losing much. Reprojections are handled by PostGIS.

Outputting the data

Finally, output is handled according to requirements. GeoRuby writes a variety of formats, (WKT, KML etc), PostGIS 1.4 outputs geoJSON natively, and AMF adaptors like Flails, RubyAMF, or WebORB allow for ultra fast connections to client apps for your spatial data.


Again, with the tiling and actual visualisation, GeoServer or Mapnik are good for tile generation, with the Google Maps API or OpenLayers being the best client side visualisation libraries available.


While I’ll leave most of the installations as an exercise to the reader until another post, if you are on OSX, you can install PostGIS easily via the lifesaving KyngChaos Binaries. That and GeoRuby+postgis_adapter should be enough to get you started.

Is that it? Sample app?

Sorry, not yet. But ping me on Twitter or the comments if you’d like to add to this, have questions or want to correct me. I’m sure I’ve got a bazillion things wrong, and would welcome any comments.

How does respond_to work in the Rails controllers?

The respond_to bloc party

This is one of the first questions I’m asked whenever I introduce someone to Ruby/Rails from another language.

WTF is going on?!?! (aka the rails respond_to block)

respond_to do |format|
  format.xml  { render :xml => @mah_blogz }

The key thing to understand is that respond_to is a method attached to your controllers superclass: ActionController, and we are passing in as an argument something called a block:

respond_to (BLOCK STARTS HERE) do |format|
  format.xml  { render :xml => @mah_blogz }

WTF is a block?

It’s like the innards of a function. Read this great post by Eli Bendersky.

Digging into Rails source: respond_to (edited for clarity)

def respond_to(&block)
  responder =

What’s the “&” prefixing the block argument?

We are passing respond_to a ruby block. That block is converted to a Proc due to the “&” prefix to the block argument. The functionality of this prefixed “&” is a Ruby feature. Procs are callable, anonymous functions.

So what’s with the |format| stuff back in the controller?

|format| defines that the block takes one argument (referred to inside the block as ‘format’).

This means that inside the respond_to method, we end up with a Proc that takes one argument. This argument has the .xml and .html methods called on it. What do we pass into the Proc as an argument when we call it from inside respond_to? We pass in an instance of the Responder class.

So we end up calling .html and .xml on an instance of the responder class as it is passed into the block (that’s been converted to a Proc) inside the respond_to method… Phew.

So here we are

I’ll leave you to dig further, but basically from here the Responder instance handles .html and .xml via method_missing, depending on mime types your rails app can process. This allows you to configure other mime types from your rails app by registering them in your initialisers.

JRuby, Postgres & Rails

Just a quickie. When using Rails, Postgres and JRuby for the first time, you’ll need to install a jdbc-friendly database driver. The nice fast ones you’re used to written in C (like ruby-pg), will simply not work.

There seems to be lots of choice here, and dead ends of old attempts. The latest and greatest however is the activerecord-jdbc-adapter and it’s set of prepackaged-adaptors.

So, to use postgres, and are using the fabulous Ruby Version Manager, you would install the postgres adaptor gem like this:

gem install activerecord-jdbcpostgresql-adapter

Then your configure your database.yml

      adapter: jdbcpostgresql
      username: blog
      hostname: localhost
      database: weblog_development

Job done!