Skip to content

Commit

Permalink
Itinerary detail map (#2258)
Browse files Browse the repository at this point in the history
* map logic

* maps showing lines and points in colors

* reorder colors

* format

* handle case where polyline is charlist

* refactor: Move TPRS logic out of the HEEx into &render/1

---------

Co-authored-by: Josh Larson <[email protected]>
  • Loading branch information
anthonyshull and joshlarson authored Dec 11, 2024
1 parent de2d3dc commit a476cd9
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 5 deletions.
64 changes: 60 additions & 4 deletions lib/dotcom/trip_plan/map.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

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)
Expand All @@ -48,6 +95,8 @@ defmodule Dotcom.TripPlan.Map do
end

@spec extend_to_endpoints(String.t(), Leg.t()) :: String.t()
defp extend_to_endpoints(polyline, _leg) when not is_binary(polyline), do: ""

defp extend_to_endpoints(polyline, %{from: from, to: to})
when is_map(from) and is_map(to) do
from = {Position.longitude(from), Position.latitude(from)}
Expand All @@ -59,9 +108,7 @@ defmodule Dotcom.TripPlan.Map do
|> Polyline.encode()
end

defp extend_to_endpoints(_polyline, _leg) do
""
end
defp extend_to_endpoints(_polyline, _leg), do: ""

@spec markers_for_legs([Leg.t()]) :: [Marker.t()]
defp markers_for_legs(legs) do
Expand Down Expand Up @@ -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"
defp tailwind_color("#00843D"), do: "green-500"
defp tailwind_color("#ED8B00"), do: "orange-500"
defp tailwind_color("#80276C"), do: "purple-500"
defp tailwind_color("#DA291C"), do: "red-500"
defp tailwind_color("#7C878E"), do: "silver-500"

defp tailwind_color(_), do: "black"
end
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,30 @@ defmodule DotcomWeb.Components.TripPlanner.TripPlannerResultsSection do

import DotcomWeb.Components.TripPlanner.{ItineraryDetail, ItinerarySummary}

def trip_planner_results_section(assigns) do
alias Dotcom.TripPlan

def trip_planner_results_section(
%{itinerary_selection: itinerary_selection, results: itinerary_results} = assigns
) do
assigns =
if itinerary_results.result && itinerary_selection != :summary do
{:detail,
%{itinerary_group_index: itinerary_group_index, itinerary_index: itinerary_index}} =
itinerary_selection

itinerary =
Enum.at(itinerary_results.result, 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)

assign(assigns, %{lines: lines, points: points})
else
assign(assigns, %{lines: [], points: []})
end

~H"""
<section class={[
"flex flex-col",
Expand Down Expand Up @@ -49,7 +72,9 @@ defmodule DotcomWeb.Components.TripPlanner.TripPlannerResultsSection do
@itinerary_selection == :summary && "hidden md:block"
]}
config={@map_config}
lines={@lines}
pins={[@from, @to]}
points={@points}
/>
<.async_result :let={results} assign={@results}>
Expand Down

0 comments on commit a476cd9

Please sign in to comment.