This is a tutorial for using the
OpenCage geocoding API
in Ruby.
Topics covered in this tutorial
- General Background
- Ruby Gems
- Reverse geocoding
- Forward geocoding
- Geocoding a list of places
- Running in parallel
- Further reading
Background
The code examples below will use your geocoding API key once you
log in.
Before we dive in to the tutorial
- Sign up for an OpenCage geocoding API key.
- Play with the demo page, so that you see the actual response the API returns.
- Browse the API reference, so you understand the optional parameters, best practices, possible response codes, and the rate limiting on free trial accounts.
Ruby gems for accessing the OpenCage Geocoding API
There are three Ruby gems you can use:
Install the Ruby gem
gem install opencage-geocoder
Or in your Gemfile:
source 'https://rubygems.org'
gem 'opencage-geocoder'
Convert latitude, longitude to an address (reverse geocoding)
require 'opencage/geocoder'
geocoder = OpenCage::Geocoder.new(api_key: 'YOUR-API-KEY')
result = geocoder.reverse_geocode(51.5019951, -0.0698806)
p result.address
# "Reeds Wharf, 33 Mill Street, London SE15, United Kingdom"
p result.confidence
# 9
Address or place name to coordinates (forward geocoding)
require 'opencage/geocoder'
geocoder = OpenCage::Geocoder.new(api_key: 'YOUR-API-KEY')
# no need to URI encode the query, the library takes care of it for us
results = geocoder.geocode('82 Clerkenwell Road, London, UK')
p results.first.coordinates
# [ 51.52215, -0.10083 ]
p results.first.lat
# 51.52215
p results.first.lng
# -0.10083
results = geocoder.geocode('Manchester')
results.each { |res| p res.address }
# "Manchester, England, United Kingdom"
# "Manchester, New Hampshire, United States of America"
# "Manchester, IA 52057, United States of America"
# "Manchester, KY 40962, United States of America"
# ...
# We want a place in Canada and results in French
results = geocoder.geocode('Manchester', countrycode: 'CA', language: 'fr')
p results.first.address
# "Manchester, NS, Canada"
p results.first.components
# {
# "_category" => "place",
# "_type" => "village",
# "village" => "Manchester"
# "state" => "Nouvelle-Écosse", # Nova Scotia
# "state_code" => "NS",
# "country" => "Canada",
# "country_code" => "ca",
# "continent" => "North America",
# "ISO_3166-1_alpha-2" => "CA",
# "ISO_3166-1_alpha-3" => "CAN",
# "ISO_3166-2" => ["CA-NS"],
# }
p results.first.annotations.dig('currency', 'name')
# "Canadian Dollar"
p results.first.annotations.dig('currency', 'iso_code')
# "CAD"
Bulk-geocode places
This example geocodes each coordinate pair in a file in series.
Fill a text file queries.txt with queries:
24.77701,121.02189
31.79261,35.21785
9.54828,44.07715
59.92903,30.32989
Then loop through the file:
require 'opencage/geocoder'
geocoder = OpenCage::Geocoder.new(api_key: 'YOUR-API-KEY')
results = []
File.foreach('queries.txt') do |line|
lat, lng = line.chomp.split(',')
begin
# Use Float() rather than #to_f because it will throw an ArgumentError if
# there is an invalid line in the queries.txt file
result = geocoder.reverse_geocode(Float(lat), Float(lng))
results.push(result)
rescue ArgumentError, OpenCage::Geocoder::GeocodingError => error
# Stop loop if there is an error
puts 'Error: ' + error.message
break
end
end
results.each { |r| puts r.address }
# 韓國館, 金山十一街, 金山里, Hsinchu 30082, Taiwan
# David Hazan 11, NO Jerusalem, Israel
# هرجيسا, Jameeco Weyn, Hargeisa, Somalia
# Китайское бистро, Apraksin Yard, Михайловский проезд ...
Running many parallel queries
We created two example scripts:
- How to geocode with multithreading — using Queue and Threads gems
- Geocode spreadsheet file in parallel — using CSV and Async gems
Before you start geocoding at high volume, please read our guide to geocoding large datasets where we explain various strategies and points to consider.
Install the Ruby gem
gem install geocoder
Or in your Gemfile:
source 'https://rubygems.org'
gem 'geocoder'
Geocode an address
#!/usr/bin/env ruby
require 'geocoder'
Geocoder.configure(lookup: :opencagedata, api_key: "YOUR-API-KEY")
results = Geocoder.search("57 Erb Street West Waterloo, ON, Canada N2L 6C2")
result = results.first
puts "#{result.latitude}, #{result.longitude}"
# output is 43.463796, -80.52608
Geocode coordinates
#!/usr/bin/env ruby
require 'geocoder'
Geocoder.configure(lookup: :opencagedata, api_key: "YOUR-API-KEY")
results = Geocoder.search([43.463796, -80.52608], reverse_geocode: true)
result = results.first
puts result.address
# output is "63 Erb Street West, Waterloo, ON N2L 1V4, Canada"
Install the Ruby gem
gem install geokit
Or in your Gemfile:
source 'https://rubygems.org'
gem 'geokit'
Geocode coordinates
require 'geokit'
Geokit::Geocoders::OpencageGeocoder.key = 'YOUR-API-KEY'
Geokit::Geocoders::provider_order = [:opencage]
result = Geokit::Geocoders::MultiGeocoder.geocode("51.2157153, 1.3903743")
puts "#{result.provider}: #{result.full_address}"
# Output is "opencage: Mill Road, South East, Kent, England, CT14 9BD, GB"
Geocode an address
#!/usr/bin/env ruby
require 'geokit'
Geokit::Geocoders::OpencageGeocoder.key = 'YOUR-API-KEY'
Geokit::Geocoders::provider_order = [:opencage]
result = Geokit::Geocoders::MultiGeocoder.geocode("900 Sycamore Drive")
puts "#{result.provider}: #{result.latitude}, #{result.longitude}"