From f0ebdd721d22056447310462ab0c04d1f6b21487 Mon Sep 17 00:00:00 2001 From: Yu-Chang YANG Date: Tue, 28 Feb 2023 17:05:30 +0800 Subject: [PATCH] feat: add `WorldClim{Elevation}` (#55) The elevation dataset from WorldClim comprises coarse-grid global elevation raster data of the same resolutions as other datasets. It is now available by calling `getraster(WorldClim{Elevation})`. The tests, docs, and README.md have been modified accordingly. Closes #55. --- README.md | 22 ++++++++--------- docs/src/index.md | 2 ++ src/RasterDataSources.jl | 3 ++- src/types.jl | 11 +++++++++ src/worldclim/elevation.jl | 49 +++++++++++++++++++++++++++++++++++++ test/runtests.jl | 1 + test/worldclim-elevation.jl | 16 ++++++++++++ 7 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 src/worldclim/elevation.jl create mode 100644 test/worldclim-elevation.jl diff --git a/README.md b/README.md index 318d94d..3aa909d 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,17 @@ RasterDataSources downloads raster data for local use or for integration into ot [Rasters.jl](https://github.com/rafaqz/Rasters.jl). The collection is largely focussed on datasets relevant to ecology, but will have a lot of crossover with other sciences. -Currently sources include : - -| Source | URL | Status | -| --------- | ---------------------------------------- |--------------------------------------| -| CHELSA | https://chelsa-climate.org | BioClim, Future BioClim and Climate | -| WorldClim | https://www.worldclim.org | Climate, Weather and BioClim | -| EarthEnv | http://www.earthenv.org | LandCover and HabitatHeterogeneity | -| AWAP | http://www.bom.gov.au/jsp/awap/index.jsp | Complete | -| ALWB | http://www.bom.gov.au/water/landscape/ | Complete | -| SRTM | https://www2.jpl.nasa.gov/srtm/ | Complete | -| MODIS | https://modis.ornl.gov | In development | +Currently sources include: + +| Source | URL | Status | +| --------- | ---------------------------------------- | ---------------------------------------- | +| CHELSA | https://chelsa-climate.org | BioClim, Future BioClim and Climate | +| WorldClim | https://www.worldclim.org | Climate, Weather, BioClim, and Elevation | +| EarthEnv | http://www.earthenv.org | LandCover and HabitatHeterogeneity | +| AWAP | http://www.bom.gov.au/jsp/awap/index.jsp | Complete | +| ALWB | http://www.bom.gov.au/water/landscape/ | Complete | +| SRTM | https://www2.jpl.nasa.gov/srtm/ | Complete | +| MODIS | https://modis.ornl.gov | In development | Please open an issue if you need more datasets added, or (even better) open a pull request following the form of the other datasets where possible. diff --git a/docs/src/index.md b/docs/src/index.md index faa40bd..c262f2c 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -58,6 +58,7 @@ WorldClim getraster(T::Type{WorldClim{BioClim}}, layers::Union{Tuple,Int,Symbol}; res) getraster(T::Type{WorldClim{Weather}}, layers::Union{Tuple,Symbol}; date) getraster(T::Type{WorldClim{Climate}}, layers::Union{Tuple,Symbol}; month, res) +getraster(T::Type{WorldClim{Elevation}}, layers::Union{Tuple,Symbol}; month, res) ``` ## MODIS @@ -76,6 +77,7 @@ RasterDataSources.RasterDataSet BioClim Climate Weather +Elevation LandCover HabitatHeterogeneity Future diff --git a/src/RasterDataSources.jl b/src/RasterDataSources.jl index 957b852..d60c15f 100644 --- a/src/RasterDataSources.jl +++ b/src/RasterDataSources.jl @@ -16,7 +16,7 @@ import JSON.Parser as JP export WorldClim, CHELSA, EarthEnv, AWAP, ALWB, SRTM, MODIS -export BioClim, Climate, Weather, LandCover, HabitatHeterogeneity +export BioClim, Climate, Weather, Elevation, LandCover, HabitatHeterogeneity export Future, CMIP5, CMIP6 @@ -60,6 +60,7 @@ include("worldclim/shared.jl") include("worldclim/bioclim.jl") include("worldclim/climate.jl") include("worldclim/weather.jl") +include("worldclim/elevation.jl") include("chelsa/shared.jl") include("chelsa/bioclim.jl") diff --git a/src/types.jl b/src/types.jl index ed4ee65..ecb3470 100644 --- a/src/types.jl +++ b/src/types.jl @@ -93,6 +93,17 @@ See the [`getraster`](@ref) docs for implementation details. """ struct Weather <: RasterDataSet end +""" + Elevation <: RasterDataSet + +Elevation datasets. + +Currently implemented for WorldClim as `WorldClim{Elevation}`. + +See the [`getraster`](@ref) docs for implementation details. +""" +struct Elevation <: RasterDataSet end + """ LandCover <: RasterDataSet diff --git a/src/worldclim/elevation.jl b/src/worldclim/elevation.jl new file mode 100644 index 0000000..dfaa0f1 --- /dev/null +++ b/src/worldclim/elevation.jl @@ -0,0 +1,49 @@ +layers(::Type{WorldClim{Elevation}}) = (:elev,) + +""" + getraster(T::Type{WorldClim{Elevation}}, [layer::Union{Tuple,Symbol}]; res::String="10m") => Union{Tuple,AbstractVector,String} + +Download [`WorldClim`](@ref) [`Elevation`](@ref) data. + +# Arguments + +- `layer`: `Symbol` or `Tuple` of `Symbol` from `$(layers(WorldClim{Elevation}))`. + Without a `layer` argument, all layers will be downloaded, and a `NamedTuple` of paths returned. + +# Keywords + +- `res`: `String` chosen from $(resolutions(WorldClim{Elevation})), "10m" by default. + +Returns the filepath/s of the downloaded or pre-existing files. +""" +function getraster(T::Type{WorldClim{Elevation}}, layers::Union{Tuple,Symbol}; + res::String=defres(T) +) + _getraster(T, layers, res) +end + +_getraster(T::Type{WorldClim{Elevation}}, layers::Tuple, res) = _map_layers(T, layers, res) +function _getraster(T::Type{WorldClim{Elevation}}, layer::Symbol, res) + _check_layer(T, layer) + _check_res(T, res) + raster_path = rasterpath(T, layer; res) + if !isfile(raster_path) + zip_path = zippath(T, layer; res) + _maybe_download(zipurl(T, layer; res), zip_path) + mkpath(dirname(raster_path)) + raster_name = rastername(T, layer; res) + zf = ZipFile.Reader(zip_path) + write(raster_path, read(_zipfile_to_read(raster_name, zf))) + close(zf) + end + return raster_path +end + +rasterpath(T::Type{<:WorldClim{Elevation}}, layer; kw...) = + joinpath(rasterpath(T), rastername(T, layer; kw...)) +rastername(T::Type{<:WorldClim{Elevation}}, key; res) = "wc2.1_$(res)_elev.tif" +zipname(T::Type{<:WorldClim{Elevation}}, key; res) = "wc2.1_$(res)_elev.zip" +zipurl(T::Type{<:WorldClim{Elevation}}, key; res) = + joinpath(WORLDCLIM_URI, "base", zipname(T, key; res)) +zippath(T::Type{<:WorldClim{Elevation}}, key; res) = + joinpath(rasterpath(T), "zips", zipname(T, key; res)) diff --git a/test/runtests.jl b/test/runtests.jl index ac3a385..de7fac3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,6 +22,7 @@ end @time @safetestset "worldclim bioclim" begin include("worldclim-bioclim.jl") end @time @safetestset "worldclim climate" begin include("worldclim-climate.jl") end @time @safetestset "worldclim weather" begin include("worldclim-weather.jl") end +@time @safetestset "worldclim elevation" begin include("worldclim-elevation.jl") end # SRTM SSL certs have expired # @time @safetestset "srtm" begin include("srtm.jl") end @time @safetestset "modis utilities" begin include("modis-utilities.jl") end diff --git a/test/worldclim-elevation.jl b/test/worldclim-elevation.jl new file mode 100644 index 0000000..152bdf3 --- /dev/null +++ b/test/worldclim-elevation.jl @@ -0,0 +1,16 @@ +using RasterDataSources, URIs, Test, Dates +using RasterDataSources: rastername, rasterpath, zipurl, zipname, zippath + +@testset "WorldClim Elevation" begin + zip_url = URI(scheme="https", host="biogeo.ucdavis.edu", path="/data/worldclim/v2.1/base/wc2.1_10m_elev.zip") + @test zipurl(WorldClim{Elevation}, :elev; res="10m") == zip_url + @test zipname(WorldClim{Elevation}, :elev; res="10m") == "wc2.1_10m_elev.zip" + + raster_file = joinpath(ENV["RASTERDATASOURCES_PATH"], "WorldClim", "Elevation", "wc2.1_10m_elev.tif") + @test rasterpath(WorldClim{Elevation}, :elev; res="10m") == raster_file + @test getraster(WorldClim{Elevation}; res="10m") == (elev=raster_file,) + @test getraster(WorldClim{Elevation}, (:elev,); res="10m") == (elev=raster_file,) + @test getraster(WorldClim{Elevation}, :elev; res="10m") == raster_file + @test getraster(WorldClim{Elevation}, [:elev]; res="10m") == (elev=raster_file,) + @test isfile(raster_file) +end