From d24f53dc31e5473fd7a4049a4cba6debb1382390 Mon Sep 17 00:00:00 2001 From: Brian Fauble Date: Wed, 27 Mar 2024 09:17:21 -0600 Subject: [PATCH 1/3] parse last_trip field from TripUpdates and VehiclePositions enhanced feeds --- .../parser/gtfs_realtime_enhanced.ex | 3 +- lib/concentrate/trip_descriptor.ex | 14 +-- .../parser/gtfs_realtime_enhanced_test.exs | 89 +++++++++++++++++++ test/concentrate/trip_descriptor_test.exs | 3 +- 4 files changed, 101 insertions(+), 8 deletions(-) diff --git a/lib/concentrate/parser/gtfs_realtime_enhanced.ex b/lib/concentrate/parser/gtfs_realtime_enhanced.ex index 338ec90d..2e91c0c5 100644 --- a/lib/concentrate/parser/gtfs_realtime_enhanced.ex +++ b/lib/concentrate/parser/gtfs_realtime_enhanced.ex @@ -248,7 +248,8 @@ defmodule Concentrate.Parser.GTFSRealtimeEnhanced do schedule_relationship: schedule_relationship(Map.get(trip, "schedule_relationship")), timestamp: Map.get(descriptor, "timestamp"), revenue: Map.get(trip, "revenue", true), - vehicle_id: vehicle_id + vehicle_id: vehicle_id, + last_trip: Map.get(trip, "last_trip", false) ) ] end diff --git a/lib/concentrate/trip_descriptor.ex b/lib/concentrate/trip_descriptor.ex index 57b75382..2da81e78 100644 --- a/lib/concentrate/trip_descriptor.ex +++ b/lib/concentrate/trip_descriptor.ex @@ -13,6 +13,7 @@ defmodule Concentrate.TripDescriptor do :start_time, :vehicle_id, :timestamp, + last_trip: false, revenue: true, schedule_relationship: :SCHEDULED ]) @@ -57,13 +58,14 @@ defmodule Concentrate.TripDescriptor do start_time: first.start_time || second.start_time, vehicle_id: first.vehicle_id || second.vehicle_id, timestamp: first.timestamp || second.timestamp, - schedule_relationship: - if first.schedule_relationship == :SCHEDULED do - second.schedule_relationship - else - first.schedule_relationship - end + last_trip: first.last_trip || second.last_trip, + schedule_relationship: merge_schedule_relationship(first, second) } end + + defp merge_schedule_relationship(%{schedule_relationship: :SCHEDULED}, second), + do: second.schedule_relationship + + defp merge_schedule_relationship(first, _), do: first.schedule_relationship end end diff --git a/test/concentrate/parser/gtfs_realtime_enhanced_test.exs b/test/concentrate/parser/gtfs_realtime_enhanced_test.exs index ef213647..640b0a97 100644 --- a/test/concentrate/parser/gtfs_realtime_enhanced_test.exs +++ b/test/concentrate/parser/gtfs_realtime_enhanced_test.exs @@ -371,6 +371,46 @@ defmodule Concentrate.Parser.GTFSRealtimeEnhancedTest do [td] = decode_trip_update(map, Helpers.parse_options([])) assert TripDescriptor.revenue(td) == true end + + test "decodes last_trip" do + not_last_trip = %{ + "trip" => %{ + "trip_id" => "trip", + "route_id" => "route", + "revenue" => true, + "last_trip" => false + }, + "stop_time_update" => [] + } + + last_trip = %{ + "trip" => %{ + "trip_id" => "trip", + "route_id" => "route", + "revenue" => true, + "last_trip" => true + }, + "stop_time_update" => [] + } + + not_specified = %{ + "trip" => %{ + "trip_id" => "trip", + "route_id" => "route", + "revenue" => true + }, + "stop_time_update" => [] + } + + [td] = decode_trip_update(not_last_trip, Helpers.parse_options([])) + assert TripDescriptor.last_trip(td) == false + + [td] = decode_trip_update(last_trip, Helpers.parse_options([])) + assert TripDescriptor.last_trip(td) == true + + [td] = decode_trip_update(not_specified, Helpers.parse_options([])) + assert TripDescriptor.last_trip(td) == false + end end describe "decode_vehicle/3" do @@ -611,5 +651,54 @@ defmodule Concentrate.Parser.GTFSRealtimeEnhancedTest do [td, _vp] = decode_vehicle(revenue_map, Helpers.parse_options([]), nil) assert TripDescriptor.revenue(td) == true end + + test "decodes last_trip" do + not_last_trip = %{ + "trip" => %{ + "trip_id" => "trip", + "route_id" => "route", + "revenue" => true, + "last_trip" => false + }, + "position" => %{ + "latitude" => 1.0, + "longitude" => 1.0 + } + } + + last_trip = %{ + "trip" => %{ + "trip_id" => "trip", + "route_id" => "route", + "revenue" => true, + "last_trip" => true + }, + "position" => %{ + "latitude" => 1.0, + "longitude" => 1.0 + } + } + + not_specified = %{ + "trip" => %{ + "trip_id" => "trip", + "route_id" => "route", + "revenue" => true + }, + "position" => %{ + "latitude" => 1.0, + "longitude" => 1.0 + } + } + + [td, _vp] = decode_vehicle(not_last_trip, Helpers.parse_options([]), nil) + assert TripDescriptor.last_trip(td) == false + + [td, _vp] = decode_vehicle(last_trip, Helpers.parse_options([]), nil) + assert TripDescriptor.last_trip(td) == true + + [td, _vp] = decode_vehicle(not_specified, Helpers.parse_options([]), nil) + assert TripDescriptor.last_trip(td) == false + end end end diff --git a/test/concentrate/trip_descriptor_test.exs b/test/concentrate/trip_descriptor_test.exs index 4e77a942..56369469 100644 --- a/test/concentrate/trip_descriptor_test.exs +++ b/test/concentrate/trip_descriptor_test.exs @@ -30,7 +30,8 @@ defmodule Concentrate.TripDescriptorTest do direction_id: 0, start_date: {2017, 12, 20}, start_time: "12:00:00", - schedule_relationship: :ADDED + schedule_relationship: :ADDED, + last_trip: false ) assert Mergeable.merge(first, second) == expected From b9108b72eab27a7270044707993bf31b0adb592f Mon Sep 17 00:00:00 2001 From: Brian Fauble Date: Wed, 27 Mar 2024 09:17:38 -0600 Subject: [PATCH 2/3] add last_trip field to TripUpdates enhanced feed --- .../encoder/trip_updates_enhanced.ex | 3 +- .../encoder/trip_updates_enhanced_test.exs | 40 ++++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/concentrate/encoder/trip_updates_enhanced.ex b/lib/concentrate/encoder/trip_updates_enhanced.ex index 3cfb7db7..096d9cab 100644 --- a/lib/concentrate/encoder/trip_updates_enhanced.ex +++ b/lib/concentrate/encoder/trip_updates_enhanced.ex @@ -19,7 +19,8 @@ defmodule Concentrate.Encoder.TripUpdatesEnhanced do defp enhanced_data(update) do %{ route_pattern_id: TripDescriptor.route_pattern_id(update), - revenue: TripDescriptor.revenue(update) + revenue: TripDescriptor.revenue(update), + last_trip: TripDescriptor.last_trip(update) } end diff --git a/test/concentrate/encoder/trip_updates_enhanced_test.exs b/test/concentrate/encoder/trip_updates_enhanced_test.exs index 96555a92..72e3e996 100644 --- a/test/concentrate/encoder/trip_updates_enhanced_test.exs +++ b/test/concentrate/encoder/trip_updates_enhanced_test.exs @@ -99,7 +99,8 @@ defmodule Concentrate.Encoder.TripUpdatesEnhancedTest do %{ "trip_update" => %{ "trip" => %{ - "route_pattern_id" => "pattern" + "route_pattern_id" => "pattern", + "last_trip" => false } } } @@ -153,7 +154,42 @@ defmodule Concentrate.Encoder.TripUpdatesEnhancedTest do "direction_id" => 0, "revenue" => false, "route_id" => "route", - "trip_id" => "NONREV-trip" + "trip_id" => "NONREV-trip", + "last_trip" => false + } + } + } + ] + } = encoded + end + + test "last_trip field is included" do + parsed = [ + TripDescriptor.new( + trip_id: "trip", + route_id: "route", + direction_id: 0, + last_trip: true + ), + StopTimeUpdate.new( + trip_id: "trip", + stop_id: "stop" + ) + ] + + encoded = Jason.decode!(encode_groups(group(parsed))) + + assert %{ + "entity" => [ + %{ + "id" => "trip", + "trip_update" => %{ + "trip" => %{ + "direction_id" => 0, + "revenue" => true, + "route_id" => "route", + "trip_id" => "trip", + "last_trip" => true } } } From 50ff43c5ce9cc9ea425a1f2458fd6c619f591e58 Mon Sep 17 00:00:00 2001 From: Brian Fauble Date: Wed, 27 Mar 2024 09:17:54 -0600 Subject: [PATCH 3/3] add last_trip field to VehiclePositions enhanced feed --- .../encoder/vehicle_positions_enhanced.ex | 16 ++++++++-- .../vehicle_positions_enhanced_test.exs | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/concentrate/encoder/vehicle_positions_enhanced.ex b/lib/concentrate/encoder/vehicle_positions_enhanced.ex index b00173fe..0b06079b 100644 --- a/lib/concentrate/encoder/vehicle_positions_enhanced.ex +++ b/lib/concentrate/encoder/vehicle_positions_enhanced.ex @@ -12,17 +12,27 @@ defmodule Concentrate.Encoder.VehiclePositionsEnhanced do def encode_groups(groups, opts \\ []) when is_list(groups) do message = %{ "header" => feed_header(opts), - "entity" => Enum.flat_map(groups, &build_entity/1) + "entity" => Enum.flat_map(groups, fn group -> build_entity(group, &enhanced_data/1) end) } Jason.encode!(message) end - def build_entity({%TripDescriptor{} = td, vps, _stus}) do + defp enhanced_data(update) do + %{ + last_trip: TripDescriptor.last_trip(update) + } + end + + def build_entity(_, enhanced_data \\ fn _ -> %{} end) + + def build_entity({%TripDescriptor{} = td, vps, _stus}, enhanced_data_fn) do trip = td |> trip_descriptor() |> Map.put("revenue", TripDescriptor.revenue(td)) + |> Map.merge(enhanced_data_fn.(td)) + |> drop_nil_values() for vp <- vps do %{ @@ -32,7 +42,7 @@ defmodule Concentrate.Encoder.VehiclePositionsEnhanced do end end - def build_entity({nil, vps, _stus}) do + def build_entity({nil, vps, _stus}, _enhanced_data_fn) do # vehicles without a trip for vp <- vps, trip_id = VehiclePosition.trip_id(vp), diff --git a/test/concentrate/encoder/vehicle_positions_enhanced_test.exs b/test/concentrate/encoder/vehicle_positions_enhanced_test.exs index 02f5c826..5569bd97 100644 --- a/test/concentrate/encoder/vehicle_positions_enhanced_test.exs +++ b/test/concentrate/encoder/vehicle_positions_enhanced_test.exs @@ -94,6 +94,35 @@ defmodule Concentrate.Encoder.VehiclePositionsEnhancedTest do } ] == FeedUpdate.updates(round_trip(data)) end + + test "includes last_trip field" do + data = [ + TripDescriptor.new(trip_id: "one", vehicle_id: "y1"), + VehiclePosition.new( + trip_id: "one", + id: "y1", + latitude: 1, + longitude: 1, + status: :IN_TRANSIT_TO + ), + TripDescriptor.new(trip_id: "two", vehicle_id: "y2", last_trip: true), + VehiclePosition.new( + trip_id: "two", + id: "y2", + latitude: 2, + longitude: 2, + status: :IN_TRANSIT_TO, + occupancy_status: :FULL, + occupancy_percentage: 101, + consist: [ + VehiclePositionConsist.new(label: "y2-1"), + VehiclePositionConsist.new(label: "y2-2") + ] + ) + ] + + assert data == FeedUpdate.updates(round_trip(data)) + end end defp round_trip(data, opts \\ []) do