Skip to content

Commit 76bc8cf

Browse files
authored
Shelter a few more modules from the kwargs explosion (#1958)
1 parent 183063b commit 76bc8cf

3 files changed

Lines changed: 65 additions & 63 deletions

File tree

src/extras/seismicity.jl

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -47,28 +47,19 @@ https://earthquake.usgs.gov
4747
```
4848
"""
4949
function seismicity(; starttime::Union{DateTime, String}="", endtime::Union{DateTime, String}="", minmagnitude=3,
50-
mindepth=0, maxdepth=0, last=0, year=0, printurl::Bool=false, layers=3, legend=true, show=true, kw...)
50+
mindepth=0, maxdepth=0, last::Union{Int, String}=0, year::Int=0, printurl::Bool=false, layers=3, legend=true, show=true, kw...)
51+
d = KW(kw)
52+
_last = ((isa(last, Int) ? last : 0), isa(last, String) ? last : "")
53+
_seismicity(d, string(starttime), string(endtime), Float64(minmagnitude), Float64(mindepth), Float64(maxdepth), _last, year, printurl, layers, legend==1, show==1)
54+
end
55+
function _seismicity(d::Dict{Symbol, Any}, starttime::String, endtime::String, minmagnitude::Float64, mindepth::Float64,
56+
maxdepth::Float64, last::Tuple{Int, String}, year::Int, printurl::Bool, layers::Int, legend::Bool, show::Bool)
5157

5258
(layers != 3 && layers != 4) && error("Only 3 or 4 (depth) layers are allowed.")
53-
d = KW(kw)
5459
url = "https://earthquake.usgs.gov/fdsnws/event/1/query.csv?format=csv&orderby=time-asc&minmagnitude=$minmagnitude"
5560

56-
url = helper_get_date_interval(d, last, url, starttime, endtime, year=year, sstart="&starttime=", send="&endtime=") # See if a period was requested
57-
58-
#=
59-
(starttime != "" && last != 0) && (@warn("Options 'starttime' and 'last' are incompatible. Droping 'last'."); last=0)
60-
(endtime != "" && starttime == "") && (@warn("Gave a 'endtime' but not a 'starttime'. Ignoring it."); endtime = "")
61-
(isa(last, Integer) && last > 0) && (starttime = string(Date(now() - Dates.Day(last))))
62-
if (isa(last, String)) # Requests of Weeks, Months, Years
63-
_last = lowercase(last)
64-
if ((ind = findfirst('y', _last)) !== nothing) starttime = Date(now() - Dates.Year(parse(Int, _last[1:ind-1])))
65-
elseif ((ind = findfirst('m', _last)) !== nothing) starttime = Date(now() - Dates.Month(parse(Int, _last[1:ind-1])))
66-
elseif ((ind = findfirst('w', _last)) !== nothing) starttime = Date(now() - Dates.Week(parse(Int, _last[1:ind-1])))
67-
end
68-
end
69-
(starttime != "") && (url *= "&starttime=" * string(starttime))
70-
(endtime != "") && (url *= "&endtime=" * string(endtime))
71-
=#
61+
url = helper_get_date_interval(d, last, url, starttime, endtime, year, "&starttime=", "&endtime=") # See if a period was requested
62+
7263
if ((opt_R::String = parse_R(d, "")[2]) != "")
7364
(opt_R[end] == 'r') && error("Region as lon_min/lat_min/lon_max/lat_max form is not supported here.")
7465
!contains(opt_R, '/') && (opt_R = " " * coast(getR=opt_R[4:end]))
@@ -116,7 +107,7 @@ function seismicity(; starttime::Union{DateTime, String}="", endtime::Union{Date
116107
# just bad use. Since that fun is complex it's better not touch it and just make an array by duplicating the scalar.
117108
_size = (_size_t === nothing) ? _size_t : isa(_size_t, Number) ? [_size_t _size_t] : _size_t
118109

119-
mag_size, opt_S = parse_opt_S(d, view(D, :, 4))
110+
_, opt_S = parse_opt_S(d, view(D, :, 4))
120111

121112
if (opt_S == "" || endswith(opt_S, "7p"))
122113
@inbounds for k =1:size(D,1) D[k,4] *= 0.02 end
@@ -137,40 +128,47 @@ function seismicity(; starttime::Union{DateTime, String}="", endtime::Union{Date
137128
d = CTRL.pocket_d[1]
138129
d[:show] = show
139130
ms = (_size !== nothing) ? parse_opt_S(Dict{Symbol,Any}(:size => _size), [3., 4, 5, 6, 7, 8, 9])[1] : [3., 4, 5, 6, 7, 8, 9] .* 0.02
140-
st = (starttime != "") ? string(starttime) : string(Date(now() - Dates.Day(30)))
141-
et = (endtime != "") ? string(endtime) : string(Date(now()))
142-
legend && seislegend(; first=false, title="From "*st*" to "*et, cmap=C, mags=ms, pos="JBC+o0/1c+w12c/2.3c", d...)
131+
st = (starttime != "") ? starttime : string(Date(now() - Dates.Day(30)))
132+
et = (endtime != "") ? endtime : string(Date(now()))
133+
legend && seislegend(; title="From "*st*" to "*et, cmap=C, mags=ms, pos="JBC+o0/1c+w12c/2.3c", d...)
143134
end
144135

145136
# ------------------------------------------------------------------------------------------------------
146-
function helper_get_date_interval(d, last, url, starttime, endtime; year::Int=0, sstart="&start_date=", send="&end_date=")
137+
function helper_get_date_interval(d::Dict{Symbol, Any}, last::Tuple{Int, String}, url, starttime::String, endtime::String, year::Int, sstart, send)
147138
# Helper function used both in seismicity and weather functions.
139+
140+
function test_last(last::Tuple{Int, String}, msg::String)
141+
# If option 'last' was used when it shouldn't return true a blank it
142+
(last[1] != 0 || last[2] != "") && (@warn(msg); return (0, ""))
143+
return last
144+
end
145+
148146
if (year != 0)
149-
(last != 0) && (@warn("Options 'year' and 'last' are incompatible. Droping 'last'."); last=0)
147+
last = test_last(last, "Options 'year' and 'last' are incompatible. Dropping 'last'.")
150148
starttime = "$year-01-01"
151149
endtime = (parse(Int,string(today())[1:4]) == year) ? string(today()) : "$year-12-31"
152150
end
153-
(starttime == "") && ((val = find_in_dict(d, [:startdate :start_date :start_time])[1]) !== nothing) && (starttime = string(val)::String)
154-
(endtime == "") && ((val = find_in_dict(d, [:enddate :end_date :end_time])[1]) !== nothing) && (endtime = string(val)::String)
155-
(starttime != "" && last != 0) && (@warn("Options 'starttime' and 'last' are incompatible. Droping 'last'."); last=0)
156-
(endtime != "" && starttime == "") && (@warn("Gave a 'endtime' but not a 'starttime'. Ignoring it."); endtime = "")
157-
(isa(last, Integer) && last > 0) && (starttime = string(Date(now() - Dates.Day(last))))
158-
if (isa(last, String)) # Requests of Weeks, Months, Years
159-
_last = lowercase(last)
160-
if ((ind = findfirst('y', _last)) !== nothing) starttime = Date(now() - Dates.Year(parse(Int, _last[1:ind-1])))
161-
elseif ((ind = findfirst('m', _last)) !== nothing) starttime = Date(now() - Dates.Month(parse(Int, _last[1:ind-1])))
162-
elseif ((ind = findfirst('w', _last)) !== nothing) starttime = Date(now() - Dates.Week(parse(Int, _last[1:ind-1])))
151+
(starttime === "") && (starttime = hlp_desnany_str(d, [:startdate :start_date :start_time]))
152+
(endtime === "") && (endtime = hlp_desnany_str(d, [:enddate :end_date :end_time]))
153+
(starttime !== "") && (last = test_last(last, "Options 'starttime' and 'last' are incompatible. Droping 'last'."))
154+
(endtime !== "" && starttime === "") && (@warn("Gave a 'endtime' but not a 'starttime'. Ignoring it."); endtime = "")
155+
(last[1] > 0) && (starttime = string(Date(now() - Dates.Day(last[1]))))
156+
if (last[2] !== "") # Requests of Weeks, Months, Years
157+
_last = lowercase(last[2])
158+
if ((ind = findfirst('y', _last)) !== nothing) starttime = string(Date(now() - Dates.Year(parse(Int, _last[1:ind-1]))))
159+
elseif ((ind = findfirst('m', _last)) !== nothing) starttime = string(Date(now() - Dates.Month(parse(Int, _last[1:ind-1]))))
160+
elseif ((ind = findfirst('w', _last)) !== nothing) starttime = string(Date(now() - Dates.Week(parse(Int, _last[1:ind-1]))))
163161
end
164162
(send == "&end_date=") && (endtime = Date(now())) # Because weather() needs an end date too.
165163
end
166-
(starttime != "") && (url *= sstart * string(starttime))
167-
(endtime != "") && (url *= send * string(endtime))
164+
(starttime != "") && (url *= sstart * starttime)
165+
(endtime != "") && (url *= send * endtime)
168166
return url
169167
end
170168

171169
# ------------------------------------------------------------------------------------------------------
172170
"""
173-
seislegend(; title="", font=(16,"Times-Roman"), cmap=GMTcpt(), mags=Float64[], lowermag=3, kw...)
171+
seislegend(; title="", font=(16,"Times-Roman"), cmap=GMTcpt(), mags=Float64[], lowermag=3.0, kw...)
174172
175173
Adds a legend to plots produced by `seismicity` function. All options are optional.
176174
@@ -179,8 +177,11 @@ Adds a legend to plots produced by `seismicity` function. All options are option
179177
- `title`: The legend head title.
180178
- `font`: The legend head font.
181179
"""
182-
function seislegend(; title="", font=(16,"Times-Roman"), cmap=GMTcpt(), mags::VecOrMat=Float64[], lowermag=3, first=true, kw...)
183-
# ...
180+
function seislegend(; title="", font=(16,"Times-Roman"), cmap=GMTcpt(), mags::VecOrMat=Float64[], lowermag=3.0, kw...)
181+
d = KW(kw)
182+
_seislegend(d, string(title), font, cmap, vec(Float64.(mags)), Float64(lowermag))
183+
end
184+
function _seislegend(d::Dict{Symbol,Any}, title::String, font, cmap::GMTcpt, mags::Vector{Float64}, lowermag::Float64)
184185
mags = isempty(mags) ? [3., 4, 5, 6, 7, 8, 9] .* 0.02 : mags
185186

186187
nc = isempty(cmap) ? 3 : size(cmap.colormap, 1)
@@ -205,14 +206,14 @@ function seislegend(; title="", font=(16,"Times-Roman"), cmap=GMTcpt(), mags::Ve
205206
end
206207

207208
extra_vs = maximum(mags) > 0.3 ? 0.05 : 0. # When symbols are big we need extra space between the hlines.
208-
d = KW(kw)
209-
!is_in_kwargs(kw, [:D :pos :position]) && (d[:D] = (paper=(0.25,0.25), width=14, justify=:BL, spacing=1.2))
210-
!is_in_kwargs(kw, [:C :clearance]) && (d[:C] = (0.25,0.25))
211-
!is_in_kwargs(kw, [:F :box]) && (d[:F] = (pen=0.5, fill=:azure1))
212-
!is_in_kwargs(kw, [:R :region :limits]) && (d[:R] = (0,10,0,4))
213-
!is_in_kwargs(kw, [:par]) && (d[:par] = (:FONT_ANNOT_PRIMARY, 8)) # Shitty solution. Must use conf for other configs
214-
215-
legend((
209+
!is_in_kwargs(d, [:D :pos :position]) && (d[:D] = (paper=(0.25,0.25), width=14, justify=:BL, spacing=1.2))
210+
#(is_in_dict(d, [:D :pos :position]) === nothing) && (d[:D] = (paper=(0.25,0.25), width=14, justify=:BL, spacing=1.2))
211+
!is_in_kwargs(d, [:C :clearance]) && (d[:C] = (0.25,0.25))
212+
!is_in_kwargs(d, [:F :box]) && (d[:F] = (pen=0.5, fill=:azure1))
213+
!is_in_kwargs(d, [:R :region :limits]) && (d[:R] = (0,10,0,4))
214+
!is_in_kwargs(d, [:par]) && (d[:par] = (:FONT_ANNOT_PRIMARY, 8)) # Shitty solution. Must use conf for other configs
215+
216+
legend("", (
216217
vspace=-0.25,
217218
header=(text= (title != "") ? title : "Map Legend", font=font),
218219
hline=(pen=0.75,),
@@ -230,5 +231,5 @@ function seislegend(; title="", font=(16,"Times-Roman"), cmap=GMTcpt(), mags::Ve
230231
vline4=(pen=0.75,),
231232
ncolumns3=1,
232233
label=(txt="Data from the US National Earthquake Information Center", justify=:R, font=(8,"Times-Italic")),
233-
); first=first, d...)
234+
), true, true, d)
234235
end

src/extras/weather.jl

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,28 @@ weather(city="Copenhagen", year=2023, variable="rain_sum", show=true)
4444
"""
4545
function weather(lon=0.0, lat=0.0; city::String="", last=0, days=7, year::Int=0, starttime::Union{DateTime, String}="",
4646
endtime::Union{DateTime, String}="", variable="temperature_2m", dryrun=false, debug=false, show=false, kw...)
47-
48-
# Keep the deprecated option 'debug' for now but remove it in the future (17-May-2025)
4947
d = KW(kw)
48+
_last = (isa(last, Int) ? last : 0, isa(last, String) ? last : "")
49+
_weather(d, Float64(lon), Float64(lat), city, _last, Int(days), year, string(starttime), string(endtime),
50+
string(variable), dryrun != 0 || debug != 0, show != 0)
51+
end
52+
function _weather(d::Dict{Symbol,Any}, lon::Float64, lat::Float64, city::String, last::Tuple{Int,String}, days::Int,
53+
year::Int, starttime::String, endtime::String, variable::String, dryrun::Bool, show::Bool)
54+
5055
url_forcast = "https://api.open-meteo.com/v1/forecast?format=csv&"
5156
url_archive = "https://archive-api.open-meteo.com/v1/archive?format=csv&"
5257
url_air = "https://air-quality-api.open-meteo.com/v1/air-quality?format=csv&"
53-
str_loc::String = (lon != 0.0 || lat != 0.0) ? "latitude=$lat&longitude=$lon" : (city != "") ? @sprintf("longitude=%f&latitude=%f", geocoder(city).data...) : @sprintf("longitude=%.3f&latitude=%.3f", whereami().data...)#"latitude=37.0695&longitude=-8.1006"
58+
str_loc::String = (lon != 0.0 || lat != 0.0) ? "latitude=$lat&longitude=$lon" : (city != "") ? @sprintf("longitude=%f&latitude=%f", geocoder(city).data...) : @sprintf("longitude=%.3f&latitude=%.3f", whereami().data...)
5459

55-
variable = string(variable)
56-
dt = helper_get_date_interval(d, last, "", starttime, endtime, year=year) # See if a period was requested
60+
dt = helper_get_date_interval(d, last, "", starttime, endtime, year, "&start_date=", "&end_date=")
5761
url = ((variable == "pm" && (variable = "pm10")) || variable == "pm10" || variable == "pm2.5" || variable == "dust" || variable == "aerosol_optical_depth") ? url_air : (dt != "") ? url_archive : url_forcast
5862
(days != 7 && url != url_archive) && (url *= string("forecast_days=", days, "&"))
5963
url *= str_loc * dt
6064
daily_vars = ["temperature_2m_max", "temperature_2m_min", "apparent_temperature_max", "apparent_temperature_min", "precipitation_sum", "rain_sum", "snowfall_sum", "precipitation_hours", "sunshine_duration", "daylight_duration", "wind_speed_10m_max", "wind_gusts_10m_max", "wind_direction_10m_dominant", "shortwave_radiation_sum", "et0_fao_evapotranspiration"]
61-
hourly = any(variable .== daily_vars) ? false : true
65+
hourly = !any(variable .== daily_vars)
6266
url *= hourly ? "&hourly=" * variable : "&daily=" * variable
6367

64-
(dryrun != 0 || debug != 0) && (println(url); return)
68+
dryrun && (println(url); return)
6569

6670
file = Downloads.download(url, "_query.csv")
6771
D = gmtread(file, h=4) # File has 4 header rows but only the 4rth matters
@@ -70,8 +74,8 @@ function weather(lon=0.0, lat=0.0; city::String="", last=0, days=7, year::Int=0,
7074
helper_set_colnames!(D) # Set column names based on info stored in the 4rth header line
7175
D.attrib["Location"] = (city != "") ? city : replace(str_loc, "&" => " ")
7276
retD = (find_in_dict(d, [:data])[1] !== nothing)
73-
(show != 0) && plot(D; legend=D.colnames[2], title=D.attrib["Location"], show=true, d...)
74-
return (retD || show == 0) ? D : nothing
77+
show && plot(D; legend=D.colnames[2], title=D.attrib["Location"], show=true, d...)
78+
return (retD || !show) ? D : nothing
7579
end
7680

7781
# ------------------------------------------------------------------------------------------------------------------------

src/pslegend.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
44
Make legends that can be overlaid on maps. It reads specific legend-related information from input or file file.
55
6-
See full GMT docs at [`legend`]($(GMTdoc)legend.html)
7-
86
Parameters
97
----------
108
@@ -49,7 +47,7 @@ function legend(cmd0::String="", arg1=nothing; first::Bool=true, kw...)
4947
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
5048
legend(cmd0, arg1, O, K, d)
5149
end
52-
function legend(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
50+
function legend(cmd0::String, @nospecialize(arg1), O::Bool, K::Bool, d::Dict{Symbol, Any})
5351

5452
gmt_proggy = (IamModern[]) ? "legend " : "pslegend "
5553

@@ -62,8 +60,7 @@ function legend(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
6260
# The call to digests_legend_bag(d) will call 'legend' again, making this a recursive call.
6361
# On that recursive call 'arg1 !== nothing' and it not pass in this code chunk, but upon return
6462
# from the digests_legend_bag() we'll return here again and either show, save or return quietly.
65-
do_show = ((val = find_in_dict(d, [:show])[1]) !== nothing && val != 0)
66-
figname::String = ((val = find_in_dict(d, [:savefig :figname :name])[1]) !== nothing) ? val : ""
63+
do_show, fmt, figname = get_show_fmt_savefig(d)
6764

6865
# Need to save the legend options in the global variable 'LEGEND_TYPE'
6966
# Must also recreate a NT if any of 'fontsize' or 'font' is present in 'd' (because of how digests_legend_bag works)
@@ -72,7 +69,7 @@ function legend(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
7269
((val = find_in_dict(d, [:pos :position])[1]) !== nothing) && (LEGEND_TYPE[].optsDict = Dict{Symbol,Any}(:pos => val))
7370

7471
digests_legend_bag(d) # It's over now, lets show up (or not) and return
75-
return (do_show || figname != "") ? showfig(show=do_show, savefig=figname) : nothing
72+
return (do_show || figname != "" || fmt !== "") ? showfig(show=do_show, savefig=figname, fmt=fmt) : nothing
7673
end
7774

7875
def_J = " -JX" * split(DEF_FIG_SIZE, '/')[1] * "/0"

0 commit comments

Comments
 (0)