graticule 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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