google_maps_apis 1.0.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 +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
|