google_maps_juice 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +2 -2
- data/README.md +54 -2
- data/google_maps_juice.gemspec +2 -2
- data/lib/google_maps_juice.rb +4 -3
- data/lib/google_maps_juice/client.rb +1 -1
- data/lib/google_maps_juice/directions.rb +55 -0
- data/lib/google_maps_juice/directions/response.rb +63 -0
- data/lib/google_maps_juice/endpoint.rb +1 -1
- data/lib/google_maps_juice/version.rb +1 -1
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f26ed08354506950932680c98e078c385bce57047a1b99bcab2a122bc26c2112
|
4
|
+
data.tar.gz: 9ea5e1e090fb76f2189468cacfdd9e6993a45936501d78f1bd6ee018a99c80b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc3ae38123522b60496ff3094678f1aef15dbda36fc4eecd0dc0cc3f18f3389c54b995064e384167ec33e945ab2f8de9766ae80c8bdf8e1086ccb855acfe9cbd
|
7
|
+
data.tar.gz: 612b4cd78edf58cc7ac7c9ba67884c37b32130d7d4eb065aabeaf5cfb9011b3652e684eae4d78fef0f7ceb65584a45721a0a1d1e3de8b20746c7737659bea9c3
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.3
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -17,6 +17,7 @@ This gem aims at progressively covering a fair amount of those widely-used servi
|
|
17
17
|
|
18
18
|
* Geocoding
|
19
19
|
* Time Zone
|
20
|
+
* Directions
|
20
21
|
|
21
22
|
Contributors are welcome!
|
22
23
|
|
@@ -72,13 +73,13 @@ This is especially useful in some "hybrid" scenario, where an API key is shared
|
|
72
73
|
|
73
74
|
## Error Handling
|
74
75
|
|
75
|
-
If Google servers respond with a non-successful HTTP status code, i.e. `4xx` or `5xx`, a `GoogleMapsJuice::
|
76
|
+
If Google servers respond with a non-successful HTTP status code, i.e. `4xx` or `5xx`, a `GoogleMapsJuice::ResponseError` is raised with a message of the form `'HTTP 503 - Error details as returned by the server'`.
|
76
77
|
|
77
78
|
API errors are also handled, based on the `status` attribute of Google's JSON response, and the optional `error_message` attribute.
|
78
79
|
|
79
80
|
* `GoogleMapsJuice::ZeroResults` is raised when `status` is `'ZERO_RESULTS'`
|
80
81
|
* `GoogleMapsJuice::ApiLimitError` is raised when `status` is `'OVER_DAILY_LIMIT'` or `'OVER_QUERY_LIMIT'`
|
81
|
-
* `GoogleMapsJuice::
|
82
|
+
* `GoogleMapsJuice::ResponseError` is raised when `status` is not `OK` with a message of the form `API <status> - <error_message>`
|
82
83
|
|
83
84
|
|
84
85
|
## Geocoding
|
@@ -181,6 +182,57 @@ The `by_location` method returns a `GoogleMapsJuice::Timezone::Response`. It's a
|
|
181
182
|
* `dst_offset`: the offset for daylight-savings time in seconds
|
182
183
|
|
183
184
|
|
185
|
+
## Directions
|
186
|
+
|
187
|
+
[Google's Directions API](https://developers.google.com/maps/documentation/directions/intro#DirectionsRequests) returns the possible routes of given origin and destination geographic locations; Google's API accepts address, textual latitude/longitude value, or place ID of which you wish to calculate directions. Currently this gem implements only latitude/longitude mode.
|
188
|
+
`GoogleMapsJuice` will raise an `ArgumentError` if some unsupported param is passed, or when none of the required params are passed.
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
response = GoogleMapsJuice::Directions.find(origin: '41.8892732,12.4921921', destination: '41.9016488,12.4583003')
|
192
|
+
```
|
193
|
+
|
194
|
+
Compared to Google's raw API request, it provides validation of both origin and destination, in order to avoid sending requests when they would fail for sure - to learn more see `spec/unit/directions_spec.rb`.
|
195
|
+
|
196
|
+
**Accepted params:**
|
197
|
+
|
198
|
+
* Both `origin` and `destination` are mandatory
|
199
|
+
* `origin` is composed by `latitude` and `longitude`, comma separated float values
|
200
|
+
* `destination` same format as `origin`
|
201
|
+
|
202
|
+
|
203
|
+
### Directions Response
|
204
|
+
|
205
|
+
The `find` method returns a `GoogleMapsJuice::Directions::Response`. It's a `Hash` representation of Google's JSON response. However, it also provides a few useful methods:
|
206
|
+
|
207
|
+
* `results`: the `Hash` raw result
|
208
|
+
|
209
|
+
* `routes`: an `Array` of `GoogleMapsJuice::Directions::Response::Route` objects
|
210
|
+
|
211
|
+
* `first`: the first `Route` of the `routes` `List`
|
212
|
+
|
213
|
+
As described in [Google's Directions API](https://developers.google.com/maps/documentation/directions/intro#Routes), the response contains all possible routes. Each route has some attributes and one or more *legs*, wich in turn have one or more *steps*.
|
214
|
+
If no waypoints are passed, the route response will contain a single leg. Since `GoogleMapsJuice::Directions` doesn't handles waypoints yet, only the first leg is considered for each route.
|
215
|
+
The `GoogleMapsJuice::Directions::Response::Route` is a representation of a response route and provides methods to access all route's attributes:
|
216
|
+
|
217
|
+
* `summary`: a brief description of the route
|
218
|
+
|
219
|
+
* `legs`: all legs of the route, generally a single one
|
220
|
+
|
221
|
+
* `steps`: all steps of the first route's leg
|
222
|
+
|
223
|
+
* `duration`: time duration of the first route's leg
|
224
|
+
|
225
|
+
* `distance`: distance between origin and destination of first route's leg
|
226
|
+
|
227
|
+
* `start_location`: `latitude`/`longitude` of the origin first route's leg
|
228
|
+
|
229
|
+
* `end_location`: `latitude`/`longitude` of the destination first route's leg
|
230
|
+
|
231
|
+
* `start_address`: address of the origin first route's leg
|
232
|
+
|
233
|
+
* `end_address`: address of the destination first route's leg
|
234
|
+
|
235
|
+
|
184
236
|
## Development
|
185
237
|
|
186
238
|
After checking out the repo, run `bin/setup` to install dependencies. Create a `.env` file and save your Google API key there; if you want to use a different key for testing, put it in `.env.test` and it will override the one in `.env`.
|
data/google_maps_juice.gemspec
CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_dependency 'activesupport'
|
25
|
+
spec.add_dependency 'activesupport'
|
26
26
|
spec.add_dependency 'excon'
|
27
27
|
|
28
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.17.2'
|
29
29
|
spec.add_development_dependency 'rake', '~> 12.3'
|
30
30
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
31
31
|
spec.add_development_dependency 'webmock', '~> 3.4'
|
data/lib/google_maps_juice.rb
CHANGED
@@ -14,8 +14,9 @@ module GoogleMapsJuice
|
|
14
14
|
autoload :Endpoint, 'google_maps_juice/endpoint'
|
15
15
|
autoload :Geocoding, 'google_maps_juice/geocoding'
|
16
16
|
autoload :Timezone, 'google_maps_juice/timezone'
|
17
|
+
autoload :Directions, 'google_maps_juice/directions'
|
17
18
|
|
18
|
-
class
|
19
|
-
class ApiLimitError <
|
20
|
-
class ZeroResults <
|
19
|
+
class ResponseError < RuntimeError; end
|
20
|
+
class ApiLimitError < ResponseError; end
|
21
|
+
class ZeroResults < ResponseError; end
|
21
22
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module GoogleMapsJuice
|
2
|
+
class Directions < Endpoint
|
3
|
+
|
4
|
+
ENDPOINT = '/directions'
|
5
|
+
|
6
|
+
autoload :Response, 'google_maps_juice/directions/response'
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def find(params, api_key: GoogleMapsJuice.config.api_key)
|
10
|
+
client = GoogleMapsJuice::Client.new(api_key: api_key)
|
11
|
+
new(client).find(params)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def find(params)
|
16
|
+
validate_find_params(params)
|
17
|
+
response_text = @client.get("#{ENDPOINT}/json", params)
|
18
|
+
response = JSON.parse(response_text, object_class: Response)
|
19
|
+
detect_errors(response)
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate_find_params(params)
|
23
|
+
raise ArgumentError, 'Hash argument expected' unless params.is_a?(Hash)
|
24
|
+
|
25
|
+
supported_keys = %w[origin destination]
|
26
|
+
validate_supported_params(params, supported_keys)
|
27
|
+
|
28
|
+
required_keys = %w[origin destination]
|
29
|
+
validate_any_required_params(params, required_keys)
|
30
|
+
|
31
|
+
validate_geo_coordinate(params)
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_geo_coordinate(params)
|
35
|
+
raise ArgumentError, 'String argument expected' unless params.values.all?(String)
|
36
|
+
|
37
|
+
geocoords = params.values.map { |x| x.split(',') }.flatten
|
38
|
+
geocoords.map! { |x| Float(x).round(7) }
|
39
|
+
raise ArgumentError, 'Wrong geo-coordinates' if geocoords.size != 4
|
40
|
+
|
41
|
+
validate_location_params(geocoords)
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate_location_params(params)
|
45
|
+
latitudes = params[0], params[2]
|
46
|
+
if latitudes.any? { |l| l.abs > 90 }
|
47
|
+
raise ArgumentError, 'Wrong latitude value'
|
48
|
+
end
|
49
|
+
longitudes = params[1], params[3]
|
50
|
+
if longitudes.any? { |l| l.abs > 180 }
|
51
|
+
raise ArgumentError, 'Wrong longitude value'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/hash/slice'
|
4
|
+
|
5
|
+
module GoogleMapsJuice
|
6
|
+
class Directions::Response < GoogleMapsJuice::Endpoint::Response
|
7
|
+
def results
|
8
|
+
self['routes']
|
9
|
+
end
|
10
|
+
|
11
|
+
def routes
|
12
|
+
results.map { |r| Route.new(r) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def first
|
16
|
+
routes.first
|
17
|
+
end
|
18
|
+
|
19
|
+
class Route
|
20
|
+
attr_reader :route, :first_leg
|
21
|
+
def initialize(route)
|
22
|
+
@route = route
|
23
|
+
@first_leg = route['legs'].first
|
24
|
+
end
|
25
|
+
|
26
|
+
def legs
|
27
|
+
route['legs']
|
28
|
+
end
|
29
|
+
|
30
|
+
def summary
|
31
|
+
route['summary']
|
32
|
+
end
|
33
|
+
|
34
|
+
def steps
|
35
|
+
first_leg['steps']
|
36
|
+
end
|
37
|
+
|
38
|
+
def duration
|
39
|
+
first_leg['duration']
|
40
|
+
end
|
41
|
+
|
42
|
+
def distance
|
43
|
+
first_leg['distance']
|
44
|
+
end
|
45
|
+
|
46
|
+
def start_location
|
47
|
+
first_leg['start_location']
|
48
|
+
end
|
49
|
+
|
50
|
+
def end_location
|
51
|
+
first_leg['end_location']
|
52
|
+
end
|
53
|
+
|
54
|
+
def start_address
|
55
|
+
first_leg['start_address']
|
56
|
+
end
|
57
|
+
|
58
|
+
def end_address
|
59
|
+
first_leg['end_address']
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -14,7 +14,7 @@ module GoogleMapsJuice
|
|
14
14
|
elsif response.limit_error?
|
15
15
|
raise GoogleMapsJuice::ApiLimitError, build_error_message(response)
|
16
16
|
elsif response.error?
|
17
|
-
raise GoogleMapsJuice::
|
17
|
+
raise GoogleMapsJuice::ResponseError, "API #{build_error_message(response)}"
|
18
18
|
else
|
19
19
|
response
|
20
20
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google_maps_juice
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algonauti srl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: excon
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.17.2
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.17.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,6 +159,8 @@ files:
|
|
159
159
|
- lib/google_maps_juice.rb
|
160
160
|
- lib/google_maps_juice/client.rb
|
161
161
|
- lib/google_maps_juice/configuration.rb
|
162
|
+
- lib/google_maps_juice/directions.rb
|
163
|
+
- lib/google_maps_juice/directions/response.rb
|
162
164
|
- lib/google_maps_juice/endpoint.rb
|
163
165
|
- lib/google_maps_juice/geocoding.rb
|
164
166
|
- lib/google_maps_juice/geocoding/response.rb
|
@@ -183,8 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
185
|
- !ruby/object:Gem::Version
|
184
186
|
version: '0'
|
185
187
|
requirements: []
|
186
|
-
|
187
|
-
rubygems_version: 2.7.3
|
188
|
+
rubygems_version: 3.0.3
|
188
189
|
signing_key:
|
189
190
|
specification_version: 4
|
190
191
|
summary: 'Client for popular Google Maps API Services: Geocoding, Time Zones'
|