Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

NM Active Alerts

docs/example.livemd

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(&amp;ReqNOAA.API.Zones.forecast(&amp;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