google_maps_service 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,8 +23,8 @@ module GoogleMapsService
23
23
  #
24
24
  # Accepts various representations:
25
25
  #
26
- # 1. Hash with two entries - +lat+ and +lng+
27
- # 2. Array or list - e.g. +[-33, 151]+
26
+ # 1. Hash with two entries - `lat` and `lng`
27
+ # 2. Array or list - e.g. `[-33, 151]`
28
28
  #
29
29
  # @param [Hash, Array] arg The lat/lon hash or array pair.
30
30
  #
@@ -136,101 +136,41 @@ module GoogleMapsService
136
136
  raise ArgumentError, "Expected a bounds (southwest/northeast) Hash, but got #{arg.class}"
137
137
  end
138
138
 
139
- # Converts an array of waypoints (path) to the format expected by the Google Maps
140
- # server.
139
+ # Converts a waypoints to the format expected by the Google Maps server.
141
140
  #
142
141
  # Accept two representation of waypoint:
143
142
  #
144
143
  # 1. String: Name of place or comma-separated lat/lon pair.
145
144
  # 2. Hash/Array: Lat/lon pair.
146
145
  #
147
- # @param [Array, String, Hash] waypoints Path.
146
+ # @param [Array, String, Hash] waypoint Path.
148
147
  #
149
148
  # @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]
149
+ def waypoint(waypoint)
150
+ if waypoint.kind_of?(String)
151
+ return waypoint
153
152
  end
154
-
155
- waypoints = as_list(waypoints)
156
- return join_list('|', waypoints.map { |k| k.kind_of?(String) ? k : latlng(k) })
153
+ return GoogleMapsService::Convert.latlng(waypoint)
157
154
  end
158
155
 
159
- # Decodes a Polyline string into a list of lat/lng hash.
160
- #
161
- # See the developer docs for a detailed description of this encoding:
162
- # https://developers.google.com/maps/documentation/utilities/polylinealgorithm
163
- #
164
- # @param [String] polyline An encoded polyline
156
+ # Converts an array of waypoints (path) to the format expected by the Google Maps
157
+ # server.
165
158
  #
166
- # @return [Array] Array of hash with lat/lng keys
167
- def decode_polyline(polyline)
168
- points = []
169
- index = lat = lng = 0
170
-
171
- while index < polyline.length
172
- result = 1
173
- shift = 0
174
- while true
175
- b = polyline[index].ord - 63 - 1
176
- index += 1
177
- result += b << shift
178
- shift += 5
179
- break if b < 0x1f
180
- end
181
- lat += (result & 1) != 0 ? (~result >> 1) : (result >> 1)
182
-
183
- result = 1
184
- shift = 0
185
- while true
186
- b = polyline[index].ord - 63 - 1
187
- index += 1
188
- result += b << shift
189
- shift += 5
190
- break if b < 0x1f
191
- end
192
- lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1)
193
-
194
- points << {lat: lat * 1e-5, lng: lng * 1e-5}
195
- end
196
-
197
- points
198
- end
199
-
200
- # Encodes a list of points into a polyline string.
159
+ # Accept two representation of waypoint:
201
160
  #
202
- # See the developer docs for a detailed description of this encoding:
203
- # https://developers.google.com/maps/documentation/utilities/polylinealgorithm
161
+ # 1. String: Name of place or comma-separated lat/lon pair.
162
+ # 2. Hash/Array: Lat/lon pair.
204
163
  #
205
- # @param [Array<Hash>, Array<Array>] points A list of lat/lng pairs.
164
+ # @param [Array, String, Hash] waypoints Path.
206
165
  #
207
166
  # @return [String]
208
- def encode_polyline(points)
209
- last_lat = last_lng = 0
210
- result = ""
211
-
212
- points.each do |point|
213
- ll = normalize_latlng(point)
214
- lat = (ll[0] * 1e5).round.to_i
215
- lng = (ll[1] * 1e5).round.to_i
216
- d_lat = lat - last_lat
217
- d_lng = lng - last_lng
218
-
219
- [d_lat, d_lng].each do |v|
220
- v = (v < 0) ? ~(v << 1) : (v << 1)
221
- while v >= 0x20
222
- result += ((0x20 | (v & 0x1f)) + 63).chr
223
- v >>= 5
224
- end
225
- result += (v + 63).chr
226
- end
227
-
228
- last_lat = lat
229
- last_lng = lng
167
+ def waypoints(waypoints)
168
+ if waypoints.kind_of?(Array) and waypoints.length == 2 and waypoints[0].kind_of?(Numeric) and waypoints[1].kind_of?(Numeric)
169
+ waypoints = [waypoints]
230
170
  end
231
171
 
232
- result
172
+ waypoints = as_list(waypoints)
173
+ return join_list('|', waypoints.map { |k| waypoint(k) })
233
174
  end
234
-
235
175
  end
236
176
  end
@@ -1,27 +1,36 @@
1
1
  module GoogleMapsService
2
+ # Specific Google Maps Service error
2
3
  module Error
3
4
  # Base error, capable of wrapping another
4
5
  class BaseError < StandardError
6
+ # HTTP response object
7
+ # @return [Hurley::Response]
5
8
  attr_reader :response
6
9
 
7
- def initialize(response)
10
+ def initialize(response = nil)
8
11
  @response = response
9
12
  end
10
13
  end
11
14
 
12
- # An exception that is raised if a redirect is required
15
+ # The response redirects to another URL.
13
16
  class RedirectError < BaseError
14
17
  end
15
18
 
16
19
  # A 4xx class HTTP error occurred.
20
+ # The request is invalid and should not be retried without modification.
17
21
  class ClientError < BaseError
18
22
  end
19
23
 
20
24
  # A 5xx class HTTP error occurred.
25
+ # An error occurred on the server and the request can be retried.
21
26
  class ServerError < BaseError
22
27
  end
23
28
 
24
- # An API error occured.
29
+ # An unknown error occured.
30
+ class UnknownError < BaseError
31
+ end
32
+
33
+ # General Google Maps Web Service API error occured.
25
34
  class ApiError < BaseError
26
35
  end
27
36
 
@@ -29,7 +38,7 @@ module GoogleMapsService
29
38
  class InvalidRequestError < ApiError
30
39
  end
31
40
 
32
- # Over quota.
41
+ # The quota for the credential is over limit.
33
42
  class RateLimitError < ApiError
34
43
  end
35
44
 
@@ -0,0 +1,90 @@
1
+ require 'google_maps_service/convert'
2
+
3
+ module GoogleMapsService
4
+
5
+ # Encoder/decoder for [Google Encoded Polyline](https://developers.google.com/maps/documentation/utilities/polylinealgorithm).
6
+ module Polyline
7
+ module_function
8
+
9
+ # Decodes a Polyline string into a list of lat/lng hash.
10
+ #
11
+ # See the developer docs for a detailed description of this encoding:
12
+ # https://developers.google.com/maps/documentation/utilities/polylinealgorithm
13
+ #
14
+ # @example
15
+ # encoded_path = '_p~iF~ps|U_ulLnnqC_mqNvxq`@'
16
+ # path = GoogleMapsService::Polyline.decode(encoded_path)
17
+ # #=> [{:lat=>38.5, :lng=>-120.2}, {:lat=>40.7, :lng=>-120.95}, {:lat=>43.252, :lng=>-126.45300000000002}]
18
+ #
19
+ # @param [String] polyline An encoded polyline
20
+ #
21
+ # @return [Array] Array of hash with lat/lng keys
22
+ def decode(polyline)
23
+ points = []
24
+ index = lat = lng = 0
25
+
26
+ while index < polyline.length
27
+ result = 1
28
+ shift = 0
29
+ while true
30
+ b = polyline[index].ord - 63 - 1
31
+ index += 1
32
+ result += b << shift
33
+ shift += 5
34
+ break if b < 0x1f
35
+ end
36
+ lat += (result & 1) != 0 ? (~result >> 1) : (result >> 1)
37
+
38
+ result = 1
39
+ shift = 0
40
+ while true
41
+ b = polyline[index].ord - 63 - 1
42
+ index += 1
43
+ result += b << shift
44
+ shift += 5
45
+ break if b < 0x1f
46
+ end
47
+ lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1)
48
+
49
+ points << {lat: lat * 1e-5, lng: lng * 1e-5}
50
+ end
51
+
52
+ points
53
+ end
54
+
55
+ # Encodes a list of points into a polyline string.
56
+ #
57
+ # See the developer docs for a detailed description of this encoding:
58
+ # https://developers.google.com/maps/documentation/utilities/polylinealgorithm
59
+ #
60
+ # @param [Array<Hash>, Array<Array>] points A list of lat/lng pairs.
61
+ #
62
+ # @return [String]
63
+ def encode(points)
64
+ last_lat = last_lng = 0
65
+ result = ""
66
+
67
+ points.each do |point|
68
+ ll = GoogleMapsService::Convert.normalize_latlng(point)
69
+ lat = (ll[0] * 1e5).round.to_i
70
+ lng = (ll[1] * 1e5).round.to_i
71
+ d_lat = lat - last_lat
72
+ d_lng = lng - last_lng
73
+
74
+ [d_lat, d_lng].each do |v|
75
+ v = (v < 0) ? ~(v << 1) : (v << 1)
76
+ while v >= 0x20
77
+ result += ((0x20 | (v & 0x1f)) + 63).chr
78
+ v >>= 5
79
+ end
80
+ result += (v + 63).chr
81
+ end
82
+
83
+ last_lat = lat
84
+ last_lng = lng
85
+ end
86
+
87
+ result
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,64 @@
1
+ require 'base64'
2
+ require 'uri'
3
+
4
+ module GoogleMapsService
5
+
6
+ # Helper for handling URL.
7
+ module Url
8
+ module_function
9
+
10
+ # Returns a base64-encoded HMAC-SHA1 signature of a given string.
11
+ #
12
+ # @param [String] secret The key used for the signature, base64 encoded.
13
+ # @param [String] payload The payload to sign.
14
+ #
15
+ # @return [String] Base64-encoded HMAC-SHA1 signature
16
+ def sign_hmac(secret, payload)
17
+ secret = secret.encode('ASCII')
18
+ payload = payload.encode('ASCII')
19
+
20
+ # Decode the private key
21
+ raw_key = Base64.urlsafe_decode64(secret)
22
+
23
+ # Create a signature using the private key and the URL
24
+ digest = OpenSSL::Digest.new('sha1')
25
+ raw_signature = OpenSSL::HMAC.digest(digest, raw_key, payload)
26
+
27
+ # Encode the signature into base64 for url use form.
28
+ signature = Base64.urlsafe_encode64(raw_signature)
29
+ return signature
30
+ end
31
+
32
+ # URL encodes the parameters.
33
+ # @param [Hash, Array<Array>] params The parameters
34
+ # @return [String]
35
+ def urlencode_params(params)
36
+ unquote_unreserved(URI.encode_www_form(params))
37
+ end
38
+
39
+ # Un-escape any percent-escape sequences in a URI that are unreserved
40
+ # characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
41
+ #
42
+ # @param [String] uri
43
+ #
44
+ # @return [String]
45
+ def unquote_unreserved(uri)
46
+ parts = uri.split('%')
47
+
48
+ (1..parts.length-1).each do |i|
49
+ h = parts[i][0..1]
50
+
51
+ if h =~ /^([\h]{2})(.*)/ and c = $1.to_i(16).chr and UNRESERVED_SET.include?(c)
52
+ parts[i] = c + $2
53
+ else
54
+ parts[i] = '%' + parts[i]
55
+ end
56
+ end
57
+
58
+ parts.join
59
+ end
60
+
61
+ # The unreserved URI characters (RFC 3986)
62
+ UNRESERVED_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
63
+ end
64
+ end
@@ -1,9 +1,18 @@
1
1
  require_relative './convert'
2
2
 
3
3
  module GoogleMapsService
4
+
5
+ # Validate value that is accepted by Google Maps.
4
6
  module Validator
5
7
  module_function
6
8
 
9
+ # Validate travel mode. The valid value of travel mode are `driving`, `walking`, `bicycling` or `transit`.
10
+ #
11
+ # @param [String, Symbol] mode Travel mode to be validated.
12
+ #
13
+ # @raise ArgumentError The travel mode is invalid.
14
+ #
15
+ # @return [String] Valid travel mode.
7
16
  def travel_mode(mode)
8
17
  # NOTE(broady): the mode parameter is not validated by the Maps API
9
18
  # server. Check here to prevent silent failures.
@@ -13,6 +22,13 @@ module GoogleMapsService
13
22
  mode
14
23
  end
15
24
 
25
+ # Validate route restriction. The valid value of route restriction are `tolls`, `highways` or `ferries`.
26
+ #
27
+ # @param [String, Symbol] avoid Route restriction to be validated.
28
+ #
29
+ # @raise ArgumentError The route restriction is invalid.
30
+ #
31
+ # @return [String] Valid route restriction.
16
32
  def avoid(avoid)
17
33
  unless [:tolls, :highways, :ferries].include?(avoid.to_sym)
18
34
  raise ArgumentError, 'Invalid route restriction.'
@@ -1,3 +1,23 @@
1
1
  module GoogleMapsService
2
- VERSION = '0.3.0'
2
+ # GoogleMapsService gem version
3
+ VERSION = '0.4.0'
4
+
5
+ # Current operating system
6
+ # @private
7
+ OS_VERSION = begin
8
+ if RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/
9
+ `ver`.sub(/\s*\[Version\s*/, '/').sub(']', '').strip
10
+ elsif RUBY_PLATFORM =~ /darwin/i
11
+ "Mac OS X/#{`sw_vers -productVersion`}"
12
+ elsif RUBY_PLATFORM == 'java'
13
+ require 'java'
14
+ name = java.lang.System.getProperty('os.name')
15
+ version = java.lang.System.getProperty('os.version')
16
+ "#{name}/#{version}"
17
+ else
18
+ `uname -sr`.sub(' ', '/')
19
+ end
20
+ rescue
21
+ RUBY_PLATFORM
22
+ end
3
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.3.0
4
+ version: 0.4.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-18 00:00:00.000000000 Z
11
+ date: 2015-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -59,61 +59,61 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  version: 2.0.2
61
61
  - !ruby/object:Gem::Dependency
62
- name: ruby-hmac
62
+ name: bundler
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 0.4.0
68
- type: :runtime
67
+ version: '1.7'
68
+ type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 0.4.0
74
+ version: '1.7'
75
75
  - !ruby/object:Gem::Dependency
76
- name: bundler
76
+ name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '1.7'
81
+ version: '10.0'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '1.7'
88
+ version: '10.0'
89
89
  - !ruby/object:Gem::Dependency
90
- name: rake
90
+ name: yard
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '10.0'
95
+ version: 0.8.7.6
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '10.0'
102
+ version: 0.8.7.6
103
103
  - !ruby/object:Gem::Dependency
104
- name: yard
104
+ name: redcarpet
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: 0.8.7.6
109
+ version: '3.3'
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 0.8.7.6
116
+ version: '3.3'
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: rspec
119
119
  requirement: !ruby/object:Gem::Requirement
@@ -188,24 +188,27 @@ files:
188
188
  - ".ruby-gemset"
189
189
  - ".ruby-version"
190
190
  - ".travis.yml"
191
+ - ".yardopts"
192
+ - CHANGELOG.md
191
193
  - CODE_OF_CONDUCT.md
192
194
  - Gemfile
193
195
  - LICENSE
194
196
  - README.md
195
197
  - Rakefile
196
- - bin/console
197
- - bin/setup
198
198
  - google_maps_service.gemspec
199
199
  - lib/google_maps_service.rb
200
+ - lib/google_maps_service/apis.rb
201
+ - lib/google_maps_service/apis/directions.rb
202
+ - lib/google_maps_service/apis/distance_matrix.rb
203
+ - lib/google_maps_service/apis/elevation.rb
204
+ - lib/google_maps_service/apis/geocoding.rb
205
+ - lib/google_maps_service/apis/roads.rb
206
+ - lib/google_maps_service/apis/time_zone.rb
200
207
  - lib/google_maps_service/client.rb
201
208
  - lib/google_maps_service/convert.rb
202
- - lib/google_maps_service/directions.rb
203
- - lib/google_maps_service/distance_matrix.rb
204
- - lib/google_maps_service/elevation.rb
205
209
  - lib/google_maps_service/errors.rb
206
- - lib/google_maps_service/geocoding.rb
207
- - lib/google_maps_service/roads.rb
208
- - lib/google_maps_service/time_zone.rb
210
+ - lib/google_maps_service/polyline.rb
211
+ - lib/google_maps_service/url.rb
209
212
  - lib/google_maps_service/validator.rb
210
213
  - lib/google_maps_service/version.rb
211
214
  homepage: https://github.com/edwardsamuel/google-maps-services-ruby
@@ -220,7 +223,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
220
223
  requirements:
221
224
  - - ">="
222
225
  - !ruby/object:Gem::Version
223
- version: '0'
226
+ version: 2.0.0
224
227
  required_rubygems_version: !ruby/object:Gem::Requirement
225
228
  requirements:
226
229
  - - ">="
@@ -231,6 +234,6 @@ rubyforge_project:
231
234
  rubygems_version: 2.4.6
232
235
  signing_key:
233
236
  specification_version: 4
234
- summary: Ruby client library (unofficial) for Google Maps API Web Services
237
+ summary: Ruby gem for Google Maps Web Service APIs
235
238
  test_files: []
236
239
  has_rdoc: yard