Like many geospatial developers, I did not originally set out with the goal of becoming a developer. I was interested in geospatial applications and realized to get the most out of them I was going to need to learn how to “code”. After some early work with Python I realized that like Indiana Jones, I am not terribly fond of snakes. I had been experimenting with Ruby and found myself wishing I could be mining gems instead of charming snakes.
Many who’ve used Ruby in spatial applications know that Ruby and spatial are not always the best of friends and in my quest to make them play nice, I discovered JRuby and began my torrid love affair with the Java Virtual Machine (JVM). JRuby is an implementation of Ruby for the JVM, the benefits of using JRuby are many, but in this post I will focus on its interoperability with Java and other JVM languages.
At FOSS4G 2011 in Denver I first learned about GeoScript, which makes it easy to take advantage of GeoTools using dynamic scripting languages. I thought it sounded great but it left me wondering: “Why is there not a GeoScript for Ruby?” After a bit of poking around and not finding what I was looking for, I set to hacking and created GeoScript for Ruby. It is available on GitHub and as a gem.
gem install geoscript
We will look at these code samples as though they are being driven interactively using IRB (Interactive RuBy):
>> require 'geoscript' # load geoscript library into IRB session
Geometries may be read easily from Well-Known Text (WKT) strings:
>> ls = GeoScript::Geom.from_wkt 'LINESTRING (30 10, 10 30, 40 40)'
The last line shows that an instance of GeoScript::Geom::LineString has been created from the specified (LINESTRING) WKT. This is an instance of GeoScript::Geom::LineString and not the underlying Java class of com.vividsolutions.jts.geom.LineString, because GeoScript takes advantage of the fact that JRuby allows Ruby class inheritance directly from Java classes to add additional niceties to the library with little effort. We can verify that this is the case by checking the class and java_class of our LineString object.
=> class com.vividsolutions.jts.geom.LineString
This means that all of the methods available to the Java class are exposed to the JRuby class as well. JRuby exposes the Java methods in their typical camel case form, but also in the snake case style with all lower case characters that is more typical of Ruby.
In the rest of the post we will use the Ruby style.
>> ls.numPoints # Oppan Java Style
>> ls.num_points # Ruby Style
Reprojecting geometries is easily accomplished with GeoScript.
>> ls_2 = GeoScript::Projection.reproject ls, 'epsg:4326', 'epsg:3857'
You may have noticed that we have been leaving the parentheses off of our method calls. This is intentional, as they are (mostly) optional in Ruby and Ruby style leans toward omitting them when possible. Another instance of GeoScript::Geom::LineString has been created here, this time with its coordinates reprojected from EPSG:4326 to EPSG:3857.
=> "LINESTRING (30 10, 10 30, 40 40)"
=> "LINESTRING (79544978.84519245 74569282.31931569, 8713934.405939918 30398359.508842178, -29513984.25511929 22214960.256206784)"
In addition to WKT, geometries may also be read from Well-Known Binary (WKB) from sources like PostGIS.
>> p = GeoScript::Geom.from_wkb '0101000000000000000000F03F000000000000F03F'
=> "POINT (1 1)"
Scooter joined the team in July. He previously worked at Sanborn, where he built spatial web applications using both Esri and open source stacks as well as combinations of the two. At Boundless, he works on collaborative data management tools like GeoGit. Interested in joining our team? We’re hiring!