Suffix

Generated maps with Ruby on Rails

Generating an image of a map with my current location.

This post is all about the map in this site’s header (the design has since been updated). The header background shows a dynamically generated map of the coordinates shown in the right top corner, or my last recorded place. I can select my current location (latitude and longitude) and the header background map updates accordingly. How does this work?

No Google or Yahoo! maps?

I integrated Yahoo! Maps first. Their maps look nice, the API is easy to use and well documented, but you are only allowed to play within the limits of the API’s terms and conditions. Example from the Yahoo! Maps API Terms of Use:

I would break these terms as I convert the original image to a grayscale version and store the map on the server for performance reasons. Yahoo! Maps are out. Google or Yahoo! Maps are great for a quick map, but if you want more freedom, you will probably have to look elsewhere (or pay for a license).

OpenStreetMap

Luckily for us there are other solutions: OpenStreetMap for example. OpenStreetMap is a “wiki style” editable map, made by people like you and me. The content is available under the Creative Commons Attribution-ShareAlike 2.0 license which means anyone can use (and remix) the data if you share it with a similar license.

This ‘Wikipedia-like’ approach has some drawbacks as well: the map is incomplete, and the data is not 100% reliable. On the other hand, you can correct or complete the map where needed. This may or may not be important for your project, but I only need a nice background image for this website, so a general overview of the area is more than sufficient.

OpenStreetMap has a RESTfull way to build a map image with a given latitude, longitude, zoom level and image size:

http://tah.openstreetmap.org/MapOf?lat=<lat>&long=<long>&z=<zoom>&w=<width>&h=<height>&skip_attr=1

The skip_attr defines if you want to include an OSM attribution image in your map or not.

The process flow:

  1. The current location is updated on the website,
  2. a map of this new location is downloaded from a map server,
  3. the downloaded map image is converted to grayscale and
  4. the generated image is saved to disk.
Flow chart with steps to produce the image

We’ll use RMagick and Ruby on Rails to convert the downloaded image to something else so make sure you have this installed first.

# Writes an image with a map of the location, the zoom ranges from 4 to 17
require 'RMagick'
require 'open-uri'
def map(latitude, longitude, width = 500, height = 500, zoom = 7)
  map_request_url = "http://tah.openstreetmap.org/MapOf?"
  map_request_url += "lat=#{latitude}&amp;long=#{longitude}&amp;z=#{zoom}&amp;w=#{width}&amp;h=#{height}"
  uri = URI.parse(map_request_url)
  map = Magick::ImageList.new
  map.from_blob(uri.read)
  map = map.quantize(256, Magick::GRAYColorspace)
  map.write(RAILS_ROOT + '/public/images/map.png')
end

That’s it, this method downloads and converts the image and saves it in your images folder so from now on you can use this image in your website:

<img src="/images/map.png" alt="Map" />

More resources