NM Active Alerts
Application.put_env(:req_noaa, :name, "Livebook")
Application.put_env(:req_noaa, :contact, "https://github.com/Morgahl/req_noaa")
Mix.install([
{:kino, "~> 0.14.2"},
{:kino_maplibre, "~> 0.1.13"},
# {:req_noaa, path: Path.join(__DIR__, "..")}
{:req_noaa, github: "Morgahl/req_noaa", branch: "main"}
])
defmodule StructCleaner do
def deep_cleanup(struct) when is_struct(struct) do
struct
|> Map.from_struct()
|> deep_cleanup()
end
def deep_cleanup(map) when is_map(map) do
Enum.reduce(Map.keys(map), map, fn key, acc ->
Map.update!(acc, key, &deep_cleanup/1)
end)
end
def deep_cleanup(list) when is_list(list) do
Enum.map(list, &deep_cleanup/1)
end
def deep_cleanup(value), do: value
end
Section
alias MapLibre, as: Ml
ml = Ml.new(
center: {-105.5, 34.0},
zoom: 5,
style: :terrain,
key: System.fetch_env!("LB_MAP_TILER_KEY")
)
ml =
with {:ok, active_alerts} <- ReqNOAA.API.Alerts.active_area("NM"),
active_alerts = StructCleaner.deep_cleanup(active_alerts) do
for feature <- active_alerts.features do
feature.properties.geocode."UGC"
end
|> List.flatten()
|> Enum.uniq()
|> Task.async_stream(&ReqNOAA.API.Zones.forecast(&1))
|> Stream.map(fn {:ok, {:ok, zone}} -> StructCleaner.deep_cleanup(zone) end)
|> Enum.reduce(ml, fn zone, ml ->
ml
|> Ml.add_source(zone.id,
type: :geojson,
data: zone
)
|> Ml.add_layer(id: zone.id,
type: :line,
source: zone.id,
paint: [line_color: "#FF0000"]
)
end)
end
|> Kino.MapLibre.new()
Kino.MapLibre.add_terrain_control(ml)
Kino.MapLibre.add_fullscreen_control(ml)
Kino.MapLibre.add_export_map(ml)
Kino.MapLibre.add_locate_control(ml)
Kino.MapLibre.add_nav_controls(ml)
Kino.MapLibre.add_scale_control(ml)
ml