mapquest 0.0.1 → 0.0.2
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/.rspec +2 -0
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/lib/mapquest.rb +10 -4
- data/lib/mapquest/request.rb +1 -1
- data/lib/mapquest/response.rb +24 -2
- data/lib/mapquest/services/core.rb +13 -2
- data/lib/mapquest/services/directions.rb +28 -22
- data/lib/mapquest/services/geocoding.rb +35 -54
- data/lib/mapquest/version.rb +1 -1
- data/mapquest.gemspec +3 -2
- data/spec/directions_spec.rb +92 -0
- data/spec/fixtures/directions/invalid_key.json +1 -0
- data/spec/fixtures/directions/invalid_value.json +1 -0
- data/spec/fixtures/directions/route_only.json +1 -0
- data/spec/fixtures/directions/valid_route.json +366 -0
- data/spec/fixtures/geocoding/illegal_argument.json +1 -0
- data/{test/fixtures → spec/fixtures/geocoding}/invalid_key.json +0 -0
- data/spec/fixtures/geocoding/location_maxResults.json +1 -0
- data/spec/fixtures/geocoding/location_only.json +1 -0
- data/spec/fixtures/geocoding/location_thumbMaps.json +1 -0
- data/spec/fixtures/geocoding/location_thumbMaps_maxResults.json +1 -0
- data/spec/fixtures/geocoding/reverse_location.json +1 -0
- data/spec/geocoding_spec.rb +172 -0
- data/spec/mapquest_spec.rb +61 -0
- data/spec/spec_helper.rb +14 -0
- metadata +53 -49
- data/test/directions_spec.rb +0 -21
- data/test/fixtures/no_data.json +0 -1
- data/test/fixtures/results.json +0 -1
- data/test/geocoding_spec.rb +0 -78
- data/test/spec_helper.rb +0 -13
data/.rspec
ADDED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# MapQuest [](https://travis-ci.org/ggordan/mapquest)
|
|
1
|
+
# MapQuest [](https://travis-ci.org/ggordan/mapquest) [](https://codeclimate.com/github/ggordan/mapquest)
|
|
2
2
|
|
|
3
3
|
A gem to communicate with the MapQuest web services.
|
|
4
4
|
|
|
@@ -28,7 +28,7 @@ Or install it yourself as:
|
|
|
28
28
|
mapquest = MapQuest.new API_KEY
|
|
29
29
|
|
|
30
30
|
# Get geolocation data
|
|
31
|
-
data = mapquest.geocoding.
|
|
31
|
+
data = mapquest.geocoding.address "London, UK"
|
|
32
32
|
|
|
33
33
|
# Get lat/long coordinates of all the locations found
|
|
34
34
|
data.locations.each { |location| puts location[:latLng] }
|
data/Rakefile
CHANGED
data/lib/mapquest.rb
CHANGED
|
@@ -8,27 +8,33 @@ require "mapquest/services/geocoding"
|
|
|
8
8
|
|
|
9
9
|
class MapQuest
|
|
10
10
|
|
|
11
|
-
attr_accessor :api_key
|
|
12
|
-
class Error < StandardError; end
|
|
11
|
+
attr_accessor :api_key
|
|
13
12
|
|
|
14
13
|
def initialize(key)
|
|
15
14
|
@api_key = key
|
|
16
15
|
end
|
|
17
16
|
|
|
17
|
+
# Acess the geocoding API
|
|
18
18
|
def geocoding
|
|
19
19
|
Services::Geocoding.new self
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
# Access the directions API
|
|
22
23
|
def directions
|
|
23
24
|
Services::Directions.new self
|
|
24
25
|
end
|
|
25
26
|
|
|
27
|
+
# Request handler for the web services. Creates a new request based on the API method provided, and returns a new
|
|
28
|
+
# response object. Removes any empty parameters that were provided. This method is only used internally.
|
|
29
|
+
# ==Required parameters
|
|
30
|
+
# * method [Hash] The hash containing the API method, version and type.
|
|
31
|
+
# * params [Hash] The parameters used for creating the query string
|
|
32
|
+
# * response [Response] The response object of the API being called
|
|
26
33
|
def request(method, params, response)
|
|
27
34
|
req = Request.new method
|
|
28
35
|
params.merge! :key => api_key
|
|
29
36
|
params.each { |k,v| params.delete(k) if v.nil? }
|
|
30
|
-
|
|
31
|
-
return @response
|
|
37
|
+
response.new req.query(params), params
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
end
|
data/lib/mapquest/request.rb
CHANGED
data/lib/mapquest/response.rb
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
class MapQuest
|
|
2
2
|
class Response
|
|
3
3
|
|
|
4
|
-
attr_reader :response, :valid
|
|
4
|
+
attr_reader :response, :valid, :params
|
|
5
5
|
|
|
6
6
|
class InvalidRequest < StandardError; end
|
|
7
7
|
|
|
8
|
-
def initialize(response_string)
|
|
8
|
+
def initialize(response_string, params = {})
|
|
9
|
+
@params = params
|
|
9
10
|
@response = JSON.parse(response_string, :symbolize_names => true)
|
|
11
|
+
valid_request?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Check whether the request made to the API call is valid. Raises an error if the response code is 500
|
|
15
|
+
def valid_request?
|
|
16
|
+
# 400 - Error with input
|
|
17
|
+
# 403 - Key related error
|
|
18
|
+
# 500 -Unknown error
|
|
19
|
+
# Check http://www.mapquestapi.com/geocoding/status_codes.html for more details
|
|
20
|
+
@valid = case status[:code]
|
|
21
|
+
when 500
|
|
22
|
+
raise InvalidRequest
|
|
23
|
+
when 400, 403
|
|
24
|
+
false
|
|
25
|
+
else
|
|
26
|
+
true
|
|
27
|
+
end
|
|
10
28
|
end
|
|
11
29
|
|
|
12
30
|
def info
|
|
@@ -17,6 +35,10 @@ class MapQuest
|
|
|
17
35
|
info[:copyright]
|
|
18
36
|
end
|
|
19
37
|
|
|
38
|
+
def options
|
|
39
|
+
response[:options]
|
|
40
|
+
end
|
|
41
|
+
|
|
20
42
|
# Returns information about the response.
|
|
21
43
|
# :code is an integer return value. See http://www.mapquestapi.com/geocoding/status_codes.html
|
|
22
44
|
# :messages subfield is an array of error messages which describe the status.
|
|
@@ -4,8 +4,19 @@ class MapQuest
|
|
|
4
4
|
|
|
5
5
|
attr_accessor :mapquest
|
|
6
6
|
|
|
7
|
-
def initialize(
|
|
8
|
-
@mapquest =
|
|
7
|
+
def initialize(mapquest)
|
|
8
|
+
@mapquest = mapquest
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call_api(api, version, call, options)
|
|
12
|
+
# Remove invalid options
|
|
13
|
+
options.keys.select { |k| api.class::VALID_OPTIONS.include? k }
|
|
14
|
+
api_method = {
|
|
15
|
+
:location => api.class::API_LOCATION,
|
|
16
|
+
:version => version,
|
|
17
|
+
:call => call
|
|
18
|
+
}
|
|
19
|
+
mapquest.request api_method, options, api.class::Response
|
|
9
20
|
end
|
|
10
21
|
|
|
11
22
|
end
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
class MapQuest
|
|
2
2
|
module Services
|
|
3
|
+
# The main class used for communicating with the MapQuest Directions API
|
|
3
4
|
class Directions < Core
|
|
4
5
|
|
|
5
6
|
API_LOCATION = :directions
|
|
7
|
+
VALID_OPTIONS = [:to, :from]
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
# Allows you to search for direction to a location. It returns a response object of the route
|
|
10
|
+
#
|
|
11
|
+
# Example: .route :to => "London, UK", "Manchester, UK"
|
|
12
|
+
#
|
|
13
|
+
# ==Required parameters
|
|
14
|
+
# * from [String] The location where to end route
|
|
15
|
+
# * to [String] The location from which to start route
|
|
16
|
+
def route(from, to, options = {})
|
|
17
|
+
if from && to
|
|
18
|
+
options[:to] = to
|
|
19
|
+
options[:from] = from
|
|
20
|
+
call_api self, 1, 'route', options
|
|
15
21
|
else
|
|
16
|
-
raise
|
|
22
|
+
raise ArgumentError, 'The method must receive the to, and from parameters'
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
class Response < MapQuest::Response
|
|
21
27
|
|
|
22
|
-
def
|
|
23
|
-
|
|
24
|
-
true
|
|
25
|
-
else
|
|
26
|
-
false
|
|
27
|
-
end
|
|
28
|
+
def initialize(response_string, params = {})
|
|
29
|
+
super
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def route
|
|
@@ -38,25 +40,29 @@ class MapQuest
|
|
|
38
40
|
|
|
39
41
|
# Returns the calculated distance of the route in <b>miles</b>
|
|
40
42
|
def distance
|
|
41
|
-
|
|
43
|
+
if valid
|
|
44
|
+
route[:distance].to_i
|
|
45
|
+
end
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def locations
|
|
45
|
-
|
|
49
|
+
if valid
|
|
50
|
+
route[:locations]
|
|
51
|
+
end
|
|
46
52
|
end
|
|
47
53
|
|
|
48
54
|
# Returns a hash of the maneuvers in the route
|
|
49
55
|
def maneuvers
|
|
50
|
-
|
|
56
|
+
if valid
|
|
57
|
+
route[:legs].first[:maneuvers]
|
|
58
|
+
end
|
|
51
59
|
end
|
|
52
60
|
|
|
53
61
|
# Returns only the narratives for the route as a list
|
|
54
62
|
def narrative
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
narrative.push maneuver[:narrative]
|
|
63
|
+
if valid
|
|
64
|
+
route[:legs].first[:maneuvers].map { |maneuver| maneuver[:narrative] }
|
|
58
65
|
end
|
|
59
|
-
narrative
|
|
60
66
|
end
|
|
61
67
|
|
|
62
68
|
end
|
|
@@ -1,79 +1,60 @@
|
|
|
1
1
|
class MapQuest
|
|
2
2
|
module Services
|
|
3
|
+
# The main class used for communicating with the MapQuest Geocoding API
|
|
3
4
|
class Geocoding < Core
|
|
4
5
|
|
|
5
6
|
API_LOCATION = :geocoding
|
|
7
|
+
VALID_OPTIONS = [:location,:maxResults,:thumbMaps]
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
#
|
|
9
|
+
class TooManyLocations < StandardError; end
|
|
10
|
+
|
|
11
|
+
# Allows you to search for a single location and returns a response object of the found locations
|
|
12
|
+
#
|
|
13
|
+
# Example: .address :location => "London, UK"
|
|
14
|
+
#
|
|
15
|
+
# ==Required parameters
|
|
16
|
+
# * location [String] The location for which you wish to get data
|
|
17
|
+
# ==Optional parameters
|
|
11
18
|
# * :maxResults [Integer] The number of results to limit the response to. Defaults to -1 (-1 indicates no limit)
|
|
12
19
|
# * :thumbMaps [Boolean] Return a URL to a static map thumbnail image for a location. Defaults to true
|
|
13
|
-
def
|
|
14
|
-
raise
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
params.keys.each { |k| params.delete(k) unless [:location,:maxResults,:thumbMaps].include? k }
|
|
18
|
-
api_method = {
|
|
19
|
-
:location => API_LOCATION,
|
|
20
|
-
:version => '1',
|
|
21
|
-
:call => 'address'
|
|
22
|
-
}
|
|
23
|
-
mapquest.request api_method, params, Response
|
|
20
|
+
def address(location, options = {})
|
|
21
|
+
raise ArgumentError, 'Method must receive a location (string)' unless location
|
|
22
|
+
options[:location] = location
|
|
23
|
+
call_api self, 1, 'address', options
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
26
|
+
# Allows you to search for a location using lat/lng values and returns a response object of the found locations
|
|
27
|
+
#
|
|
28
|
+
# Example: .reverse :location => ['40.0755','-76.329999']
|
|
29
|
+
#
|
|
30
|
+
# ==Required parameters
|
|
31
|
+
# * location [Array] The lat, and lng to search for
|
|
32
|
+
# ==Optional parameters
|
|
30
33
|
# * :maxResults [Integer] The number of results to limit the response to. Defaults to -1 (-1 indicates no limit)
|
|
31
34
|
# * :thumbMaps [Boolean] Return a URL to a static map thumbnail image for a location. Defaults to true
|
|
32
|
-
def reverse(
|
|
33
|
-
raise
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
:location => API_LOCATION,
|
|
37
|
-
:version => '1',
|
|
38
|
-
:call => 'reverse'
|
|
39
|
-
}
|
|
40
|
-
mapquest.request api_method, params, Response
|
|
35
|
+
def reverse(location, options = {})
|
|
36
|
+
raise ArgumentError, 'Method must receive a location (array)' unless location && location.kind_of?(Array)
|
|
37
|
+
options[:location] = location.join(',')
|
|
38
|
+
call_api self, 1, 'reverse', options
|
|
41
39
|
end
|
|
42
40
|
|
|
43
|
-
class Response < MapQuest::Response
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
super response_string
|
|
47
|
-
valid_request?
|
|
48
|
-
end
|
|
42
|
+
class Response < MapQuest::Response
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# 400 - Error with input
|
|
53
|
-
# 403 - Key related error
|
|
54
|
-
# 500 -Unknown error
|
|
55
|
-
# Check http://www.mapquestapi.com/geocoding/status_codes.html for more details
|
|
56
|
-
invalid_requests = [400, 403, 500]
|
|
57
|
-
if invalid_requests.include? status[:code]
|
|
58
|
-
if status[:code] === 500
|
|
59
|
-
raise InvalidRequest
|
|
60
|
-
end
|
|
61
|
-
@valid = false
|
|
62
|
-
else
|
|
63
|
-
@valid = true
|
|
64
|
-
end
|
|
44
|
+
def initialize(response_string, params = {})
|
|
45
|
+
super
|
|
65
46
|
end
|
|
66
47
|
|
|
67
48
|
def locations
|
|
68
|
-
if valid
|
|
49
|
+
if valid
|
|
50
|
+
response[:results].first[:locations]
|
|
51
|
+
end
|
|
69
52
|
end
|
|
70
53
|
|
|
71
54
|
def providedLocation
|
|
72
|
-
if valid
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def options
|
|
76
|
-
if valid then response[:options] else status end
|
|
55
|
+
if valid
|
|
56
|
+
response[:results].first[:providedLocation]
|
|
57
|
+
end
|
|
77
58
|
end
|
|
78
59
|
|
|
79
60
|
end
|
data/lib/mapquest/version.rb
CHANGED
data/mapquest.gemspec
CHANGED
|
@@ -21,7 +21,8 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.add_dependency "json"
|
|
22
22
|
spec.add_dependency "rest-client"
|
|
23
23
|
|
|
24
|
-
spec.add_development_dependency "rspec", "~> 2.8
|
|
25
|
-
spec.add_development_dependency "bundler", "~> 1.
|
|
24
|
+
spec.add_development_dependency "rspec", "~> 2.8"
|
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.0"
|
|
26
|
+
spec.add_development_dependency "webmock", "~> 1.11"
|
|
26
27
|
spec.add_development_dependency "rake"
|
|
27
28
|
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe MapQuest::Services::Directions do
|
|
4
|
+
|
|
5
|
+
let(:mapquest) { MapQuest.new 'xxx' }
|
|
6
|
+
|
|
7
|
+
describe '#route' do
|
|
8
|
+
it 'should be an instance of Directions' do
|
|
9
|
+
mapquest.directions.should be_an_instance_of MapQuest::Services::Directions
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '#route' do
|
|
14
|
+
|
|
15
|
+
context 'to or from are not provided' do
|
|
16
|
+
it 'should raise an error if location is not provided' do
|
|
17
|
+
expect { mapquest.directions.route 'xxx' }.to raise_error ArgumentError
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'to and from are provided' do
|
|
22
|
+
subject(:directions) { mapquest.directions.route 'Lancaster,PA', 'York,PA' }
|
|
23
|
+
|
|
24
|
+
it 'should receive to and from' do
|
|
25
|
+
fixture = fixture 'directions/route_only'
|
|
26
|
+
query = {
|
|
27
|
+
:key => 'xxx',
|
|
28
|
+
:from => 'Lancaster,PA',
|
|
29
|
+
:to => 'York,PA'
|
|
30
|
+
}
|
|
31
|
+
stub_request(:get, 'www.mapquestapi.com/directions/v1/route').with(:query => query).to_return(:body => fixture)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'when request is valid' do
|
|
36
|
+
|
|
37
|
+
describe MapQuest::Services::Directions::Response do
|
|
38
|
+
|
|
39
|
+
let(:max_results) { -1 }
|
|
40
|
+
let(:fixt) { 'directions/route_only' }
|
|
41
|
+
let(:thumb_maps) { true }
|
|
42
|
+
|
|
43
|
+
let(:valid_response) do
|
|
44
|
+
query = {
|
|
45
|
+
:key => 'xxx',
|
|
46
|
+
:from => 'Lancaster,PA',
|
|
47
|
+
:to => 'York,PA'
|
|
48
|
+
}
|
|
49
|
+
MapQuest::Services::Directions::Response.new fixture(fixt), query
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it { valid_response.status[:code].should == 0 }
|
|
53
|
+
it { valid_response.status[:messages].should == [] }
|
|
54
|
+
it { valid_response.valid.should == true }
|
|
55
|
+
it { valid_response.locations.should be_kind_of(Array) }
|
|
56
|
+
it { valid_response.maneuvers.should be_kind_of(Array) }
|
|
57
|
+
it { valid_response.distance.should be_kind_of(Integer) }
|
|
58
|
+
it { valid_response.time.should be_kind_of(Integer) }
|
|
59
|
+
it { valid_response.route.should be_kind_of(Hash) }
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'when invalid request' do
|
|
65
|
+
|
|
66
|
+
context 'when api key is invalid' do
|
|
67
|
+
let(:wrong_api_key_response) do
|
|
68
|
+
MapQuest::Services::Directions::Response.new fixture 'directions/invalid_key'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe MapQuest::Services::Geocoding::Response do
|
|
72
|
+
it { wrong_api_key_response.status[:code].should == 403 }
|
|
73
|
+
it { wrong_api_key_response.status[:messages].first.should match /^This is not a valid key/ }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when argument is invalid' do
|
|
78
|
+
|
|
79
|
+
let(:invalid_argument) do
|
|
80
|
+
MapQuest::Services::Geocoding::Response.new fixture 'directions/invalid_value'
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe MapQuest::Services::Geocoding::Response do
|
|
84
|
+
it { invalid_argument.status[:code].should == 400 }
|
|
85
|
+
it { invalid_argument.status[:messages].first.should match /^Error processing route/ }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
end
|