Class: GoogleMaps::Services::Convert
- Inherits:
-
Object
- Object
- GoogleMaps::Services::Convert
- Defined in:
- lib/googlemaps/services/util.rb
Overview
Converts Ruby types to string representations suitable for Google Maps API server.
Class Method Summary collapse
-
.bounds(arg) ⇒ String
Converts a lat/lng bounds to a comma- and pipe-separated string.
-
.components(arg) ⇒ String
Converts a Hash of components to the format expect by the Google Maps API server.
-
.decode_polyline(polyline) ⇒ Array
Decodes a Polyline string into an array of lat/lng hashes.
-
.encode_polyline(points) ⇒ String
Encodes an array of points into a polyline string.
-
.format_float(arg) ⇒ String
Formats a float value to as short as possible.
-
.get_mime_type(content_type) ⇒ String
Returns the MIME type from the given header value.
-
.join_array(sep, arg) ⇒ String
If arg is array-like, then joins it with sep.
-
.piped_location(arg) ⇒ String
Joins an array of locations into a pipe separated string, handling the various formats supported for lat/lng values.
-
.rectangular_dimensions(size) ⇒ String
Returns the rectangular dimensions in the form horizontal_valuexvertical_value.
-
.shortest_path(locations) ⇒ String
Returns the shortest representation of the given locations.
-
.to_latlng(arg) ⇒ String
Converts a lat/lng value to a comma-separated string.
-
.unix_time(val) ⇒ String
Converts the value into a unix time (seconds since unix epoch).
Class Method Details
.bounds(arg) ⇒ String
Converts a lat/lng bounds to a comma- and pipe-separated string.
220 221 222 223 |
# File 'lib/googlemaps/services/util.rb', line 220 def self.bounds(arg) raise TypeError, "#{__method__.to_s} expected a Hash of bounds." unless arg.is_a? Hash "#{to_latlng(arg[:southwest])}|#{to_latlng(arg[:northeast])}" end |
.components(arg) ⇒ String
Converts a Hash of components to the format expect by the Google Maps API server.
200 201 202 203 204 205 206 |
# File 'lib/googlemaps/services/util.rb', line 200 def self.components(arg) raise TypeError, "#{__method__.to_s} expected a Hash of components." unless arg.is_a? Hash arg.map { |c, val| ArrayBox.wrap(val).map {|elem| "#{c}:#{elem}"}.sort_by(&:downcase) }.join('|') end |
.decode_polyline(polyline) ⇒ Array
Decodes a Polyline string into an array of lat/lng hashes.
See the developer docs for a detailed description of this algorithm: developers.google.com/maps/documentation/utilities/polylinealgorithm
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/googlemaps/services/util.rb', line 266 def self.decode_polyline(polyline) raise TypeError, "#{__method__.to_s} expected an argument of type String." unless polyline.is_a? String points = Array.new index, lat, lng = 0, 0, 0 while index < polyline.length result = 1 shift = 0 while true b = polyline[index].ord - 63 - 1 index += 1 result += (b << shift) shift += 5 if b < 0x1f break end end lat += (result & 1) != 0 ? (~result >> 1) : (result >> 1) result = 1 shift = 0 while true b = polyline[index].ord - 63 - 1 index += 1 result += (b << shift) shift += 5 if b < 0x1f break end end lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1) points.push({:lat => lat * 1e-5, :lng => lng * 1e-5}) end points end |
.encode_polyline(points) ⇒ String
Encodes an array of points into a polyline string.
See the developer docs for a detailed description of this algorithm: developers.google.com/maps/documentation/utilities/polylinealgorithm
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/googlemaps/services/util.rb', line 233 def self.encode_polyline(points) raise TypeError, "#{__method__.to_s} expected an Array of points." unless points.is_a? Array last_lat, last_lng = 0, 0 result = '' points.each { |point| lat = (point[:lat] * 1e5).round.to_i lng = (point[:lng] * 1e5).round.to_i delta_lat = lat - last_lat delta_lng = lng - last_lng [delta_lat, delta_lng].each { |val| val = (val < 0) ? ~(val << 1) : (val << 1) while val >= 0x20 result += ((0x20 | (val & 0x1f)) + 63).chr val >>= 5 end result += (val + 63).chr } last_lat = lat last_lng = lng } result end |
.format_float(arg) ⇒ String
Formats a float value to as short as possible.
164 165 166 |
# File 'lib/googlemaps/services/util.rb', line 164 def self.format_float(arg) arg.to_s.chomp('0').chomp('.') end |
.get_mime_type(content_type) ⇒ String
Returns the MIME type from the given header value.
324 325 326 |
# File 'lib/googlemaps/services/util.rb', line 324 def self.get_mime_type(content_type) content_type.split(';').first end |
.join_array(sep, arg) ⇒ String
If arg is array-like, then joins it with sep
188 189 190 |
# File 'lib/googlemaps/services/util.rb', line 188 def self.join_array(sep, arg) ArrayBox.wrap(arg).join(sep) end |
.piped_location(arg) ⇒ String
Joins an array of locations into a pipe separated string, handling the various formats supported for lat/lng values.
177 178 179 180 |
# File 'lib/googlemaps/services/util.rb', line 177 def self.piped_location(arg) raise TypeError, "#{__method__.to_s} expected argument to be an Array." unless arg.instance_of? Array arg.map { |location| to_latlng(location) }.join('|') end |
.rectangular_dimensions(size) ⇒ String
Returns the rectangular dimensions in the form horizontal_valuexvertical_value.
336 337 338 339 |
# File 'lib/googlemaps/services/util.rb', line 336 def self.rectangular_dimensions(size) raise TypeError, "#{__method__.to_s} expected a Hash." unless size.is_a? Hash "#{size[:length]}x#{size[:width]}" end |
.shortest_path(locations) ⇒ String
Returns the shortest representation of the given locations.
The Elevation API limits requests to 2000 characters, and accepts multiple locations either as pipe-delimited lat/lng values, or an encoded polyline, so we determine which is shortest and use it.
312 313 314 315 316 317 |
# File 'lib/googlemaps/services/util.rb', line 312 def self.shortest_path(locations) raise TypeError, "#{__method__.to_s} expected an Array of locations." unless locations.is_a? Array encoded = "enc:#{encode_polyline(locations)}" unencoded = piped_location(locations) encoded.length < unencoded.length ? encoded : unencoded end |
.to_latlng(arg) ⇒ String
Converts a lat/lng value to a comma-separated string.
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/googlemaps/services/util.rb', line 146 def self.to_latlng(arg) case arg when String arg when Hash "#{self.format_float(arg[:lat])},#{self.format_float(arg[:lng])}" else raise TypeError, "#{__method__.to_s} expected location to be String or Hash." end end |
.unix_time(val) ⇒ String
Converts the value into a unix time (seconds since unix epoch).
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/googlemaps/services/util.rb', line 124 def self.unix_time(val) case val when Integer val.to_s when Time val.to_i.to_s when Date val.to_time.to_i.to_s else raise TypeError, "#{__method__.to_s} expected value to be Integer, Time or Date." end end |