aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tom_tom
diff options
context:
space:
mode:
authorAlban Peignier2018-04-04 10:03:40 +0200
committerGitHub2018-04-04 10:03:40 +0200
commitecf0dd6406576f8a63ee056fab73b05171c3e767 (patch)
treed48bf1be4052ca446bd6c715698d857a9102d914 /lib/tom_tom
parent6262b1cf8c536fb59997119a28420584ab08994c (diff)
parent2cb5225efbb080707c060e4038ae6d48612515f0 (diff)
downloadchouette-core-ecf0dd6406576f8a63ee056fab73b05171c3e767.tar.bz2
Merge pull request #413 from af83/6222-route-way-costs--use-TomTom-matrix-API-instead-of-batch
Route way costs use tom tom matrix api instead of batch. Refs #6222
Diffstat (limited to 'lib/tom_tom')
-rw-r--r--lib/tom_tom/matrix.rb114
-rw-r--r--lib/tom_tom/matrix/point.rb18
-rw-r--r--lib/tom_tom/matrix/request_json_serializer.rb25
3 files changed, 157 insertions, 0 deletions
diff --git a/lib/tom_tom/matrix.rb b/lib/tom_tom/matrix.rb
new file mode 100644
index 000000000..b0c8cc335
--- /dev/null
+++ b/lib/tom_tom/matrix.rb
@@ -0,0 +1,114 @@
+module TomTom
+ class Matrix
+ def initialize(connection)
+ @connection = connection
+ end
+
+ def matrix(way_costs)
+ points_with_ids = points_from_way_costs(way_costs)
+ points = points_as_params(points_with_ids)
+
+ Rails.logger.info "Invoke TomTom for #{points.size} points"
+
+ response = @connection.post do |req|
+ req.url '/routing/1/matrix/json'
+ req.headers['Content-Type'] = 'application/json'
+
+ req.params[:routeType] = 'shortest'
+ req.params[:travelMode] = 'bus'
+
+ req.body = build_request_body(points)
+ end
+
+ extract_costs_to_way_costs!(
+ way_costs,
+ points_with_ids,
+ JSON.parse(response.body)
+ )
+ end
+
+ def points_from_way_costs(way_costs)
+ points = []
+
+ way_costs.each do |way_cost|
+ departure_id, arrival_id = way_cost.id.split('-')
+
+ departure = TomTom::Matrix::Point.new(
+ way_cost.departure,
+ departure_id
+ )
+ arrival = TomTom::Matrix::Point.new(
+ way_cost.arrival,
+ arrival_id
+ )
+
+ # Don't add duplicate coordinates. This assumes that
+ # `way_costs` consists of an ordered route of points where
+ # each departure coordinate is the same as the preceding
+ # arrival coordinate.
+ if points.empty? ||
+ points.last.coordinates != departure.coordinates
+ points << departure
+ end
+
+ points << arrival
+ end
+
+ points
+ end
+
+ def points_as_params(points)
+ points.map do |point|
+ {
+ point: {
+ latitude: point.coordinates.lat,
+ longitude: point.coordinates.lng
+ }
+ }
+ end
+ end
+
+ def build_request_body(points)
+ # Serialize `BigDecimal` values as floats to please the TomTom API
+ RequestJSONSerializer.dump({
+ origins: points,
+ destinations: points
+ })
+ end
+
+ def extract_costs_to_way_costs!(way_costs, points, matrix_json)
+ way_costs = []
+
+ # `row` and `column` order is the same as `points`
+ matrix_json['matrix'].each_with_index do |row, row_i|
+ row.each_with_index do |column, column_i|
+ next if column['statusCode'] != 200
+
+ distance = column['response']['routeSummary']['lengthInMeters']
+
+ # Ignore costs between a point and itself (e.g. from A to A)
+ next if distance == 0
+
+ departure = points[row_i]
+ arrival = points[column_i]
+
+ way_costs << WayCost.new(
+ departure: Geokit::LatLng.new(
+ departure.coordinates.lat,
+ departure.coordinates.lng
+ ),
+ arrival: Geokit::LatLng.new(
+ arrival.coordinates.lat,
+ arrival.coordinates.lng
+ ),
+ distance: distance,
+ time: column['response']['routeSummary']['travelTimeInSeconds'],
+ id: "#{departure.id}-#{arrival.id}"
+ )
+ end
+ end
+
+ way_costs
+ end
+ end
+end
diff --git a/lib/tom_tom/matrix/point.rb b/lib/tom_tom/matrix/point.rb
new file mode 100644
index 000000000..435b4d4b0
--- /dev/null
+++ b/lib/tom_tom/matrix/point.rb
@@ -0,0 +1,18 @@
+module TomTom
+ class Matrix
+ class Point
+ attr_reader :coordinates, :id
+
+ def initialize(coordinates, id)
+ @coordinates = coordinates
+ @id = id
+ end
+
+ def ==(other)
+ other.is_a?(self.class) &&
+ @coordinates == other.coordinates &&
+ @id == other.id
+ end
+ end
+ end
+end
diff --git a/lib/tom_tom/matrix/request_json_serializer.rb b/lib/tom_tom/matrix/request_json_serializer.rb
new file mode 100644
index 000000000..f4d12e482
--- /dev/null
+++ b/lib/tom_tom/matrix/request_json_serializer.rb
@@ -0,0 +1,25 @@
+module TomTom
+ class Matrix
+ class RequestJSONSerializer
+ def self.dump(hash)
+ hash[:origins].map! do |point|
+ point_to_f(point)
+ end
+ hash[:destinations].map! do |point|
+ point_to_f(point)
+ end
+
+ JSON.dump(hash)
+ end
+
+ private
+
+ def self.point_to_f(point)
+ point[:point][:latitude] = point[:point][:latitude].to_f
+ point[:point][:longitude] = point[:point][:longitude].to_f
+
+ point
+ end
+ end
+ end
+end