Skip to content
This repository has been archived by the owner on Dec 11, 2022. It is now read-only.

Commit

Permalink
✨ ASCII (Fixes #26)
Browse files Browse the repository at this point in the history
  • Loading branch information
tpoisot committed Feb 20, 2021
1 parent ed1eef5 commit 97b2da6
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/src/man/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ bioclim
```@docs
landcover
```

## ASCII files

```@docs
ascii
```
69 changes: 69 additions & 0 deletions src/datasets/ascii.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
function _get_asc_field(lines, field, type)
field_line = first(filter(startswith(field), lines))
return parse(type, last(split(field_line, " "))), findfirst(startswith(field), lines)
end

"""
ascii(file::AbstractString, datatype::Type{T}=Float64) where {T <: Number}
Reads the content of a grid file to a `SimpleSDMPredictor`, the type of which is
given by the `datatype` argument.
"""
function ascii(file::AbstractString, datatype::Type{T}=Float64) where {T <: Number}
lines = lowercase.(readlines(file))
# Get the information
ncols, ncols_line = _get_asc_field(lines, "ncols", Int64)
nrows, nrows_line = _get_asc_field(lines, "nrows", Int64)
xl, xl_line = _get_asc_field(lines, "xllcorner", Float64)
yl, yl_line = _get_asc_field(lines, "yllcorner", Float64)
cs, cs_line = _get_asc_field(lines, "cellsize", Float64)
nodata, nodata_line = _get_asc_field(lines, "nodata", datatype)
# Read the data
M = zeros(datatype, (ncols, nrows))
data_start = nodata_line+1
data_end = length(lines)
for line_id in data_start:data_end
M[:,nrows-(line_id-(data_start))] = parse.(datatype, split(lines[line_id]))
end
println(permutedims(M))
# Put data in the grid
grid = convert(Matrix{Union{datatype,Nothing}}, permutedims(M))
for i in eachindex(M)
if grid[i] == nodata
grid[i] = nothing
end
end
@info ncols, nrows, cs
return SimpleSDMPredictor(grid, xl, xl+cs*2ncols, yl, yl+cs*2nrows)
end

"""
ascii(layer::SimpleSDMPredictor{T}, file::AbstractString; nodata::T=convert(T, -9999)) where {T <: Number}
Writes a `layer` to a grid file, with a given `nodata` value. The layer must store numbers.
"""
function ascii(layer::SimpleSDMPredictor{T}, file::AbstractString; nodata::T=convert(T, -9999)) where {T <: Number}
if !(stride(layer)[1] stride(layer)[2])
throw(DimensionMismatch("The cells of the layer to write must be square (i.e. both values of stride must be equal)"))
end
open(file, "w") do io

write(io, "ncols $(size(layer, 2))\n")
write(io, "nrows $(size(layer, 1))\n")
write(io, "cellsize $(stride(layer)[1])\n")
write(io, "xllcorner $(layer.left)\n")
write(io, "yllcorner $(layer.bottom)\n")
write(io, "yllcorner $(layer.bottom)\n")
write(io, "nodata_value $(nodata)\n")
for row in reverse(1:size(layer.grid, 1))
for el in layer.grid[row,:]
if isnothing(el)
write(io, "$(nodata) ")
else
write(io, "$(el) ")
end
end
write(io, "\n")
end
end
end
24 changes: 24 additions & 0 deletions test/ascii.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module SSLTestASCII
using SimpleSDMLayers
using Test

M = rand(Float64, 4, 8)
M = convert(Matrix{Union{Nothing,Float64}}, M)
M[rand(Bool, size(M))] .= nothing
S = SimpleSDMPredictor(M, 0.0, 2.0, 0.0, 1.0)

ascii(S, "test.asc")
U = ascii("test.asc")

@test isfile("test.asc")
@test all(S.grid .== U.grid)
@test S.left == U.left
@test S.bottom == U.bottom
@test S.right == U.right
@test S.top == U.top
@test s
@test size(S) == size(U)

rm("test.asc")

end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ tests = [
"overloads" => "overloads.jl",
"generated" => "generated.jl",
"import" => "dataread.jl",
"ascii" => "ascii.jl",
"worldclim" => "worldclim.jl",
"landcover" => "landcover.jl",
"chelsa" => "chelsa.jl",
Expand Down

0 comments on commit 97b2da6

Please sign in to comment.