google_maps_service 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/README.md +4 -2
- data/google_maps_service.gemspec +2 -1
- data/lib/google_maps_service.rb +1 -1
- data/lib/google_maps_service/client.rb +28 -5
- data/lib/google_maps_service/convert.rb +26 -17
- data/lib/google_maps_service/directions.rb +7 -12
- data/lib/google_maps_service/distance_matrix.rb +11 -30
- data/lib/google_maps_service/roads.rb +3 -17
- data/lib/google_maps_service/validator.rb +23 -0
- data/lib/google_maps_service/version.rb +1 -1
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03d75b9918a795abfabe46f98659846b37979be9
|
4
|
+
data.tar.gz: 7a501e622f0d8898ad38b65b30e9957fce151aad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b67c6aac29d022afc1fb48106c436cfcec7f3370d1de7e7a5eb63f339ebe52ef198cd4f7e6797a2865ff7ea1566165ad40f6c413e92de58ccd27bc82140e965b
|
7
|
+
data.tar.gz: 972a7298efc5729bf9a1cba1f617a9dfdee1096fcc3056dcad1b705d792df8230e5fd48caed3009aeee552594a26c1ad00f2df3a362feee2898d5232fa40cf37
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Ruby Client for Google Maps Services
|
2
2
|
|
3
|
-
|
3
|
+
[](http://badge.fury.io/rb/google_maps_service) [](https://travis-ci.org/edwardsamuel/google-maps-services-ruby) [](https://gemnasium.com/edwardsamuel/google-maps-services-ruby) [](https://codeclimate.com/github/edwardsamuel/google-maps-services-ruby) [](https://coveralls.io/github/edwardsamuel/google-maps-services-ruby?branch=master)
|
4
|
+
|
5
|
+
*This is porting of [Python Client for Google Maps Services](https://github.com/googlemaps/google-maps-services-python). All Google Maps Service APIs are supported, but some features (e.g: rate limiting) are not supported right now.*
|
4
6
|
|
5
7
|
## Description
|
6
8
|
|
@@ -129,4 +131,4 @@ For more usage examples, check out [the tests](spec/).
|
|
129
131
|
[Time Zone API]: https://developers.google.com/maps/documentation/timezone/
|
130
132
|
[Roads API]: https://developers.google.com/maps/documentation/roads/
|
131
133
|
|
132
|
-
[issues]: https://github.com/
|
134
|
+
[issues]: https://github.com/edwardsamuel/google-maps-services-ruby/issues
|
data/google_maps_service.gemspec
CHANGED
@@ -19,8 +19,9 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_runtime_dependency 'multi_json', '~> 1.11'
|
21
21
|
spec.add_runtime_dependency 'hurley', '~> 0.1'
|
22
|
+
spec.add_runtime_dependency 'retriable', '~> 2.0.2'
|
22
23
|
spec.add_runtime_dependency 'ruby-hmac', '~> 0.4.0'
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
24
25
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
26
|
spec.add_development_dependency 'yard', '~> 0.8.7.6'
|
26
27
|
spec.add_development_dependency 'rspec', '~> 3.3'
|
data/lib/google_maps_service.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'hurley'
|
3
3
|
require 'multi_json'
|
4
|
+
require 'retriable'
|
4
5
|
|
5
6
|
module GoogleMapsService
|
6
7
|
class Client
|
7
8
|
USER_AGENT = "GoogleGeoApiClientRuby/#{GoogleMapsService::VERSION}"
|
8
9
|
DEFAULT_BASE_URL = "https://maps.googleapis.com"
|
9
|
-
|
10
|
+
RETRIABLE_ERRORS = [GoogleMapsService::Error::ServerError, GoogleMapsService::Error::RateLimitError]
|
10
11
|
|
11
12
|
include GoogleMapsService::Directions
|
12
13
|
include GoogleMapsService::DistanceMatrix
|
@@ -28,10 +29,27 @@ module GoogleMapsService
|
|
28
29
|
# @return [String]
|
29
30
|
attr_reader :client_secret
|
30
31
|
|
32
|
+
# Connection timeout for HTTP requests, in seconds.
|
33
|
+
# You should specify read_timeout in addition to this option.
|
34
|
+
# @return [Integer]
|
35
|
+
attr_reader :connect_timeout
|
36
|
+
|
37
|
+
# Read timeout for HTTP requests, in seconds.
|
38
|
+
# You should specify connect_timeout in addition to this
|
39
|
+
# @return [Integer]
|
40
|
+
attr_reader :read_timeout
|
41
|
+
|
42
|
+
# Timeout across multiple retriable requests, in seconds.
|
43
|
+
# @return [Integer]
|
44
|
+
attr_reader :retry_timeout
|
45
|
+
|
31
46
|
def initialize(options={})
|
32
47
|
@key = options[:key] || GoogleMapsService.key
|
33
48
|
@client_id = options[:client_id] || GoogleMapsService.client_id
|
34
49
|
@client_secret = options[:client_secret] || GoogleMapsService.client_secret
|
50
|
+
@connect_timeout = options[:connect_timeout] || GoogleMapsService.connect_timeout
|
51
|
+
@read_timeout = options[:read_timeout] || GoogleMapsService.read_timeout
|
52
|
+
@retry_timeout = options[:retry_timeout] || GoogleMapsService.retry_timeout || 60
|
35
53
|
end
|
36
54
|
|
37
55
|
# Get the current HTTP client
|
@@ -47,18 +65,23 @@ module GoogleMapsService
|
|
47
65
|
def new_client
|
48
66
|
client = Hurley::Client.new
|
49
67
|
client.request_options.query_class = Hurley::Query::Flat
|
68
|
+
client.request_options.timeout = @read_timeout if @read_timeout
|
69
|
+
client.request_options.open_timeout = @connect_timeout if @connect_timeout
|
50
70
|
client.header[:user_agent] = USER_AGENT
|
51
71
|
client
|
52
72
|
end
|
53
73
|
|
54
74
|
def get(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custom_response_decoder: nil)
|
55
75
|
url = base_url + generate_auth_url(path, params, accepts_client_id)
|
56
|
-
response = client.get url
|
57
76
|
|
58
|
-
|
59
|
-
|
77
|
+
Retriable.retriable timeout: @retry_timeout,
|
78
|
+
on: RETRIABLE_ERRORS do |try|
|
79
|
+
response = client.get url
|
80
|
+
if custom_response_decoder
|
81
|
+
return custom_response_decoder.call(response)
|
82
|
+
end
|
83
|
+
return decode_response_body(response)
|
60
84
|
end
|
61
|
-
return decode_response_body(response)
|
62
85
|
end
|
63
86
|
|
64
87
|
# Extract and parse body response as hash. Throw an error if there is something wrong with the response.
|
@@ -31,18 +31,9 @@ module GoogleMapsService
|
|
31
31
|
# @return [Array] Pair of lat and lng array.
|
32
32
|
def normalize_latlng(arg)
|
33
33
|
if arg.kind_of?(Hash)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
if arg.has_key?(:latitude) and arg.has_key?(:longitude)
|
38
|
-
return arg[:latitude], arg[:longitude]
|
39
|
-
end
|
40
|
-
if arg.has_key?("lat") and arg.has_key?("lng")
|
41
|
-
return arg["lat"], arg["lng"]
|
42
|
-
end
|
43
|
-
if arg.has_key?("latitude") and arg.has_key?("longitude")
|
44
|
-
return arg["latitude"], arg["longitude"]
|
45
|
-
end
|
34
|
+
lat = arg[:lat] || arg[:latitude] || arg["lat"] || arg["latitude"]
|
35
|
+
lng = arg[:lng] || arg[:longitude] || arg["lng"] || arg["longitude"]
|
36
|
+
return lat, lng
|
46
37
|
elsif arg.kind_of?(Array)
|
47
38
|
return arg[0], arg[1]
|
48
39
|
end
|
@@ -137,16 +128,34 @@ module GoogleMapsService
|
|
137
128
|
# @return [String]
|
138
129
|
def bounds(arg)
|
139
130
|
if arg.kind_of?(Hash)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
return "#{latlng(arg[:southwest])}|#{latlng(arg[:northeast])}"
|
144
|
-
end
|
131
|
+
southwest = arg[:southwest] || arg["southwest"]
|
132
|
+
northeast = arg[:northeast] || arg["northeast"]
|
133
|
+
return "#{latlng(southwest)}|#{latlng(northeast)}"
|
145
134
|
end
|
146
135
|
|
147
136
|
raise ArgumentError, "Expected a bounds (southwest/northeast) Hash, but got #{arg.class}"
|
148
137
|
end
|
149
138
|
|
139
|
+
# Converts an array of waypoints (path) to the format expected by the Google Maps
|
140
|
+
# server.
|
141
|
+
#
|
142
|
+
# Accept two representation of waypoint:
|
143
|
+
#
|
144
|
+
# 1. String: Name of place or comma-separated lat/lon pair.
|
145
|
+
# 2. Hash/Array: Lat/lon pair.
|
146
|
+
#
|
147
|
+
# @param [Array, String, Hash] waypoints Path.
|
148
|
+
#
|
149
|
+
# @return [String]
|
150
|
+
def waypoints(waypoints)
|
151
|
+
if waypoints.kind_of?(Array) and waypoints.length == 2 and waypoints[0].kind_of?(Numeric) and waypoints[1].kind_of?(Numeric)
|
152
|
+
waypoints = [waypoints]
|
153
|
+
end
|
154
|
+
|
155
|
+
waypoints = as_list(waypoints)
|
156
|
+
return join_list('|', waypoints.map { |k| k.kind_of?(String) ? k : latlng(k) })
|
157
|
+
end
|
158
|
+
|
150
159
|
# Decodes a Polyline string into a list of lat/lng hash.
|
151
160
|
#
|
152
161
|
# See the developer docs for a detailed description of this encoding:
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative './validator'
|
2
|
+
|
1
3
|
module GoogleMapsService
|
2
4
|
|
3
5
|
# Performs requests to the Google Maps Directions API.
|
@@ -47,14 +49,7 @@ module GoogleMapsService
|
|
47
49
|
destination: _convert_waypoint(destination)
|
48
50
|
}
|
49
51
|
|
50
|
-
if mode
|
51
|
-
# NOTE(broady): the mode parameter is not validated by the Maps API
|
52
|
-
# server. Check here to prevent silent failures.
|
53
|
-
unless ["driving", "walking", "bicycling", "transit"].include?(mode)
|
54
|
-
raise ArgumentError, "Invalid travel mode."
|
55
|
-
end
|
56
|
-
params[:mode] = mode
|
57
|
-
end
|
52
|
+
params[:mode] = GoogleMapsService::Validator.travel_mode(mode) if mode
|
58
53
|
|
59
54
|
if waypoints
|
60
55
|
waypoints = GoogleMapsService::Convert.as_list(waypoints)
|
@@ -64,8 +59,8 @@ module GoogleMapsService
|
|
64
59
|
params[:waypoints] = GoogleMapsService::Convert.join_list("|", waypoints)
|
65
60
|
end
|
66
61
|
|
67
|
-
params[:alternatives] =
|
68
|
-
params[:avoid] = GoogleMapsService::Convert.join_list(
|
62
|
+
params[:alternatives] = 'true' if alternatives
|
63
|
+
params[:avoid] = GoogleMapsService::Convert.join_list('|', avoid) if avoid
|
69
64
|
params[:language] = language if language
|
70
65
|
params[:units] = units if units
|
71
66
|
params[:region] = region if region
|
@@ -73,13 +68,13 @@ module GoogleMapsService
|
|
73
68
|
params[:arrival_time] = GoogleMapsService::Convert.time(arrival_time) if arrival_time
|
74
69
|
|
75
70
|
if departure_time and arrival_time
|
76
|
-
raise ArgumentError,
|
71
|
+
raise ArgumentError, 'Should not specify both departure_time and arrival_time.'
|
77
72
|
end
|
78
73
|
|
79
74
|
params[:transit_mode] = GoogleMapsService::Convert.join_list("|", transit_mode) if transit_mode
|
80
75
|
params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference
|
81
76
|
|
82
|
-
return get(
|
77
|
+
return get('/maps/api/directions/json', params)[:routes]
|
83
78
|
end
|
84
79
|
|
85
80
|
private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative './validator'
|
2
|
+
|
1
3
|
module GoogleMapsService
|
2
4
|
|
3
5
|
# Performs requests to the Google Maps Distance Matrix API.
|
@@ -39,47 +41,26 @@ module GoogleMapsService
|
|
39
41
|
departure_time: nil, arrival_time: nil, transit_mode: nil,
|
40
42
|
transit_routing_preference: nil)
|
41
43
|
params = {
|
42
|
-
origins:
|
43
|
-
destinations:
|
44
|
+
origins: GoogleMapsService::Convert.waypoints(origins),
|
45
|
+
destinations: GoogleMapsService::Convert.waypoints(destinations)
|
44
46
|
}
|
45
47
|
|
46
|
-
if mode
|
47
|
-
# NOTE(broady): the mode parameter is not validated by the Maps API
|
48
|
-
# server. Check here to prevent silent failures.
|
49
|
-
unless ["driving", "walking", "bicycling", "transit"].include?(mode)
|
50
|
-
raise ArgumentError, "Invalid travel mode."
|
51
|
-
end
|
52
|
-
params[:mode] = mode
|
53
|
-
end
|
54
|
-
|
55
48
|
params[:language] = language if language
|
56
|
-
|
57
|
-
if avoid
|
58
|
-
unless ["tolls", "highways", "ferries"].include?(avoid)
|
59
|
-
raise ArgumentError, "Invalid route restriction."
|
60
|
-
end
|
61
|
-
params[:avoid] = avoid
|
62
|
-
end
|
63
|
-
|
49
|
+
params[:mode] = GoogleMapsService::Validator.travel_mode(mode) if mode
|
50
|
+
params[:avoid] = GoogleMapsService::Validator.avoid(avoid) if avoid
|
64
51
|
|
65
52
|
params[:units] = units if units
|
66
|
-
params[:departure_time] =
|
67
|
-
params[:arrival_time] =
|
53
|
+
params[:departure_time] = GoogleMapsService::Convert.time(departure_time) if departure_time
|
54
|
+
params[:arrival_time] = GoogleMapsService::Convert.time(arrival_time) if arrival_time
|
68
55
|
|
69
56
|
if departure_time and arrival_time
|
70
|
-
raise ArgumentError,
|
57
|
+
raise ArgumentError, 'Should not specify both departure_time and arrival_time.'
|
71
58
|
end
|
72
59
|
|
73
|
-
params[:transit_mode] =
|
60
|
+
params[:transit_mode] = GoogleMapsService::Convert.join_list("|", transit_mode) if transit_mode
|
74
61
|
params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference
|
75
62
|
|
76
|
-
return get(
|
63
|
+
return get('/maps/api/distancematrix/json', params)
|
77
64
|
end
|
78
|
-
|
79
|
-
private
|
80
|
-
def _convert_path(waypoints)
|
81
|
-
waypoints = GoogleMapsService::Convert.as_list(waypoints)
|
82
|
-
return GoogleMapsService::Convert.join_list("|", waypoints.map { |k| k.kind_of?(String) ? k : GoogleMapsService::Convert.latlng(k) })
|
83
|
-
end
|
84
65
|
end
|
85
66
|
end
|
@@ -27,11 +27,7 @@ module GoogleMapsService
|
|
27
27
|
#
|
28
28
|
# :rtype: A list of snapped points.
|
29
29
|
def snap_to_roads(path: nil, interpolate: false)
|
30
|
-
|
31
|
-
path = [path]
|
32
|
-
end
|
33
|
-
|
34
|
-
path = _convert_path(path)
|
30
|
+
path = GoogleMapsService::Convert.waypoints(path)
|
35
31
|
|
36
32
|
params = {
|
37
33
|
path: path
|
@@ -71,12 +67,7 @@ module GoogleMapsService
|
|
71
67
|
# @return [Hash] a dict with both a list of speed limits and a list of the snapped
|
72
68
|
# points.
|
73
69
|
def snapped_speed_limits(path: nil)
|
74
|
-
|
75
|
-
if path.kind_of?(Array) and path.length == 2 and not path[0].kind_of?(Array)
|
76
|
-
path = [path]
|
77
|
-
end
|
78
|
-
|
79
|
-
path = _convert_path(path)
|
70
|
+
path = GoogleMapsService::Convert.waypoints(path)
|
80
71
|
|
81
72
|
params = {
|
82
73
|
path: path
|
@@ -89,11 +80,6 @@ module GoogleMapsService
|
|
89
80
|
end
|
90
81
|
|
91
82
|
private
|
92
|
-
def _convert_path(paths)
|
93
|
-
paths = GoogleMapsService::Convert.as_list(paths)
|
94
|
-
return GoogleMapsService::Convert.join_list("|", paths.map { |k| k.kind_of?(String) ? k : GoogleMapsService::Convert.latlng(k) })
|
95
|
-
end
|
96
|
-
|
97
83
|
# Extracts a result from a Roads API HTTP response.
|
98
84
|
def extract_roads_body(response)
|
99
85
|
begin
|
@@ -132,7 +118,7 @@ module GoogleMapsService
|
|
132
118
|
end
|
133
119
|
|
134
120
|
unless response.status_code == 200
|
135
|
-
raise GoogleMapsService::Error::
|
121
|
+
raise GoogleMapsService::Error::ApiError.new(response)
|
136
122
|
end
|
137
123
|
|
138
124
|
return body
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative './convert'
|
2
|
+
|
3
|
+
module GoogleMapsService
|
4
|
+
module Validator
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def travel_mode(mode)
|
8
|
+
# NOTE(broady): the mode parameter is not validated by the Maps API
|
9
|
+
# server. Check here to prevent silent failures.
|
10
|
+
unless [:driving, :walking, :bicycling, :transit].include?(mode.to_sym)
|
11
|
+
raise ArgumentError, 'Invalid travel mode.'
|
12
|
+
end
|
13
|
+
mode
|
14
|
+
end
|
15
|
+
|
16
|
+
def avoid(avoid)
|
17
|
+
unless [:tolls, :highways, :ferries].include?(avoid.to_sym)
|
18
|
+
raise ArgumentError, 'Invalid route restriction.'
|
19
|
+
end
|
20
|
+
avoid
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google_maps_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edward Samuel Pasaribu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: retriable
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.0.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.0.2
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: ruby-hmac
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +72,14 @@ dependencies:
|
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1.
|
75
|
+
version: '1.7'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '1.
|
82
|
+
version: '1.7'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rake
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,6 +200,7 @@ files:
|
|
186
200
|
- lib/google_maps_service/geocoding.rb
|
187
201
|
- lib/google_maps_service/roads.rb
|
188
202
|
- lib/google_maps_service/time_zone.rb
|
203
|
+
- lib/google_maps_service/validator.rb
|
189
204
|
- lib/google_maps_service/version.rb
|
190
205
|
homepage: https://github.com/edwardsamuel/google-maps-services-ruby
|
191
206
|
licenses:
|