[R-sig-Geo] gdal error 1 (execution halted)
sj
saimon at student.ethz.ch
Mon Mar 17 00:15:26 CET 2008
Dear Roger
Thanks for your detailed reply.
>> I would like to use R from my bash console with the following
>> command:
>>
>> /path/to/R --vanilla --slave --args < /data/myscript.R
>>
>> this script invokes a range of functions and tools, among others to
>> process a bunch of raster images in a loop using GDAL. The thing
>> is that
>> releasing this command in the bash results in the following error:
>
> The possibilities are almost endless. Without having any idea of the
> classes of the arguments to your function, it is hard to know why the
> object passed to writeGDAL() may be corrupt.
>
> Only write a script when you have a good practical understanding of
> all
> the steps you are taking. Your script indicates that this is not
> the case.
> You have not even explained that what you seem to be trying to do
> is to
> take a SpatialGridDataFrame with one column, and to convert it into a
> four-column SpatialGridDataFrame with red, green, blue, and alpha
> columns,
> based on a classification of the input variable given in a numeric
> vector
> breaks.
Yes, the description of what the script intends to do is missing.
Sorry, my fault. Your description of the script is correct. And yes,
it was the first time I did anything with GDAL.
>> ERROR:
>> *************************************
>>
>> Error in GDAL.close(tds.out) :
>> GDAL Error 1: TIFFReadDirectory:/tmp/RtmpBgrSyt/file2ef6a5b2:
>> cannot handle zero scanline size
>> Calls: plot.georef -> GDAL.close -> .Call
>> Execution halted
The weird thing is, that the script works as expected if called
interactively from the R console. It gives the same error, but the
resulting TIFF images are ok. The execution is only halted if R is
called from the command line (with the script name as argument).
>> CODE:
>> *************************************
>>
>> plot.georef=function(grid.sp,graph.file,col.palette,breaks){
>
> grid.sp is what? A SpatialGridDataFrame?
Yes, this SpatialGridDataFrame results from an interpolated
temperature field. writeAsciiGrid(grid.sp,asc.file) results in the
expected text file with a correct georef.
> str(grid.sp)
Formal class 'SpatialGridDataFrame' [package "sp"] with 6 slots
..@ data :'data.frame': 84000 obs. of 2 variables:
.. ..$ temperature_mean.pred: num [1:84000] 5.4 5.4 5.4 5.4 5.5
5.5 5.5 5.5 5.5 5.5 ...
.. ..$ temperature_mean.var : num [1:84000] NA NA NA NA NA NA NA
NA NA NA ...
..@ grid :Formal class 'GridTopology' [package "sp"] with 3
slots
.. .. ..@ cellcentre.offset: Named num [1:2] 655050 278050
.. .. .. ..- attr(*, "names")= chr [1:2] "x_coord" "y_coord"
.. .. ..@ cellsize : Named num [1:2] 100 100
.. .. .. ..- attr(*, "names")= chr [1:2] "x_coord" "y_coord"
.. .. ..@ cells.dim : Named int [1:2] 350 240
.. .. .. ..- attr(*, "names")= chr [1:2] "x_coord" "y_coord"
..@ grid.index : int(0)
..@ coords : num [1:2, 1:2] 655050 689950 278050 301950
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : NULL
.. .. ..$ : chr [1:2] "x_coord" "y_coord"
..@ bbox : num [1:2, 1:2] 655000 278000 690000 302000
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "x_coord" "y_coord"
.. .. ..$ : chr [1:2] "min" "max"
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slots
.. .. ..@ projargs: chr "+init=world:CH1903"
> graph.file is what? A file name - single element character vector?
> str(graph.file)
chr "/data/graph_output/temp_205_100m_2008031117.tiff"
> col.palette is what? A character vector?
> str(col.palette)
chr [1:26] "#97FF02" "#5BFA05" "#00C632" "#17D9ED" "#28CCEE" ...
> breaks is what? A numeric vector?
> str(breaks)
num [1:27] -100 -18 -16 -14 -12 -10 -8 -6 -4 -2 ...
>> # get desired picture type
>> base.name=strsplit(graph.file,"/")[[1]][length(strsplit
>> (graph.file,"/")[[1]])]
>
> Do you know that base.name is what you think it is? Did you
> consider using
> the basename() function?
Yes, basename() should be used. The above is a relict from an old
script, and does the same as basename().
>> ft=0
>> ft=sum(c(ft,grep(".tiff",base.name)))
>
> See ?grep - "." means something.
>
>> if (ft==1){ file.typ="TIFF" }
>> ft=0
>> ft=sum(c(ft,grep(".jpg",base.name)))
>> if (ft==1){ file.typ="JPG" }
>> ft=0
>> ft=sum(c(ft,grep(".png",base.name)))
>> if (ft==1){ file.typ="PNG" }
This part of the script actually works without problems. I know that
the determination of the file type from the given file name is not
done in a very elaborate way. Any suggestions?
>> # create RGB bands
>> names(grid.sp)=c("band1","band2")
>
> How many columns did grid.sp have when it came into the function,
> do you
> know that there were two? If not, this will not create them.
Yes, it always has two.
>> grid.sp$band3=grid.sp$band2
>> grid.sp$band4=grid.sp$band2
>
> If band2 wasn't created above, this won't create band3 or band4.
Yes, but as band2 is always present, this is not an issue.
>> col.class=as.vector(cut(grid.sp$band1,br = breaks,
>> labels=col.palette))
>
> Curious use of cut:
>
> col.class <- col.palette[findInterval(grid.sp$band1, vec=breaks,
> all.inside=TRUE)]
>
> seems more natural, and avoids creating a factor (which is what cut
> () is
> for).
I'll keep this in mind. But doesn't findInterval() need sorted input?
For this specific problem I would now use vec2RGB as suggested below.
>> col.class[is.na(col.class)]="#FFFFFF"
>
> Do you know how many are NAs?
No, this differs for the individual cases.
>> col.class.rgb=col2rgb(col.class)
>
> Assuming that you have full control of col.class, this should work.
It does:
> str(col.class.rgb)
int [1:3, 1:84000] 214 226 238 214 226 238 214 226 238 214 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:3] "red" "green" "blue"
..$ : NULL
>> grid.sp$band1=col.class.rgb["red",]
>
> Here you are overwriting the input object - do you need to?
> Wouldn't it be
> cleaner to start a fresh object?
As I do not need the data from the input object any more, I tried to
save memory by reusing this object (as these can become fairly
large). Could this be done better in a different way?
>> grid.sp$band2=col.class.rgb["green",]
>> grid.sp$band3=col.class.rgb["blue",]
>> grid.sp$band4[]=256
>
> Should the alpha band run 0-255 or 1-256? col2rgb() uses 0-255 (and
> can
> also add an alpha column).
I actually determined 256 by trial and error (the alpha channel
option from col2rgb() gives 255). With 256, writeGDAL() produced an
image with a transparent alpha channel. Assumed that the higher
number represents complete transparency.
The script results in the following SpatialGridDataFrame:
> str(grid.sp)
Formal class 'SpatialGridDataFrame' [package "sp"] with 6 slots
..@ data :'data.frame': 84000 obs. of 4 variables:
.. ..$ band1: int [1:84000] 214 214 214 214 214 214 214 214 214
214 ...
.. ..$ band2: int [1:84000] 226 226 226 226 226 226 226 226 226
226 ...
.. ..$ band3: int [1:84000] 238 238 238 238 238 238 238 238 238
238 ...
.. ..$ band4: num [1:84000] 256 256 256 256 256 256 256 256 256
256 ...
..@ grid :Formal class 'GridTopology' [package "sp"] with 3
slots
.. .. ..@ cellcentre.offset: Named num [1:2] 655050 278050
.. .. .. ..- attr(*, "names")= chr [1:2] "x_coord" "y_coord"
.. .. ..@ cellsize : Named num [1:2] 100 100
.. .. .. ..- attr(*, "names")= chr [1:2] "x_coord" "y_coord"
.. .. ..@ cells.dim : Named int [1:2] 350 240
.. .. .. ..- attr(*, "names")= chr [1:2] "x_coord" "y_coord"
..@ grid.index : int(0)
..@ coords : num [1:2, 1:2] 655050 689950 278050 301950
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : NULL
.. .. ..$ : chr [1:2] "x_coord" "y_coord"
..@ bbox : num [1:2, 1:2] 655000 278000 690000 302000
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "x_coord" "y_coord"
.. .. ..$ : chr [1:2] "min" "max"
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slots
.. .. ..@ projargs: chr "+init=world:CH1903"
>> #writeGDAL(grid.sp, graph.file,drivername = "GTiff",type =
>> "band",options="ALPHA=YES")
>
> The two versions are equivalent.
I know. I first suspected the error in writeGDAL() and therefore
tried to achieve the same result by directly using the "underlying"
function.
> Most likely, the cause of your problems
> is type = "band", which is not a valid type, being passed to
> underlying
> GDAL functions as "Unknown". My guess would be that you mean "Byte".
>
> The full list of GDAL data types is on www.gdal.org (down now for
> me, so
> no specific link), and from the R prompt as:
>
> rgdal:::.GDALDataTypes
That's the one! When I checked out writeGDAL I obviously
misinterpreted the type option. As it worked from the command line, I
did not suspect this option to be wrong.
> Finally, wouldn't it be easier to use the vec2RGB() function in
> rgdal, see
> the example using the meuse.grid data set at the foot of the
> example on
> the help page?
Yes, could be used instead of the "misused" cut (gives the same
result). Another reinvention from my side ...
Thanks a lot for your help and time.
Best regards,
Simon
More information about the R-sig-Geo
mailing list