[geos-devel] GEOS Ruby bindings gem and extensions

J Smith jay at zoocasa.com
Tue Nov 30 17:05:35 EST 2010


Hello list!

I work on a project that has been using the GEOS Ruby bindings for
years and and we've been adding a bunch of extensions and
modifications to it throughout that time. We've gotten to the point
now where we'd like to release this code into the wild world of free
software and open source and thought we'd drop a line to the
geos-devel list to get some feedback and whatnot before releasing the
code.

We're specifically looking to release the following:

- we've gemified the Ruby bindings portion of the GEOS library so it
can be installed separately from the library itself. It still depends
on the library, obviously, but can be built as a standalone gem. We've
extracted the geos.i.in and ruby.i files from the GEOS tarball and
wrote a gemspec and extconf.rb for it that extracts the relevant
version information from geos_c.h and builds the SWIG output
accordingly.

- we've also extracted the Ruby test files and the gem has been tested
on OSX and CentOS 5.5, although some of the tests appear to fail. (The
tests themselves may be a bit stale, perhaps -- one test looks for a
version string matching "3.0.0rc4-CAPI-1.3.3", for instance.)

As for the extensions to the library, we've implemented the following
in Ruby userland as wrappers and whatnot around the GEOS library:

- a host of helper methods to make reading and writing to and from WKT
and WKB easier. For instance, rather than

Geos::WktReader.new.read('POINT(0 0')

you can quickly use

Geos.read('POINT(0 0)')

The Geos.read method also works with WKB in both binary and hex,
recognizes EWKB and EWKT and can read several of Google Maps
JavaScript output formats that we use for our applications. There are
also similar methods for outputting to WKT and WKB such as
Geos::Geometry#to_wkt, #to_kml, #to_georss and a number of methods to
output to Google Maps API v2-style JavaScript.

- a bunch of helper methods to quickly grab some information from
geometries like Geos::Point#lat and Geos::Point#lng.

- in all, some 70+ helper methods have been added to Geos::Geometry types.

- Geos::GeometryCollection has been made an Enumerable.

We've also included some Rails integration for PostGIS, including:

- automatic detection of geometry columns and just-in-time conversions
for input and output to and from WKB when using PostGIS. This allows
you to do stuff like this with your ActiveRecord models:

m = MyModel.find(12345)
m.the_geom # => spits out the untouched geometry value as a string in WKB
m.the_geom_geos # => spits out the geometry wrapped in a Geos::Geometry object
m.the_geom = 'POINT(0 0)' # => setters will automatically make
conversions from any of the formats that the Geos.read can recognize,
so Google Maps formats, WKT, WKB, etc. are all converted
automatically.
m.the_geom_wkt # => automatically converts to a WKT string
m.the_geom_wkb_bin # => automatically converts to WKB in binary

There's also some funky SRID handling code that will automatically
look in the geometry_columns table to make conversions for you when
necessary. Saving WKT as "SRID=default; POINT(0 0)" for instance will
automatically set the SRID when saving the ActiveRecord, or the SRID
can be specified manually.

- multiple geometry columns are supported and detected for
automatically. These column accessors are all generated dynamically at
run time.

- automatic generation of named scopes for ActiveRecord models. The
usual suspects are supported:

* st_contains
* st_containsproperly
* st_covers
* st_coveredby
* st_crosses
* st_disjoint
* st_equals
* st_intersects
* st_orderingequals
* st_overlaps
* st_touches
* st_within
* st_dwithin

These let you chain together scopes to build geospatial queries:

neighbourhood = Neighbourhood.find(12345)
my_model = MyModel.active.
 recent.
 st_within(neighbourhood.the_geom_geos.envelope).
 st_dwithin(point, 0.1).
 all(
  :limit => 10
 )

- we wrote this code for Rails 2.3 and are currently testing on Rails
3, but it appears that everything is working as expected and is
working with Arel (hopefully!).

Our plan at the moment would be to put the code up on to github along
with the appropriate Rubygems releases. We'd like to license the
extensions code under the MIT license as per the usual Ruby and Rails
library terms. As for the gemified build of the GEOS bindings library
itself, would the correct license in this case be the LGPL? We've
included several files from the main GEOS library along with the Ruby
test files, so would this extend that license to the rest of the gem,
which includes only build files like a Rakefile, extconf.rb and a
gemspec and such. We could otherwise license this gem as perhaps a
combination license -- the files from the GEOS library would be marked
as being covered under the LGPL, while the collection as a whole would
be released under our preferred MIT license.

We hope to release this code soon and hope it proves useful to the
GEOS project and Ruby GIS coders. The GEOS Ruby library has been a
real boon to our development, and we hope that our extensions and the
gem build will be useful to others.

Any comments and suggestions are appreciated.

Cheers!

J


More information about the geos-devel mailing list