-
Notifications
You must be signed in to change notification settings - Fork 10
/
weather.jl
74 lines (62 loc) · 3.05 KB
/
weather.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
layers(::Type{WorldClim{Weather}}) = (:tmin, :tmax, :prec)
date_step(::Type{WorldClim{Weather}}) = Month(1)
"""
getraster(T::Type{WorldClim{Weather}}, [layer::Union{Tuple,Symbol}]; date) => Union{String,Tuple{String},Vector{String}}
Download [`WorldClim`](@ref) [`Weather`](@ref) data, for `layer`/s in: `$(layers(WorldClim{Weather}))`.
Without a layer argument, all layers will be downloaded, and a `NamedTuple` of paths returned.
# Keywords
- `date`: a `Date` or `DateTime` object, a `Vector` of dates, or `Tuple` of start/end dates.
WorldClim Weather is available with a daily timestep.
Returns the filepath/s of the downloaded or pre-existing files.
"""
function getraster(T::Type{WorldClim{Weather}}, layers::Union{Tuple,Symbol}; date)
_getraster(T, layers, date)
end
getraster_keywords(::Type{WorldClim{Weather}}) = (:date,)
function _getraster(T::Type{WorldClim{Weather}}, layers, date::Tuple)
_getraster(T, layers, date_sequence(T, date))
end
function _getraster(T::Type{WorldClim{Weather}}, layers, dates::AbstractArray)
_getraster.(T, Ref(layers), dates)
end
function _getraster(T::Type{WorldClim{Weather}}, layers::Tuple, date::Dates.TimeType)
_map_layers(T, layers, date)
end
function _getraster(T::Type{WorldClim{Weather}}, layer::Symbol, date::Dates.TimeType)
decadestart = Date.(1960:10:2020)
for i in eachindex(decadestart[1:end-1])
# At least one date is in the decade
date >= decadestart[i] && date < decadestart[i+1] || continue
zip_path = zippath(T, layer; decade=decadestart[i])
_maybe_download(zipurl(T, layer; decade=decadestart[i]), zip_path)
zf = ZipFile.Reader(zip_path)
raster_path = rasterpath(T, layer; date=date)
mkpath(dirname(raster_path))
if !isfile(raster_path)
raster_name = rastername(T, layer; date=date)
println("Writing $(raster_path)...")
write(raster_path, read(_zipfile_to_read(raster_name, zf)))
end
close(zf)
return raster_path
end
error("Date $date not between 1960 and 2020")
end
const WEATHER_DECADES = Dict(Date(1960) => "1960-1969",
Date(1970) => "1970-1979",
Date(1980) => "1980-1989",
Date(1990) => "1990-1999",
Date(2000) => "2000-2009",
Date(2010) => "2010-2018")
rastername(T::Type{<:WorldClim{Weather}}, layer; date) =
joinpath("wc2.1_2.5m_$(layer)_$(_date2string(T, date)).tif")
zipname(T::Type{<:WorldClim{Weather}}, layer; decade) =
"wc2.1_2.5m_$(layer)_$(WEATHER_DECADES[decade]).zip"
zipurl(T::Type{<:WorldClim{Weather}}, layer; decade) =
joinpath(WORLDCLIM_URI, "hist", zipname(T, layer; decade))
zippath(T::Type{<:WorldClim{Weather}}, layer; decade) =
joinpath(rasterpath(T), "zips", zipname(T, layer; decade))
# Utility methods
_dateformat(::Type{<:WorldClim}) = DateFormat("yyyy-mm")
_filename2date(T::Type{<:WorldClim}, fn::AbstractString) =
_string2date(T, basename(fn)[findfirst(r"\d\d\d\d-\d\d", basename(fn))])