Skip to content

Commit

Permalink
refactor: split subway station module from Stop
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalcora committed Nov 5, 2024
1 parent fe7b330 commit f04f570
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 361 deletions.
328 changes: 2 additions & 326 deletions lib/screens/stops/stop.ex
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
defmodule Screens.Stops.Stop do
@moduledoc """
This file handles involves stop-related fetching / enrichment.
For a while, all stop-related data was fetched from the API, until we needed to provide consistent
abbreviations in the reconstructed alert. Now it's valuable to have a local copy of these stop sequences.
A lot of our code still collects these sequences from the API, though, whether in functions here
or in functions in `route_pattern.ex` (see fetch_tagged_parent_station_sequences_through_stop).
So there's inconsistent use of this local data.
"""
@moduledoc false

require Logger

Expand All @@ -33,224 +26,6 @@ defmodule Screens.Stops.Stop do

@type screen_type :: BusEink | BusShelter | GlEink | PreFare | Dup

@blue_line_stops [
{"place-wondl", {"Wonderland", "Wonderland"}},
{"place-rbmnl", {"Revere Beach", "Revere Bch"}},
{"place-bmmnl", {"Beachmont", "Beachmont"}},
{"place-sdmnl", {"Suffolk Downs", "Suffolk Dns"}},
{"place-orhte", {"Orient Heights", "Orient Hts"}},
{"place-wimnl", {"Wood Island", "Wood Island"}},
{"place-aport", {"Airport", "Airport"}},
{"place-mvbcl", {"Maverick", "Maverick"}},
{"place-aqucl", {"Aquarium", "Aquarium"}},
{"place-state", {"State", "State"}},
{"place-gover", {"Government Center", "Gov't Ctr"}},
{"place-bomnl", {"Bowdoin", "Bowdoin"}}
]

@orange_line_stops [
{"place-ogmnl", {"Oak Grove", "Oak Grove"}},
{"place-mlmnl", {"Malden Center", "Malden Ctr"}},
{"place-welln", {"Wellington", "Wellington"}},
{"place-astao", {"Assembly", "Assembly"}},
{"place-sull", {"Sullivan Square", "Sullivan Sq"}},
{"place-ccmnl", {"Community College", "Com College"}},
{"place-north", {"North Station", "North Sta"}},
{"place-haecl", {"Haymarket", "Haymarket"}},
{"place-state", {"State", "State"}},
{"place-dwnxg", {"Downtown Crossing", "Downt'n Xng"}},
{"place-chncl", {"Chinatown", "Chinatown"}},
{"place-tumnl", {"Tufts Medical Center", "Tufts Med"}},
{"place-bbsta", {"Back Bay", "Back Bay"}},
{"place-masta", {"Massachusetts Avenue", "Mass Ave"}},
{"place-rugg", {"Ruggles", "Ruggles"}},
{"place-rcmnl", {"Roxbury Crossing", "Roxbury Xng"}},
{"place-jaksn", {"Jackson Square", "Jackson Sq"}},
{"place-sbmnl", {"Stony Brook", "Stony Brook"}},
{"place-grnst", {"Green Street", "Green St"}},
{"place-forhl", {"Forest Hills", "Frst Hills"}}
]

@red_line_trunk_stops [
{"place-alfcl", {"Alewife", "Alewife"}},
{"place-davis", {"Davis", "Davis"}},
{"place-portr", {"Porter", "Porter"}},
{"place-harsq", {"Harvard", "Harvard"}},
{"place-cntsq", {"Central", "Central"}},
{"place-knncl", {"Kendall/MIT", "Kendall/MIT"}},
{"place-chmnl", {"Charles/MGH", "Charles/MGH"}},
{"place-pktrm", {"Park Street", "Park St"}},
{"place-dwnxg", {"Downtown Crossing", "Downt'n Xng"}},
{"place-sstat", {"South Station", "South Sta"}},
{"place-brdwy", {"Broadway", "Broadway"}},
{"place-andrw", {"Andrew", "Andrew"}},
{"place-jfk", {"JFK/UMass", "JFK/UMass"}}
]

@red_line_ashmont_branch_stops [
{"place-shmnl", {"Savin Hill", "Savin Hill"}},
{"place-fldcr", {"Fields Corner", "Fields Cnr"}},
{"place-smmnl", {"Shawmut", "Shawmut"}},
{"place-asmnl", {"Ashmont", "Ashmont"}}
]

@red_line_braintree_branch_stops [
{"place-nqncy", {"North Quincy", "N Quincy"}},
{"place-wlsta", {"Wollaston", "Wollaston"}},
{"place-qnctr", {"Quincy Center", "Quincy Ctr"}},
{"place-qamnl", {"Quincy Adams", "Quincy Adms"}},
{"place-brntn", {"Braintree", "Braintree"}}
]

@green_line_b_stops [
{"place-gover", {"Government Center", "Gov't Ctr"}},
{"place-pktrm", {"Park Street", "Park St"}},
{"place-boyls", {"Boylston", "Boylston"}},
{"place-armnl", {"Arlington", "Arlington"}},
{"place-coecl", {"Copley", "Copley"}},
{"place-hymnl", {"Hynes Convention Center", "Hynes"}},
{"place-kencl", {"Kenmore", "Kenmore"}},
{"place-bland", {"Blandford Street", "Blandford"}},
{"place-buest", {"Boston University East", "BU East"}},
{"place-bucen", {"Boston University Central", "BU Central"}},
{"place-amory", {"Amory Street", "Amory St"}},
{"place-babck", {"Babcock Street", "Babcock St"}},
{"place-brico", {"Packards Corner", "Packards Cn"}},
{"place-harvd", {"Harvard Avenue", "Harvard Ave"}},
{"place-grigg", {"Griggs Street", "Griggs St"}},
{"place-alsgr", {"Allston Street", "Allston St"}},
{"place-wrnst", {"Warren Street", "Warren St"}},
{"place-wascm", {"Washington Street", "Washington"}},
{"place-sthld", {"Sutherland Road", "Sutherland"}},
{"place-chswk", {"Chiswick Road", "Chiswick Rd"}},
{"place-chill", {"Chestnut Hill Avenue", "Chestnut Hl"}},
{"place-sougr", {"South Street", "South St"}},
{"place-lake", {"Boston College", "Boston Coll"}}
]

@green_line_c_stops [
{"place-gover", {"Government Center", "Gov't Ctr"}},
{"place-pktrm", {"Park Street", "Park St"}},
{"place-boyls", {"Boylston", "Boylston"}},
{"place-armnl", {"Arlington", "Arlington"}},
{"place-coecl", {"Copley", "Copley"}},
{"place-hymnl", {"Hynes Convention Center", "Hynes"}},
{"place-kencl", {"Kenmore", "Kenmore"}},
{"place-smary", {"Saint Mary's Street", "St. Mary's"}},
{"place-hwsst", {"Hawes Street", "Hawes St"}},
{"place-kntst", {"Kent Street", "Kent St"}},
{"place-stpul", {"Saint Paul Street", "St. Paul St"}},
{"place-cool", {"Coolidge Corner", "Coolidge Cn"}},
{"place-sumav", {"Summit Avenue", "Summit Ave"}},
{"place-bndhl", {"Brandon Hall", "Brandon Hll"}},
{"place-fbkst", {"Fairbanks Street", "Fairbanks"}},
{"place-bcnwa", {"Washington Square", "Washington"}},
{"place-tapst", {"Tappan Street", "Tappan St"}},
{"place-denrd", {"Dean Road", "Dean Rd"}},
{"place-engav", {"Englewood Avenue", "Englew'd Av"}},
{"place-clmnl", {"Cleveland Circle", "Clvlnd Cir"}}
]

@green_line_d_stops [
{"place-unsqu", {"Union Square", "Union Sq"}},
{"place-lech", {"Lechmere", "Lechmere"}},
{"place-spmnl", {"Science Park/West End", "Science Pk"}},
{"place-north", {"North Station", "North Sta"}},
{"place-haecl", {"Haymarket", "Haymarket"}},
{"place-gover", {"Government Center", "Gov't Ctr"}},
{"place-pktrm", {"Park Street", "Park St"}},
{"place-boyls", {"Boylston", "Boylston"}},
{"place-armnl", {"Arlington", "Arlington"}},
{"place-coecl", {"Copley", "Copley"}},
{"place-hymnl", {"Hynes Convention Center", "Hynes"}},
{"place-kencl", {"Kenmore", "Kenmore"}},
{"place-fenwy", {"Fenway", "Fenway"}},
{"place-longw", {"Longwood", "Longwood"}},
{"place-bvmnl", {"Brookline Village", "B'kline Vil"}},
{"place-brkhl", {"Brookline Hills", "B'kline Hls"}},
{"place-bcnfd", {"Beaconsfield", "B'consfield"}},
{"place-rsmnl", {"Reservoir", "Reservoir"}},
{"place-chhil", {"Chestnut Hill", "Chestnut Hl"}},
{"place-newto", {"Newton Centre", "Newton Ctr"}},
{"place-newtn", {"Newton Highlands", "Newton Hlnd"}},
{"place-eliot", {"Eliot", "Eliot"}},
{"place-waban", {"Waban", "Waban"}},
{"place-woodl", {"Woodland", "Woodland"}},
{"place-river", {"Riverside", "Riverside"}}
]

@green_line_e_stops [
{"place-mdftf", {"Medford / Tufts", "Medford"}},
{"place-balsq", {"Ball Square", "Ball Sq"}},
{"place-mgngl", {"Magoun Square", "Magoun Sq"}},
{"place-gilmn", {"Gilman Square", "Gilman Sq"}},
{"place-esomr", {"East Somerville", "E Somerville"}},
{"place-lech", {"Lechmere", "Lechmere"}},
{"place-spmnl", {"Science Park/West End", "Science Pk"}},
{"place-north", {"North Station", "North Sta"}},
{"place-haecl", {"Haymarket", "Haymarket"}},
{"place-gover", {"Government Center", "Gov't Ctr"}},
{"place-pktrm", {"Park Street", "Park St"}},
{"place-boyls", {"Boylston", "Boylston"}},
{"place-armnl", {"Arlington", "Arlington"}},
{"place-coecl", {"Copley", "Copley"}},
{"place-prmnl", {"Prudential", "Prudential"}},
{"place-symcl", {"Symphony", "Symphony"}},
{"place-nuniv", {"Northeastern University", "Northeast'n"}},
{"place-mfa", {"Museum of Fine Arts", "MFA"}},
{"place-lngmd", {"Longwood Medical Area", "Lngwd Med"}},
{"place-brmnl", {"Brigham Circle", "Brigham Cir"}},
{"place-fenwd", {"Fenwood Road", "Fenwood Rd"}},
{"place-mispk", {"Mission Park", "Mission Pk"}},
{"place-rvrwy", {"Riverway", "Riverway"}},
{"place-bckhl", {"Back of the Hill", "Back o'Hill"}},
{"place-hsmnl", {"Heath Street", "Heath St"}}
]

@green_line_trunk_stops [
{"place-lech", {"Lechmere", "Lechmere"}},
{"place-spmnl", {"Science Park/West End", "Science Pk"}},
{"place-north", {"North Station", "North Sta"}},
{"place-haecl", {"Haymarket", "Haymarket"}},
{"place-gover", {"Government Center", "Gov't Ctr"}},
{"place-pktrm", {"Park Street", "Park St"}},
{"place-boyls", {"Boylston", "Boylston"}},
{"place-armnl", {"Arlington", "Arlington"}},
{"place-coecl", {"Copley", "Copley"}},
{"place-hymnl", {"Hynes Convention Center", "Hynes"}},
{"place-kencl", {"Kenmore", "Kenmore"}}
]

@medford_tufts_branch_stops [
{"place-mdftf", {"Medford / Tufts", "Medford"}},
{"place-balsq", {"Ball Square", "Ball Sq"}},
{"place-mgngl", {"Magoun Square", "Magoun Sq"}},
{"place-gilmn", {"Gilman Square", "Gilman Sq"}},
{"place-esomr", {"East Somerville", "E Somerville"}}
]

@union_square_branch_stops [
{"place-unsqu", {"Union Square", "Union Sq"}}
]

@route_stop_sequences %{
"Blue" => [@blue_line_stops],
"Orange" => [@orange_line_stops],
"Red" => [
@red_line_trunk_stops ++ @red_line_ashmont_branch_stops,
@red_line_trunk_stops ++ @red_line_braintree_branch_stops
],
"Green-B" => [@green_line_b_stops],
"Green-C" => [@green_line_c_stops],
"Green-D" => [@green_line_d_stops],
"Green-E" => [@green_line_e_stops],
"Green" => [@green_line_trunk_stops]
}

@green_line_branches ["Green-B", "Green-C", "Green-D", "Green-E"]

# --- These functions involve the API ---

def fetch_parent_station_name_map(get_json_fn \\ &V3Api.get_json/2) do
case get_json_fn.("stops", %{
"filter[location_type]" => 1
Expand Down Expand Up @@ -342,92 +117,6 @@ defmodule Screens.Stops.Stop do
end
end

# --- END API functions ---

def stop_on_route?(stop_id, stop_sequence) when not is_nil(stop_id) do
Enum.any?(stop_sequence, fn {station_id, _} -> station_id == stop_id end)
end

def to_stop_index(%{stop: stop_id}, stop_sequence) do
Enum.find_index(stop_sequence, fn {station_id, _} -> station_id == stop_id end)
end

# --- These use the local version of the stop_sequences from the top of this file ---

@doc """
Finds a stop sequence which contains all stations in informed_entities.
"""
def get_stop_sequence(informed_entities, "Green") do
Enum.find_value(@green_line_branches, fn branch ->
get_stop_sequence(informed_entities, branch)
end)
end

def get_stop_sequence(informed_entities, route_id) do
stop_sequences = Map.get(@route_stop_sequences, route_id)
Enum.find(stop_sequences, &sequence_match?(&1, informed_entities))
end

def get_route_stop_sequence(route_id) do
@route_stop_sequences
|> Map.get(route_id)
|> Enum.flat_map(fn x -> x end)
|> Enum.map(fn {k, _v} -> k end)
|> Enum.uniq()
end

def get_all_routes_stop_sequence do
@route_stop_sequences
end

def get_gl_stop_sequences do
Enum.map(@green_line_branches, &get_route_stop_sequence/1)
end

@doc """
Returns an unordered MapSet of all GL stops west of Copley.
"""
@spec get_gl_stops_west_of_copley() :: MapSet.t(id())
def get_gl_stops_west_of_copley do
get_gl_stop_sequences()
|> Enum.flat_map(fn stop_sequence ->
[_copley | west_of_copley] = Enum.drop_while(stop_sequence, &(&1 != "place-coecl"))
west_of_copley
end)
|> MapSet.new()
end

defp sequence_match?(stop_sequence, informed_entities) do
ie_stops =
informed_entities
|> Enum.map(fn %{stop: stop_id} -> stop_id end)
|> Enum.reject(&is_nil/1)

if Enum.empty?(ie_stops) do
nil
else
ie_stops
|> Enum.filter(&String.starts_with?(&1, "place-"))
|> Enum.all?(&stop_on_route?(&1, stop_sequence))
end
end

def gl_trunk_stops do
@green_line_trunk_stops
end

def rl_trunk_stops do
@red_line_trunk_stops
end

def stop_id_to_name(route_id) do
@route_stop_sequences
|> Map.get(route_id)
|> Enum.flat_map(fn x -> x end)
|> Enum.uniq()
|> Enum.into(%{})
end

@doc """
Fetches all the location context for a screen given its app type, stop id, and time
"""
Expand Down Expand Up @@ -472,8 +161,7 @@ defmodule Screens.Stops.Stop do
end

# Returns the route types we care about for the alerts of this screen type / place
@spec get_route_type_filter(screen_type(), String.t()) ::
list(RouteType.t())
@spec get_route_type_filter(screen_type(), String.t()) :: list(RouteType.t())
def get_route_type_filter(app, _) when app in [BusEink, BusShelter], do: [:bus]
def get_route_type_filter(GlEink, _), do: [:light_rail]
# Ashmont should not show Mattapan alerts for PreFare or Dup
Expand All @@ -497,18 +185,6 @@ defmodule Screens.Stops.Stop do
|> MapSet.new()
end

def on_glx?(stop_id) do
stop_id in Enum.map(@medford_tufts_branch_stops ++ @union_square_branch_stops, &elem(&1, 0))
end

def on_ashmont_branch?(stop_id) do
stop_id in Enum.map(@red_line_ashmont_branch_stops, &elem(&1, 0))
end

def on_braintree_branch?(stop_id) do
stop_id in Enum.map(@red_line_braintree_branch_stops, &elem(&1, 0))
end

defp fetch_tagged_stop_sequences_by_app(app, stop_id, _routes_at_stop)
when app in [BusEink, BusShelter, GlEink] do
RoutePattern.fetch_tagged_stop_sequences_through_stop(stop_id)
Expand Down
Loading

0 comments on commit f04f570

Please sign in to comment.