Skip to content

Commit e0a6bb7

Browse files
committed
add a one-in-all dataset creation method
1 parent 1be89d6 commit e0a6bb7

File tree

4 files changed

+102
-13
lines changed

4 files changed

+102
-13
lines changed

src/axisarrays/archgdal.jl

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import .ArchGDAL: RasterDataset, AbstractRasterBand,
22
getgeotransform, width, height, getname, getcolorinterp,
33
getband, nraster, getdataset
4+
const AG = ArchGDAL
5+
46
function dimname(a::RasterDataset, i)
57
if i == 1
68
return :Y
@@ -66,20 +68,17 @@ function getattributes(a::AbstractRasterBand)
6668
merge(atts, bandatts)
6769
end
6870

71+
function insertattifnot!(attrs, val, name, condition)
72+
if !condition(val)
73+
attrs[name] = val
74+
end
75+
end
6976
function getbandattributes(a::AbstractRasterBand)
7077
atts = Dict{String,Any}()
71-
offs = ArchGDAL.getoffset(a)
72-
sf = ArchGDAL.getscale(a)
73-
missval = ArchGDAL.getnodatavalue(a)
74-
if !iszero(offs)
75-
atts["add_offset"] = offs
76-
end
77-
if sf != one(sf)
78-
atts["scale_factor"] = sf
79-
end
80-
T = eltype(a)
81-
if missval !== nothing
82-
atts["missing_value"] = missval
83-
end
78+
insertattifnot!(atts, AG.getnodatavalue(a), "missing_value", isnothing)
79+
insertattifnot!(atts, AG.getcategorynames(a), "Categories", isempty)
80+
insertattifnot!(atts, AG.GDAL.gdalgetrasterunittype(a.ptr), "Units", isempty)
81+
insertattifnot!(atts, AG.getoffset(a), "add_offset", iszero)
82+
insertattifnot!(atts, AG.getscale(a), "scale_factor", x->isequal(x, one(x)))
8483
atts
8584
end

src/datasets/archgdal.jl

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const AG = ArchGDAL
2+
3+
struct GDALBand{T} <: AbstractDiskArray{T,2}
4+
filename::String
5+
band::Int
6+
size::Tuple{Int,Int}
7+
attrs::Dict{String,Any}
8+
cs::GridChunks{2}
9+
end
10+
function GDALBand(b,filename,i)
11+
s = size(b)
12+
atts = getbandattributes(b)
13+
GDALBand{AG.pixeltype(b)}(filename, i, s, atts, eachchunk(b))
14+
end
15+
Base.size(b::GDALBand) = b.size
16+
DiskArrays.eachchunk(b::GDALBand) = b.cs
17+
DiskArrays.haschunks(::GDALBand) = DiskArrays.Chunked()
18+
function DiskArrays.readblock!(b::GDALBand,aout,r::AbstractUnitRange...)
19+
AG.read(b.filename) do ds
20+
AG.getband(ds,b.band) do bh
21+
DiskArrays.readblock!(bh,aout,r...)
22+
end
23+
end
24+
end
25+
26+
struct GDALDataset
27+
filename::String
28+
bandsize::Tuple{Int,Int}
29+
projection::String
30+
trans::NTuple{6,Float64}
31+
bands::OrderedDict{String}
32+
end
33+
34+
function GDALDataset(filename)
35+
AG.read(filename) do r
36+
nb = AG.nraster(r)
37+
allbands = map(1:nb) do iband
38+
b = AG.getband(r,iband)
39+
gb = GDALBand(b, filename,iband)
40+
name = AG.getname(AG.getcolorinterp(b))
41+
isempty(name) && (name = string("Band",iband))
42+
name => gb
43+
end
44+
proj = AG.getproj(r)
45+
trans = (AG.getgeotransform(r)...,)
46+
s = AG._common_size(r)
47+
GDALDataset(filename, s[1:end-1], proj, trans, OrderedDict(allbands))
48+
end
49+
end
50+
Base.haskey(ds::GDALDataset, k) = in(k,("X","Y")) || haskey(ds.bands,k)
51+
#Implement Dataset interface
52+
function get_var_handle(ds::GDALDataset, name)
53+
if name == "X"
54+
range(ds.trans[1],length=ds.bandsize[1], step=ds.trans[2])
55+
elseif name == "Y"
56+
range(ds.trans[4],length=ds.bandsize[2], step=ds.trans[6])
57+
else
58+
ds.bands[name]
59+
end
60+
end
61+
62+
63+
get_varnames(ds::GDALDataset) = collect(keys(ds.bands))
64+
65+
get_var_dims(ds::GDALDataset, _) = ("X", "Y")
66+
67+
function get_var_attrs(ds::GDALDataset,name)
68+
if name in ("Y","X")
69+
Dict{String,Any}()
70+
else
71+
ds.bands[name].attrs
72+
end
73+
end

src/datasets/datasetinterface.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,28 @@ Returns true if Union{T,Missing} is an allowed data type for the backend
4141
and if an array containing missings can be written to the array.
4242
"""
4343
allow_missings(ds) = true
44+
4445
#Fallback for writing array
4546
function add_var(ds,x::AbstractArray,name,dimlist,atts;kwargs...)
4647
a = add_var(ds,eltype(x),name,size(x),dimlist,atts;kwargs...)
4748
a .= x
4849
a
4950
end
5051

52+
function create_dataset(T::Type, path, dimnames, dimvals, dimattrs, vartypes, varnames, vardims, varattrs, varchunks, kwargs)
53+
ds = create_empty(T, path)
54+
axlengths = Dict{String, Int}()
55+
for (dname, dval, dattr) in zip(dimnames, dimvals, dimattrs)
56+
add_var(ds, dval, dname, (dname,), dattr)
57+
axlengths[dname] = length(dval)
58+
end
59+
for (T, vn, vd, va, vc) in zip(vartypes, varnames, vardims, varattrs, varchunks)
60+
s = getindex.(Ref(axlengths),vd)
61+
add_var(ds, T, vn, s, vd, va; chunksize = vc, kwargs...)
62+
end
63+
ds
64+
end
65+
5166
using DataStructures: OrderedDict
5267
"""
5368
YAXArrayBase.backendlist

src/datasets/netcdf.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ function create_empty(::Type{NetCDFDataset}, path)
5656
NetCDFDataset(path)
5757
end
5858

59+
allow_parallel_write(::Type{<:NetCDFDataset}) = false
5960
allow_parallel_write(::NetCDFDataset) = false
6061

62+
allow_missings(::Type{<:NetCDFDataset}) = false
6163
allow_missings(::NetCDFDataset) = false
6264

6365
backendlist[:netcdf] = NetCDFDataset

0 commit comments

Comments
 (0)