Skip to content

Commit 65c0b13

Browse files
authored
Merge pull request #27 from JuliaDataCubes/la/write_tif
La/write tif
2 parents 2d6f7d7 + 674236c commit 65c0b13

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

ext/ArchGDALExt/ArchGDALExt.jl

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ module ArchGDALExt
4040
error("RasterDataset only has 3 dimensions")
4141
end
4242
end
43+
4344
iscontdim(a::RasterDataset, i) = i < 3 ? true : nraster(a)<8
4445
function getattributes(a::RasterDataset)
4546
globatts = Dict{String,Any}(
@@ -50,7 +51,7 @@ module ArchGDALExt
5051
allbands = mergewith(bands...) do a1,a2
5152
isequal(a1,a2) ? a1 : missing
5253
end
53-
merge(globatts, allbands)
54+
return merge(globatts, allbands)
5455
end
5556

5657

@@ -75,9 +76,9 @@ module ArchGDALExt
7576
end
7677
iscontdim(a::AbstractRasterBand, i) = true
7778
function getattributes(a::AbstractRasterBand)
78-
atts = getattributes(AG.RasterDataset(AG.getdataset(a)))
79-
bandatts = getbandattributes(a)
80-
merge(atts, bandatts)
79+
atts = getattributes(AG.RasterDataset(AG.getdataset(a)))
80+
bandatts = getbandattributes(a)
81+
return merge(atts, bandatts)
8182
end
8283

8384
function insertattifnot!(attrs, val, name, condition)
@@ -86,13 +87,13 @@ module ArchGDALExt
8687
end
8788
end
8889
function getbandattributes(a::AbstractRasterBand)
89-
atts = Dict{String,Any}()
90-
catdict = Dict((i-1)=>v for (i,v) in enumerate(AG.getcategorynames(a)))
91-
insertattifnot!(atts, AG.getnodatavalue(a), "missing_value", isnothing)
92-
insertattifnot!(atts, catdict, "labels", isempty)
93-
insertattifnot!(atts, AG.getunittype(a), "units", isempty)
94-
insertattifnot!(atts, AG.getoffset(a), "add_offset", iszero)
95-
insertattifnot!(atts, AG.getscale(a), "scale_factor", x->isequal(x, one(x)))
96-
atts
90+
atts = Dict{String,Any}()
91+
catdict = Dict((i-1)=>v for (i,v) in enumerate(AG.getcategorynames(a)))
92+
insertattifnot!(atts, AG.getnodatavalue(a), "missing_value", isnothing)
93+
insertattifnot!(atts, catdict, "labels", isempty)
94+
insertattifnot!(atts, AG.getunittype(a), "units", isempty)
95+
insertattifnot!(atts, AG.getoffset(a), "add_offset", iszero)
96+
insertattifnot!(atts, AG.getscale(a), "scale_factor", x->isequal(x, one(x)))
97+
return atts
9798
end
9899
end

ext/ArchGDALExt/archgdaldataset.jl

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,37 @@ DiskArrays.haschunks(::GDALBand) = DiskArrays.Chunked()
1717
function DiskArrays.readblock!(b::GDALBand, aout::Matrix, r::AbstractUnitRange...)
1818
AG.read(b.filename) do ds
1919
AG.getband(ds, b.band) do bh
20-
DiskArrays.readblock!(bh, aout, r...)
21-
20+
DiskArrays.readblock!(bh, aout, r...) # ? what to do if size(aout) < r ranges ?, i.e. chunk reads! is a DiskArrays issue!
2221
end
2322
end
2423
end
2524

26-
function DiskArrays.readblock!(b::GDALBand, aout, r::AbstractUnitRange...)
27-
aout2 = similar(aout)
28-
DiskArrays.readblock!(b, aout2, r)
29-
aout .= aout2
30-
end
31-
25+
function DiskArrays.readblock!(b::GDALBand, aout::Matrix, r::Tuple{AbstractUnitRange, AbstractUnitRange})
26+
DiskArrays.readblock!(b, aout, r...)
27+
end
3228

3329
function DiskArrays.writeblock!(b::GDALBand, ain, r::AbstractUnitRange...)
34-
AG.read(b.filename, flags=AG.OF_Update) do ds
30+
AG.read(b.filename, flags=AG.OF_UPDATE) do ds
3531
AG.getband(ds, b.band) do bh
3632
DiskArrays.writeblock!(bh, ain, r...)
3733
end
3834
end
3935
end
36+
function DiskArrays.readblock!(b::GDALBand, aout, r::AbstractUnitRange...)
37+
aout2 = similar(aout)
38+
DiskArrays.readblock!(b, aout2, r)
39+
aout .= aout2
40+
end
4041

4142
struct GDALDataset
4243
filename::String
4344
bandsize::Tuple{Int,Int}
44-
projection::String
45+
projection::Union{String, AG.AbstractSpatialRef}
4546
trans::Vector{Float64}
4647
bands::OrderedDict{String}
4748
end
4849

49-
function GDALDataset(filename;mode="r")
50+
function GDALDataset(filename; mode="r")
5051
AG.read(filename) do r
5152
nb = AG.nraster(r)
5253
allbands = map(1:nb) do iband
@@ -120,21 +121,22 @@ function totransform(x, y)
120121
end
121122
totransform(x::AbstractRange, y::AbstractRange) =
122123
Float64[first(x), step(x), 0.0, first(y), 0.0, step(y)]
124+
123125
getproj(userproj::String, attrs) = AG.importPROJ4(userproj)
124126
getproj(userproj::AG.AbstractSpatialRef, attrs) = userproj
127+
125128
function getproj(::Nothing, attrs)
126-
if haskey(attrs, "projection_PROJ4")
129+
if haskey(attrs, "projection")
130+
return AG.importWKT(attrs["projection"])
131+
elseif haskey(attrs, "projection_PROJ4")
127132
return AG.importPROJ4(attrs["projection_PROJ4"])
128133
elseif haskey(attrs, "projection_WKT")
129134
return AG.importWKT(attrs["projection_WKT"])
130135
else
131-
error(
132-
"Could not determine output projection from attributes, please specify userproj",
133-
)
136+
error("Could not determine output projection from attributes, please specify userproj")
134137
end
135138
end
136139

137-
138140
function YAB.create_dataset(
139141
::Type{<:GDALDataset},
140142
outpath,
@@ -150,15 +152,22 @@ function YAB.create_dataset(
150152
userproj = nothing,
151153
kwargs...,
152154
)
155+
# ? flip dimnames and dimvals, this needs a more generic solution!
156+
dimnames = reverse(dimnames)
157+
dimvals = reverse(dimvals)
158+
153159
@assert length(dimnames) == 2
160+
merged_varattrs = merge(varattrs...)
161+
154162
proj, trans = if islon(dimnames[1]) && islat(dimnames[2])
155163
#Lets set the crs to EPSG:4326
156164
proj = AG.importEPSG(4326)
157165
trans = totransform(dimvals[1], dimvals[2])
158166
proj, trans
159167
elseif isx(dimnames[1]) && isy(dimnames[2])
160-
#Try to find out srs
161-
proj = getproj(userproj, merge(gatts,varattrs...))
168+
# Try to find out crs
169+
all_attrs = merge(gatts, merged_varattrs)
170+
proj = getproj(userproj, all_attrs)
162171
trans = totransform(dimvals[1], dimvals[2])
163172
proj, trans
164173
else
@@ -167,7 +176,13 @@ function YAB.create_dataset(
167176
cs = first(varchunks)
168177
@assert all(isequal(varchunks[1]), varchunks)
169178

170-
driver = AG.getdriver(AG.extensiondriver(outpath))
179+
# driver = AG.getdriver(AG.extensiondriver(outpath)) # ? it looks like this driver (for .tif) is not working
180+
181+
if !endswith(lowercase(outpath), ".tif") && !endswith(lowercase(outpath), ".tiff")
182+
outpath = outpath * ".tif"
183+
end
184+
# Use this:
185+
driver = AG.getdriver("GTiff")
171186

172187
nbands = length(varnames)
173188
dtype = promote_type(vartypes...)
@@ -179,16 +194,21 @@ function YAB.create_dataset(
179194
height = length(dimvals[2]),
180195
nbands = nbands,
181196
dtype = dtype,
182-
options = ["BLOCKXSIZE=$(cs[1])", "BLOCKYSIZE=$(cs[2])"]
197+
options = [
198+
"BLOCKXSIZE=$(cs[1])",
199+
"BLOCKYSIZE=$(cs[2])",
200+
"TILED=YES",
201+
"COMPRESS=LZW"
202+
]
183203
) do ds
184204
AG.setgeotransform!(ds, trans)
185205
bands = map(1:length(varnames)) do i
186206
b = AG.getband(ds, i)
187207
icol = findfirst(isequal(varnames[i]), colornames)
188208
if isnothing(icol)
189-
AG.setcolorinterp!(b, AG.GDAL.GDALColorInterp(0))
209+
AG.setcolorinterp!(b, AG.GDALColorInterp(0))
190210
else
191-
AG.setcolorinterp!(b, AG.GDAL.GDALColorInterp(icol - 1))
211+
AG.setcolorinterp!(b, AG.GDALColorInterp(icol - 1))
192212
end
193213
AG.GDAL.gdalsetdescription(b.ptr, varnames[i])
194214
atts = varattrs[i]

0 commit comments

Comments
 (0)