google_maps_service 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/google_maps_service.svg)](http://badge.fury.io/rb/google_maps_service) [![Build Status](https://travis-ci.org/edwardsamuel/google-maps-services-ruby.svg?branch=master)](https://travis-ci.org/edwardsamuel/google-maps-services-ruby) [![Dependency Status](https://gemnasium.com/edwardsamuel/google-maps-services-ruby.svg)](https://gemnasium.com/edwardsamuel/google-maps-services-ruby) [![Code Climate](https://codeclimate.com/github/edwardsamuel/google-maps-services-ruby/badges/gpa.svg)](https://codeclimate.com/github/edwardsamuel/google-maps-services-ruby) [![Coverage Status](https://coveralls.io/repos/edwardsamuel/google-maps-services-ruby/badge.svg?branch=master&service=github)](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:
|