I have a relatively short list of cities which I want to plot on a world map. The list is a little too long for a manual lookup, but I don’t know exactly how I’ll use it in an app, so I figured out how to do it with some simple ruby in irb using the lovely geocoder gem.

I had my cities in a spreadsheet. Selected a few cells, and was able to simply paste into irb and split the string on newlines to get an array of the cities.


gem install geocoder
irb
>> require 'geocoder
>> a = "Honolulu, HI
>> Boston, MA
>> New York, NY".split("\n")
 => ["Honolulu, HI", "Boston, MA", "New York, NY"] 

>>a.map do |city| 
    d = Geocoder.search(city)
    ll = d[0].data["geometry"]["location"]
    puts "#{city}\t#{ll['lat']}\t#{ll['lng']}" 
end

Honolulu, HI    21.3069444  -157.8583333
Boston, MA  42.3584308  -71.0597732
New York, NY    40.7143528  -74.00597309999999

Then I could copy/paste the irb output back into my spreadsheet. Ta Da!

It appears that the free Google API has some kind of throttling, so this is only good for short lists of <20 cities.

3 thoughts on “ruby to find latitude/longitude for a list of cities

  1. Another thing to be aware of with the Google API: to comply with their TOS, you can’t store geocodes locally (except to cache them for a bit) and the points must be displayed on a free, publicly accessible Google map.

    Not a big deal for a small side project, but something to be aware of for any professional work.

    (This info is based on my last reading of the maps API TOS a few years ago, so things may have changed.)

  2. Thanks for the note about API. True that I’m doing open source work so the free terms are not an issue; however, you prompted me to re-read the terms of service, I hadn’t remembered that the Google API data MUST be also used with a Google Map. Yet another caution for anyone using this methodology. Relevant sections below.

    9.1.1

    (a) Free Access (No Fees). Your Maps API Implementation must be generally accessible to users without charge and must not require a fee-based subscription or other fee-based restricted access. This rule applies to Your Content and any other content in your Maps API Implementation, whether Your Content or the other content is in existence now or is added later.

    (b) Public Access (No Firewall). Your Maps API implementation must not operate (i) only behind a firewall; or (ii) only on an internal network (except during the development and testing phase); or (iii) in a closed community (for example, through invitation-only access).

    10.1.1

    (g) No Use of Content without a Google Map. You must not use or display the Content without a corresponding Google map, unless you are explicitly permitted to do so in the Maps APIs Documentation, or through written permission from Google. In any event, you must not use or display the Content on or in conjunction with a non-Google map. For example, you must not use geocodes obtained through the Service in conjunction with a non-Google map. As another example, you must not display Street View imagery alongside a non-Google map, but you may display Street View imagery without a corresponding Google map because the Maps APIs Documentation explicitly permits you to do so.

    10.1.3

    (b) No Pre-Fetching, Caching, or Storage of Content. You must not pre-fetch, cache, or store any Content, except that you may store: (i) limited amounts of Content for the purpose of improving the performance of your Maps API Implementation if you do so temporarily (and in no event for more than 30 calendar days), securely, and in a manner that does not permit use of the Content outside of the Service; and (ii) any content identifier or key that the Maps APIs Documentation specifically permits you to store. For example, you must not use the Content to create an independent database of “places” or other local listings information.

  3. If you need something without restrictions, you can use this gem with datasciencetoolkit (:dstk) and run the above code.

What do you think?