[GRASS-dev] How to read a raster cell value?

Hello again,
I hope this is an easy question:
I took this chunk of r.drain which reads single int CELL values given
a row and col:

    CELL direction;
    CELL *dir;

    dir = G_allocate_c_raster_buf();
    next_row = list->row;
    next_col = list->col;
...
  lseek(fd, (off_t) list->row * ncol * sizeof(CELL), SEEK_SET);
  read(fd, dir, ncol * sizeof(CELL));
  direction = *(dir + list->col);
  G_message(_("row:%i, col:%i, direction:%i"), next_row, next_col, direction);

And tried to replicate it for use with a double DCELL like this:

  int row, col, next_row, next_col;
  DCELL direction;
  DCELL *dir_buf;
  dir_buf = G_allocate_d_raster_buf();
  
  next_row = list->row;
  next_col = list->col;
  lseek(dir_fd, (off_t) list->row * ncol * sizeof(DCELL), SEEK_SET);
  read(dir_fd, dir_buf, ncol * sizeof(DCELL));
  direction = *(dir_buf + list->col);
  G_message(_("row:%i, col:%i, direction:%lf"), next_row, next_col, direction);

Somehow the top int section functions properly, while my modified
section for doubles does not (ie. it returns the wrong "direction"
value). I suspect it has something to do with the offset in lseek, but
I can't figure it out. Does it matter that the row and col are int,
while the value is double?

Is there an easier way to read a single cell value given that you know
the row and col?

Thanks,
-Colin

Colin Nielsen wrote:

I hope this is an easy question:
I took this chunk of r.drain which reads single int CELL values given
a row and col:

    CELL direction;
    CELL *dir;

    dir = G_allocate_c_raster_buf();
    next_row = list->row;
    next_col = list->col;
...
  lseek(fd, (off_t) list->row * ncol * sizeof(CELL), SEEK_SET);
  read(fd, dir, ncol * sizeof(CELL));
  direction = *(dir + list->col);
  G_message(_("row:%i, col:%i, direction:%i"), next_row, next_col, direction);

And tried to replicate it for use with a double DCELL like this:

  int row, col, next_row, next_col;
  DCELL direction;
  DCELL *dir_buf;
  dir_buf = G_allocate_d_raster_buf();
  
  next_row = list->row;
  next_col = list->col;
  lseek(dir_fd, (off_t) list->row * ncol * sizeof(DCELL), SEEK_SET);
  read(dir_fd, dir_buf, ncol * sizeof(DCELL));
  direction = *(dir_buf + list->col);
  G_message(_("row:%i, col:%i, direction:%lf"), next_row, next_col, direction);

Somehow the top int section functions properly, while my modified
section for doubles does not (ie. it returns the wrong "direction"
value). I suspect it has something to do with the offset in lseek, but
I can't figure it out.

Does the file actually contain doubles? If it doesn't, trying to read
doubles from the file isn't going to work.

Does it matter that the row and col are int, while the value is
double?

No.

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

As far as I can tell I have set the dir_fd file up to be full of double values:

      dir_buf = G_allocate_d_raster_buf();
        dir_id = G_open_cell_old(dir_name, dir_mapset);
      tempfile3 = G_tempfile();
    dir_fd = open(tempfile3, O_RDWR | O_CREAT);

      //cn: transfer dir input map to a temp file
      for (i = 0; i < nrows; i++) {
        G_get_d_raster_row(dir_id, dir_buf, i);
        //get_row(dir_id, dir_buf, i);
        write(dir_fd, dir_buf, sizeof(DCELL));
      }
      G_close_cell(dir_id);

Colin Nielsen wrote:

As far as I can tell I have set the dir_fd file up to be full of double values:

      for (i = 0; i < nrows; i++) {
        G_get_d_raster_row(dir_id, dir_buf, i);
        //get_row(dir_id, dir_buf, i);
        write(dir_fd, dir_buf, sizeof(DCELL));

You are writing *one* DCELL value for each row. That should probably
be something like:

         write(dir_fd, dir_buf, ncols * sizeof(DCELL));

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

Thank you so much Glynn, that fixed it exactly. I left out that
element when I converted from CELL to DCELL. Too bad I wasn't trying
to read data from the first column or I might have noticed.

-Colin

On Thu, Jun 26, 2008 at 7:30 PM, Glynn Clements
<glynn@gclements.plus.com> wrote:

Colin Nielsen wrote:

As far as I can tell I have set the dir_fd file up to be full of double values:

          for (i = 0; i < nrows; i++) {
              G_get_d_raster_row(dir_id, dir_buf, i);
              //get_row(dir_id, dir_buf, i);
              write(dir_fd, dir_buf, sizeof(DCELL));

You are writing *one* DCELL value for each row. That should probably
be something like:

               write(dir_fd, dir_buf, ncols * sizeof(DCELL));

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