google_maps_apis 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/ruby.yml +28 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +11 -0
- data/CHANGELOG.md +47 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +26 -0
- data/LICENSE +202 -0
- data/README.md +379 -0
- data/Rakefile +15 -0
- data/bin/console +15 -0
- data/google_maps_apis.gemspec +23 -0
- data/lib/google_maps_apis/client.rb +294 -0
- data/lib/google_maps_apis/convert.rb +176 -0
- data/lib/google_maps_apis/errors.rb +82 -0
- data/lib/google_maps_apis/polyline.rb +90 -0
- data/lib/google_maps_apis/services/directions.rb +101 -0
- data/lib/google_maps_apis/services/distance_matrix.rb +85 -0
- data/lib/google_maps_apis/services/elevation.rb +58 -0
- data/lib/google_maps_apis/services/geocoding.rb +85 -0
- data/lib/google_maps_apis/services/places.rb +20 -0
- data/lib/google_maps_apis/services/roads.rb +187 -0
- data/lib/google_maps_apis/services/time_zone.rb +41 -0
- data/lib/google_maps_apis/services.rb +6 -0
- data/lib/google_maps_apis/url.rb +64 -0
- data/lib/google_maps_apis/validator.rb +39 -0
- data/lib/google_maps_apis/version.rb +23 -0
- data/lib/google_maps_apis.rb +56 -0
- metadata +117 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative '../validator'
|
2
|
+
|
3
|
+
module GoogleMapsApis::Services
|
4
|
+
|
5
|
+
# Performs requests to the Google Maps Directions API.
|
6
|
+
module Directions
|
7
|
+
|
8
|
+
# Get directions between an origin point and a destination point.
|
9
|
+
#
|
10
|
+
# @example Simple directions
|
11
|
+
# routes = client.directions('Sydney', 'Melbourne')
|
12
|
+
#
|
13
|
+
# @example Complex bicycling directions
|
14
|
+
# routes = client.directions('Sydney', 'Melbourne',
|
15
|
+
# mode: 'bicycling',
|
16
|
+
# avoid: ['highways', 'tolls', 'ferries'],
|
17
|
+
# units: 'metric',
|
18
|
+
# region: 'au')
|
19
|
+
#
|
20
|
+
# @example Public transportation directions
|
21
|
+
# an_hour_from_now = Time.now - (1.0/24)
|
22
|
+
# routes = client.directions('Sydney Town Hall', 'Parramatta, NSW',
|
23
|
+
# mode: 'transit',
|
24
|
+
# arrival_time: an_hour_from_now)
|
25
|
+
#
|
26
|
+
# @example Walking with alternative routes
|
27
|
+
# routes = client.directions('Sydney Town Hall', 'Parramatta, NSW',
|
28
|
+
# mode: 'walking',
|
29
|
+
# alternatives: true)
|
30
|
+
#
|
31
|
+
# @param [String, Hash, Array] origin The address or latitude/longitude value from which you wish
|
32
|
+
# to calculate directions.
|
33
|
+
# @param [String, Hash, Array] destination The address or latitude/longitude value from which
|
34
|
+
# you wish to calculate directions.
|
35
|
+
# @param [String] mode Specifies the mode of transport to use when calculating
|
36
|
+
# directions. One of `driving`, `walking`, `bicycling` or `transit`.
|
37
|
+
# @param [Array<String>, Array<Hash>, Array<Array>] waypoints Specifies an array of waypoints. Waypoints alter a
|
38
|
+
# route by routing it through the specified location(s).
|
39
|
+
# @param [Boolean] alternatives If True, more than one route may be returned in the
|
40
|
+
# response.
|
41
|
+
# @param [Array, String] avoid Indicates that the calculated route(s) should avoid the
|
42
|
+
# indicated features.
|
43
|
+
# @param [String] language The language in which to return results.
|
44
|
+
# @param [String] units Specifies the unit system to use when displaying results.
|
45
|
+
# `metric` or `imperial`.
|
46
|
+
# @param [String] region The region code, specified as a ccTLD (_top-level domain_)
|
47
|
+
# two-character value.
|
48
|
+
# @param [Integer, DateTime] departure_time Specifies the desired time of departure.
|
49
|
+
# @param [Integer, DateTime] arrival_time Specifies the desired time of arrival for transit
|
50
|
+
# directions. Note: you can not specify both `departure_time` and
|
51
|
+
# `arrival_time`.
|
52
|
+
# @param [Boolean] optimize_waypoints Optimize the provided route by rearranging the
|
53
|
+
# waypoints in a more efficient order.
|
54
|
+
# @param [String, Array<String>] transit_mode Specifies one or more preferred modes of transit.
|
55
|
+
# This parameter may only be specified for requests where the mode is
|
56
|
+
# transit. Valid values are `bus`, `subway`, `train`, `tram` or `rail`.
|
57
|
+
# `rail` is equivalent to `["train", "tram", "subway"]`.
|
58
|
+
# @param [String] transit_routing_preference Specifies preferences for transit
|
59
|
+
# requests. Valid values are `less_walking` or `fewer_transfers`.
|
60
|
+
#
|
61
|
+
# @return [Array] Array of routes.
|
62
|
+
def directions(origin, destination,
|
63
|
+
mode: nil, waypoints: nil, alternatives: false, avoid: nil,
|
64
|
+
language: nil, units: nil, region: nil, departure_time: nil,
|
65
|
+
arrival_time: nil, optimize_waypoints: false, transit_mode: nil,
|
66
|
+
transit_routing_preference: nil)
|
67
|
+
|
68
|
+
params = {
|
69
|
+
origin: GoogleMapsApis::Convert.waypoint(origin),
|
70
|
+
destination: GoogleMapsApis::Convert.waypoint(destination)
|
71
|
+
}
|
72
|
+
|
73
|
+
params[:mode] = GoogleMapsApis::Validator.travel_mode(mode) if mode
|
74
|
+
|
75
|
+
if waypoints = waypoints
|
76
|
+
waypoints = GoogleMapsApis::Convert.as_list(waypoints)
|
77
|
+
waypoints = waypoints.map { |waypoint| GoogleMapsApis::Convert.waypoint(waypoint) }
|
78
|
+
waypoints = ['optimize:true'] + waypoints if optimize_waypoints
|
79
|
+
|
80
|
+
params[:waypoints] = GoogleMapsApis::Convert.join_list("|", waypoints)
|
81
|
+
end
|
82
|
+
|
83
|
+
params[:alternatives] = 'true' if alternatives
|
84
|
+
params[:avoid] = GoogleMapsApis::Convert.join_list('|', avoid) if avoid
|
85
|
+
params[:language] = language if language
|
86
|
+
params[:units] = units if units
|
87
|
+
params[:region] = region if region
|
88
|
+
params[:departure_time] = GoogleMapsApis::Convert.time(departure_time) if departure_time
|
89
|
+
params[:arrival_time] = GoogleMapsApis::Convert.time(arrival_time) if arrival_time
|
90
|
+
|
91
|
+
if departure_time and arrival_time
|
92
|
+
raise ArgumentError, 'Should not specify both departure_time and arrival_time.'
|
93
|
+
end
|
94
|
+
|
95
|
+
params[:transit_mode] = GoogleMapsApis::Convert.join_list("|", transit_mode) if transit_mode
|
96
|
+
params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference
|
97
|
+
|
98
|
+
return get('/maps/api/directions/json', params)[:routes]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require_relative '../validator'
|
2
|
+
|
3
|
+
module GoogleMapsApis::Services
|
4
|
+
|
5
|
+
# Performs requests to the Google Maps Distance Matrix API.
|
6
|
+
module DistanceMatrix
|
7
|
+
|
8
|
+
# Gets travel distance and time for a matrix of origins and destinations.
|
9
|
+
#
|
10
|
+
# @example Simple distance matrix
|
11
|
+
# origins = ["Perth, Australia", "Sydney, Australia",
|
12
|
+
# "Melbourne, Australia", "Adelaide, Australia",
|
13
|
+
# "Brisbane, Australia", "Darwin, Australia",
|
14
|
+
# "Hobart, Australia", "Canberra, Australia"]
|
15
|
+
# destinations = ["Uluru, Australia",
|
16
|
+
# "Kakadu, Australia",
|
17
|
+
# "Blue Mountains, Australia",
|
18
|
+
# "Bungle Bungles, Australia",
|
19
|
+
# "The Pinnacles, Australia"]
|
20
|
+
# matrix = client.distance_matrix(origins, destinations)
|
21
|
+
#
|
22
|
+
# @example Complex distance matrix
|
23
|
+
# origins = ["Bobcaygeon ON", [41.43206, -81.38992]]
|
24
|
+
# destinations = [[43.012486, -83.6964149], {lat: 42.8863855, lng: -78.8781627}]
|
25
|
+
# matrix = client.distance_matrix(origins, destinations,
|
26
|
+
# mode: 'driving',
|
27
|
+
# language: 'en-AU',
|
28
|
+
# avoid: 'tolls',
|
29
|
+
# units: 'imperial')
|
30
|
+
#
|
31
|
+
# @param [Array] origins One or more addresses and/or lat/lon pairs,
|
32
|
+
# from which to calculate distance and time. If you pass an address
|
33
|
+
# as a string, the service will geocode the string and convert it to
|
34
|
+
# a lat/lon coordinate to calculate directions.
|
35
|
+
# @param [Array] destinations One or more addresses and/or lat/lon pairs, to
|
36
|
+
# which to calculate distance and time. If you pass an address as a
|
37
|
+
# string, the service will geocode the string and convert it to a
|
38
|
+
# lat/lon coordinate to calculate directions.
|
39
|
+
# @param [String] mode Specifies the mode of transport to use when calculating
|
40
|
+
# directions. Valid values are `driving`, `walking`, `transit` or `bicycling`.
|
41
|
+
# @param [String] language The language in which to return results.
|
42
|
+
# @param [String] avoid Indicates that the calculated route(s) should avoid the
|
43
|
+
# indicated features. Valid values are `tolls`, `highways` or `ferries`.
|
44
|
+
# @param [String] units Specifies the unit system to use when displaying results.
|
45
|
+
# Valid values are `metric` or `imperial`.
|
46
|
+
# @param [Integer, DateTime] departure_time Specifies the desired time of departure.
|
47
|
+
# @param [Integer, DateTime] arrival_time Specifies the desired time of arrival for transit
|
48
|
+
# directions. Note: you can not specify both `departure_time` and `arrival_time`.
|
49
|
+
# @param [String, Array<String>] transit_mode Specifies one or more preferred modes of transit.
|
50
|
+
# This parameter may only be specified for requests where the mode is
|
51
|
+
# transit. Valid values are `bus`, `subway`, `train`, `tram`, or `rail`.
|
52
|
+
# `rail` is equivalent to `["train", "tram", "subway"]`.
|
53
|
+
# @param [String] transit_routing_preference Specifies preferences for transit
|
54
|
+
# requests. Valid values are `less_walking` or `fewer_transfers`.
|
55
|
+
#
|
56
|
+
# @return [Hash] Matrix of distances. Results are returned in rows, each row
|
57
|
+
# containing one origin paired with each destination.
|
58
|
+
def distance_matrix(origins, destinations,
|
59
|
+
mode: nil, language: nil, avoid: nil, units: nil,
|
60
|
+
departure_time: nil, arrival_time: nil, transit_mode: nil,
|
61
|
+
transit_routing_preference: nil)
|
62
|
+
params = {
|
63
|
+
origins: GoogleMapsApis::Convert.waypoints(origins),
|
64
|
+
destinations: GoogleMapsApis::Convert.waypoints(destinations)
|
65
|
+
}
|
66
|
+
|
67
|
+
params[:language] = language if language
|
68
|
+
params[:mode] = GoogleMapsApis::Validator.travel_mode(mode) if mode
|
69
|
+
params[:avoid] = GoogleMapsApis::Validator.avoid(avoid) if avoid
|
70
|
+
|
71
|
+
params[:units] = units if units
|
72
|
+
params[:departure_time] = GoogleMapsApis::Convert.time(departure_time) if departure_time
|
73
|
+
params[:arrival_time] = GoogleMapsApis::Convert.time(arrival_time) if arrival_time
|
74
|
+
|
75
|
+
if departure_time and arrival_time
|
76
|
+
raise ArgumentError, 'Should not specify both departure_time and arrival_time.'
|
77
|
+
end
|
78
|
+
|
79
|
+
params[:transit_mode] = GoogleMapsApis::Convert.join_list('|', transit_mode) if transit_mode
|
80
|
+
params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference
|
81
|
+
|
82
|
+
return get('/maps/api/distancematrix/json', params)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module GoogleMapsApis::Services
|
2
|
+
|
3
|
+
# Performs requests to the Google Maps Elevation API.
|
4
|
+
module Elevation
|
5
|
+
|
6
|
+
# Provides elevation data for locations provided on the surface of the
|
7
|
+
# earth, including depth locations on the ocean floor (which return negative
|
8
|
+
# values).
|
9
|
+
#
|
10
|
+
# @example Single point elevation
|
11
|
+
# results = client.elevation({latitude: 40.714728, longitude: -73.998672})
|
12
|
+
#
|
13
|
+
# @example Multiple points elevation
|
14
|
+
# locations = [[40.714728, -73.998672], [-34.397, 150.644]]
|
15
|
+
# results = client.elevation(locations)
|
16
|
+
#
|
17
|
+
# @param [Array] locations A single latitude/longitude hash, or an array of
|
18
|
+
# latitude/longitude hash from which you wish to calculate
|
19
|
+
# elevation data.
|
20
|
+
#
|
21
|
+
# @return [Array] Array of elevation data responses
|
22
|
+
def elevation(locations)
|
23
|
+
params = {
|
24
|
+
locations: GoogleMapsApis::Convert.waypoints(locations)
|
25
|
+
}
|
26
|
+
|
27
|
+
return get('/maps/api/elevation/json', params)[:results]
|
28
|
+
end
|
29
|
+
|
30
|
+
# Provides elevation data sampled along a path on the surface of the earth.
|
31
|
+
#
|
32
|
+
# @example Elevation along path
|
33
|
+
# locations = [[40.714728, -73.998672], [-34.397, 150.644]]
|
34
|
+
# results = client.elevation_along_path(locations, 5)
|
35
|
+
#
|
36
|
+
# @param [String, Array] path A encoded polyline string, or a list of
|
37
|
+
# latitude/longitude pairs from which you wish to calculate
|
38
|
+
# elevation data.
|
39
|
+
# @param [Integer] samples The number of sample points along a path for which to
|
40
|
+
# return elevation data.
|
41
|
+
#
|
42
|
+
# @return [Array] Array of elevation data responses
|
43
|
+
def elevation_along_path(path, samples)
|
44
|
+
if path.kind_of?(String)
|
45
|
+
path = "enc:%s" % path
|
46
|
+
else
|
47
|
+
path = GoogleMapsApis::Convert.waypoints(path)
|
48
|
+
end
|
49
|
+
|
50
|
+
params = {
|
51
|
+
path: path,
|
52
|
+
samples: samples
|
53
|
+
}
|
54
|
+
|
55
|
+
return get('/maps/api/elevation/json', params)[:results]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'google_maps_apis/convert'
|
2
|
+
|
3
|
+
module GoogleMapsApis::Services
|
4
|
+
|
5
|
+
# Performs requests to the Google Maps Geocoding API.
|
6
|
+
module Geocoding
|
7
|
+
|
8
|
+
# Geocoding is the process of converting addresses
|
9
|
+
# (like `"1600 Amphitheatre Parkway, Mountain View, CA"`) into geographic
|
10
|
+
# coordinates (like latitude 37.423021 and longitude -122.083739), which you
|
11
|
+
# can use to place markers or position the map.
|
12
|
+
#
|
13
|
+
# @example Geocode an address
|
14
|
+
# results = client.geocode('Sydney')
|
15
|
+
#
|
16
|
+
# @example Geocode a component only
|
17
|
+
# results = client.geocode(nil, components: {administrative_area: 'TX', country: 'US'})
|
18
|
+
#
|
19
|
+
# @example Geocode an address and component
|
20
|
+
# results = client.geocode('Sydney', components: {administrative_area: 'TX', country: 'US'})
|
21
|
+
#
|
22
|
+
# @example Multiple parameters
|
23
|
+
# results = client.geocode('Sydney',
|
24
|
+
# components: {administrative_area: 'TX', country: 'US'},
|
25
|
+
# bounds: {
|
26
|
+
# northeast: {lat: 32.7183997, lng: -97.26864001970849},
|
27
|
+
# southwest: {lat: 32.7052583, lng: -97.27133798029149}
|
28
|
+
# },
|
29
|
+
# region: 'us')
|
30
|
+
#
|
31
|
+
# @param [String] address The address to geocode. You must specify either this value and/or `components`.
|
32
|
+
# @param [Hash] components A component filter for which you wish to obtain a geocode,
|
33
|
+
# for example: `{'administrative_area': 'TX','country': 'US'}`
|
34
|
+
# @param [String, Hash] bounds The bounding box of the viewport within which to bias geocode
|
35
|
+
# results more prominently. Accept string or hash with `northeast` and `southwest` keys.
|
36
|
+
# @param [String] region The region code, specified as a ccTLD (_top-level domain_)
|
37
|
+
# two-character value.
|
38
|
+
# @param [String] language The language in which to return results.
|
39
|
+
#
|
40
|
+
# @return [Array] Array of geocoding results.
|
41
|
+
def geocode(address, components: nil, bounds: nil, region: nil, language: nil)
|
42
|
+
params = {}
|
43
|
+
|
44
|
+
params[:address] = address if address
|
45
|
+
params[:components] = GoogleMapsApis::Convert.components(components) if components
|
46
|
+
params[:bounds] = GoogleMapsApis::Convert.bounds(bounds) if bounds
|
47
|
+
params[:region] = region if region
|
48
|
+
params[:language] = language if language
|
49
|
+
|
50
|
+
return get('/maps/api/geocode/json', params)[:results]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Reverse geocoding is the process of converting geographic coordinates into a
|
54
|
+
# human-readable address.
|
55
|
+
#
|
56
|
+
# @example Simple lat/lon pair
|
57
|
+
# client.reverse_geocode({lat: 40.714224, lng: -73.961452})
|
58
|
+
#
|
59
|
+
# @example Multiple parameters
|
60
|
+
# client.reverse_geocode([40.714224, -73.961452],
|
61
|
+
# location_type: ['ROOFTOP', 'RANGE_INTERPOLATED'],
|
62
|
+
# result_type: ['street_address', 'route'],
|
63
|
+
# language: 'es')
|
64
|
+
#
|
65
|
+
# @param [Hash, Array] latlng The latitude/longitude value for which you wish to obtain
|
66
|
+
# the closest, human-readable address.
|
67
|
+
# @param [String, Array<String>] location_type One or more location types to restrict results to.
|
68
|
+
# @param [String, Array<String>] result_type One or more address types to restrict results to.
|
69
|
+
# @param [String] language The language in which to return results.
|
70
|
+
#
|
71
|
+
# @return [Array] Array of reverse geocoding results.
|
72
|
+
def reverse_geocode(latlng, location_type: nil, result_type: nil, language: nil)
|
73
|
+
params = {
|
74
|
+
latlng: GoogleMapsApis::Convert.latlng(latlng)
|
75
|
+
}
|
76
|
+
|
77
|
+
params[:result_type] = GoogleMapsApis::Convert.join_list('|', result_type) if result_type
|
78
|
+
params[:location_type] = GoogleMapsApis::Convert.join_list('|', location_type) if location_type
|
79
|
+
params[:language] = language if language
|
80
|
+
|
81
|
+
return get('/maps/api/geocode/json', params)[:results]
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'google_maps_apis/convert'
|
2
|
+
|
3
|
+
module GoogleMapsApis::Services
|
4
|
+
|
5
|
+
# Performs requests to the Google Maps Geocoding API.
|
6
|
+
module Places
|
7
|
+
def places_autocomplete(input, components: nil, bounds: nil, types: nil, region: nil, language: nil)
|
8
|
+
params = {}
|
9
|
+
|
10
|
+
params[:input] = input
|
11
|
+
params[:components] = GoogleMapsApis::Convert.components(components) if components
|
12
|
+
params[:bounds] = GoogleMapsApis::Convert.bounds(bounds) if bounds
|
13
|
+
params[:region] = region if region
|
14
|
+
params[:language] = language if language
|
15
|
+
params[:types] = types if types
|
16
|
+
|
17
|
+
return get('/maps/api/place/autocomplete/json', params)[:predictions]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module GoogleMapsApis::Services
|
4
|
+
|
5
|
+
# Performs requests to the Google Maps Roads API.
|
6
|
+
module Roads
|
7
|
+
|
8
|
+
# Base URL of Google Maps Roads API
|
9
|
+
ROADS_BASE_URL = "https://roads.googleapis.com"
|
10
|
+
|
11
|
+
# Snaps a path to the most likely roads travelled.
|
12
|
+
#
|
13
|
+
# Takes up to 100 GPS points collected along a route, and returns a similar
|
14
|
+
# set of data with the points snapped to the most likely roads the vehicle
|
15
|
+
# was traveling along.
|
16
|
+
#
|
17
|
+
# @example Single point snap
|
18
|
+
# results = client.snap_to_roads([40.714728, -73.998672])
|
19
|
+
#
|
20
|
+
# @example Multi points snap
|
21
|
+
# path = [
|
22
|
+
# [-33.8671, 151.20714],
|
23
|
+
# [-33.86708, 151.20683000000002],
|
24
|
+
# [-33.867070000000005, 151.20674000000002],
|
25
|
+
# [-33.86703, 151.20625]
|
26
|
+
# ]
|
27
|
+
# results = client.snap_to_roads(path, interpolate: true)
|
28
|
+
#
|
29
|
+
# @param [Array] path The path to be snapped. Array of latitude/longitude pairs.
|
30
|
+
# @param [Boolean] interpolate Whether to interpolate a path to include all points
|
31
|
+
# forming the full road-geometry. When true, additional interpolated
|
32
|
+
# points will also be returned, resulting in a path that smoothly
|
33
|
+
# follows the geometry of the road, even around corners and through
|
34
|
+
# tunnels. Interpolated paths may contain more points than the
|
35
|
+
# original path.
|
36
|
+
#
|
37
|
+
# @return [Array] Array of snapped points.
|
38
|
+
def snap_to_roads(path, interpolate: false)
|
39
|
+
path = GoogleMapsApis::Convert.waypoints(path)
|
40
|
+
|
41
|
+
params = {
|
42
|
+
path: path
|
43
|
+
}
|
44
|
+
|
45
|
+
params[:interpolate] = 'true' if interpolate
|
46
|
+
|
47
|
+
return get('/v1/snapToRoads', params,
|
48
|
+
base_url: ROADS_BASE_URL,
|
49
|
+
accepts_client_id: false,
|
50
|
+
custom_response_decoder: method(:extract_roads_body))[:snappedPoints]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the posted speed limit (in km/h) for given road segments.
|
54
|
+
#
|
55
|
+
# @example Multi places snap
|
56
|
+
# place_ids = [
|
57
|
+
# 'ChIJ0wawjUCuEmsRgfqC5Wd9ARM',
|
58
|
+
# 'ChIJ6cs2kkCuEmsRUfqC5Wd9ARM'
|
59
|
+
# ]
|
60
|
+
# results = client.speed_limits(place_ids)
|
61
|
+
#
|
62
|
+
# @param [String, Array<String>] place_ids The Place ID of the road segment. Place IDs are returned
|
63
|
+
# by the snap_to_roads function. You can pass up to 100 Place IDs.
|
64
|
+
#
|
65
|
+
# @return [Array] Array of speed limits.
|
66
|
+
def speed_limits(place_ids)
|
67
|
+
params = GoogleMapsApis::Convert.as_list(place_ids).map { |place_id| ['placeId', place_id] }
|
68
|
+
|
69
|
+
return get('/v1/speedLimits', params,
|
70
|
+
base_url: ROADS_BASE_URL,
|
71
|
+
accepts_client_id: false,
|
72
|
+
custom_response_decoder: method(:extract_roads_body))[:speedLimits]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the posted speed limit (in km/h) for given road segments.
|
76
|
+
#
|
77
|
+
# The provided points will first be snapped to the most likely roads the
|
78
|
+
# vehicle was traveling along.
|
79
|
+
#
|
80
|
+
# @example Multi points snap
|
81
|
+
# path = [
|
82
|
+
# [-33.8671, 151.20714],
|
83
|
+
# [-33.86708, 151.20683000000002],
|
84
|
+
# [-33.867070000000005, 151.20674000000002],
|
85
|
+
# [-33.86703, 151.20625]
|
86
|
+
# ]
|
87
|
+
# results = client.snapped_speed_limits(path)
|
88
|
+
#
|
89
|
+
# @param [Hash, Array] path The path of points to be snapped. A list of (or single)
|
90
|
+
# latitude/longitude tuples.
|
91
|
+
#
|
92
|
+
# @return [Hash] A hash with both a list of speed limits and a list of the snapped
|
93
|
+
# points.
|
94
|
+
def snapped_speed_limits(path)
|
95
|
+
path = GoogleMapsApis::Convert.waypoints(path)
|
96
|
+
|
97
|
+
params = {
|
98
|
+
path: path
|
99
|
+
}
|
100
|
+
|
101
|
+
return get('/v1/speedLimits', params,
|
102
|
+
base_url: ROADS_BASE_URL,
|
103
|
+
accepts_client_id: false,
|
104
|
+
custom_response_decoder: method(:extract_roads_body))
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the nearest road segments for provided points.
|
108
|
+
# The points passed do not need to be part of a continuous path.
|
109
|
+
#
|
110
|
+
# @example Single point snap
|
111
|
+
# results = client.nearest_roads([40.714728, -73.998672])
|
112
|
+
#
|
113
|
+
# @example Multi points snap
|
114
|
+
# points = [
|
115
|
+
# [-33.8671, 151.20714],
|
116
|
+
# [-33.86708, 151.20683000000002],
|
117
|
+
# [-33.867070000000005, 151.20674000000002],
|
118
|
+
# [-33.86703, 151.20625]
|
119
|
+
# ]
|
120
|
+
# results = client.nearest_roads(points)
|
121
|
+
#
|
122
|
+
# @param [Array] points The points to be used for nearest road segment lookup. Array of latitude/longitude pairs
|
123
|
+
# which do not need to be a part of continuous part.
|
124
|
+
# Takes up to 100 independent coordinates, and returns the closest road segment for each point.
|
125
|
+
#
|
126
|
+
# @return [Array] Array of snapped points.
|
127
|
+
|
128
|
+
def nearest_roads(points)
|
129
|
+
points = GoogleMapsApis::Convert.waypoints(points)
|
130
|
+
|
131
|
+
params = {
|
132
|
+
points: points
|
133
|
+
}
|
134
|
+
|
135
|
+
return get('/v1/nearestRoads', params,
|
136
|
+
base_url: ROADS_BASE_URL,
|
137
|
+
accepts_client_id: false,
|
138
|
+
custom_response_decoder: method(:extract_roads_body))[:snappedPoints]
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
private
|
144
|
+
# Extracts a result from a Roads API HTTP response.
|
145
|
+
def extract_roads_body(response)
|
146
|
+
begin
|
147
|
+
body = MultiJson.load(response.body, :symbolize_keys => true)
|
148
|
+
rescue
|
149
|
+
unless response.status == 200
|
150
|
+
check_response_status(response)
|
151
|
+
end
|
152
|
+
raise GoogleMapsApis::Error::ApiError.new(response), 'Received a malformed response.'
|
153
|
+
end
|
154
|
+
|
155
|
+
check_roads_body_error(response, body)
|
156
|
+
|
157
|
+
unless response.status == 200
|
158
|
+
raise GoogleMapsApis::Error::ApiError.new(response)
|
159
|
+
end
|
160
|
+
return body
|
161
|
+
end
|
162
|
+
|
163
|
+
# Check response body for error status.
|
164
|
+
#
|
165
|
+
# @param [Faraday::Response] response Response object.
|
166
|
+
# @param [Hash] body Response body.
|
167
|
+
def check_roads_body_error(response, body)
|
168
|
+
error = body[:error]
|
169
|
+
return unless error
|
170
|
+
|
171
|
+
case error[:status]
|
172
|
+
when 'INVALID_ARGUMENT'
|
173
|
+
if error[:message] == 'The provided API key is invalid.'
|
174
|
+
raise GoogleMapsApis::Error::RequestDeniedError.new(response), error[:message]
|
175
|
+
end
|
176
|
+
raise GoogleMapsApis::Error::InvalidRequestError.new(response), error[:message]
|
177
|
+
when 'PERMISSION_DENIED'
|
178
|
+
raise GoogleMapsApis::Error::RequestDeniedError.new(response), error[:message]
|
179
|
+
when 'RESOURCE_EXHAUSTED'
|
180
|
+
raise GoogleMapsApis::Error::RateLimitError.new(response), error[:message]
|
181
|
+
else
|
182
|
+
raise GoogleMapsApis::Error::ApiError.new(response), error[:message]
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module GoogleMapsApis::Services
|
4
|
+
|
5
|
+
# Performs requests to the Google Maps TimeZone API."""
|
6
|
+
module TimeZone
|
7
|
+
|
8
|
+
# Get time zone for a location on the earth, as well as that location's
|
9
|
+
# time offset from UTC.
|
10
|
+
#
|
11
|
+
# @example Current time zone
|
12
|
+
# timezone = client.timezone([39.603481, -119.682251])
|
13
|
+
#
|
14
|
+
# @example Time zone at certain time
|
15
|
+
# timezone = client.timezone([39.603481, -119.682251], timestamp: Time.at(1608))
|
16
|
+
#
|
17
|
+
# @param [Hash, Array] location The latitude/longitude value representing the location to
|
18
|
+
# look up.
|
19
|
+
# @param [Integer, DateTime] timestamp Timestamp specifies the desired time as seconds since
|
20
|
+
# midnight, January 1, 1970 UTC. The Time Zone API uses the timestamp to
|
21
|
+
# determine whether or not Daylight Savings should be applied. Times
|
22
|
+
# before 1970 can be expressed as negative values. Optional. Defaults to
|
23
|
+
# `Time.now`.
|
24
|
+
# @param [String] language The language in which to return results.
|
25
|
+
#
|
26
|
+
# @return [Hash] Time zone object.
|
27
|
+
def timezone(location, timestamp: Time.now, language: nil)
|
28
|
+
location = GoogleMapsApis::Convert.latlng(location)
|
29
|
+
timestamp = GoogleMapsApis::Convert.time(timestamp)
|
30
|
+
|
31
|
+
params = {
|
32
|
+
location: location,
|
33
|
+
timestamp: timestamp
|
34
|
+
}
|
35
|
+
|
36
|
+
params[:language] = language if language
|
37
|
+
|
38
|
+
return get('/maps/api/timezone/json', params)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module GoogleMapsApis
|
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
|