-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* itinerary group start * first official pass at producing groups * correct grouping * empty line
- Loading branch information
1 parent
07edd26
commit 7941622
Showing
2 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# Itinerary Groups | ||
|
||
## Section | ||
|
||
```elixir | ||
defmodule ItineraryGroups.Helpers do | ||
@moduledoc false | ||
|
||
def attach_groups_to_plan(%{"from" => from, "to" => to} = trip) do | ||
plan(from, to) | ||
|> Kernel.elem(1) | ||
|> Enum.reject(&Kernel.is_binary/1) | ||
|> group() | ||
|> Kernel.then(&Map.put(trip, "groups", &1)) | ||
end | ||
|
||
defp combined_leg_to_tuple(%TripPlan.Leg{mode: %TripPlan.PersonalDetail{}} = leg) do | ||
unique_leg_to_tuple(leg) | ||
end | ||
|
||
defp combined_leg_to_tuple(%TripPlan.Leg{mode: %{route: route}} = leg) do | ||
{route.id, leg.from.name, leg.to.name} | ||
end | ||
|
||
defp departures(group) do | ||
group | ||
|> Enum.take(5) | ||
|> Enum.map(&itinerary_to_departure/1) | ||
end | ||
|
||
defp format_datetime(datetime) do | ||
Timex.format!(datetime, "%H:%M %p", :strftime) | ||
end | ||
|
||
defp group(itineraries) do | ||
itineraries | ||
|> Enum.group_by(&unique_legs_to_hash/1) | ||
|> groups_to_strings() | ||
end | ||
|
||
defp groups_to_strings(groups) do | ||
Enum.map(groups, fn {_, group} -> | ||
%{ | ||
departures: departures(group), | ||
legs: | ||
group | ||
|> Enum.uniq_by(&itinerary_to_hash/1) | ||
|> Enum.map(fn itinerary -> | ||
itinerary |> Map.get(:legs) |> legs_to_string() | ||
end) | ||
} | ||
end) | ||
|> Enum.reject(fn group -> Kernel.length(group.legs) == 0 end) | ||
end | ||
|
||
defp itinerary_to_departure(itinerary) do | ||
format_datetime(itinerary.start) | ||
end | ||
|
||
defp itinerary_to_hash(itinerary) do | ||
itinerary | ||
|> Map.get(:legs) | ||
|> Enum.reject(&short_walking_leg?/1) | ||
|> Enum.map(&combined_leg_to_tuple/1) | ||
|> :erlang.phash2() | ||
end | ||
|
||
defp leg_to_string(%TripPlan.Leg{mode: %TripPlan.PersonalDetail{}} = leg) do | ||
"WALK #{leg.distance} MILES FROM #{leg.from.name} TO #{leg.to.name}" | ||
end | ||
|
||
defp leg_to_string(%TripPlan.Leg{mode: %{mode: "BUS"} = mode} = leg) do | ||
"TAKE THE #{mode.route.id} BUS FROM #{leg.from.name} TO #{leg.to.name}" | ||
end | ||
|
||
defp leg_to_string(%TripPlan.Leg{mode: %{mode: _} = mode} = leg) do | ||
"TAKE THE #{mode.route.long_name} #{mode.mode} FROM #{leg.from.name} TO #{leg.to.name}" | ||
end | ||
|
||
defp legs_to_string(legs) do | ||
legs | ||
|> Enum.reject(&short_walking_leg?/1) | ||
|> Enum.map(&leg_to_string/1) | ||
end | ||
|
||
defp named_position(stop) do | ||
stop = Stops.Repo.get(stop) | ||
|
||
parent_stop = | ||
if stop.child? do | ||
Stops.Repo.get(stop.parent_id) | ||
else | ||
nil | ||
end | ||
|
||
%TripPlan.NamedPosition{ | ||
stop: parent_stop || stop | ||
} | ||
end | ||
|
||
defp plan(from, to) do | ||
TripPlanner.OpenTripPlanner.plan( | ||
named_position(from), | ||
named_position(to), | ||
[] | ||
# [depart_at: DateTime.from_naive!(~N[2024-07-31T08:30:00], "America/New_York")] | ||
) | ||
end | ||
|
||
def short_walking_leg?(%TripPlan.Leg{mode: %TripPlan.PersonalDetail{}} = leg) do | ||
leg.distance <= 0.2 | ||
end | ||
|
||
def short_walking_leg?(_), do: false | ||
|
||
defp unique_leg_to_tuple(%TripPlan.Leg{mode: %TripPlan.PersonalDetail{}} = leg) do | ||
{"WALK", leg.from.name, leg.to.name} | ||
end | ||
|
||
defp unique_leg_to_tuple(%TripPlan.Leg{mode: %{route: route}} = leg) do | ||
{Routes.Route.type_atom(route.type), leg.from.name, leg.to.name} | ||
end | ||
|
||
defp unique_legs_to_hash(legs) do | ||
legs | ||
|> Enum.reject(&short_walking_leg?/1) | ||
|> Enum.map(&unique_leg_to_tuple/1) | ||
|> :erlang.phash2() | ||
end | ||
end | ||
|
||
alias ItineraryGroups.Helpers | ||
``` | ||
|
||
```elixir | ||
Application.start(:yamerl) | ||
|
||
write_path = | ||
System.tmp_dir!() | ||
|> Path.join("itinerary-groups.yml") | ||
|> IO.inspect() | ||
|
||
plans = | ||
File.cwd!() | ||
|> Path.join("/livebooks/trips.yml") | ||
|> YamlElixir.read_from_file!() | ||
|> Enum.map(fn plan -> | ||
Helpers.attach_groups_to_plan(plan) | ||
end) | ||
|> List.flatten() | ||
|
||
yaml = Ymlr.document!(plans) | ||
|
||
File.write!(write_path, yaml) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
--- | ||
- check: No mode grouping | ||
name: Symphony to Fenwood Rd | ||
from: place-symcl | ||
to: place-fenwd | ||
- check: Group same parent stop, different child stops | ||
name: Forest Hills to Roslindale Village | ||
from: place-forhl | ||
to: place-NB-0064 | ||
- check: Group same parent stop, different child stops | ||
name: Harvard Square to Concord Ave @ Corporal Burns Rd | ||
from: place-harsq | ||
to: '2179' | ||
- check: Group same parent stop, different child stops | ||
name: Silver Line Way to South Station | ||
from: place-conrd | ||
to: place-sstat | ||
- check: Group same parent stop, different child stops | ||
name: Sullivan Square to Somerville Ave @ Stone Ave | ||
from: place-sull | ||
to: '2612' | ||
- check: Group with same origin/destination | ||
name: Davis to Lechmere | ||
from: place-davis | ||
to: place-lech | ||
- check: Green Line and Orange Line overlap | ||
name: North Station to Haymarket | ||
from: place-north | ||
to: place-haecl | ||
- check: Subway grouping; Green Line trunk | ||
name: Government Center to Copley | ||
from: place-gover | ||
to: place-coecl | ||
- check: Subway grouping; Green Line branches | ||
name: Government Center to Kenmore | ||
from: place-gover | ||
to: place-kencl | ||
- check: Bus or Subway grouping | ||
name: Chelsea to Government Center | ||
from: place-chels | ||
to: place-gover |