-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Itinerary detail map #2258
Itinerary detail map #2258
Changes from 2 commits
4a0d006
e1b2b80
d827e4b
841ba9c
f06445c
6e93a85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ defmodule Dotcom.TripPlan.Map do | |
@moduledoc """ | ||
Handles generating the maps displayed within the TripPlan Controller | ||
""" | ||
|
||
alias Dotcom.TripPlan.{Leg, NamedPosition, TransitDetail} | ||
alias Leaflet.{MapData, MapData.Marker} | ||
alias Leaflet.MapData.Polyline, as: LeafletPolyline | ||
|
@@ -15,7 +16,6 @@ defmodule Dotcom.TripPlan.Map do | |
|> MapData.new(14) | ||
end | ||
|
||
# Maps for results | ||
@doc """ | ||
Returns the static map data and source URL | ||
Accepts a function that will return either a | ||
|
@@ -37,6 +37,53 @@ defmodule Dotcom.TripPlan.Map do | |
|> MapData.add_polylines(paths) | ||
end | ||
|
||
@doc """ | ||
Given an `itinerary_map`, convert the polylines to lines (for maplibre-gl-js). | ||
|
||
This involves changing some key names and inverting lat/long to long/lat. | ||
""" | ||
def get_lines(itinerary_map) do | ||
itinerary_map | ||
|> Map.get(:polylines, []) | ||
|> Enum.map(&polyline_to_line/1) | ||
end | ||
|
||
@doc """ | ||
Given an `itinerary_map`, convert the markers to points (for maplibre-gl-js). | ||
|
||
This just gets the longitude and latitude from each marker. | ||
""" | ||
def get_points(itinerary_map) do | ||
itinerary_map | ||
|> Map.get(:markers, []) | ||
|> Enum.map(&marker_to_point/1) | ||
|> Enum.reject(&is_nil/1) | ||
end | ||
|
||
defp invert_coordinates(coordinates) do | ||
coordinates | ||
|> Enum.map(&invert_coordinate/1) | ||
|> Enum.reject(&is_nil/1) | ||
end | ||
|
||
defp invert_coordinate([a, b]), do: [b, a] | ||
|
||
defp invert_coordinate(_), do: nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we ever get a coordinate that isn't a tuple it will crash the process otherwise. |
||
|
||
defp marker_to_point(%{longitude: longitude, latitude: latitude}) do | ||
[longitude, latitude] | ||
end | ||
|
||
defp marker_to_point(_), do: nil | ||
|
||
defp polyline_to_line(polyline) do | ||
%{ | ||
color: Map.get(polyline, :color) |> tailwind_color(), | ||
coordinates: Map.get(polyline, :positions, []) |> invert_coordinates(), | ||
width: Map.get(polyline, :weight, 4) | ||
} | ||
end | ||
|
||
@spec build_leg_path(Leg.t()) :: LeafletPolyline.t() | ||
defp build_leg_path(leg) do | ||
color = leg_color(leg) | ||
|
@@ -150,4 +197,13 @@ defmodule Dotcom.TripPlan.Map do | |
def z_index(%{current: idx, start: idx}), do: 100 | ||
def z_index(%{current: idx, end: idx}), do: 100 | ||
def z_index(%{}), do: 0 | ||
|
||
defp tailwind_color("#003DA5"), do: "blue-500" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm torn about this. Most of the other places where we translate things from GTFS to color, we do it based on the route, but here we're pulling the color out of the polyline directly. If it turns out that we can get this to work, should we use the colors directly in otther contexts too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The color that's in the polyline came from the associated route, it's just parsed roundaboutly because legacy.... |
||
defp tailwind_color("#80276C"), do: "purple-500" | ||
defp tailwind_color("#00843D"), do: "green-500" | ||
defp tailwind_color("#ED8B00"), do: "orange-500" | ||
defp tailwind_color("#DA291C"), do: "red-500" | ||
defp tailwind_color("#7C878E"), do: "silver-500" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📓 For now, we have to use the Metro colors because it will only accept those. We can change Metro to pass in an arbitrary hex code. |
||
|
||
defp tailwind_color(_), do: "black" | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,8 @@ defmodule DotcomWeb.Components.TripPlanner.TripPlannerResultsSection do | |
|
||
import DotcomWeb.Components.TripPlanner.{ItineraryDetail, ItinerarySummary} | ||
|
||
alias Dotcom.TripPlan | ||
|
||
def trip_planner_results_section(assigns) do | ||
~H""" | ||
<section class={[ | ||
|
@@ -39,19 +41,41 @@ defmodule DotcomWeb.Components.TripPlanner.TripPlannerResultsSection do | |
</button> | ||
</div> | ||
</.async_result> | ||
<.async_result :let={results} assign={@results}> | ||
<%= if results && @itinerary_selection != :summary do %> | ||
<% {:detail, %{itinerary_group_index: itinerary_group_index, itinerary_index: itinerary_index}} = @itinerary_selection %> | ||
<% itinerary = Enum.at(results, itinerary_group_index).itineraries |> Enum.at(itinerary_index) %> | ||
<% itinerary_map = TripPlan.Map.itinerary_map(itinerary) %> | ||
<% lines = TripPlan.Map.get_lines(itinerary_map) %> | ||
<% points = TripPlan.Map.get_points(itinerary_map) %> | ||
<.live_component | ||
module={MbtaMetro.Live.Map} | ||
id="trip-planner-map" | ||
class={[ | ||
"h-64 md:h-96 w-full", | ||
"relative overflow-none row-span-2", | ||
@itinerary_selection == :summary && "hidden md:block" | ||
]} | ||
config={@map_config} | ||
lines={lines} | ||
pins={[@from, @to]} | ||
points={points} | ||
/> | ||
<% else %> | ||
<.live_component | ||
module={MbtaMetro.Live.Map} | ||
id="trip-planner-map" | ||
class={[ | ||
"h-64 md:h-96 w-full", | ||
"relative overflow-none row-span-2", | ||
@itinerary_selection == :summary && "hidden md:block" | ||
]} | ||
config={@map_config} | ||
pins={[@from, @to]} | ||
/> | ||
<% end %> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📓 None of this will be here after we change the state management. It must be embedded like this because the results component includes the map. |
||
|
||
<.live_component | ||
module={MbtaMetro.Live.Map} | ||
id="trip-planner-map" | ||
class={[ | ||
"h-64 md:h-96 w-full", | ||
"relative overflow-none row-span-2", | ||
@itinerary_selection == :summary && "hidden md:block" | ||
]} | ||
config={@map_config} | ||
pins={[@from, @to]} | ||
/> | ||
|
||
</.async_result> | ||
<.async_result :let={results} assign={@results}> | ||
<div :if={results} class="w-full p-4 row-start-2 col-start-1"> | ||
<.itinerary_panel results={results} itinerary_selection={@itinerary_selection} /> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (non-blocking): This kind of thing is exactly why I would prefer to see us standardize on
%{latitude: lat, longitude: long}
(or%{lat: lat, long: long}
or whatever), rather than having to keep track of which intermediate objects use[long, lat]
versus which ones use[lat, long]
.My ideal would be that any intermediate, dotcom-controlled data is always stored as a struct, and is only translated to
[lat, long]
or[long, lat]
at the boundary, like right before being passed into MapLibreGL, or right after being parsed out of GTFS, etc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is right before it is being passed into maplibre gl.