Skip to content

Commit

Permalink
🧠 Surface last_trip TripDescriptor through Concentrate enhanced feeds (…
Browse files Browse the repository at this point in the history
…#348)

* parse last_trip field from TripUpdates and VehiclePositions enhanced feeds

* add last_trip field to TripUpdates enhanced feed

* add last_trip field to VehiclePositions enhanced feed
  • Loading branch information
bfauble authored Apr 3, 2024
1 parent a478d5f commit dc28e82
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 14 deletions.
3 changes: 2 additions & 1 deletion lib/concentrate/encoder/trip_updates_enhanced.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 13 additions & 3 deletions lib/concentrate/encoder/vehicle_positions_enhanced.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
%{
Expand All @@ -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),
Expand Down
3 changes: 2 additions & 1 deletion lib/concentrate/parser/gtfs_realtime_enhanced.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 8 additions & 6 deletions lib/concentrate/trip_descriptor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule Concentrate.TripDescriptor do
:start_time,
:vehicle_id,
:timestamp,
last_trip: false,
revenue: true,
schedule_relationship: :SCHEDULED
])
Expand Down Expand Up @@ -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
40 changes: 38 additions & 2 deletions test/concentrate/encoder/trip_updates_enhanced_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ defmodule Concentrate.Encoder.TripUpdatesEnhancedTest do
%{
"trip_update" => %{
"trip" => %{
"route_pattern_id" => "pattern"
"route_pattern_id" => "pattern",
"last_trip" => false
}
}
}
Expand Down Expand Up @@ -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
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions test/concentrate/encoder/vehicle_positions_enhanced_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
89 changes: 89 additions & 0 deletions test/concentrate/parser/gtfs_realtime_enhanced_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
3 changes: 2 additions & 1 deletion test/concentrate/trip_descriptor_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit dc28e82

Please sign in to comment.