From 8e5906016bf52319bb421b952c4515fd41ca5c91 Mon Sep 17 00:00:00 2001 From: Felix Cremer Date: Wed, 20 Jan 2021 17:04:31 +0100 Subject: [PATCH 1/4] Allow AbstractDataset in unsafe_gdalbuildvrt This would allow to build longer input arrays into vrts. --- src/utilities.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utilities.jl b/src/utilities.jl index 01240b6e..99a6bd7e 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -221,7 +221,7 @@ Build a VRT from a list of datasets. The output dataset. """ function unsafe_gdalbuildvrt( - datasets::Vector{Dataset}, + datasets::Vector{<:AbstractDataset}, options = String[]; dest = "/vsimem/tmp" ) From 430c0fc770ca1eae1652dfa480587aa65a1a5bfb Mon Sep 17 00:00:00 2001 From: Felix Cremer Date: Fri, 22 Jan 2021 10:57:11 +0100 Subject: [PATCH 2/4] Allow AbstractDataset for all functions in utilities.jl This allows to use interactive datasets in the unsafe_gdal functions in utilities.jl. --- src/utilities.jl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/utilities.jl b/src/utilities.jl index 99a6bd7e..1c304bda 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -1,5 +1,5 @@ """ - gdalinfo(dataset::Dataset, options = String[]) + gdalinfo(dataset::AbstractDataset, options = String[]) List various information about a GDAL supported raster dataset. @@ -11,7 +11,7 @@ List various information about a GDAL supported raster dataset. ### Returns String corresponding to the information about the raster dataset. """ -function gdalinfo(dataset::Dataset, options = String[]) +function gdalinfo(dataset::AbstractDataset, options = String[]) options = GDAL.gdalinfooptionsnew(options, C_NULL) result = GDAL.gdalinfo(dataset.ptr, options) GDAL.gdalinfooptionsfree(options) @@ -19,7 +19,7 @@ function gdalinfo(dataset::Dataset, options = String[]) end """ - unsafe_gdaltranslate(dataset::Dataset, options = String[]; dest = "/vsimem/tmp") + unsafe_gdaltranslate(dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp") Convert raster data between different formats. @@ -32,7 +32,7 @@ Convert raster data between different formats. The output dataset. """ function unsafe_gdaltranslate( - dataset::Dataset, + dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp" ) @@ -44,7 +44,7 @@ function unsafe_gdaltranslate( end """ - unsafe_gdalwarp(datasets::Vector{Dataset}, options = String[]; dest = "/vsimem/tmp") + unsafe_gdalwarp(datasets::Vector{<:AbstractDataset}, options = String[]; dest = "/vsimem/tmp") Image reprojection and warping function. @@ -57,7 +57,7 @@ Image reprojection and warping function. The output dataset. """ function unsafe_gdalwarp( - datasets::Vector{Dataset}, + datasets::Vector{<:AbstractDataset}, options = String[]; dest = "/vsimem/tmp" ) @@ -70,7 +70,7 @@ function unsafe_gdalwarp( end """ - unsafe_gdalvectortranslate(datasets::Vector{Dataset}, options = String[]; dest = "/vsimem/tmp") + unsafe_gdalvectortranslate(datasets::Vector{<:AbstractDataset}, options = String[]; dest = "/vsimem/tmp") Convert vector data between file formats. @@ -83,7 +83,7 @@ Convert vector data between file formats. The output dataset. """ function unsafe_gdalvectortranslate( - datasets::Vector{Dataset}, + datasets::Vector{<:AbstractDataset}, options = String[]; dest = "/vsimem/tmp" ) @@ -96,7 +96,7 @@ function unsafe_gdalvectortranslate( end """ - unsafe_gdaldem(dataset::Dataset, processing::String, options = String[]; dest = "/vsimem/tmp", colorfile) + unsafe_gdaldem(dataset::AbstractDataset, processing::String, options = String[]; dest = "/vsimem/tmp", colorfile) Tools to analyze and visualize DEMs. @@ -115,7 +115,7 @@ Tools to analyze and visualize DEMs. The output dataset. """ function unsafe_gdaldem( - dataset::Dataset, + dataset::AbstractDataset, processing::String, options = String[]; dest = "/vsimem/tmp", @@ -133,7 +133,7 @@ function unsafe_gdaldem( end """ - unsafe_gdalnearblack(dataset::Dataset, options = String[]; dest = "/vsimem/tmp") + unsafe_gdalnearblack(dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp") Convert nearly black/white borders to exact value. @@ -146,7 +146,7 @@ Convert nearly black/white borders to exact value. The output dataset. """ function unsafe_gdalnearblack( - dataset::Dataset, + dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp" ) @@ -158,7 +158,7 @@ function unsafe_gdalnearblack( end """ - unsafe_gdalgrid(dataset::Dataset, options = String[]; dest = "/vsimem/tmp") + unsafe_gdalgrid(dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp") Create a raster from the scattered data. @@ -171,7 +171,7 @@ Create a raster from the scattered data. The output dataset. """ function unsafe_gdalgrid( - dataset::Dataset, + dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp" ) @@ -183,7 +183,7 @@ function unsafe_gdalgrid( end """ - unsafe_gdalrasterize(dataset::Dataset, options = String[]; dest = "/vsimem/tmp") + unsafe_gdalrasterize(dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp") Burn vector geometries into a raster. @@ -196,7 +196,7 @@ Burn vector geometries into a raster. The output dataset. """ function unsafe_gdalrasterize( - dataset::Dataset, + dataset::AbstractDataset, options = String[]; dest = "/vsimem/tmp" ) @@ -208,7 +208,7 @@ function unsafe_gdalrasterize( end """ - unsafe_gdalbuildvrt(datasets::Vector{Dataset}, options = String[]; dest = "/vsimem/tmp") + unsafe_gdalbuildvrt(datasets::Vector{<:AbstractDataset}, options = String[]; dest = "/vsimem/tmp") Build a VRT from a list of datasets. From 7d17803589230c101c92c41cfe35789544902738 Mon Sep 17 00:00:00 2001 From: Felix Cremer Date: Fri, 22 Jan 2021 22:22:14 +0100 Subject: [PATCH 3/4] Change type restriction on unsafe_gdalfuns Allow subtypes of AbstractDataset in unsafe_gdal... functions so that we could use these with IDatasets. We use the type of the input as return type, so that we wouldn't accidentally change the approach by using these functions. --- src/utilities.jl | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/utilities.jl b/src/utilities.jl index 1c304bda..a1b4e0fc 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -32,15 +32,15 @@ Convert raster data between different formats. The output dataset. """ function unsafe_gdaltranslate( - dataset::AbstractDataset, + dataset::T, options = String[]; dest = "/vsimem/tmp" - ) + ) where {T<:AbstractDataset} options = GDAL.gdaltranslateoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdaltranslate(dest, dataset.ptr, options, usage_error) GDAL.gdaltranslateoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -57,16 +57,16 @@ Image reprojection and warping function. The output dataset. """ function unsafe_gdalwarp( - datasets::Vector{<:AbstractDataset}, + datasets::Vector{T}, options = String[]; dest = "/vsimem/tmp" - ) + ) where T<:AbstractDataset options = GDAL.gdalwarpappoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdalwarp(dest, C_NULL, length(datasets), [ds.ptr for ds in datasets], options, usage_error) GDAL.gdalwarpappoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -83,16 +83,16 @@ Convert vector data between file formats. The output dataset. """ function unsafe_gdalvectortranslate( - datasets::Vector{<:AbstractDataset}, + datasets::Vector{T}, options = String[]; dest = "/vsimem/tmp" - ) + ) where T<:AbstractDataset options = GDAL.gdalvectortranslateoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdalvectortranslate(dest, C_NULL, length(datasets), [ds.ptr for ds in datasets], options, usage_error) GDAL.gdalvectortranslateoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -115,12 +115,12 @@ Tools to analyze and visualize DEMs. The output dataset. """ function unsafe_gdaldem( - dataset::AbstractDataset, + dataset::T, processing::String, options = String[]; dest = "/vsimem/tmp", colorfile = C_NULL - ) + ) where T<:AbstractDataset if processing == "color-relief" @assert colorfile != C_NULL end @@ -129,7 +129,7 @@ function unsafe_gdaldem( result = GDAL.gdaldemprocessing(dest, dataset.ptr, processing, colorfile, options, usage_error) GDAL.gdaldemprocessingoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -146,15 +146,15 @@ Convert nearly black/white borders to exact value. The output dataset. """ function unsafe_gdalnearblack( - dataset::AbstractDataset, + dataset::T, options = String[]; dest = "/vsimem/tmp" - ) + ) where T<:AbstractDataset options = GDAL.gdalnearblackoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdalnearblack(dest, C_NULL, dataset.ptr, options, usage_error) GDAL.gdalnearblackoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -171,15 +171,15 @@ Create a raster from the scattered data. The output dataset. """ function unsafe_gdalgrid( - dataset::AbstractDataset, + dataset::T, options = String[]; dest = "/vsimem/tmp" - ) + ) where T<:AbstractDataset options = GDAL.gdalgridoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdalgrid(dest, dataset.ptr, options, usage_error) GDAL.gdalgridoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -196,15 +196,15 @@ Burn vector geometries into a raster. The output dataset. """ function unsafe_gdalrasterize( - dataset::AbstractDataset, + dataset::T, options = String[]; dest = "/vsimem/tmp" - ) + ) where T<:AbstractDataset options = GDAL.gdalrasterizeoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdalrasterize(dest, C_NULL, dataset.ptr, options, usage_error) GDAL.gdalrasterizeoptionsfree(options) - return Dataset(result) + return T(result) end """ @@ -221,14 +221,14 @@ Build a VRT from a list of datasets. The output dataset. """ function unsafe_gdalbuildvrt( - datasets::Vector{<:AbstractDataset}, + datasets::Vector{T}, options = String[]; dest = "/vsimem/tmp" - ) + ) where T <:AbstractDataset options = GDAL.gdalbuildvrtoptionsnew(options, C_NULL) usage_error = Ref{Cint}() result = GDAL.gdalbuildvrt(dest, length(datasets), [ds.ptr for ds in datasets], C_NULL, options, usage_error) GDAL.gdalbuildvrtoptionsfree(options) - return Dataset(result) + return T(result) end From 3e6c9ffca2d0a3ce684eb4f772df19555c270e71 Mon Sep 17 00:00:00 2001 From: Felix Cremer Date: Fri, 22 Jan 2021 22:26:20 +0100 Subject: [PATCH 4/4] Add tests for interactive unsafe_gdalfuns The tests are copied from the non-interactive utilities tests and converted to not use the do block notation, but to set the variable and reuse the variable later in the tests. --- test/test_gdalutilities.jl | 81 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/test/test_gdalutilities.jl b/test/test_gdalutilities.jl index ab0d09ed..80e8d204 100644 --- a/test/test_gdalutilities.jl +++ b/test/test_gdalutilities.jl @@ -113,3 +113,84 @@ AG.read("data/point.geojson") do ds_point rm("data/point.csv") end end + + +@testset "Interactive data/utmsmall.tif" begin + ds_small = AG.read("data/utmsmall.tif") + @testset "GDAL Error" begin + @test_throws GDAL.GDALError AG.gdalinfo(ds_small, ["-novalidoption"]) + @test_throws GDAL.GDALError AG.unsafe_gdaltranslate(ds_small, ["-novalidoption"]) + @test_throws GDAL.GDALError AG.unsafe_gdalbuildvrt([ds_small], ["-novalidoption"]) + @test_throws GDAL.GDALError AG.unsafe_gdaldem(ds_small, "hillshade", ["-novalidoption"]) + @test_throws GDAL.GDALError AG.unsafe_gdalnearblack(ds_small, ["-novalidoption"]) + @test_throws GDAL.GDALError AG.unsafe_gdalwarp([ds_small], ["-novalidoption"]) + end + + @testset "GDAL Info" begin + infostr = AG.gdalinfo(ds_small, ["-checksum"]) + @test occursin("Checksum=50054", infostr) + info_default = AG.gdalinfo(ds_small) + @test occursin("Driver: GTiff/GeoTIFF", info_default) + end + + ds_tiny = AG.unsafe_gdaltranslate(ds_small, # resample to a 5×5 ascii grid + ["-of","AAIGrid","-r","cubic","-tr","1200","1200"]) + @test typeof(ds_tiny) == AG.IDataset + @testset "GDAL Translate" begin + @test AG.read(ds_tiny, 1) == [128 171 127 93 83; + 126 164 148 114 101; + 161 175 177 164 140; + 185 206 205 172 128; + 193 205 209 181 122] + end + + @testset "GDAL Build VRT" begin + ds_vrt = AG.unsafe_gdalbuildvrt([ds_tiny]) + @test AG.read(ds_vrt, 1) == [128 171 127 93 83; + 126 164 148 114 101; + 161 175 177 164 140; + 185 206 205 172 128; + 193 205 209 181 122] + end + + @testset "GDAL DEM Processing" begin + ds_dempr = AG.unsafe_gdaldem(ds_tiny, "hillshade", ["-of","AAIGrid"]) + @test AG.read(ds_dempr, 1) == [ 0 0 0 0 0; + 0 183 180 181 0; + 0 184 182 181 0; + 0 183 181 177 0; + 0 0 0 0 0] + end + + @testset "GDAL Near Black" begin + ds_nearblack = AG.unsafe_gdalnearblack(ds_tiny, ["-of","GTiff","-color","0"]) + @test AG.read(ds_nearblack, 1) == [ 0 0 0 0 0; + 0 0 0 0 0; + 0 0 177 0 0; + 0 0 0 0 0; + 0 0 0 0 0] + end + + # cannot reproject file on AppVeyor yet + # GDALError (CE_Failure, code 4): + # Unable to open EPSG support file gcs.csv. Try setting the + # GDAL_DATA environment variable to point to the directory + # containing EPSG csv files. + # @testset "GDAL Warp" begin + # AG.gdalwarp([ds_small], ["-of","MEM","-t_srs","EPSG:4326"]) do ds_warped + # @test AG.width(ds_small) == 100 + # @test AG.height(ds_small) == 100 + # @test AG.width(ds_warped) == 109 + # @test AG.height(ds_warped) == 91 + # end + # end + @testset "GDAL Warp" begin + ds_warped = AG.unsafe_gdalwarp([ds_small], ["-of","MEM"]) + @test AG.width(ds_small) == 100 + @test AG.height(ds_small) == 100 + @test AG.shortname(AG.getdriver(ds_small)) == "GTiff" + @test AG.width(ds_warped) == 100 + @test AG.height(ds_warped) == 100 + @test AG.shortname(AG.getdriver(ds_warped)) == "MEM" + end +end \ No newline at end of file