123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*!
- * \file lib/raster/window_map.c
- *
- * \brief Raster Library - Window mapping functions.
- *
- * (C) 2001-2009 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public License
- * (>=v2). Read the file COPYING that comes with GRASS for details.
- *
- * \author Original author CERL
- */
- #include <stdlib.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include "R.h"
- #define alloc_index(n) (COLUMN_MAPPING *) G_malloc((n)*sizeof(COLUMN_MAPPING))
- /*!
- * \brief Create window mapping.
- *
- * Creates mapping from cell header into window. The boundaries and
- * resolution of the two spaces do not have to be the same or aligned in
- * any way.
- *
- * \param fd file descriptor
- */
- void Rast__create_window_mapping(int fd)
- {
- struct fileinfo *fcb = &R__.fileinfo[fd];
- COLUMN_MAPPING *col;
- int i;
- int x;
- double C1, C2;
- double west, east;
- if (fcb->open_mode >= 0 && fcb->open_mode != OPEN_OLD) /* open for write? */
- return;
- if (fcb->open_mode == OPEN_OLD) /* already open ? */
- G_free(fcb->col_map);
- col = fcb->col_map = alloc_index(R__.rd_window.cols);
- /*
- * for each column in the window, go to center of the cell,
- * compute nearest column in the data file
- * if column is not in data file, set column to 0
- *
- * for lat/lon move window so that west is bigger than
- * cellhd west.
- */
- west = R__.rd_window.west;
- east = R__.rd_window.east;
- if (R__.rd_window.proj == PROJECTION_LL) {
- while (west > fcb->cellhd.west + 360.0) {
- west -= 360.0;
- east -= 360.0;
- }
- while (west < fcb->cellhd.west) {
- west += 360.0;
- east += 360.0;
- }
- }
- C1 = R__.rd_window.ew_res / fcb->cellhd.ew_res;
- C2 = (west - fcb->cellhd.west +
- R__.rd_window.ew_res / 2.0) / fcb->cellhd.ew_res;
- for (i = 0; i < R__.rd_window.cols; i++) {
- x = C2;
- if (C2 < x) /* adjust for rounding of negatives */
- x--;
- if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
- x = -1;
- *col++ = x + 1;
- C2 += C1;
- }
- /* do wrap around for lat/lon */
- if (R__.rd_window.proj == PROJECTION_LL) {
-
- while (east - 360.0 > fcb->cellhd.west) {
- east -= 360.0;
- west -= 360.0;
- col = fcb->col_map;
- C2 = (west - fcb->cellhd.west +
- R__.rd_window.ew_res / 2.0) / fcb->cellhd.ew_res;
- for (i = 0; i < R__.rd_window.cols; i++) {
- x = C2;
- if (C2 < x) /* adjust for rounding of negatives */
- x--;
- if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
- x = -1;
- if (*col == 0) /* only change those not already set */
- *col = x + 1;
- col++;
- C2 += C1;
- }
- }
- }
- G_debug(3, "create window mapping (%d columns)", R__.rd_window.cols);
- /* for (i = 0; i < R__.rd_window.cols; i++)
- fprintf(stderr, "%s%ld", i % 15 ? " " : "\n", (long)fcb->col_map[i]);
- fprintf(stderr, "\n");
- */
- /* compute C1,C2 for row window mapping */
- fcb->C1 = R__.rd_window.ns_res / fcb->cellhd.ns_res;
- fcb->C2 =
- (fcb->cellhd.north - R__.rd_window.north +
- R__.rd_window.ns_res / 2.0) / fcb->cellhd.ns_res;
- }
- /*!
- * \brief Loops rows until mismatch?.
- *
- * This routine works fine if the mask is not set. It may give
- * incorrect results with a mask, since the mask row may have a
- * different repeat value. The issue can be fixed by doing it for the
- * mask as well and using the smaller value.
- *
- * \param fd file descriptor
- * \param row starting row
- *
- * \return number of rows completed
- */
- int Rast_row_repeat_nomask(int fd, int row)
- {
- struct fileinfo *fcb = &R__.fileinfo[fd];
- double f;
- int r1, r2;
- int count;
- count = 1;
- /* r1 is the row in the raster map itself.
- * r2 is the next row(s) in the raster map
- * see get_row.c for details on this calculation
- */
- f = row * fcb->C1 + fcb->C2;
- r1 = f;
- if (f < r1)
- r1--;
- while (++row < R__.rd_window.rows) {
- f = row * fcb->C1 + fcb->C2;
- r2 = f;
- if (f < r2)
- r2--;
- if (r1 != r2)
- break;
- count++;
- }
- return count;
- }
|