graticule 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -1,3 +1,8 @@
1
+ 0.2.9 (2009-04-14)
2
+ * Remove retired MapQuest geocoder
3
+ * Slightly more aggressive error handling for Geocoder.us
4
+ * Extend Numeric with #to_radians and #to_degrees
5
+
1
6
  0.2.8 (2008-10-03)
2
7
  * fixed missing files from gem
3
8
 
data/Manifest.txt CHANGED
@@ -7,6 +7,7 @@ bin/geocode
7
7
  init.rb
8
8
  lib/graticule.rb
9
9
  lib/graticule/cli.rb
10
+ lib/graticule/core_ext.rb
10
11
  lib/graticule/distance.rb
11
12
  lib/graticule/distance/haversine.rb
12
13
  lib/graticule/distance/spherical.rb
@@ -19,7 +20,6 @@ lib/graticule/geocoder/geocoder_us.rb
19
20
  lib/graticule/geocoder/google.rb
20
21
  lib/graticule/geocoder/host_ip.rb
21
22
  lib/graticule/geocoder/local_search_maps.rb
22
- lib/graticule/geocoder/map_quest.rb
23
23
  lib/graticule/geocoder/meta_carta.rb
24
24
  lib/graticule/geocoder/multi.rb
25
25
  lib/graticule/geocoder/multimap.rb
@@ -41,6 +41,7 @@ test/fixtures/responses/google/only_coordinates.xml
41
41
  test/fixtures/responses/google/partial.xml
42
42
  test/fixtures/responses/google/server_error.xml
43
43
  test/fixtures/responses/google/success.xml
44
+ test/fixtures/responses/google/success_multiple_results.xml
44
45
  test/fixtures/responses/google/unavailable.xml
45
46
  test/fixtures/responses/google/unknown_address.xml
46
47
  test/fixtures/responses/host_ip/private.txt
data/README.txt CHANGED
@@ -26,4 +26,4 @@ Graticule includes a command line interface (CLI).
26
26
 
27
27
  = Source
28
28
 
29
- The source code for Graticule is available at http://source.collectiveidea.com/public/geocode/trunk
29
+ The source code for Graticule is available at http://github.com/collectiveidea/graticule. Patches and bug reports are welcome at http://collectiveidea.lighthouseapp.com/projects/20262-graticule
data/lib/graticule.rb CHANGED
@@ -3,6 +3,7 @@ $:.unshift(File.dirname(__FILE__))
3
3
  require 'active_support'
4
4
 
5
5
  require 'graticule/version'
6
+ require 'graticule/core_ext'
6
7
  require 'graticule/location'
7
8
  require 'graticule/geocoder'
8
9
  require 'graticule/geocoder/base'
@@ -10,7 +11,6 @@ require 'graticule/geocoder/bogus'
10
11
  require 'graticule/geocoder/rest'
11
12
  require 'graticule/geocoder/google'
12
13
  require 'graticule/geocoder/host_ip'
13
- require 'graticule/geocoder/map_quest'
14
14
  require 'graticule/geocoder/multi'
15
15
  require 'graticule/geocoder/yahoo'
16
16
  require 'graticule/geocoder/geocoder_ca'
@@ -0,0 +1,15 @@
1
+ module Graticule
2
+ module RadiansAndDegrees
3
+ # Convert from degrees to radians
4
+ def to_radians
5
+ ( self / 360.0 ) * Math::PI * 2
6
+ end
7
+
8
+ # Convert from radians to degrees
9
+ def to_degrees
10
+ ( self * 360.0 ) / Math::PI / 2
11
+ end
12
+ end
13
+ end
14
+
15
+ Numeric.send :include, Graticule::RadiansAndDegrees
@@ -13,17 +13,6 @@ module Graticule
13
13
  def initialize
14
14
  raise NotImplementedError
15
15
  end
16
-
17
- # Convert from degrees to radians
18
- def self.deg2rad(deg)
19
- (deg * PI / 180)
20
- end
21
-
22
- # Convert from radians to degrees
23
- def self.rad2deg(rad)
24
- (rad * 180 / PI)
25
- end
26
-
27
16
  end
28
17
  end
29
18
  end
@@ -17,10 +17,10 @@ module Graticule
17
17
  # #=> 101.061720831836
18
18
  #
19
19
  def self.distance(from, to, units = :miles)
20
- from_longitude = deg2rad(from.longitude)
21
- from_latitude = deg2rad(from.latitude)
22
- to_longitude = deg2rad(to.longitude)
23
- to_latitude = deg2rad(to.latitude)
20
+ from_longitude = from.longitude.to_radians
21
+ from_latitude = from.latitude.to_radians
22
+ to_longitude = to.longitude.to_radians
23
+ to_latitude = to.latitude.to_radians
24
24
 
25
25
  latitude_delta = to_latitude - from_latitude
26
26
  longitude_delta = to_longitude - from_longitude
@@ -16,10 +16,10 @@ module Graticule
16
16
  # #=> 101.061720831853
17
17
  #
18
18
  def self.distance(from, to, units = :miles)
19
- from_longitude = deg2rad(from.longitude)
20
- from_latitude = deg2rad(from.latitude)
21
- to_longitude = deg2rad(to.longitude)
22
- to_latitude = deg2rad(to.latitude)
19
+ from_longitude = from.longitude.to_radians
20
+ from_latitude = from.latitude.to_radians
21
+ to_longitude = to.longitude.to_radians
22
+ to_latitude = to.latitude.to_radians
23
23
 
24
24
  Math.acos(
25
25
  Math.sin(from_latitude) *
@@ -18,10 +18,10 @@ module Graticule
18
18
  # #=> 101.070118000159
19
19
  #
20
20
  def self.distance(from, to, units = :miles)
21
- from_longitude = deg2rad(from.longitude)
22
- from_latitude = deg2rad(from.latitude)
23
- to_longitude = deg2rad(to.longitude)
24
- to_latitude = deg2rad(to.latitude)
21
+ from_longitude = from.longitude.to_radians
22
+ from_latitude = from.latitude.to_radians
23
+ to_longitude = to.longitude.to_radians
24
+ to_latitude = to.latitude.to_radians
25
25
 
26
26
  earth_major_axis_radius = EARTH_MAJOR_AXIS_RADIUS[units.to_sym]
27
27
  earth_minor_axis_radius = EARTH_MINOR_AXIS_RADIUS[units.to_sym]
@@ -42,6 +42,8 @@ module Graticule #:nodoc:
42
42
 
43
43
  def check_error(xml) #:nodoc:
44
44
  raise AddressError, xml.text if xml.text =~ /couldn't find this address! sorry/
45
+ raise Error, xml.text if xml.text =~ /Your browser sent a request that this server could not understand./
46
+ raise Error, xml.text if !(xml.text =~ /geo:Point/)
45
47
  end
46
48
 
47
49
  end
@@ -47,11 +47,11 @@ module Graticule #:nodoc:
47
47
  'xal' => "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0")
48
48
 
49
49
  if address
50
- l.street = value(address.elements['//ThoroughfareName/text()'])
51
- l.locality = value(address.elements['//LocalityName/text()'])
52
- l.region = value(address.elements['//AdministrativeAreaName/text()'])
53
- l.postal_code = value(address.elements['//PostalCodeNumber/text()'])
54
- l.country = value(address.elements['//CountryNameCode/text()'])
50
+ l.street = value(address.elements['.//ThoroughfareName/text()'])
51
+ l.locality = value(address.elements['.//LocalityName/text()'])
52
+ l.region = value(address.elements['.//AdministrativeAreaName/text()'])
53
+ l.postal_code = value(address.elements['.//PostalCodeNumber/text()'])
54
+ l.country = value(address.elements['.//CountryNameCode/text()'])
55
55
  l.precision = PRECISION[address.attribute('Accuracy').value.to_i] || :unknown
56
56
  end
57
57
  end
@@ -15,7 +15,7 @@ module Graticule
15
15
  end
16
16
 
17
17
  def attributes
18
- [:latitude, :longitude, :street, :locality, :region, :postal_code, :country].inject({}) do |result,attr|
18
+ [:latitude, :longitude, :street, :locality, :region, :postal_code, :country, :precision].inject({}) do |result,attr|
19
19
  result[attr] = self.send(attr) unless self.send(attr).blank?
20
20
  result
21
21
  end
@@ -2,7 +2,7 @@ module Graticule #:nodoc:
2
2
  module Version #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 8
5
+ TINY = 9
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -54,10 +54,6 @@ a {
54
54
  padding: 1em 0;
55
55
  }
56
56
 
57
- pre {
58
- background-color: #2A2A2A;
59
- }
60
-
61
57
  dl {
62
58
  background-color: #DDD;
63
59
  padding: 1em;
@@ -0,0 +1,88 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <kml xmlns='http://earth.google.com/kml/2.0'><Response>
3
+ <name>Queen St West</name>
4
+ <Status>
5
+ <code>200</code>
6
+ <request>geocode</request>
7
+ </Status>
8
+ <Placemark id='p1'>
9
+ <address>Queen St W, Toronto, ON, Canada</address>
10
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Toronto</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare></Locality></AdministrativeArea></Country></AddressDetails>
11
+ <ExtendedData>
12
+ <LatLonBox east='-79.3792510' south='43.6387420' west='-79.4460830' north='43.6524210'/>
13
+ </ExtendedData>
14
+ <Point><coordinates>-79.4125590,43.6455030,0</coordinates></Point>
15
+ </Placemark>
16
+ <Placemark id='p2'>
17
+ <address>Queen St W, Brampton, ON, Canada</address>
18
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Brampton</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare></Locality></AdministrativeArea></Country></AddressDetails>
19
+ <ExtendedData>
20
+ <LatLonBox east='-79.7599410' south='43.6477210' west='-79.8030440' north='43.6859000'/>
21
+ </ExtendedData>
22
+ <Point><coordinates>-79.7814960,43.6665410,0</coordinates></Point>
23
+ </Placemark>
24
+ <Placemark id='p3'>
25
+ <address>Queen St W, Levin, 5510, New Zealand</address>
26
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>NZ</CountryNameCode><CountryName>New Zealand</CountryName><Locality><LocalityName>Levin</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>5510</PostalCodeNumber></PostalCode></Locality></Country></AddressDetails>
27
+ <ExtendedData>
28
+ <LatLonBox east='175.2872230' south='-40.6221080' west='175.2645080' north='-40.6111560'/>
29
+ </ExtendedData>
30
+ <Point><coordinates>175.2753040,-40.6170160,0</coordinates></Point>
31
+ </Placemark>
32
+ <Placemark id='p4'>
33
+ <address>Queen St W, Mt Forest, ON, Canada</address>
34
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Mt Forest</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>N0G</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
35
+ <ExtendedData>
36
+ <LatLonBox east='-80.7320620' south='43.9748569' west='-80.7542680' north='43.9811521'/>
37
+ </ExtendedData>
38
+ <Point><coordinates>-80.7434380,43.9779890,0</coordinates></Point>
39
+ </Placemark>
40
+ <Placemark id='p5'>
41
+ <address>Queen St W, St Marys, ON, Canada</address>
42
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>St Marys</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>N4X</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
43
+ <ExtendedData>
44
+ <LatLonBox east='-81.1442510' south='43.2548039' west='-81.1674090' north='43.2610991'/>
45
+ </ExtendedData>
46
+ <Point><coordinates>-81.1556430,43.2579490,0</coordinates></Point>
47
+ </Placemark>
48
+ <Placemark id='p6'>
49
+ <address>Queen St W, Barrie, ON, Canada</address>
50
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Barrie</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>L0L</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
51
+ <ExtendedData>
52
+ <LatLonBox east='-79.8661300' south='44.5748470' west='-79.8859520' north='44.5835790'/>
53
+ </ExtendedData>
54
+ <Point><coordinates>-79.8762460,44.5791840,0</coordinates></Point>
55
+ </Placemark>
56
+ <Placemark id='p7'>
57
+ <address>Queen St W, Owen Sound, ON, Canada</address>
58
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Owen Sound</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>N0H</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
59
+ <ExtendedData>
60
+ <LatLonBox east='-81.1333070' south='44.6303544' west='-81.1489540' north='44.6366496'/>
61
+ </ExtendedData>
62
+ <Point><coordinates>-81.1428830,44.6334130,0</coordinates></Point>
63
+ </Placemark>
64
+ <Placemark id='p8'>
65
+ <address>Queen St W, Mississauga, ON, Canada</address>
66
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Mississauga</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>L5H</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
67
+ <ExtendedData>
68
+ <LatLonBox east='-79.5927510' south='43.5315270' west='-79.6117140' north='43.5498140'/>
69
+ </ExtendedData>
70
+ <Point><coordinates>-79.6023990,43.5407460,0</coordinates></Point>
71
+ </Placemark>
72
+ <Placemark id='p9'>
73
+ <address>Queen St W, Cambridge, ON, Canada</address>
74
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Cambridge</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>N3C</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
75
+ <ExtendedData>
76
+ <LatLonBox east='-80.3108330' south='43.4202100' west='-80.3287680' north='43.4312910'/>
77
+ </ExtendedData>
78
+ <Point><coordinates>-80.3202040,43.4267810,0</coordinates></Point>
79
+ </Placemark>
80
+ <Placemark id='p10'>
81
+ <address>Queen St W, Sault Ste. Marie, ON, Canada</address>
82
+ <AddressDetails Accuracy='6' xmlns='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0'><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Sault Ste. Marie</LocalityName><Thoroughfare><ThoroughfareName>Queen St W</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>P6A</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
83
+ <ExtendedData>
84
+ <LatLonBox east='-84.3411900' south='46.5155194' west='-84.3592850' north='46.5218146'/>
85
+ </ExtendedData>
86
+ <Point><coordinates>-84.3506780,46.5187300,0</coordinates></Point>
87
+ </Placemark>
88
+ </Response></kml>
@@ -25,6 +25,27 @@ module Graticule
25
25
  assert_equal location, @geocoder.locate('1600 Amphitheatre Parkway, Mountain View, CA')
26
26
  end
27
27
 
28
+
29
+ # The #locate parameters are broad, so the XML response contains
30
+ # multiple results at street-level precision. We expect to get the
31
+ # first result back, and it should not contain a postal code.
32
+ def test_success_multiple_results
33
+ return unless prepare_response(:success_multiple_results)
34
+
35
+ location = Location.new(
36
+ :street => "Queen St W",
37
+ :locality => "Toronto",
38
+ :region => "ON",
39
+ :postal_code => nil,
40
+ :country => "CA",
41
+ :longitude => -79.4125590,
42
+ :latitude => 43.6455030,
43
+ :precision => :street
44
+ )
45
+ assert_equal location, @geocoder.locate('Queen St West, Toronto, ON CA')
46
+ end
47
+
48
+
28
49
  # <?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://earth.google.com/kml/2.0'><Response><name>15-17 </name><Status><code>200</code><request>geocode</request></Status><Placemark id='p1'><Point><coordinates>-17.000000,15.000000,0</coordinates></Point></Placemark></Response></kml>
29
50
  def test_only_coordinates
30
51
  return unless prepare_response(:only_coordinates)
@@ -43,7 +64,8 @@ module Graticule
43
64
  :region => "CA",
44
65
  :country => "US",
45
66
  :longitude => -122.418333,
46
- :latitude => 37.775000
67
+ :latitude => 37.775000,
68
+ :precision => :city
47
69
  )
48
70
 
49
71
  assert_equal location, @geocoder.locate('sf ca')
@@ -11,7 +11,6 @@ module Graticule
11
11
  @location = Location.new(
12
12
  :street => "Oxford Street",
13
13
  :locality => "London",
14
- :region => "London",
15
14
  :postal_code => "W1",
16
15
  :country => "GB",
17
16
  :longitude => -0.14839,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graticule
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Keepers
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-03 00:00:00 -04:00
12
+ date: 2009-04-14 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.7.0
33
+ version: 1.8.2
34
34
  version:
35
35
  description: Graticule is a geocoding API that provides a common interface to all the popular services, including Google, Yahoo, Geocoder.us, and MetaCarta.
36
36
  email: brandon@opensoul.org
@@ -59,6 +59,7 @@ files:
59
59
  - init.rb
60
60
  - lib/graticule.rb
61
61
  - lib/graticule/cli.rb
62
+ - lib/graticule/core_ext.rb
62
63
  - lib/graticule/distance.rb
63
64
  - lib/graticule/distance/haversine.rb
64
65
  - lib/graticule/distance/spherical.rb
@@ -71,7 +72,6 @@ files:
71
72
  - lib/graticule/geocoder/google.rb
72
73
  - lib/graticule/geocoder/host_ip.rb
73
74
  - lib/graticule/geocoder/local_search_maps.rb
74
- - lib/graticule/geocoder/map_quest.rb
75
75
  - lib/graticule/geocoder/meta_carta.rb
76
76
  - lib/graticule/geocoder/multi.rb
77
77
  - lib/graticule/geocoder/multimap.rb
@@ -93,6 +93,7 @@ files:
93
93
  - test/fixtures/responses/google/partial.xml
94
94
  - test/fixtures/responses/google/server_error.xml
95
95
  - test/fixtures/responses/google/success.xml
96
+ - test/fixtures/responses/google/success_multiple_results.xml
96
97
  - test/fixtures/responses/google/unavailable.xml
97
98
  - test/fixtures/responses/google/unknown_address.xml
98
99
  - test/fixtures/responses/host_ip/private.txt
@@ -152,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
153
  requirements: []
153
154
 
154
155
  rubyforge_project: graticule
155
- rubygems_version: 1.2.0
156
+ rubygems_version: 1.3.1
156
157
  signing_key:
157
158
  specification_version: 2
158
159
  summary: API for using all the popular geocoding services.
@@ -1,109 +0,0 @@
1
- module Graticule #:nodoc:
2
- module Geocoder #:nodoc:
3
-
4
- # First you need a Mapquest API key. You can register for one here:
5
- # http://www.mapquest.com/features/main.adp?page=developer_tools_oapi
6
- #
7
- # Then you create a MapquestGeocode object and start locating addresses:
8
- #
9
- # gg = Graticule.service(:map_quest).new(MAPS_API_KEY)
10
- # location = gg.locate :street => '1600 Amphitheater Pkwy', :locality => 'Mountain View', :region => 'CA'
11
- # p location.coordinates
12
- #
13
- class MapQuest < Rest
14
- # http://trc.mapquest.com
15
-
16
- PRECISION = {
17
- 0 => :unknown,
18
- 'COUNTRY' => :country,
19
- 'STATE' => :state,
20
- 'COUNTY' => :state,
21
- 'CITY' => :city,
22
- 'ZIP' => :zip,'ZIP7' => :zip,'ZIP9' => :zip,
23
- 'INTERSECTIONS' => :street,
24
- 'STREET' => :street,
25
- 'ADDRESS' => :address
26
- }
27
-
28
- # Creates a new MapquestGeocode that will use Mapquest API key +key+.
29
- #
30
- # WARNING: The MapQuest API Keys tend to be already URI encoded. If this is the case
31
- # be sure to URI.unescape the key in the call to new
32
- def initialize(key)
33
- @key = key
34
- @url = URI.parse 'http://web.openapi.mapquest.com/oapi/transaction'
35
- end
36
-
37
- # Locates +address+ returning a Location
38
- def locate(address)
39
- get map_attributes(location_from_params(address))
40
- end
41
-
42
- private
43
-
44
- def map_attributes(location)
45
- mapping = {:street => :address, :locality => :city, :region => :stateProvince, :postal_code => :postalcoe, :country => :country}
46
- mapping.keys.inject({}) do |result,attribute|
47
- result[mapping[attribute]] = location.attributes[attribute] unless location.attributes[attribute].blank?
48
- result
49
- end
50
- end
51
-
52
- # Extracts a Location from +xml+.
53
- def parse_response(xml) #:nodoc:
54
- address = REXML::XPath.first(xml, '/advantage/geocode/locations/location')
55
-
56
- Location.new \
57
- :street => value(address.elements['//address/text()']),
58
- :locality => value(address.elements['//city/text()']),
59
- :region => value(address.elements['//stateProvince/text()']),
60
- :postal_code => value(address.elements['//postalCode/text()']),
61
- :country => value(address.elements['//country/text()']),
62
- :latitude => value(address.elements['//latitude/text()']),
63
- :longitude => value(address.elements['//longitude/text()']),
64
- :precision => PRECISION[address.elements['//geocodeQuality'].text] || :unknown
65
- end
66
-
67
- # Extracts and raises an error from +xml+, if any.
68
- def check_error(xml) #:nodoc:
69
- return unless xml.elements['//error']
70
- status = xml.elements['//error/code'].text.to_i
71
- msg = xml.elements['//error/text'].text
72
- case status
73
- when 255..299 then
74
- raise CredentialsError, msg
75
- when 400..500 then
76
- raise AddressError, msg
77
- when 600.699 then
78
- raise Error, msg
79
- when 900 then
80
- raise AddressError, 'invalid latitude'
81
- when 901 then
82
- raise AddressError, 'invalid longitude'
83
- when 902 then
84
- raise AddressError, 'error parsing params'
85
- when 9902 then
86
- raise CredentialsError, 'invalid key'
87
- when 9904 then
88
- raise CredentialsError, 'key missing'
89
- else
90
- raise Error, "unknown error #{status}: #{msg}"
91
- end
92
- end
93
-
94
- # Creates a URL from the Hash +params+. Automatically adds the key and
95
- # sets the output type to 'xml'.
96
- def make_url(params) #:nodoc:
97
- super params.merge({:key => @key, :transaction => 'geocode', :ambiguities => 0})
98
- end
99
-
100
- def value(element)
101
- element.value if element
102
- end
103
-
104
- def text(element)
105
- element.text if element
106
- end
107
- end
108
- end
109
- end