geocoder 0.9.13 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

@@ -15,6 +15,12 @@ module Geocoder
15
15
  # use HTTPS for lookup requests? (if supported)
16
16
  [:use_https, false],
17
17
 
18
+ # HTTP proxy server (user:pass@host:port)
19
+ [:http_proxy, nil],
20
+
21
+ # HTTPS proxy server (user:pass@host:port)
22
+ [:https_proxy, nil],
23
+
18
24
  # API key for geocoding service
19
25
  [:api_key, nil],
20
26
 
@@ -32,13 +38,6 @@ module Geocoder
32
38
  eval("def self.#{o}=(obj); @@#{o} = obj; end")
33
39
  end
34
40
 
35
- # legacy support
36
- def self.yahoo_app_id=(value)
37
- warn "DEPRECATION WARNING: Geocoder's 'yahoo_app_id' setting has been replaced by 'api_key'. " +
38
- "This method will be removed in Geocoder v1.0."
39
- @@api_key = value
40
- end
41
-
42
41
  ##
43
42
  # Set all values to default.
44
43
  #
@@ -1,4 +1,6 @@
1
1
  require 'net/http'
2
+ require 'uri'
3
+
2
4
  unless defined?(ActiveSupport::JSON)
3
5
  begin
4
6
  require 'rubygems' # for Ruby 1.8
@@ -20,12 +22,7 @@ module Geocoder
20
22
  # "205.128.54.202") for geocoding, or coordinates (latitude, longitude)
21
23
  # for reverse geocoding. Returns an array of <tt>Geocoder::Result</tt>s.
22
24
  #
23
- def search(query, *args)
24
- # convert coordinates as separate arguments to an array
25
- if query.is_a?(Numeric) and args.first.is_a?(Numeric)
26
- warn "DEPRECATION WARNING: Instead of passing latitude/longitude as separate arguments to the search method, please pass an array: [#{query},#{args.first}]. The old argument format will not be supported in Geocoder v.1.0."
27
- query = [query, args.first]
28
- end
25
+ def search(query)
29
26
 
30
27
  # if coordinates given as string, turn into array
31
28
  query = query.split(/\s*,\s*/) if coordinates?(query)
@@ -39,9 +36,39 @@ module Geocoder
39
36
  results(query, reverse).map{ |r| result_class.new(r) }
40
37
  end
41
38
 
39
+ ##
40
+ # Return the URL for a map of the given coordinates.
41
+ #
42
+ # Not necessarily implemented by all subclasses as only some lookups
43
+ # also provide maps.
44
+ #
45
+ def map_link_url(coordinates)
46
+ nil
47
+ end
48
+
42
49
 
43
50
  private # -------------------------------------------------------------
44
51
 
52
+ ##
53
+ # Object used to make HTTP requests.
54
+ #
55
+ def http_client
56
+ protocol = "http#{'s' if Geocoder::Configuration.use_https}"
57
+ proxy_name = "#{protocol}_proxy"
58
+ if proxy = Geocoder::Configuration.send(proxy_name)
59
+ proxy_url = protocol + '://' + proxy
60
+ begin
61
+ uri = URI.parse(proxy_url)
62
+ rescue URI::InvalidURIError
63
+ raise ConfigurationError,
64
+ "Error parsing #{protocol.upcase} proxy URL: '#{proxy_url}'"
65
+ end
66
+ Net::HTTP::Proxy(uri.host, uri.port, uri.user, uri.password)
67
+ else
68
+ Net::HTTP
69
+ end
70
+ end
71
+
45
72
  ##
46
73
  # Geocoder::Result object or nil on timeout or other error.
47
74
  #
@@ -74,7 +101,7 @@ module Geocoder
74
101
  rescue TimeoutError
75
102
  warn "Geocoding API not responding fast enough " +
76
103
  "(see Geocoder::Configuration.timeout to set limit)."
77
- end
104
+ end
78
105
  end
79
106
 
80
107
  ##
@@ -107,7 +134,7 @@ module Geocoder
107
134
  timeout(Geocoder::Configuration.timeout) do
108
135
  url = query_url(query, reverse)
109
136
  unless cache and response = cache[url]
110
- response = Net::HTTP.get_response(URI.parse(url)).body
137
+ response = http_client.get_response(URI.parse(url)).body
111
138
  if cache
112
139
  cache[url] = response
113
140
  end
@@ -134,7 +161,7 @@ module Geocoder
134
161
  # Does the given string look like latitude/longitude coordinates?
135
162
  #
136
163
  def coordinates?(value)
137
- !!value.to_s.match(/^[0-9\.\-]+, *[0-9\.\-]+$/)
164
+ value.is_a?(String) and !!value.to_s.match(/^-?[0-9\.]+, *-?[0-9\.]+$/)
138
165
  end
139
166
 
140
167
  ##
@@ -0,0 +1,33 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/bing"
3
+
4
+ module Geocoder::Lookup
5
+ class Bing < Base
6
+
7
+ def map_link_url(coordinates)
8
+ "http://www.bing.com/maps/default.aspx?cp=#{coordinates.join('~')}"
9
+ end
10
+
11
+ private # ---------------------------------------------------------------
12
+
13
+ def results(query, reverse = false)
14
+ return [] unless doc = fetch_data(query, reverse)
15
+
16
+ if doc['statusDescription'] == "OK"
17
+ return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : []
18
+ else
19
+ warn "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']})."
20
+ return []
21
+ end
22
+ end
23
+
24
+ def query_url(query, reverse = false)
25
+ params = {:key => Geocoder::Configuration.api_key}
26
+ params[:query] = query unless reverse
27
+
28
+ base_url = "http://dev.virtualearth.net/REST/v1/Locations"
29
+ url_tail = reverse ? "/#{query}?" : "?"
30
+ base_url + url_tail + hash_to_query(params)
31
+ end
32
+ end
33
+ end
@@ -4,6 +4,10 @@ require "geocoder/results/google"
4
4
  module Geocoder::Lookup
5
5
  class Google < Base
6
6
 
7
+ def map_link_url(coordinates)
8
+ "http://maps.google.com/maps?q=#{coordinates.join(',')}"
9
+ end
10
+
7
11
  private # ---------------------------------------------------------------
8
12
 
9
13
  def results(query, reverse = false)
@@ -4,6 +4,10 @@ require "geocoder/results/yahoo"
4
4
  module Geocoder::Lookup
5
5
  class Yahoo < Base
6
6
 
7
+ def map_link_url(coordinates)
8
+ "http://maps.yahoo.com/#lat=#{coordinates[0]}&lon=#{coordinates[1]}"
9
+ end
10
+
7
11
  private # ---------------------------------------------------------------
8
12
 
9
13
  def results(query, reverse = false)
@@ -18,7 +22,7 @@ module Geocoder::Lookup
18
22
 
19
23
  def query_url(query, reverse = false)
20
24
  params = {
21
- :location => query,
25
+ :location => query,
22
26
  :flags => "JXTSR",
23
27
  :gflags => "AC#{'R' if reverse}",
24
28
  :locale => "#{Geocoder::Configuration.language}_US",
@@ -28,4 +32,3 @@ module Geocoder::Lookup
28
32
  end
29
33
  end
30
34
  end
31
-
@@ -0,0 +1,39 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/yandex"
3
+
4
+ module Geocoder::Lookup
5
+ class Yandex < Base
6
+
7
+ def map_link_url(coordinates)
8
+ "http://maps.yandex.ru/?ll=#{coordinates.reverse.join(',')}"
9
+ end
10
+
11
+ private # ---------------------------------------------------------------
12
+
13
+ def results(query, reverse = false)
14
+ return [] unless doc = fetch_data(query, reverse)
15
+ if err = doc['error']
16
+ warn "Yandex Geocoding API error: #{err['status']} (#{err['message']})."
17
+ return []
18
+ end
19
+ if doc = doc['response']['GeoObjectCollection']
20
+ meta = doc['metaDataProperty']['GeocoderResponseMetaData']
21
+ return meta['found'].to_i > 0 ? doc['featureMember'] : []
22
+ else
23
+ warn "Yandex Geocoding API error: unexpected response format."
24
+ return []
25
+ end
26
+ end
27
+
28
+ def query_url(query, reverse = false)
29
+ query = query.split(",").reverse.join(",") if reverse
30
+ params = {
31
+ :geocode => query,
32
+ :format => "json",
33
+ :plng => "#{Geocoder::Configuration.language}", # supports ru, uk, be
34
+ :key => Geocoder::Configuration.api_key
35
+ }
36
+ "http://geocode-maps.yandex.ru/1.x/?" + hash_to_query(params)
37
+ end
38
+ end
39
+ end
@@ -9,7 +9,11 @@ module Geocoder
9
9
  module Base
10
10
 
11
11
  def geocoder_options
12
- @geocoder_options
12
+ if defined?(@geocoder_options)
13
+ @geocoder_options
14
+ elsif superclass.respond_to?(:geocoder_options)
15
+ superclass.geocoder_options
16
+ end
13
17
  end
14
18
 
15
19
  def geocoded_by
@@ -32,6 +32,22 @@ module Geocoder
32
32
  coordinates[1]
33
33
  end
34
34
 
35
+ def state
36
+ fail
37
+ end
38
+
39
+ def province
40
+ state
41
+ end
42
+
43
+ def state_code
44
+ fail
45
+ end
46
+
47
+ def province_code
48
+ state_code
49
+ end
50
+
35
51
  def country
36
52
  fail
37
53
  end
@@ -0,0 +1,48 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Bing < Base
5
+
6
+ def address(format = :full)
7
+ @data['address']['formattedAddress']
8
+ end
9
+
10
+ def city
11
+ @data['address']['locality']
12
+ end
13
+
14
+ def state_code
15
+ @data['address']['adminDistrict']
16
+ end
17
+
18
+ alias_method :state, :state_code
19
+
20
+ def country
21
+ @data['address']['countryRegion']
22
+ end
23
+
24
+ alias_method :country_code, :country
25
+
26
+ def postal_code
27
+ @data['address']['postalCode']
28
+ end
29
+
30
+ def coordinates
31
+ @data['point']['coordinates']
32
+ end
33
+
34
+ def address_data
35
+ @data['address']
36
+ end
37
+
38
+ def self.response_attributes
39
+ %w[bbox name confidence entityType]
40
+ end
41
+
42
+ response_attributes.each do |a|
43
+ define_method a do
44
+ @data[a]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -4,13 +4,21 @@ module Geocoder::Result
4
4
  class Freegeoip < Base
5
5
 
6
6
  def address(format = :full)
7
- "#{city}#{', ' + region_code unless region_code == ''} #{postal_code}, #{country}"
7
+ "#{city}#{', ' + state_code unless state_code == ''} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
8
8
  end
9
9
 
10
10
  def city
11
11
  @data['city']
12
12
  end
13
13
 
14
+ def state
15
+ @data['region_name']
16
+ end
17
+
18
+ def state_code
19
+ @data['region_code']
20
+ end
21
+
14
22
  def country
15
23
  @data['country_name']
16
24
  end
@@ -24,8 +32,7 @@ module Geocoder::Result
24
32
  end
25
33
 
26
34
  def self.response_attributes
27
- %w[city region_code region_name metrocode
28
- zipcode country_name country_code ip]
35
+ %w[metrocode ip]
29
36
  end
30
37
 
31
38
  response_attributes.each do |a|
@@ -8,7 +8,7 @@ module Geocoder::Result
8
8
  end
9
9
 
10
10
  def address(format = :full)
11
- "#{street_address}, #{city}, #{state} #{postal_code}, #{country}"
11
+ "#{street_address}, #{city}, #{state} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
12
12
  end
13
13
 
14
14
  def street_address
@@ -23,7 +23,7 @@ module Geocoder::Result
23
23
  @data['prov']
24
24
  end
25
25
 
26
- alias_method :province, :state
26
+ alias_method :state_code, :state
27
27
 
28
28
  def postal_code
29
29
  @data['postal']
@@ -34,19 +34,14 @@ module Geocoder::Result
34
34
  end
35
35
 
36
36
  def country_code
37
- prov = @data['prov']
38
- return nil if prov.nil? || prov == ""
39
- canadian_province_abbreviations.include?(@data['prov']) ? "CA" : "US"
40
- end
41
-
42
- def canadian_province_abbreviations
43
- %w[ON QC NS NB MB BC PE SK AB NL]
37
+ return nil if state.nil? || state == ""
38
+ canadian_province_abbreviations.include?(state) ? "CA" : "US"
44
39
  end
45
40
 
46
41
  def self.response_attributes
47
- %w[latt longt inlatt inlongt betweenRoad1 betweenRoad2 distance
48
- stnumber staddress city prov postal
49
- NearRoad NearRoadDistance intersection major_intersection]
42
+ %w[latt longt inlatt inlongt distance stnumber staddress prov
43
+ NearRoad NearRoadDistance betweenRoad1 betweenRoad2
44
+ intersection major_intersection]
50
45
  end
51
46
 
52
47
  response_attributes.each do |a|
@@ -54,5 +49,12 @@ module Geocoder::Result
54
49
  @data[a]
55
50
  end
56
51
  end
52
+
53
+
54
+ private # ----------------------------------------------------------------
55
+
56
+ def canadian_province_abbreviations
57
+ %w[ON QC NS NB MB BC PE SK AB NL]
58
+ end
57
59
  end
58
60
  end
@@ -12,8 +12,9 @@ module Geocoder::Result
12
12
  end
13
13
 
14
14
  def city
15
- fields = [:locality, :sublocality, :administrative_area_level_3,
16
- :administrative_area_level_2, :administrative_area_level_1]
15
+ fields = [:locality, :sublocality,
16
+ :administrative_area_level_3,
17
+ :administrative_area_level_2]
17
18
  fields.each do |f|
18
19
  if entity = address_components_of_type(f).first
19
20
  return entity['long_name']
@@ -21,6 +22,18 @@ module Geocoder::Result
21
22
  end
22
23
  end
23
24
 
25
+ def state
26
+ if state = address_components_of_type(:administrative_area_level_1).first
27
+ state['long_name']
28
+ end
29
+ end
30
+
31
+ def state_code
32
+ if state = address_components_of_type(:administrative_area_level_1).first
33
+ state['short_name']
34
+ end
35
+ end
36
+
24
37
  def country
25
38
  if country = address_components_of_type(:country).first
26
39
  country['long_name']
@@ -11,6 +11,14 @@ module Geocoder::Result
11
11
  @data['city']
12
12
  end
13
13
 
14
+ def state
15
+ @data['state']
16
+ end
17
+
18
+ def state_code
19
+ @data['statecode']
20
+ end
21
+
14
22
  def country
15
23
  @data['country']
16
24
  end
@@ -25,8 +33,8 @@ module Geocoder::Result
25
33
 
26
34
  def self.response_attributes
27
35
  %w[quality offsetlat offsetlon radius boundingbox name
28
- line1 line2 line3 line4 cross house street xstreet unittype unit postal
29
- neighborhood city county state country countrycode statecode countycode
36
+ line1 line2 line3 line4 cross house street xstreet unittype unit
37
+ neighborhood county countycode
30
38
  level0 level1 level2 level3 level4 level0code level1code level2code
31
39
  timezone areacode uzip hash woeid woetype]
32
40
  end