GEOS – library for spatial magic
We use GEOS here in GeoIQ Towers, and love how powerful it is. If you are into your geospatial applications and you’ve never heard of it, you may well have heard of other applications that use it – such as PostGIS, Mapserver, GRASS, GeoDjango and FME. We use it a lot behind the scenes in our suite of geospatial analysis tools – tools that anyone can use now on GeoCommons.com

It’s a C port of the Java Topology Suite but they both do the same things very well – basically they do spatial functions for processing geometries.
What does it do?
The kinds of things it can do include:
- Supports all OGC Geometry types, like Points, Polygons etc
- Area calculations
- Distance between geometries
- Point in polygon calculations
- Intersects, overlaps, touches, contains operations
- Buffer, difference, union
- Geometry simplification
And we use it for pretty much all of the above!
How to get it
Since we use Ruby, we use the GEOS Ruby Bindings. I get mine from the UbuntuGIS repository and install the libgeos-ruby1.8 package (and the associated dependencies). I’m assuming you would know how to go ahead and get it.
You can also try out the newer FFI bindings for GEOS and let me know how you get on, and you can also use JTS with JRuby if you feel like it too!

Donut Photo by http://www.flickr.com/photos/amylovesyah/
How to use it
Donut Buffers
Here’s a snippet of code that is used when you want to buffer a dataset.
def buffer(feature, radius, min_radius=0.0)wkb_writer = Geos::WkbWriter.new wkb_reader = Geos::WkbReader.new geom = wkb_reader.read_hex feature.geometry buffer_geom = geom.buffer(radius) if min_radius != 0.0 hole_geom = geom.buffer(min_radius) buffer_geom = buffer_geom.difference(hole_geom) end feature.geometry = wkb_writer.write_hex buffer_geom featureend
Going through the code, the method takes in a feature object, which has a geometry attribute which in this case is in the HEX WKB format (01010000002FDD2406816154C0C66D3480B7A03B40 for example)
Geometries can be stored in many formats, and GEOS can read them. But the key bit is that we have to use a GEOS::WkbReader to read in a string object and convert it into a geometry.
POINT(-81.5235 27.6278) Would be the same point geometry but in Well Known Text, or WKT.
So, we read the geometry in, and convert it into a special GEOS object, ready to be worked upon.
The next line down is where the buffer operation takes place.
buffer_geom = geom.buffer(radius)
Pretty simple, eh?
This makes a polygon around a buffer, with the radius variable as distance.
The next few lines are donut making – we see if the method was called with a min_radius value, buffer the same point but with the smaller radius and then do a difference operation on that!
buffer_geom = buffer_geom.difference(hole_geom)
And the final of the method uses the geos wkb_writer to write back the new donuted geometry for that feature.
GeoIQ Blog- White House Maps and the Federal Cloud February 16, 2012 Andrew Turner
- UNEP/GRID-Arendal launches OCEANIDS February 15, 2012 Andrew Turner
- Using the Google Translate Function to Make Multilingual Maps in GeoCommons February 9, 2012 Sean Gorman
- Tech@State Panel – Realtime Awareness February 2, 2012 Andrew Turner
- 2011 in Review January 27, 2012 Andrew Turner




