google_distance_matrix 0.4.0 → 0.6.3
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 +5 -5
- data/.editorconfig +16 -0
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -6
- data/CHANGELOG.md +40 -0
- data/Gemfile +2 -0
- data/README.md +0 -3
- data/Rakefile +9 -4
- data/google_distance_matrix.gemspec +21 -19
- data/lib/google_distance_matrix.rb +25 -23
- data/lib/google_distance_matrix/client.rb +32 -18
- data/lib/google_distance_matrix/client_cache.rb +9 -3
- data/lib/google_distance_matrix/configuration.rb +39 -24
- data/lib/google_distance_matrix/errors.rb +6 -3
- data/lib/google_distance_matrix/log_subscriber.rb +14 -14
- data/lib/google_distance_matrix/logger.rb +7 -5
- data/lib/google_distance_matrix/matrix.rb +45 -22
- data/lib/google_distance_matrix/place.rb +37 -28
- data/lib/google_distance_matrix/places.rb +5 -4
- data/lib/google_distance_matrix/polyline_encoder.rb +2 -2
- data/lib/google_distance_matrix/polyline_encoder/delta.rb +4 -2
- data/lib/google_distance_matrix/polyline_encoder/value_encoder.rb +13 -5
- data/lib/google_distance_matrix/railtie.rb +4 -1
- data/lib/google_distance_matrix/route.rb +22 -15
- data/lib/google_distance_matrix/routes_finder.rb +27 -29
- data/lib/google_distance_matrix/url_builder.rb +44 -16
- data/lib/google_distance_matrix/url_builder/polyline_encoder_buffer.rb +3 -0
- data/lib/google_distance_matrix/version.rb +3 -1
- data/spec/lib/google_distance_matrix/client_cache_spec.rb +27 -11
- data/spec/lib/google_distance_matrix/client_spec.rb +40 -30
- data/spec/lib/google_distance_matrix/configuration_spec.rb +36 -24
- data/spec/lib/google_distance_matrix/log_subscriber_spec.rb +13 -44
- data/spec/lib/google_distance_matrix/logger_spec.rb +16 -13
- data/spec/lib/google_distance_matrix/matrix_spec.rb +90 -57
- data/spec/lib/google_distance_matrix/place_spec.rb +38 -25
- data/spec/lib/google_distance_matrix/places_spec.rb +29 -28
- data/spec/lib/google_distance_matrix/polyline_encoder/delta_spec.rb +5 -3
- data/spec/lib/google_distance_matrix/polyline_encoder_spec.rb +7 -2
- data/spec/lib/google_distance_matrix/route_spec.rb +11 -9
- data/spec/lib/google_distance_matrix/routes_finder_spec.rb +124 -81
- data/spec/lib/google_distance_matrix/url_builder_spec.rb +97 -48
- data/spec/spec_helper.rb +3 -1
- metadata +46 -18
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
2
4
|
# Public: Error class for lib.
|
3
5
|
class Error < StandardError
|
@@ -67,7 +69,8 @@ module GoogleDistanceMatrix
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def to_s
|
70
|
-
"GoogleDistanceMatrix::ClientError -
|
72
|
+
"GoogleDistanceMatrix::ClientError - \
|
73
|
+
#{[response, status_read_from_api_response].compact.join('. ')}."
|
71
74
|
end
|
72
75
|
end
|
73
76
|
|
@@ -75,7 +78,8 @@ module GoogleDistanceMatrix
|
|
75
78
|
#
|
76
79
|
# See https://developers.google.com/maps/documentation/distancematrix/#Limits, which states:
|
77
80
|
# "Distance Matrix API URLs are restricted to 2048 characters, before URL encoding."
|
78
|
-
# "As some Distance Matrix API service URLs may involve many locations,
|
81
|
+
# "As some Distance Matrix API service URLs may involve many locations,
|
82
|
+
# be aware of this limit when constructing your URLs."
|
79
83
|
#
|
80
84
|
class MatrixUrlTooLong < ClientError
|
81
85
|
attr_reader :url, :max_url_size
|
@@ -91,5 +95,4 @@ module GoogleDistanceMatrix
|
|
91
95
|
"Matrix API URL max size is: #{max_url_size}. Built URL was: #{url.length}. URL: '#{url}'."
|
92
96
|
end
|
93
97
|
end
|
94
|
-
|
95
98
|
end
|
@@ -1,8 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
4
|
+
# LogSubscriber logs to GoogleDistanceMatrix.logger by subscribing to gem's intstrumentation.
|
5
|
+
#
|
6
|
+
# NOTE: This log subscruber uses the default_configuration as it's configuration.
|
7
|
+
# This is relevant for example for the filter_parameters_in_logged_url configuration
|
2
8
|
class LogSubscriber < ActiveSupport::LogSubscriber
|
3
9
|
attr_reader :logger, :config
|
4
10
|
|
5
|
-
def initialize(
|
11
|
+
def initialize(
|
12
|
+
logger: GoogleDistanceMatrix.logger,
|
13
|
+
config: GoogleDistanceMatrix.default_configuration
|
14
|
+
)
|
6
15
|
super()
|
7
16
|
|
8
17
|
@logger = logger
|
@@ -10,20 +19,11 @@ module GoogleDistanceMatrix
|
|
10
19
|
end
|
11
20
|
|
12
21
|
def client_request_matrix_data(event)
|
13
|
-
url =
|
14
|
-
logger.info "(#{event.duration}ms) (elements: #{event.payload[:elements]}) GET #{url}",
|
15
|
-
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def filter_url!(url)
|
20
|
-
config.filter_parameters_in_logged_url.each do |param|
|
21
|
-
url.gsub! %r{(#{param})=.*?(&|$)}, '\1=[FILTERED]\2'
|
22
|
-
end
|
23
|
-
|
24
|
-
url
|
22
|
+
url = event.payload[:filtered_url]
|
23
|
+
logger.info "(#{event.duration}ms) (elements: #{event.payload[:elements]}) GET #{url}",
|
24
|
+
tag: :client
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
GoogleDistanceMatrix::LogSubscriber.attach_to
|
29
|
+
GoogleDistanceMatrix::LogSubscriber.attach_to 'google_distance_matrix'
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
4
|
+
# Logger class for Google Distance Matrix
|
2
5
|
class Logger
|
3
|
-
PREFIXES = %w[google_distance_matrix]
|
4
|
-
LEVELS = %w[fatal error warn info debug]
|
6
|
+
PREFIXES = %w[google_distance_matrix].freeze
|
7
|
+
LEVELS = %w[fatal error warn info debug].freeze
|
5
8
|
|
6
9
|
attr_reader :backend
|
7
10
|
|
@@ -16,17 +19,16 @@ module GoogleDistanceMatrix
|
|
16
19
|
msg = args.first
|
17
20
|
tags = PREFIXES.dup.concat Array.wrap(options[:tag])
|
18
21
|
|
19
|
-
backend
|
22
|
+
backend&.public_send level, tag_msg(msg, tags)
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
|
-
|
24
26
|
private
|
25
27
|
|
26
28
|
def tag_msg(msg, tags)
|
27
29
|
msg_buffer = tags.map { |tag| "[#{tag}]" }
|
28
30
|
msg_buffer << msg
|
29
|
-
msg_buffer.join
|
31
|
+
msg_buffer.join ' '
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
2
4
|
# Public: Represents a distance matrix.
|
3
5
|
#
|
@@ -25,23 +27,25 @@ module GoogleDistanceMatrix
|
|
25
27
|
# config.mode = "walking"
|
26
28
|
# end
|
27
29
|
#
|
28
|
-
# You can set default configuration by doing:
|
30
|
+
# You can set default configuration by doing:
|
31
|
+
# GoogleDistanceMatrix.configure_defaults { |c| c.sensor = true }
|
29
32
|
#
|
30
33
|
#
|
31
34
|
# Query API and get the matrix back
|
32
35
|
#
|
33
36
|
# matrix.data # Returns a two dimensional array.
|
34
37
|
# # Rows are ordered according to the values in the origins.
|
35
|
-
# # Each row corresponds to an origin, and each element
|
38
|
+
# # Each row corresponds to an origin, and each element
|
39
|
+
# # within that row corresponds to
|
36
40
|
# # a pairing of the origin with a destination.
|
37
41
|
#
|
38
42
|
#
|
39
43
|
class Matrix
|
40
44
|
include ActiveModel::Validations
|
41
45
|
|
42
|
-
validates :origins, length: {minimum: 1, too_short:
|
43
|
-
validates :destinations, length: {minimum: 1, too_short:
|
44
|
-
validate { errors.add(:configuration,
|
46
|
+
validates :origins, length: { minimum: 1, too_short: 'must have at least one origin' }
|
47
|
+
validates :destinations, length: { minimum: 1, too_short: 'must have at least one destination' }
|
48
|
+
validate { errors.add(:configuration, 'is invalid') if configuration.invalid? }
|
45
49
|
|
46
50
|
attr_reader :origins, :destinations, :configuration
|
47
51
|
|
@@ -53,6 +57,7 @@ module GoogleDistanceMatrix
|
|
53
57
|
@configuration = attributes[:configuration] || GoogleDistanceMatrix.default_configuration.dup
|
54
58
|
end
|
55
59
|
|
60
|
+
delegate :sensitive_url, :filtered_url, to: :url_builder
|
56
61
|
|
57
62
|
delegate :route_for, :routes_for, to: :routes_finder
|
58
63
|
delegate :route_for!, :routes_for!, to: :routes_finder
|
@@ -61,7 +66,6 @@ module GoogleDistanceMatrix
|
|
61
66
|
delegate :shortest_route_by_duration_in_traffic_to, to: :routes_finder
|
62
67
|
delegate :shortest_route_by_duration_in_traffic_to!, to: :routes_finder
|
63
68
|
|
64
|
-
|
65
69
|
# Public: The data for this matrix.
|
66
70
|
#
|
67
71
|
# Returns a two dimensional array, the matrix's data
|
@@ -83,40 +87,59 @@ module GoogleDistanceMatrix
|
|
83
87
|
@data.present?
|
84
88
|
end
|
85
89
|
|
86
|
-
|
87
|
-
|
88
90
|
def configure
|
89
91
|
yield configuration
|
90
92
|
end
|
91
93
|
|
92
|
-
def url
|
93
|
-
UrlBuilder.new(self).url
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
94
|
def inspect
|
98
95
|
attributes = %w[origins destinations]
|
99
|
-
attributes <<
|
96
|
+
attributes << 'data' if loaded?
|
100
97
|
inspection = attributes.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
|
101
98
|
|
102
99
|
"#<#{self.class} #{inspection}>"
|
103
100
|
end
|
104
101
|
|
105
|
-
|
106
102
|
private
|
107
103
|
|
104
|
+
def url_builder
|
105
|
+
# We do not keep url builder as an instance variable as origins and destinations
|
106
|
+
# may be added after URL is being built for the first time. We should either
|
107
|
+
# make our matrix immutable or reset if origins/destinations are added after data (and
|
108
|
+
# the url) first being built and data fetched.
|
109
|
+
UrlBuilder.new self
|
110
|
+
end
|
111
|
+
|
108
112
|
def routes_finder
|
109
113
|
@routes_finder ||= RoutesFinder.new self
|
110
114
|
end
|
111
115
|
|
112
116
|
def load_matrix
|
113
|
-
|
117
|
+
body = client.get(
|
118
|
+
sensitive_url,
|
119
|
+
instrumentation: instrumentation_for_api_request,
|
120
|
+
configuration: configuration
|
121
|
+
).body
|
122
|
+
|
123
|
+
parsed = JSON.parse(body)
|
124
|
+
create_route_objects_for_parsed_data parsed
|
125
|
+
end
|
126
|
+
|
127
|
+
def instrumentation_for_api_request
|
128
|
+
{
|
129
|
+
elements: origins.length * destinations.length,
|
130
|
+
sensitive_url: sensitive_url,
|
131
|
+
filtered_url: filtered_url
|
132
|
+
}
|
133
|
+
end
|
114
134
|
|
115
|
-
|
135
|
+
def create_route_objects_for_parsed_data(parsed)
|
136
|
+
parsed['rows'].each_with_index.map do |row, origin_index|
|
116
137
|
origin = origins[origin_index]
|
117
138
|
|
118
|
-
row[
|
119
|
-
route_attributes = element.merge(
|
139
|
+
row['elements'].each_with_index.map do |element, destination_index|
|
140
|
+
route_attributes = element.merge(
|
141
|
+
origin: origin, destination: destinations[destination_index]
|
142
|
+
)
|
120
143
|
Route.new route_attributes
|
121
144
|
end
|
122
145
|
end
|
@@ -133,9 +156,9 @@ module GoogleDistanceMatrix
|
|
133
156
|
end
|
134
157
|
|
135
158
|
def clear_from_cache!
|
136
|
-
if configuration.cache
|
137
|
-
|
138
|
-
|
159
|
+
return if configuration.cache.nil?
|
160
|
+
|
161
|
+
configuration.cache.delete ClientCache.key(sensitive_url, configuration)
|
139
162
|
end
|
140
163
|
end
|
141
164
|
end
|
@@ -1,28 +1,31 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Examples
|
4
|
-
#
|
5
|
-
# GoogleDistanceMatrix::Place.new address: "My address"
|
6
|
-
# GoogleDistanceMatrix::Place.new lat: 1, lng: 3
|
7
|
-
#
|
8
|
-
# You may also build places by other objects responding to lat and lng or address.
|
9
|
-
# If your object responds to all of the attributes we'll use lat and lng as data
|
10
|
-
# for the Place.
|
11
|
-
#
|
12
|
-
# GoogleDistanceMatrix::Place.new object
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
13
3
|
module GoogleDistanceMatrix
|
4
|
+
# Public: Represents a place and knows how to convert it to param.
|
5
|
+
#
|
6
|
+
# Examples
|
7
|
+
#
|
8
|
+
# GoogleDistanceMatrix::Place.new address: "My address"
|
9
|
+
# GoogleDistanceMatrix::Place.new lat: 1, lng: 3
|
10
|
+
#
|
11
|
+
# You may also build places by other objects responding to lat and lng or address.
|
12
|
+
# If your object responds to all of the attributes we'll use lat and lng as data
|
13
|
+
# for the Place.
|
14
|
+
#
|
15
|
+
# GoogleDistanceMatrix::Place.new object
|
14
16
|
class Place
|
15
|
-
ATTRIBUTES = %w[address lat lng]
|
17
|
+
ATTRIBUTES = %w[address lat lng].freeze
|
16
18
|
|
17
|
-
attr_reader
|
19
|
+
attr_reader(*ATTRIBUTES, :extracted_attributes_from)
|
18
20
|
|
19
21
|
def initialize(attributes_or_object)
|
20
22
|
if respond_to_needed_attributes? attributes_or_object
|
21
23
|
extract_and_assign_attributes_from_object attributes_or_object
|
22
24
|
elsif attributes_or_object.is_a? Hash
|
25
|
+
@extracted_attributes_from = attributes_or_object.with_indifferent_access
|
23
26
|
assign_attributes attributes_or_object
|
24
27
|
else
|
25
|
-
|
28
|
+
raise ArgumentError, 'Must be either hash or object responding to lat, lng or address. '
|
26
29
|
end
|
27
30
|
|
28
31
|
validate_attributes
|
@@ -33,14 +36,16 @@ module GoogleDistanceMatrix
|
|
33
36
|
address.present? ? address : lat_lng(options[:lat_lng_scale]).join(',')
|
34
37
|
end
|
35
38
|
|
36
|
-
|
37
39
|
def eql?(other)
|
40
|
+
return false unless other.is_a? self.class
|
41
|
+
|
38
42
|
if address.present?
|
39
43
|
address == other.address
|
40
44
|
else
|
41
45
|
lat_lng == other.lat_lng
|
42
46
|
end
|
43
47
|
end
|
48
|
+
alias == eql?
|
44
49
|
|
45
50
|
def lat_lng?
|
46
51
|
lat.present? && lng.present?
|
@@ -58,7 +63,9 @@ module GoogleDistanceMatrix
|
|
58
63
|
end
|
59
64
|
|
60
65
|
def inspect
|
61
|
-
inspection =
|
66
|
+
inspection = (ATTRIBUTES | [:extracted_attributes_from])
|
67
|
+
.reject { |a| public_send(a).blank? }
|
68
|
+
.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
|
62
69
|
|
63
70
|
"#<#{self.class} #{inspection}>"
|
64
71
|
end
|
@@ -66,19 +73,15 @@ module GoogleDistanceMatrix
|
|
66
73
|
private
|
67
74
|
|
68
75
|
def respond_to_needed_attributes?(object)
|
69
|
-
(object.respond_to?(:lat) &&
|
76
|
+
(object.respond_to?(:lat) && object.respond_to?(:lng)) || object.respond_to?(:address)
|
70
77
|
end
|
71
78
|
|
72
79
|
def extract_and_assign_attributes_from_object(object)
|
73
|
-
attrs =
|
74
|
-
if object.respond_to? attr_name
|
75
|
-
[attr_name, object.public_send(attr_name)]
|
76
|
-
end
|
80
|
+
attrs = Hash[ATTRIBUTES.map do |attr_name|
|
81
|
+
[attr_name, object.public_send(attr_name)] if object.respond_to? attr_name
|
77
82
|
end.compact]
|
78
83
|
|
79
|
-
if attrs.
|
80
|
-
attrs.delete 'address'
|
81
|
-
end
|
84
|
+
attrs.delete 'address' if attrs.key?('lat') || attrs.key?('lng')
|
82
85
|
|
83
86
|
@extracted_attributes_from = object
|
84
87
|
assign_attributes attrs
|
@@ -92,14 +95,20 @@ module GoogleDistanceMatrix
|
|
92
95
|
@lng = attributes[:lng]
|
93
96
|
end
|
94
97
|
|
98
|
+
# rubocop:disable Metrics/AbcSize
|
99
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
100
|
+
# rubocop:disable Style/GuardClause
|
95
101
|
def validate_attributes
|
96
|
-
|
97
|
-
|
102
|
+
unless address.present? || (lat.present? && lng.present?)
|
103
|
+
raise ArgumentError, 'Must provide an address, or lat and lng.'
|
98
104
|
end
|
99
105
|
|
100
106
|
if address.present? && lat.present? && lng.present?
|
101
|
-
|
107
|
+
raise ArgumentError, 'Cannot provide address, lat and lng.'
|
102
108
|
end
|
103
109
|
end
|
110
|
+
# rubocop:enable Metrics/AbcSize
|
111
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
112
|
+
# rubocop:enable Style/GuardClause
|
104
113
|
end
|
105
114
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
4
|
+
# Represents a collection of places
|
2
5
|
class Places
|
3
6
|
include Enumerable
|
4
7
|
|
@@ -7,10 +10,9 @@ module GoogleDistanceMatrix
|
|
7
10
|
concat Array.wrap(places)
|
8
11
|
end
|
9
12
|
|
10
|
-
|
11
13
|
delegate :each, :[], :length, :index, :pop, :shift, :delete_at, :compact, :inspect, to: :places
|
12
14
|
|
13
|
-
[
|
15
|
+
%i[<< push unshift].each do |method|
|
14
16
|
define_method method do |*args|
|
15
17
|
args = ensure_args_are_places args
|
16
18
|
|
@@ -22,10 +24,9 @@ module GoogleDistanceMatrix
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def concat(other)
|
25
|
-
push
|
27
|
+
push(*other)
|
26
28
|
end
|
27
29
|
|
28
|
-
|
29
30
|
private
|
30
31
|
|
31
32
|
attr_reader :places
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'polyline_encoder/delta'
|
2
4
|
require_relative 'polyline_encoder/value_encoder'
|
3
5
|
|
@@ -7,7 +9,6 @@ module GoogleDistanceMatrix
|
|
7
9
|
#
|
8
10
|
# See https://developers.google.com/maps/documentation/utilities/polylinealgorithm
|
9
11
|
class PolylineEncoder
|
10
|
-
|
11
12
|
# Encodes a set of lat/lng pairs
|
12
13
|
#
|
13
14
|
# Example
|
@@ -16,7 +17,6 @@ module GoogleDistanceMatrix
|
|
16
17
|
new(array_of_lat_lng_pairs).encode
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
20
|
# Initialize a new encoder
|
21
21
|
#
|
22
22
|
# Arguments
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
2
4
|
class PolylineEncoder
|
3
5
|
# Calculates deltas between lat_lng values, internal helper class for PolylineEncoder.
|
@@ -20,7 +22,6 @@ module GoogleDistanceMatrix
|
|
20
22
|
calculate_deltas rounded
|
21
23
|
end
|
22
24
|
|
23
|
-
|
24
25
|
private
|
25
26
|
|
26
27
|
def round_to_precision(array_of_lat_lng_pairs)
|
@@ -42,7 +43,8 @@ module GoogleDistanceMatrix
|
|
42
43
|
deltas << lat - delta_lat
|
43
44
|
deltas << lng - delta_lng
|
44
45
|
|
45
|
-
delta_lat
|
46
|
+
delta_lat = lat
|
47
|
+
delta_lng = lng
|
46
48
|
end
|
47
49
|
|
48
50
|
deltas
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Style/NumericPredicate
|
1
4
|
module GoogleDistanceMatrix
|
2
5
|
class PolylineEncoder
|
3
6
|
# Encodes a single value, like 17998321, in to encoded polyline value,
|
@@ -9,6 +12,8 @@ module GoogleDistanceMatrix
|
|
9
12
|
#
|
10
13
|
# @see GoogleDistanceMatrix::PolylineEncoder
|
11
14
|
class ValueEncoder
|
15
|
+
# rubocop:disable Metrics/MethodLength
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
12
17
|
def encode(value)
|
13
18
|
negative = value < 0
|
14
19
|
value = value.abs
|
@@ -27,7 +32,7 @@ module GoogleDistanceMatrix
|
|
27
32
|
# Right shift bits to get rid of the ones we just put on the array.
|
28
33
|
# Bits will end up in reverse order.
|
29
34
|
chunks_of_5_bits = []
|
30
|
-
while value > 0
|
35
|
+
while value > 0
|
31
36
|
chunks_of_5_bits.push(value & 0x1f)
|
32
37
|
value >>= 5
|
33
38
|
end
|
@@ -44,6 +49,8 @@ module GoogleDistanceMatrix
|
|
44
49
|
# step 11: Convert to ASCII
|
45
50
|
chunks_of_5_bits.map(&:chr)
|
46
51
|
end
|
52
|
+
# rubocop:enable Metrics/MethodLength
|
53
|
+
# rubocop:enable Metrics/AbcSize
|
47
54
|
|
48
55
|
private
|
49
56
|
|
@@ -51,11 +58,12 @@ module GoogleDistanceMatrix
|
|
51
58
|
#
|
52
59
|
# Example of usage
|
53
60
|
# p d 17998321 # => "00000001 00010010 10100001 11110001"
|
54
|
-
def d(
|
55
|
-
(bits - 1).downto(0)
|
56
|
-
|
57
|
-
|
61
|
+
def d(val, bits = 32, chunk_size = 8)
|
62
|
+
(bits - 1).downto(0)
|
63
|
+
.map { |n| val[n] }
|
64
|
+
.each_slice(chunk_size).map(&:join).join ' '
|
58
65
|
end
|
59
66
|
end
|
60
67
|
end
|
61
68
|
end
|
69
|
+
# rubocop:enable Style/NumericPredicate
|