[GRASS-dev] [grass-code P][372] scritps for converting raster maps into GRASS 7 format, and back

code P item #372, was opened at 2007-04-18 21:38
Status: Open
Priority: 1
Submitted By: Hamish Bowman (hamish)
Assigned to: Nobody (None)
Summary: scritps for converting raster maps into GRASS 7 format, and back
Patch status: postponed
Patch type: new
GRASS component: raster
GRASS version: None
GRASS CVS checkout date, if applies (YYMMDD):

Initial Comment:
r.convert and r.convert.all:

Converts a GRASS 4-6 raster map to a GRASS 7 raster map by moving files around in the $MAPSET.

Mostly untested, probably misses some bits.

I did not use g.message as I think it should be fully backwards-compatible with GRASS 5.0.0 and newer.

Tries to be really really cautious.

Hamish

----------------------------------------------------------------------

You can respond by visiting:
http://wald.intevation.org/tracker/?func=detail&atid=205&aid=372&group_id=21

Hello Hamish
Could it be written in C so it is more cross-platform? There is a new function G_copy_file() in CVS that can copy files on disk. There is also the C rename() function.

The script could still be available to work with older versions of GRASS.

Although I still don't think I like the idea of changing the internal raster format as I expect it will break lots of 3rd-party software that reads GRASS raster files directly, and could make GRASS look bad for changing things. E.g. thinking of the detailed discussion of the raster format a year or two ago for JavaGrass which reads it directly I think. Also even GDAL must be passed the path to the cellhd directory to read a GRASS raster I think? Also might it not be worth taking the opportunity to modernise the raster format further than just re-arranging the files, and perhaps providing some kind of LGPL library for developers of 3rd-party software to use to read GRASS rasters (actually that already exists I think - isn't it what GDAL uses?
http://freegis.org/cgi-bin/viewcvs.cgi/libgrass/ but don't think its used much.)

Sorry, just a few thoughts I've had for a while; wanted to get them out on the list.

Paul

On Wed, 18 Apr 2007 grass-codep@wald.intevation.org wrote:

code P item #372, was opened at 2007-04-18 21:38
Status: Open
Priority: 1
Submitted By: Hamish Bowman (hamish)
Assigned to: Nobody (None)
Summary: scritps for converting raster maps into GRASS 7 format, and back
Patch status: postponed
Patch type: new
GRASS component: raster
GRASS version: None
GRASS CVS checkout date, if applies (YYMMDD):

Initial Comment:
r.convert and r.convert.all:

Converts a GRASS 4-6 raster map to a GRASS 7 raster map by moving files around in the $MAPSET.

Mostly untested, probably misses some bits.

I did not use g.message as I think it should be fully backwards-compatible with GRASS 5.0.0 and newer.

Tries to be really really cautious.

Hamish

----------------------------------------------------------------------

You can respond by visiting:
http://wald.intevation.org/tracker/?func=detail&atid=205&aid=372&group_id=21

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I agree (for what is worth): changing format is reasonable only to
substantially improve things, not for minor cosmetics.
Ideally, switching to a more standard format (eg geoTIFF, or anything
read through gdal) would be good.
Has the grass7 format already been agreed upon?
All the best.
pc

Paul Kelly ha scritto:

Hello Hamish
Could it be written in C so it is more cross-platform? There is a new
function G_copy_file() in CVS that can copy files on disk. There is also
the C rename() function.

The script could still be available to work with older versions of GRASS.

Although I still don't think I like the idea of changing the internal
raster format as I expect it will break lots of 3rd-party software that
reads GRASS raster files directly, and could make GRASS look bad for
changing things. E.g. thinking of the detailed discussion of the raster
format a year or two ago for JavaGrass which reads it directly I think.
Also even GDAL must be passed the path to the cellhd directory to read a
GRASS raster I think? Also might it not be worth taking the opportunity
to modernise the raster format further than just re-arranging the files,
and perhaps providing some kind of LGPL library for developers of
3rd-party software to use to read GRASS rasters (actually that already
exists I think - isn't it what GDAL uses?
http://freegis.org/cgi-bin/viewcvs.cgi/libgrass/ but don't think its
used much.)

Sorry, just a few thoughts I've had for a while; wanted to get them out
on the list.

Paul

- --
Paolo Cavallini
http://www.faunalia.it/pc
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGJhAH/NedwLUzIr4RAtKLAKCBEuMKSIjLmI4tNYd0IzA99b2+FwCfbVDC
IsDhQSA3ZBdYkQ+dbTieFuo=
=3VJR
-----END PGP SIGNATURE-----

Paul Kelly wrote:

Although I still don't think I like the idea of changing the internal
raster format as I expect it will break lots of 3rd-party software that
reads GRASS raster files directly, and could make GRASS look bad for
changing things.

FWIW, I don't feel that the future of GRASS should be constrained by
whether or not third parties are willing to maintain compatibility.

E.g. thinking of the detailed discussion of the raster
format a year or two ago for JavaGrass which reads it directly I think.
Also even GDAL must be passed the path to the cellhd directory to read a
GRASS raster I think? Also might it not be worth taking the opportunity to
modernise the raster format further than just re-arranging the files, and
perhaps providing some kind of LGPL library for developers of 3rd-party
software to use to read GRASS rasters (actually that already exists I
think - isn't it what GDAL uses?
http://freegis.org/cgi-bin/viewcvs.cgi/libgrass/ but don't think its used
much.)

Actually, I've been thinking about hiving off the base raster format
to a separate library, along with generalising the low-level I/O to
allow for an "r.external" command, i.e. allow GRASS raster I/O to
directly read external files through GDAL.

The higher level stuff (rescaling, format conversion, reclassing, MASK
etc) would remain in GRASS.

The main issue is that some modules perform random access (i.e. don't
read the rows in top-to-bottom order), and not all raster formats can
support this efficiently (uncompressed formats such as BMP or raw-PPM
can, but anything which uses compression needs an index).

A related problem is that modules don't have to explicitly request
non-linear access at open time, so there's no simple way to identify
which modules would be affected.

--
Glynn Clements <glynn@gclements.plus.com>

Hi,

Am Mittwoch, 18. April 2007 17:59 schrieb Glynn Clements:

Paul Kelly wrote:
> Although I still don't think I like the idea of changing the internal
> raster format as I expect it will break lots of 3rd-party software that
> reads GRASS raster files directly, and could make GRASS look bad for
> changing things.

FWIW, I don't feel that the future of GRASS should be constrained by
whether or not third parties are willing to maintain compatibility.

> E.g. thinking of the detailed discussion of the raster
> format a year or two ago for JavaGrass which reads it directly I think.
> Also even GDAL must be passed the path to the cellhd directory to read a
> GRASS raster I think? Also might it not be worth taking the opportunity
> to modernise the raster format further than just re-arranging the files,
> and perhaps providing some kind of LGPL library for developers of
> 3rd-party software to use to read GRASS rasters (actually that already
> exists I think - isn't it what GDAL uses?
> http://freegis.org/cgi-bin/viewcvs.cgi/libgrass/ but don't think its used
> much.)

Actually, I've been thinking about hiving off the base raster format
to a separate library, along with generalising the low-level I/O to
allow for an "r.external" command, i.e. allow GRASS raster I/O to
directly read external files through GDAL.

The higher level stuff (rescaling, format conversion, reclassing, MASK
etc) would remain in GRASS.

That is an interesting approach. But we already have a very sophisticated
library in grass, which can be used for raster data management.
Im talking about the g3d library. IMHO this lib can be extended to support
raster maps.

The g3d lib supports state of the art data access.
I recently readed a terralib document
about handling raster data and noticed that the g3d library features are quite
progressive.

It supports:
* variable tile sizes
* direct uncached tile access
* cached random value access
** while random acces, the tiles which are accessed last are kept in the
   cache memory
** support of different data type sizes
* the directory structure is of type g3d/map_name/files

We should consider to extent this lib for internal usage. There is no problem
to add an abstraction layer to support external raster map implementations,
like the callback design in the display driver code.

Some kind of OO design would be great:

example:

typedef struct G2d_data {

  Data_source *map; /*g3d or what ever*/
  Metadata stuff .... ;

  /*value access member functions*/
  CELL (*get_c_value)(struct G2d_data*, int, int);
  FCELL (*get_f_value)(struct G2d_data*, int, int);
  ...
  void (*put_c_value)(struct G2d_data*, int, int, CELL);
  void (*put_f_value)(struct G2d_data*, int, int, FCELL);
...

  /*tile access meber functions*/
  CELL *(*get_c_row)(struct G2d_data*, int, int);
  CELL *(*get_c_tile)(struct G2d_data*, int, int);
  ...
  int (*put_tile)(struct G2d_data *, int, int);
  ...
} G2d_data;

The callback member functions are static functions like this:

G_put_c_value(G2d_data* map, int col, int row, CELL value);
and so on ...
And set while opening a raster data source.

A simple data acces should look like this:

{
G2d_data *data_source;
CELL value;

data_source = G_open_raster_data_source(name, type, ...);

value = data_source->get_c_value(data_source, 3, 4);
data_source->put_c_value(data_source, 3, 4, value);
}

I will upadte the gpde library with this kind of member function data access.
I hope we consider to extent the g3d lib and additionally add new metadata
handling and temporal data management.

Best regards
Soeren

The main issue is that some modules perform random access (i.e. don't
read the rows in top-to-bottom order), and not all raster formats can
support this efficiently (uncompressed formats such as BMP or raw-PPM
can, but anything which uses compression needs an index).

A related problem is that modules don't have to explicitly request
non-linear access at open time, so there's no simple way to identify
which modules would be affected.

Soeren Gebbert wrote:

> Actually, I've been thinking about hiving off the base raster format
> to a separate library, along with generalising the low-level I/O to
> allow for an "r.external" command, i.e. allow GRASS raster I/O to
> directly read external files through GDAL.
>
> The higher level stuff (rescaling, format conversion, reclassing, MASK
> etc) would remain in GRASS.

That is an interesting approach. But we already have a very sophisticated
library in grass, which can be used for raster data management.
Im talking about the g3d library. IMHO this lib can be extended to support
raster maps.

THe key point is that we need to preserve the G_get_raster_row() etc
interface.

Also, when downscaling, you ideally want to completely skip any rows
which aren't actually requested, rather than doing most of the work
then discarding unused data at the end.

The idea behind r.external is that it would require relatively modest
changes to the lowest levels of the raster I/O code (i.e. the parts
that read/write raw data to/from the cell/fcell files). The rest of
the I/O stack (and, most importantly, the API) would remain
unaffected.

BTW, one of the main priorities for the the G3D library should be to
enable LFS. I didn't touch it in my recent round of LFS changes
because the issues were too pervasive (e.g. the various offsets in the
G3D_Map structure).

--
Glynn Clements <glynn@gclements.plus.com>

Am Mittwoch, 18. April 2007 20:04 schrieb Glynn Clements:

Soeren Gebbert wrote:
> > Actually, I've been thinking about hiving off the base raster format
> > to a separate library, along with generalising the low-level I/O to
> > allow for an "r.external" command, i.e. allow GRASS raster I/O to
> > directly read external files through GDAL.
> >
> > The higher level stuff (rescaling, format conversion, reclassing, MASK
> > etc) would remain in GRASS.
>
> That is an interesting approach. But we already have a very sophisticated
> library in grass, which can be used for raster data management.
> Im talking about the g3d library. IMHO this lib can be extended to
> support raster maps.

THe key point is that we need to preserve the G_get_raster_row() etc
interface.

If we set the tile size to the size of one raster row, the tile functions
of the g3d library will show the behaviour of G_get_raster_row() without
skipping any kind of data. There is no need to skip existing API, we just need
to wrap the g3d lib calls:

First set the tile size when open a new map:

void *G_open_raster_new (const char *name, RASTER_MAP_TYPE type)
{
  struct Cell_head region2d;
  G3d_Region region3d;
  ...

  G3d_getWindow (&region3d);
  G_get_set_window(&region2d);

  G3d_regionFromToCellHead(&region2d, &region3d);
  region3d.depths = 1;
  region3d.top = 1;
  region3d.bottom = 0;
  region3d.tb_res = 1;

  return G3d_openCellNewParam(name, RASTER_MAP_TYPE, G3D_NO_CACHE, &region3d,
type, doLzw, doRle, precision, rows, 1, 1);
}

Now we can access the tiles:

int G_put_raster_row (void *map, void *rast, RASTER_MAP_TYPE data_type)
{
  return G3d_writeTile(map, row, rast, RASTER_MAP_TYPE );
}

int G_get_raster_row (void* map, void *rast, int row, RASTER_MAP_TYPE
data_type)
{
   return G3d_readTile(map, row, rast, RASTER_MAP_TYPE );
}

The API will change a bit because of the first argument of G_get_raster_row().

Also, when downscaling, you ideally want to completely skip any rows
which aren't actually requested, rather than doing most of the work
then discarding unused data at the end.

The idea behind r.external is that it would require relatively modest
changes to the lowest levels of the raster I/O code (i.e. the parts
that read/write raw data to/from the cell/fcell files). The rest of
the I/O stack (and, most importantly, the API) would remain
unaffected.

BTW, one of the main priorities for the the G3D library should be to
enable LFS. I didn't touch it in my recent round of LFS changes
because the issues were too pervasive (e.g. the various offsets in the
G3D_Map structure).

That's too bad, i have no clue how to enable LFS support. :frowning:

Best regards
Soeren

Paul Kelly wrote:

Could it be written in C so it is more cross-platform? There is a new
function G_copy_file() in CVS that can copy files on disk. There is
also the C rename() function.

I am sure it could, I'm just a lot more comfortable moving files around
in the shell. (mostly just ignorance of how to do it safely in C)

Perhaps Python would be a better compromise? (assuming it will be
required dependency for the GUI+1 anyway)

Although I still don't think I like the idea of changing the internal
raster format as I expect it will break lots of 3rd-party software
that reads GRASS raster files directly, and could make GRASS look bad
for changing things. E.g. thinking of the detailed discussion of the
raster format a year or two ago for JavaGrass which reads it directly
I think. Also even GDAL must be passed the path to the cellhd
directory to read a GRASS raster I think? Also might it not be worth
taking the opportunity to modernise the raster format further than
just re-arranging the files, and perhaps providing some kind of LGPL
library for developers of 3rd-party software to use to read GRASS
rasters (actually that already exists I think - isn't it what GDAL
uses? http://freegis.org/cgi-bin/viewcvs.cgi/libgrass/ but don't think
its used much.)

Of course we should try to minimize the change. My beef with the current
format is that it is hard to archive and copy maps easily, and is
generally not cosmetically pleasing. As it is only dir structure
changing it wouldn't so bad an update for the 3rd party authors to deal
with.

Sure we can and should help package a LGPL or MIT/X licensed reference
implementation data reader for 3rd parties. Probably aim for GDAL/OGR
first/only. I don't know enough about the nuts and bolts of the formats
to know if this could be done cleanly without having to use any GPL
code. Presumably the raster format could be done from CERL code (what
about FP and NULL, is that pre-GPL grass?) but the vector format is
surely GPL encumbered. Maybe Radim could be convinced to relicense any
needed parts written by him as LGPL?

If we contribute something new to GDAL I guess it should be MIT/X.
But that is more of an issue for a whole new binary format, not just
an internal rearrangement?

see also gdal-1.4.1/frmts/grass/

[I should revisit r.(un)pack to be more like this r.convert script +
.tar.gz instead of using r.*.mat. Shrug, I don't use that much- instead
I just make a new mapset, g.copy map@other,map then tar.gz the new
mapset]

Sorry, just a few thoughts I've had for a while; wanted to get them
out on the list.

Don't apologize -- I wrote the script to help get the ball rolling and
garner discussion. But if it is to happen, the format change should
happen as the first task of the GRASS 7 branch, IMO.

Paolo:

Has the grass7 format already been agreed upon?

No. Just ideas. see:
http://grass.gdf-hannover.de/wiki/Replacement_raster_format

Hamish

On 4/18/07 11:02 PM, "Hamish" <hamish_nospam@yahoo.com> wrote:

Perhaps Python would be a better compromise? (assuming it will be
required dependency for the GUI+1 anyway)

Unless there is a strong movement in another direction, this will be the
case.

The GUI development is moving along so well that we can drop TclTk
completely if we can get a wxPython equivalent for NVIZ. This is a lot of
work, of course, but wxPython development has moved at surprising speed once
we really started working on it. There is built in support for an OGL canvas
within wxPython once pyOpenGL is installed.

If Python becomes a required dependency, it opens up a lot of potential for
very sophisticated scripting.

Michael

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Hamish wrote:

Sure we can and should help package a LGPL or MIT/X licensed reference
implementation data reader for 3rd parties. Probably aim for GDAL/OGR
first/only. I don't know enough about the nuts and bolts of the formats
to know if this could be done cleanly without having to use any GPL
code. Presumably the raster format could be done from CERL code (what
about FP and NULL, is that pre-GPL grass?)

I think that FP/NULL are post-GPL. There have been several other
enhancements more recently, e.g. allowing 64-bit offsets on all
platforms, and allowing zlib compression for raster mapset.

--
Glynn Clements <glynn@gclements.plus.com>

Michael Barton wrote:

> Perhaps Python would be a better compromise? (assuming it will be
> required dependency for the GUI+1 anyway)

Unless there is a strong movement in another direction, this will be the
case.

The GUI development is moving along so well that we can drop TclTk
completely if we can get a wxPython equivalent for NVIZ. This is a lot of
work, of course, but wxPython development has moved at surprising speed once
we really started working on it. There is built in support for an OGL canvas
within wxPython once pyOpenGL is installed.

GLCanvas is part of wxPython itself:

  http://wxpython.wxcommunity.com/docs/api/wx.glcanvas.GLCanvas-class.html

You shouldn't need pyOpenGL unless you're planning on making OpenGL
calls from Python. The only parts of NVIZ which make OpenGL calls are
Togl and do_zoom.c. NVIZ is just a UI; all of the actual work is done
by the OGSF library.

--
Glynn Clements <glynn@gclements.plus.com>

When I tried the GLCanvas demo, it told me I needed to have pyOpenGL
installed. If we don't really need this, it makes things MUCH easier by
removing a group of additional dependencies.

Michael

On 4/19/07 9:08 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Michael Barton wrote:

Perhaps Python would be a better compromise? (assuming it will be
required dependency for the GUI+1 anyway)

Unless there is a strong movement in another direction, this will be the
case.

The GUI development is moving along so well that we can drop TclTk
completely if we can get a wxPython equivalent for NVIZ. This is a lot of
work, of course, but wxPython development has moved at surprising speed once
we really started working on it. There is built in support for an OGL canvas
within wxPython once pyOpenGL is installed.

GLCanvas is part of wxPython itself:

NameBright - Coming Soon

You shouldn't need pyOpenGL unless you're planning on making OpenGL
calls from Python. The only parts of NVIZ which make OpenGL calls are
Togl and do_zoom.c. NVIZ is just a UI; all of the actual work is done
by the OGSF library.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Michael Barton wrote:

When I tried the GLCanvas demo, it told me I needed to have pyOpenGL
installed. If we don't really need this, it makes things MUCH easier by
removing a group of additional dependencies.

The demo needs pyOpenGL so that it can draw stuff on the canvas.

NVIZ doesn't use OpenGL from Tcl. NVIZ itself (as opposed to the OGSF
library) only barely uses it at all: Togl, which is rougly analogous
to GLCanvas, and do_zoom.c, which sets up an off-screen "canvas". And
most of that is glX/wgl/agl rather than OpenGL proper.

--
Glynn Clements <glynn@gclements.plus.com>

That's great. So we are not stuck with **new** dependencies beyond Python
and wxPython. If we trade these for TclTk (as fond as I've become of it), I
think we'll come out ahead in the end.

Michael

On 4/19/07 10:28 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Michael Barton wrote:

When I tried the GLCanvas demo, it told me I needed to have pyOpenGL
installed. If we don't really need this, it makes things MUCH easier by
removing a group of additional dependencies.

The demo needs pyOpenGL so that it can draw stuff on the canvas.

NVIZ doesn't use OpenGL from Tcl. NVIZ itself (as opposed to the OGSF
library) only barely uses it at all: Togl, which is rougly analogous
to GLCanvas, and do_zoom.c, which sets up an off-screen "canvas". And
most of that is glX/wgl/agl rather than OpenGL proper.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

On 4/19/07 9:08 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

You shouldn't need pyOpenGL unless you're planning on making OpenGL
calls from Python. The only parts of NVIZ which make OpenGL calls are
Togl and do_zoom.c. NVIZ is just a UI; all of the actual work is done
by the OGSF library.

So we don't need pyOpenGL to replace Togl? Does the wxPython GLCanvas
replace Togl? Somehow we need to make calls from wxPython event handlers to
actually display/render a 3D image. I'm totally in the dark as to how this
is done. I've worked with the UI part of NVIZ (this is the overwhelmingly
greatest part, as you point out), but don't understand how the OGL calls are
actually made.

Michael

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Michael Barton wrote:

> You shouldn't need pyOpenGL unless you're planning on making OpenGL
> calls from Python. The only parts of NVIZ which make OpenGL calls are
> Togl and do_zoom.c. NVIZ is just a UI; all of the actual work is done
> by the OGSF library.

So we don't need pyOpenGL to replace Togl?

No.

Does the wxPython GLCanvas replace Togl?

Yes.

Somehow we need to make calls from wxPython event handlers to
actually display/render a 3D image. I'm totally in the dark as to how this
is done. I've worked with the UI part of NVIZ (this is the overwhelmingly
greatest part, as you point out), but don't understand how the OGL calls are
actually made.

OpenGL is called by OGSF (GS_*, gsd_* etc), which is called by the
various N_*_cmd() functions in the C part of NVIZ. These functions are
registered as Tcl commands, and the Tcl commands are called from the
various Tcl scripts.

In general, any Tcl command which begins with "N" (but not "Nv_"),
e.g. Ndraw_all, is implemented in C. Typically a Tcl command "Nfoo"
corresponds to the C function Nfoo_cmd(), although there are some
exceptions, e.g. Ndraw_all corresponds to Ndraw_all_together_cmd().

Some of the functions are little more than wrappers around individual
OGSF functions, which others (e.g. Ndraw_all) are more complex.

Most of the bindings are in src/init_commands.c; grep for
"Tcl_CreateCommand" in src/*.c for a complete list.

--
Glynn Clements <glynn@gclements.plus.com>