Created
June 27, 2016 12:52
-
-
Save eidge/0bc450350b9eaeaccc64e09f4c0bf3ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Weather.NOAA.Forecast.PathBuilder do | |
@moduledoc """ | |
Contains helper functions to build paths for retrieving NOAA forecasts. | |
""" | |
use Timex | |
alias Weather.NOAA.Forecast.Params | |
@nomads_url "http://nomads.ncep.noaa.gov/cgi-bin/" | |
@gfs_models [ | |
gfs_0p25_hourly: [ | |
name: "filter_gfs_0p25_1hr", | |
precision: "0p25", | |
], | |
gfs_0p25: [ | |
name: "filter_gfs_0p25", | |
precision: "0p25", | |
], | |
gfs_1p00: [ | |
name: "filter_gfs_1p00", | |
precision: "1p00", | |
] | |
] | |
@doc """ | |
Returns the path for the directory listing of a given model. | |
Args: | |
- model_name - One of [:gfs_0p25_hourly, :gfs_0p25, :gfs_1p00], atom | |
""" | |
def directory_path_for(model_name) when is_atom(model_name) do | |
model = Keyword.fetch! @gfs_models, model_name | |
@nomads_url <> model[:name] <> ".pl" | |
end | |
@doc """ | |
Builds a path to retrive a forecast based on the model name. | |
Args: | |
- params - %Weather.NOAA.ForecastParams | |
""" | |
def path_for(%Params{} = params) do | |
model = Keyword.fetch! @gfs_models, params.model_name | |
@nomads_url <> | |
"#{model[:name]}.pl?file=#{file_name(model, params.cycle, params.hour_delta)}" <> | |
variables_query <> | |
"&#{bounding_box_query_str(params.bounding_box)}" <> | |
"&dir=#{dir_name(params.date, params.cycle)}" | |
end | |
defp file_name(model, cycle, hour_delta) do | |
formatted_hour_delta = format_hour_delta(hour_delta) | |
formatted_cycle = format_cycle(cycle) | |
"gfs.t#{formatted_cycle}z.pgrb2.#{model[:precision]}.#{formatted_hour_delta}" | |
end | |
defp format_hour_delta(nil), do: "anl" | |
defp format_hour_delta("anl"), do: "anl" | |
defp format_hour_delta(hour_delta) when hour_delta < 10, do: "f00#{hour_delta}" | |
defp format_hour_delta(hour_delta) when hour_delta < 100, do: "f0#{hour_delta}" | |
defp format_hour_delta(hour_delta) when hour_delta < 1000, do: "f#{hour_delta}" | |
defp format_cycle(nil), do: format_cycle(0) | |
defp format_cycle(cycle) when cycle < 10, do: "0#{cycle}" | |
defp format_cycle(cycle) when cycle < 24, do: "#{cycle}" | |
defp variables_query do | |
"&lev_1000_mb=on&lev_100_mb=on&lev_150_mb=on&lev_200_mb=on&lev_250_mb=on&lev_300_mb=on" <> | |
"&lev_350_mb=on&lev_400_mb=on&lev_450_mb=on&lev_500_mb=on&lev_550_mb=on&lev_600_mb=on" <> | |
"&lev_650_mb=on&lev_700_mb=on&lev_750_mb=on&lev_800_mb=on&lev_850_mb=on&lev_900_mb=on" <> | |
"&lev_925_mb=on&lev_950_mb=on&lev_975_mb=on&lev_high_cloud_layer=on" <> | |
"&lev_low_cloud_layer=on&lev_mean_sea_level=on&lev_middle_cloud_layer=on&lev_surface=on" <> | |
"&var_CAPE=on&var_CIN=on&var_DPT=on&var_GUST=on&var_HGT=on&var_HPBL=on&var_PRES=on" <> | |
"&var_PRMSL=on&var_RH=on&var_TCDC=on&var_TMP=on&var_UGRD=on&var_VGRD=on&lev_2_m_above_ground=on" | |
end | |
defp bounding_box_query_str(bounding_box) do | |
"leftlon=#{bounding_box.left_longitude}" <> | |
"&rightlon=#{bounding_box.right_longitude}" <> | |
"&toplat=#{bounding_box.top_latitude}" <> | |
"&bottomlat=#{bounding_box.bottom_latitude}" | |
end | |
defp dir_name(date, cycle) do | |
"%2Fgfs.#{format_date(date)}#{format_cycle(cycle)}" | |
end | |
defp format_date(date) do | |
Timex.format!(date, "{YYYY}{0M}{D}") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment