[gdal-dev] Re: a generic options facility for GDAL
Ivan Shmakov
ivan at theory.asu.ru
Thu Jan 24 16:10:45 EST 2008
* Preface
Here I'm posting a proof of concept patch implementing (a part
of) a generic options facility for GDAL. The goals of having
such a facility are as follows (see, e. g., [1, 2]):
* provide a generic way to obtain the information about a
specific dataset from a helper file, either distributed with
GDAL, or created by the user; (especially for the information
that cannot be obtained by any other means, or needs some
complex heuristics to be implemented by the driver);
* provide an easy to use API for an application developer to
pass the options to a GDAL driver;
* provide a way to specify options for the dataset by encoding
them within the dataset name.
Reaching the first goal will allow for some hard-coded defaults
and heuristics to be thrown away from the drivers' source and be
put into a helper file, thus easing the maintenance of the
driver and offering more flexibility to the user.
The last goal is so that the extra flexibility will be available
in a backward compatible way.
By no means the code or the interface below is of a production
quality. I explicitly state that it is not intended for
inclusion into the official GDAL source. The code is provided
so that the people interested in the problem could evaluate the
approach and (I hope) eventually come up with a solution
suitable for inclusion into GDAL.
The added code is in the public domain.
Use the code at your own risk.
* The interface
The interface currently implemented allows for the hierarchy of
options to be specified either with a helper file, or from the
command line. E. g.:
$ cat "$GDAL_OPTIONS_FILE"
{ match "^HDF4_EOS:EOS_GRID:.*:MOD_Grid_BRDF:Albedo\$" } {
options hdf4 { dims { iy 0 ix 1 iband 2 i4 3 } }
}
{ match "^HDF4_EOS:EOS_GRID:.*:MOD_Grid_BRDF:BRDF_Albedo_Parameters\$" } {
options hdf4 { dims { iy 0 ix 1 iband 2 i4 3 } }
}
$ file=2006-08-02-brdf-22-3/2006-08-02-brdf.1.hdf
$ dataset="HDF4_EOS:EOS_GRID:\"${file}\":MOD_Grid_BRDF:BRDF_Albedo_Parameters"
$ gdalinfo "${dataset}:OPTIONS:dict create hdf4 { dims { iy 0 ix 1 iband 2 i4 3 } }"
Driver: HDF4Image/HDF4 Dataset
Size is 1200, 1200
...
Band 1 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
Band 2 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
...
Band 29 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
Band 30 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
$
Either way the options specified are as follows:
hdf4
`-- dims
|-- iy => 0
|-- ix => 1
|-- iband => 2
`-- i4 => 3
The HDF4 driver fails to determine the meaning of the dimensions
when no options are specified:
$ gdalinfo "${dataset}"
Driver: HDF4Image/HDF4 Dataset
Size is 1200, 1200
...
Band 1 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
Band 2 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
...
Band 11999 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
Band 12000 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
$
The options support is currently added only to the HDF4 driver
and only the options in `dims' subspace (namely, `ix', `iy',
`iband' and `i4') are handled.
There're no substantial API to be described at the moment.
Please refer to the source if you need to know the details.
* The implementation
In order not to invent either a string representation or a
simple hierarchial database, I've chosen to use the facilities
provided by Tcl [3] -- the language notable for its ``everything
is a string'' concept. In particular, I've used the
``dictionaries'' facility [4] introduced in Tcl version 8.5.
Using of a programming language here also allows for different
strategies for the options processing to be easily evaluated.
In particular, the `GDAL_OPTIONS_FILE' support is currently
implemented in pure Tcl:
$ cat gdal-options.tcl
proc merge-in { args } {
global GDALdict
## .
set GDALdict [ uplevel \#0 { dict merge } [ list $GDALdict ] $args ]
}
proc match { regexp } {
global GDALinfo
## .
regexp -- $regexp $GDALinfo
}
proc options { args } {
## .
merge-in [ uplevel \#0 { dict create } $args ]
}
set varn env(GDAL_OPTIONS_FILE)
if { [ info exists $varn ]
&& [ file exists [ set $varn ] ] } {
set chan [ open [ set $varn ] "r" ]
foreach { condition body } [ read $chan ] {
if { [ uplevel \#0 $condition ] } {
uplevel \#0 $body
}
}
close $chan
}
## .
set GDALdict
$
In order to use such a file, the Tcl `source' [5] command may be
specified in the `:OPTIONS:' part, e. g. (provided that
`$GDAL_OPTIONS_FILE' points to a suitable file):
$ gdalinfo "${dataset}:OPTIONS:source gdal-options.tcl"
Driver: HDF4Image/HDF4 Dataset
Size is 1200, 1200
...
Band 1 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
Band 2 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
...
Band 29 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
Band 30 Block=1200x1 Type=Int16, ColorInterp=Gray
NoData Value=32767
$
Using both the helper file and the dataset name is also
possible, e. g.:
HDF4_EOS:EOS_GRID:"FILE.hdf":Foo_Grid:Bar_Field:OPTIONS:source gdal-options.tcl; options hdf4 { subspace { option-1 value-1 } }
[1] http://lists.osgeo.org/pipermail/gdal-dev/2007-November/014853.html
[2] http://lists.osgeo.org/pipermail/gdal-dev/2007-December/015343.html
[3] http://www.tcl.tk/
[4] http://www.tcl.tk/man/tcl8.5/TclCmd/dict.htm
[5] http://www.tcl.tk/man/tcl8.5/TclCmd/source.htm
The changes were made against SVN r13584. The short description
is as follows.
* patch #2 -- options support for the HDF4 driver
frmts/hdf4/hdf4imagedataset.cpp
(HDF4ImageDataset::go_dims): New member.
(HDF4ImageDataset::go_geoloc): Likewise.
(HDF4ImageDataset::HDF4ImageDataset): Initialize `go_dims' and
`go_geoloc' with a null pointer.
(HDF4ImageDataset::GetImageDimensions): Override guessing if the
dimensions indices were specified explicitly via the options.
(HDF4ImageDataset::Open): Initialize `go_dims' and `go_geoloc' using
the `options' field of the `GDALOpenInfo' object passed.
* patch #1 -- generic options facility, proof of concept
gcore/gdal_priv.h
(tcl8.5/tcl.h): Include it.
(struct gdal_options): New type.
(gdal_options_process_string): New function declaration.
(gdal_options_sub): Likewise.
(gdal_option_get): Likewise.
(gdal_option_put): Likewise.
(GDALOpenInfo::GDALOpenInfo): Allow for optional `go_override' argument.
(GDALOpenInfo::options): New member.
gcore/gdalopeninfo.cpp
(GDALOpenInfo::GDALOpenInfo): Added `go_override' argument; initialize
the `options' member; implemented `:OPTIONS:' handling.
(GDALOpenInfo::~GDALOpenInfo): Call `gdal_options_free' on `options'.
(assert.h): Include it.
(MALLOC_VAR): New macro.
(MALLOC_ARY): Likewise.
(tclobjs_from_strings): New function.
(tclobjs_decrement_refcount): Likewise.
(dict_get): Likewise.
(gdal_options_new): Likewise.
(gdal_options_free): Likewise.
(gdal_options_process_string): Likewise.
(gdal_options_sub): Likewise.
(gdal_option_get): Likewise.
(gdal_option_put): Likewise.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch-1.diff.gz
Type: text/x-diff
Size: 10430 bytes
Desc: patch #1 -- generic options facility, proof of concept
Url : http://lists.osgeo.org/pipermail/gdal-dev/attachments/20080125/b0aeda79/patch-1.diff-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch-2.diff.gz
Type: text/x-diff
Size: 4871 bytes
Desc: patch #2 -- options support for the HDF4 driver
Url : http://lists.osgeo.org/pipermail/gdal-dev/attachments/20080125/b0aeda79/patch-2.diff-0001.bin
More information about the gdal-dev
mailing list