Monthly Archive for May, 2010

Postgis and Rails on Snow Leopard

So you decided to work with geo data within your rails application? To do so, some additional gems are required and over here you will find a simple example using rails with an underlying postgres database to store your geo data.

First download Postgres and PostGIS from here and the additional frameworks GEOS and PROJ from here and install them in the following order

  • PostgreSQL
  • GEOS
  • PROJ
  • PostGIS

After you ensured you have a working PostgreSQL (default install directory isĀ  /usr/local/pgsql/) and PostGIS, continue to the next steps. Note: If you get errors on non-existing role, use the option -U postgres for the following commands.

createdb [yourdatabase]

The next step before creating the PostGIS database is to enable PLSQL.

createlang plpgsql [yourdatabase]

Now load the PostGIS object and function definitions (usually located in /usr/local/pgsql/share/contrib).

psql -d [yourdatabase] -f postgis.sql

For a complete set of EPSG coordinate system definition identifiers, you can also load the spatial_ref_sys.sql definitions file and populate the spatial_ref_sys table. This will permit you to perform ST_Transform() operations on geometries.

psql -d [yourdatabase] -f spatial_ref_sys.sql

After that your postgres and postgis installation is complete. Now we can configure our rails environment. First of all install the GeoRuby and Spatial Adapter gem.

sudo gem install GeoRuby
sudo gem install spatial_adapter

or simply add following lines to your environment.rb

config.gem "GeoRuby", :lib => "geo_ruby"
config.gem "spatial_adapter"

and run

sudo rake gems:install

From now on, you are ready to use special geo column types (like point, line string, polygon, ...) within your database and also a corresponding active record object types. For example you will be able to create your database tables like the following

create_table :places do |t|
   t.point :location, :null => false, :srid => 4326
   t.string :address
   t.timestamps
end

and within your application you are able to work with geo data as you can see in this code snippet

place = Place.new (
  :location => Point.from_x_y(-1.0, 2.0, 4326),
  :address => "My home is my castle"
)
...
place = Place.find(:all).first
puts place.location.x
puts place.location.y
...

Enjoy,
J.

References:
[1] Using Postgis, http://postgis.refractions.net/docs/ch04.html
[2] spatial_adapter, http://github.com/fragility/spatial_adapter
[3] GeoRuby, http://georuby.rubyforge.org/georuby-doc/index.html