Permalink
Browse files

Change preferred config read/write syntax.

Make Geocoder.configure accept a hash (now preferred) and add
Geocoder.config method (for reading config). Deprecate old syntax.
  • Loading branch information...
1 parent 4c9d28a commit a0448d4c7498dd76deb3b74494972481f5d1c4f9 @alexreisner committed Dec 8, 2012
View
@@ -266,29 +266,29 @@ Geocoding Services
By default Geocoder uses Google's geocoding API to fetch coordinates and street addresses (FreeGeoIP is used for IP address info). However there are several other APIs supported, as well as a variety of settings. Please see the listing and comparison below for details on specific geocoding services (not all settings are supported by all services). Some common configuration options are:
# config/initializers/geocoder.rb
- Geocoder.configure do |config|
+ Geocoder.configure(
# geocoding service (see below for supported options):
- config.lookup = :yandex
+ :lookup => :yandex,
# to use an API key:
- config.api_key = "..."
+ :api_key => "...",
# geocoding service request timeout, in seconds (default 3):
- config.timeout = 5
+ :timeout => 5,
# set default units to kilometers:
- config.units = :km
+ :units => :km,
# caching (see below for details):
- config.cache = Redis.new
- config.cache_prefix = "..."
+ :cache => Redis.new,
+ :cache_prefix => "..."
end
Please see lib/geocoder/configuration.rb for a complete list of configuration options. Additionally, some lookups have their own configuration options which are listed in the comparison chart below, and as of version 1.2.0 you can pass arbitrary parameters to any geocoding service. For example, to use Nominatim's `countrycodes` parameter:
- Geocoder::Configuration.lookup = :nominatim
+ Geocoder.configure(:lookup => :nominatim)
Geocoder.search("Paris", :params => {:countrycodes => "gb,de,fr,es,us"})
@@ -308,13 +308,13 @@ The following is a comparison of the supported geocoding APIs. The "Limitations"
* **Documentation**: http://code.google.com/apis/maps/documentation/geocoding/#JSON
* **Terms of Service**: http://code.google.com/apis/maps/terms.html#section_10_12
* **Limitations**: "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." "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..."
-* **Notes**: To use Google Premier set `Geocoder::Configuration.lookup = :google_premier` and `Geocoder::Configuration.api_key = [key, client, channel]`.
+* **Notes**: To use Google Premier set `Geocoder.configure(:lookup => :google_premier, :api_key => [key, client, channel])`.
#### Yahoo BOSS (`:yahoo`)
Yahoo BOSS is **not a free service**. As of November 17, 2012 Yahoo no longer offers a free geocoding API.
-* **API key**: requires OAuth consumer key and secret (set `Geocoder::Configuration.api_key = [key, secret]`)
+* **API key**: requires OAuth consumer key and secret (set `Geocoder.configure(:api_key => [key, secret])`)
* **Key signup**: http://developer.yahoo.com/boss/geo/
* **Quota**: unlimited, but subject to usage fees
* **Region**: world
@@ -374,7 +374,7 @@ Yahoo BOSS is **not a free service**. As of November 17, 2012 Yahoo no longer of
* **API key**: required for the licensed API, do not use for open tier
* **Quota**: ?
* **HTTP Headers**: in order to use the licensed API you can configure the http_headers to include a referer as so:
- `Geocoder::Configuration.http_headers = { "Referer" => "http://foo.com" }`
+ `Geocoder.configure(:http_headers => { "Referer" => "http://foo.com" })`
You can also allow a blank referer from the API management console via mapquest but it is potentially a security risk that someone else could use your API key from another domain.
* **Region**: world
* **SSL support**: no
@@ -400,7 +400,7 @@ Caching
It's a good idea, when relying on any external service, to cache retrieved data. When implemented correctly it improves your app's response time and stability. It's easy to cache geocoding results with Geocoder, just configure a cache store:
- Geocoder::Configuration.cache = Redis.new
+ Geocoder.configure(:cache => Redis.new)
This example uses Redis, but the cache store can be any object that supports these methods:
@@ -413,7 +413,7 @@ Even a plain Ruby hash will work, though it's not a great choice (cleared out wh
You can also set a custom prefix to be used for cache keys:
- Geocoder::Configuration.cache_prefix = "..."
+ Geocoder.configure(:cache_prefix => "...")
By default the prefix is `geocoder:`
@@ -477,7 +477,7 @@ Testing Apps that Use Geocoder
When writing tests for an app that uses Geocoder it may be useful to avoid network calls and have Geocoder return consistent, configurable results. To do this, configure and use the `:test` lookup. For example:
- Geocoder::Configuration.lookup = :test
+ Geocoder.configure(:lookup => :test)
Geocoder::Lookup::Test.add_stub(
"New York, NY", [
@@ -583,11 +583,11 @@ Error Handling
By default Geocoder will rescue any exceptions raised by calls to the geocoding service and return an empty array (using warn() to inform you of the error). You can override this and implement custom error handling for certain exceptions by using the `:always_raise` option:
- Geocoder::Configuration.always_raise = [SocketError, TimeoutError]
+ Geocoder.configure(:always_raise => [SocketError, TimeoutError])
You can also do this to raise all exceptions:
- Geocoder::Configuration.always_raise = :all
+ Geocoder.configure(:always_raise => :all)
See `lib/geocoder/exceptions.rb` for a list of raise-able exceptions.
@@ -25,6 +25,4 @@ def del(url)
end
end
-Geocoder.configure do |config|
- config.cache = AutoexpireCache.new(Redis.new)
-end
+Geocoder.configure(:cache => AutoexpireCache.new(Redis.new))
@@ -1,25 +1,21 @@
-Geocoder.configure do |config|
- ## Configurable parameters: if you wish to change some configurable
- ## behaviour in Geocoder, feel free to uncomment the following lines
- ## and provide custom parameters.
+Geocoder.configure(
+ # geocoding options
+ # :timeout => 3, # geocoding service timeout (secs)
+ # :lookup => :google, # name of geocoding service (symbol)
+ # :language => :en, # ISO-639 language code
+ # :use_https => false, # use HTTPS for lookup requests? (if supported)
+ # :http_proxy => nil, # HTTP proxy server (user:pass@host:port)
+ # :https_proxy => nil, # HTTPS proxy server (user:pass@host:port)
+ # :api_key => nil, # API key for geocoding service
+ # :cache => nil, # cache object (must respond to #[], #[]=, and #keys)
+ # :cache_prefix => "geocoder:", # prefix (string) to use for all cache keys
- # config.timeout = 3 # geocoding service timeout (secs)
- # config.lookup = :google # name of geocoding service (symbol)
- # config.language = :en # ISO-639 language code
- # config.use_https = false # use HTTPS for lookup requests? (if supported)
- # config.http_proxy = nil # HTTP proxy server (user:pass@host:port)
- # config.https_proxy = nil # HTTPS proxy server (user:pass@host:port)
- # config.api_key = nil # API key for geocoding service
- # config.cache = nil # cache object (must respond to #[], #[]=, and #keys)
- # config.cache_prefix = "geocoder:" # prefix (string) to use for all cache keys
+ # exceptions that should not be rescued by default
+ # (if you want to implement custom error handling);
+ # supports SocketError and TimeoutError
+ # :always_raise => [],
- ## exceptions that should not be rescued by default
- ## (if you want to implement custom error handling);
- ## supports SocketError and TimeoutError
- # config.always_raise = []
-
- ## Calculation options
- # config.units = :mi # :km for kilometers or :mi for miles
- # config.distances = :linear # :spherical or :linear
+ # calculation options
+ # :units => :mi, # :km for kilometers or :mi for miles
+ # :distances => :linear # :spherical or :linear
end
-
@@ -40,7 +40,7 @@ def coordinates_present?(*args)
# Distance spanned by one degree of latitude in the given units.
#
def latitude_degree_distance(units = nil)
- units ||= Geocoder::Configuration.units
+ units ||= Geocoder.config.units
2 * Math::PI * earth_radius(units) / 360
end
@@ -49,7 +49,7 @@ def latitude_degree_distance(units = nil)
# This ranges from around 69 miles at the equator to zero at the poles.
#
def longitude_degree_distance(latitude, units = nil)
- units ||= Geocoder::Configuration.units
+ units ||= Geocoder.config.units
latitude_degree_distance(units) * Math.cos(to_radians(latitude))
end
@@ -67,12 +67,12 @@ def longitude_degree_distance(latitude, units = nil)
# The options hash supports:
#
# * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>
- # See Geocoder::Configuration to know how configure default units.
+ # Use Geocoder.configure(:units => ...) to configure default units.
#
def distance_between(point1, point2, options = {})
# set default options
- options[:units] ||= Geocoder::Configuration.units
+ options[:units] ||= Geocoder.config.units
# convert to coordinate arrays
point1 = extract_coordinates(point1)
@@ -103,14 +103,14 @@ def distance_between(point1, point2, options = {})
# the spherical method is "correct" in that it returns the shortest path
# (one along a great circle) but the linear method is less confusing
# (returns due east or west when given two points with the same latitude).
- # See Geocoder::Configuration to know how configure default method.
+ # Use Geocoder.configure(:distances => ...) to configure calculation method.
#
# Based on: http://www.movable-type.co.uk/scripts/latlong.html
#
def bearing_between(point1, point2, options = {})
# set default options
- options[:method] ||= Geocoder::Configuration.distances
+ options[:method] ||= Geocoder.config.distances
options[:method] = :linear unless options[:method] == :spherical
# convert to coordinate arrays
@@ -197,12 +197,12 @@ def geographic_center(points)
# ways of specifying the point. Also accepts an options hash:
#
# * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>.
- # See Geocoder::Configuration to know how configure default units.
+ # Use Geocoder.configure(:units => ...) to configure default units.
#
def bounding_box(point, radius, options = {})
lat,lon = extract_coordinates(point)
radius = radius.to_f
- units = options[:units] || Geocoder::Configuration.units
+ units = options[:units] || Geocoder.config.units
[
lat - (radius / latitude_degree_distance(units)),
lon - (radius / longitude_degree_distance(lat, units)),
@@ -240,12 +240,12 @@ def to_degrees(*args)
end
def distance_to_radians(distance, units = nil)
- units ||= Geocoder::Configuration.units
+ units ||= Geocoder.config.units
distance.to_f / earth_radius(units)
end
def radians_to_distance(radians, units = nil)
- units ||= Geocoder::Configuration.units
+ units ||= Geocoder.config.units
radians * earth_radius(units)
end
@@ -265,10 +265,10 @@ def to_miles(km)
##
# Radius of the Earth in the given units (:mi or :km).
- # See Geocoder::Configuration to know how configure default units.
+ # Use Geocoder.configure(:units => ...) to configure default units.
#
def earth_radius(units = nil)
- units ||= Geocoder::Configuration.units
+ units ||= Geocoder.config.units
units == :km ? EARTH_RADIUS : to_miles(EARTH_RADIUS)
end
View
@@ -16,31 +16,31 @@ def self.run(args, out = STDOUT)
"Key for geocoding API (optional for most). For Google Premier use 'key client channel' separated by spaces") do |key|
premier_key = key.split(' ')
if premier_key.length == 3
- Geocoder::Configuration.api_key = premier_key
+ Geocoder.configure(:api_key => premier_key)
else
- Geocoder::Configuration.api_key = key
+ Geocoder.configure(:api_key => key)
end
end
opts.on("-l <language>", "--language <language>",
"Language of output (see API docs for valid choices)") do |language|
- Geocoder::Configuration.language = language
+ Geocoder.configure(:language => language)
end
opts.on("-p <proxy>", "--proxy <proxy>",
"HTTP proxy server to use (user:pass@host:port)") do |proxy|
- Geocoder::Configuration.http_proxy = proxy
+ Geocoder.configure(:http_proxy => proxy)
end
opts.on("-s <service>", Geocoder::Lookup.all_services_except_test, "--service <service>",
"Geocoding service: #{Geocoder::Lookup.all_services_except_test * ', '}") do |service|
- Geocoder::Configuration.lookup = service.to_sym
- Geocoder::Configuration.ip_lookup = service.to_sym
+ Geocoder.configure(:lookup => service.to_sym)
+ Geocoder.configure(:ip_lookup => service.to_sym)
end
opts.on("-t <seconds>", "--timeout <seconds>",
"Maximum number of seconds to wait for API response") do |timeout|
- Geocoder::Configuration.timeout = timeout.to_i
+ Geocoder.configure(:timeout => timeout.to_i)
end
opts.on("-j", "--json", "Print API's raw JSON response") do
Oops, something went wrong.

3 comments on commit a0448d4

@DouweM
DouweM commented on a0448d4 Mar 21, 2013

Our of curiosity, why was this change made? The block-based syntax seems to be the de-facto standard.

@alexreisner
Owner

The hash makes it easier to use nesting (for API-specific config). Also, this way the configuration is more like data than code, which seems simpler and more appropriate. I think DSLs are a little overused for configuration. What's the advantage?

@DouweM
DouweM commented on a0448d4 Mar 21, 2013

No big advantages, just the one: consistency among gems.

Please sign in to comment.