Rails Geocoder: A Guide to Managing Locations in Your Apps

Rails Geocoder: A Guide to Managing Locations in Your Apps

Eric Boersma Developer Tips, Tricks & Resources

The introduction of Google Maps in 2005 changed the way we think about the internet. It’s hard to remember now, but there was a time where the internet was disconnected from the physical world. You might find a business’s website, and if you were lucky, they’d have an address included. A national chain of restaurants or grocery stores probably wouldn’t be able to tell you their nearest location to your home.

All of that has changed, today. Now, it’s expected that your website not only know where all your business’s locations are, but where your users are located, too. Thankfully, in 2019 there are a myriad of options for mapping and geolocation services that help developers add those features to websites. Today we’ll take a look at Rails geocoder.

The Ruby on Rails Geocoder Gem

For developers writing Ruby, the geocoder gem provides a one-stop shop to finding your way around those services. It integrates with a dizzying list of service options as well as working seamlessly with data store options like Mongo and PostGIS. Thankfully, plugging it into your app is simple. Simply add the gem to your gemfile, install the gem with bundler, and you’re off to the races.

Integrating the geocoder gem into Rails itself isn’t entirely seamless. You’ll need to do some manual setup to generate models and forms to store data about the locations you’ll be geocoding. That’s okay! You’ll have full flexibility to approach geocoding exactly as you like.

What’s more, geocoder itself isn’t tied to Rails. You can use it in other software projects with the same installation steps. By decoupling itself from Rails, geocoder is able to suit a broader variety of applications out of the box.

Choosing a Geocoding library

Once you’ve installed Rails geocoder, you’ll have a decision to make about which geocoding API to use. If you’re just making a website for yourself, that decision will probably be pretty easy. You’ll probably want to use the Google Geocoding API. Google geocoding comes with a number of free requests per day, and provides gobs of good information. It’s easy to sign up for a key, and nearly everyone has a Google account for some purpose these days. That’s all you need to sign up.

If you’re working for a business or professional site, you might need to do a bit more research ahead of time. Google provides terrific professional plans, but you might also want to check out Bing Maps or potentially MapQuest. Be sure to work with your employer to determine if you already have a license for one service or another. There are dozens of options, so pick what works best for you and your company.

The good news is that all those services are directly integrated into the geocoder gem. You’ll work with the gem the same way no matter which API you choose. That’s convenient; it means that if you ever need to switch providers, all you’ll need to do is edit some config files.

Integrating with a database system

If you’re bootstrapping an application, you should make sure that your database will work with geocoder. There are two primary databases on the market today for geospatial work. The first is PostGIS, an add-on for PostgreSQL. PostGIS provides a terrific API for querying geospatial data within a relational database paradigm. It’s easy to store latitude and longitude values in a PostgreSQL database, then query them using the PostGIS library. This works natively within the geocoder app.

The second primary database you’ll run into is MongoDB’s geospatial library. Much like PostGIS, this is a first-class system for working with geospatial data in MongoDB. Unlike PostgreSQL, MongoDB is not a relational database. It’s known as a NoSQL database.

If you’re building an application using the geocoder gem, you’ll probably want to use one of those two databases. Geocoder also supports MySQL, but my experience is that MySQL’s geospatial features are a bit slower to use than PostGIS. Geocoder supports SQLite, but SQLite is not a production-level database, and you should only use it for testing.

Finally, there are other databases which do provide geospatial capabilities, like MsSQL. Unfortunately, at the time of publication, Rails geocoder doesn’t support Microsoft  SQL Server, so you should avoid using it for this application.

Integrating Geocoder into your app

To imagine integrating geocoder into your app, let’s consider a practical example. I’m lucky enough that I work from home in my day job, in exurban West Michigan. I love not having a commute, but I do miss being able to grab a quick lunch with a friend during the work week. I still make regular plans to visit with friends and find lunch, but it can be difficult knowing where to go. Often times, we’re 30-40 minutes by car away from one another. Neither one of us wanting to drive too far means we’ve got to try to find something in between our current locations.

This would be a great use for the geocoder gem. We could easily code up an application that would find the median point between our two locations, and feed us back a list of restaurants that are near that midpoint. This isn’t a coding tutorial post, but let’s walk through the geocoder gem API quickly and we can see just how easy this would be.

Using Geocoder to find things near a midpoint

The first thing we’d need to do is collect the addresses for each person. In my personal usage, I’d only ever use two, but the function you need from geocoder actually supports a list of locations. You could build a quick Rails form or CLI program to collect a list of addresses from a user. Once you have those, you’d need to run each address through the Geocoder.search function. That will return information about the address you chose, including the latitude and longitude. You’ll want to save those.

Once you have the latitude and longitude for all points, you can use that data to calculate the central point between them. This is once again, a pretty simple function call. You’ll want the Geocoder::Calculations.geographic_center function. This will provide you another latitude and longitude. It’s the one that lies at the geographic center of the points that you provided.

Once you have the central point of the group, finding nearby items is academic. In my experience, the best way to do that is to use the Google Places API, and for example search for “restaurants” near your central latitude and longitude. Maybe, if you’re feeling fancy, you can add an option to provide a search term as well—for those days when you want to search for “steakhouse” instead.

A quick note on Geocoding APIs: sometimes, they can be a little flaky. My experience is that your code might work fine for weeks, then suddenly have a day where everything is broken. All this despite the fact that you didn’t change anything at all. If you’re setting up an application on the web that uses geocoding APIs, I’d highly recommend looking into quality application performance monitoring like Stackify Retrace. If things start to break, you really want to know about that, ASAP.

Pinpoint

Making the world your oyster

The time when your application could be ignorant of the Earth around it is long past. The good news is, it’s easier than ever to hook your application up to mapping services. Most of the time, you can add mapping to your application in a day or less. Doing so is almost always low cost, and usually free. Having quick and easy mapping capabilities will drive scores of customers to your business. If you’re someone who’s just tinkering, there are great options too. Things are only limited by your imagination. And if you decide to build a web application that can find restaurants at the midpoint between two locations, drop me a line. I’m always looking for a good place to get lunch.

Start Free Trial

About Eric Boersma

This post was written by Eric Boersma. Eric is a software developer and development manager who's done everything from IT security in pharmaceuticals to writing intelligence software for the US government to building international development teams for non-profits. He loves to talk about the things he's learned along the way, and he enjoys listening to and learning from others as well.