5
* \brief GIS Library - Window mapping functions.
7
* (C) 2001-2008 by the GRASS Development Team
9
* This program is free software under the GNU General Public License
10
* (>=v2). Read the file COPYING that comes with GRASS for details.
12
* \author GRASS GIS Development Team
2
\file lib/gis/window_map.c
4
\brief GIS Library - Window mapping functions.
6
(C) 2001-2009, 2011 by the GRASS Development Team
8
This program is free software under the GNU General Public License
9
(>=v2). Read the file COPYING that comes with GRASS for details.
11
\author Original author CERL
18
14
#include <grass/gis.h>
22
#define alloc_index(n) (COLUMN_MAPPING *) G_malloc((n)*sizeof(COLUMN_MAPPING))
26
* \brief Create window mapping.
28
* Creates mapping from cell header into window. The boundaries and
29
* resolution of the two spaces do not have to be the same or aligned in
32
* \param[in] fd file descriptor
33
* \return always returns 0
36
int G__create_window_mapping(int fd)
38
struct fileinfo *fcb = &G__.fileinfo[fd];
47
if (fcb->open_mode >= 0 && fcb->open_mode != OPEN_OLD) /* open for write? */
49
if (fcb->open_mode == OPEN_OLD) /* already open ? */
52
col = fcb->col_map = alloc_index(G__.window.cols);
55
* for each column in the window, go to center of the cell,
56
* compute nearest column in the data file
57
* if column is not in data file, set column to 0
59
* for lat/lon move window so that west is bigger than
62
west = G__.window.west;
63
if (G__.window.proj == PROJECTION_LL) {
64
while (west > fcb->cellhd.west + 360.0)
66
while (west < fcb->cellhd.west)
70
C1 = G__.window.ew_res / fcb->cellhd.ew_res;
71
C2 = (west - fcb->cellhd.west +
72
G__.window.ew_res / 2.0) / fcb->cellhd.ew_res;
73
for (i = 0; i < G__.window.cols; i++) {
75
if (C2 < x) /* adjust for rounding of negatives */
77
if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
83
/* do wrap around for lat/lon */
84
if (G__.window.proj == PROJECTION_LL) {
86
C2 = (west - 360.0 - fcb->cellhd.west +
87
G__.window.ew_res / 2.0) / fcb->cellhd.ew_res;
88
for (i = 0; i < G__.window.cols; i++) {
90
if (C2 < x) /* adjust for rounding of negatives */
92
if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
94
if (*col == 0) /* only change those not already set */
101
G_debug(3, "create window mapping (%d columns)", G__.window.cols);
102
/* for (i = 0; i < G__.window.cols; i++)
103
fprintf(stderr, "%s%ld", i % 15 ? " " : "\n", (long)fcb->col_map[i]);
104
fprintf(stderr, "\n");
19
\brief Adjust east longitude.
21
This routine returns an equivalent <i>east</i> that is larger, but
22
no more than 360 larger than the <i>west</i> coordinate.
24
<b>Note:</b> This routine should be used only with
25
latitude-longitude coordinates.
27
\param east east coordinate
28
\param west west coordinate
30
\return east coordinate
107
/* compute C1,C2 for row window mapping */
108
fcb->C1 = G__.window.ns_res / fcb->cellhd.ns_res;
110
(fcb->cellhd.north - G__.window.north +
111
G__.window.ns_res / 2.0) / fcb->cellhd.ns_res;
118
* \brief Northing to row.
120
* Converts a <b>north</b>ing relative to a <b>window</b> to a row.<br>
121
* <b>Note:</b> The result is a double. Casting it to an integer will
122
* give the row number.
129
double G_northing_to_row(double north, const struct Cell_head *window)
131
return (window->north - north) / window->ns_res;
136
* \brief Adjust east longitude.
138
* This routine returns an equivalent <b>east</b> that is
139
* larger, but no more than 360 larger than the <b>west</b>
141
* <b>Note:</b> This routine should be used only with latitude-longitude
144
* \param[in,out] east
146
* \return east coordinate
149
32
double G_adjust_east_longitude(double east, double west)
151
34
while (east > west + 360.0)
161
* \brief Returns east larger than west.
163
* If the region projection is <i>PROJECTION_LL</i>, then this routine
164
* returns an equivalent <b>east</b> that is larger, but no more than
165
* 360 degrees larger, than the coordinate for the western edge of the
166
* region. Otherwise no adjustment is made and the original
167
* <b>east</b> is returned.
169
* \param[in,out] east
171
* \return east coordinate
43
\brief Returns east larger than west.
45
If the region projection is <tt>PROJECTION_LL</tt>, then this
46
routine returns an equivalent <i>east</i> that is larger, but no
47
more than 360 degrees larger, than the coordinate for the western
48
edge of the region. Otherwise no adjustment is made and the original
49
<i>east</i> is returned.
51
\param east east coordinate
52
\param window pointer to Cell_head
54
\return east coordinate
174
56
double G_adjust_easting(double east, const struct Cell_head *window)
176
58
if (window->proj == PROJECTION_LL) {
187
* \brief Easting to column.
189
* Converts <b>east</b> relative to a <b>window</b> to a column.<br>
190
* <b>Note:</b> The result is a <i>double</i>. Casting it to an
191
* <i>int</i> will give the column number.
198
double G_easting_to_col(double east, const struct Cell_head *window)
200
east = G_adjust_easting(east, window);
202
return (east - window->west) / window->ew_res;
207
* \brief Row to northing.
209
* Converts a <b>row</b> relative to a <b>window</b> to a
211
* <b>Note:</b> row is a double:
212
* - row+0.0 will return the northing for the northern edge of the row.<br>
213
* - row+0.5 will return the northing for the center of the row.<br>
214
* - row+1.0 will return the northing for the southern edge of the row.<br>
215
* <b>Note:</b> The result is a <i>double</i>. Casting it to an
216
* <i>int</i> will give the column number.
220
* \return north coordinate
223
double G_row_to_northing(double row, const struct Cell_head *window)
225
return window->north - row * window->ns_res;
230
* \brief Column to easting.
232
* Converts a <b>col</b> relative to a <b>window</b> to an easting.<br>
233
* <b>Note:</b> <b>col</b> is a <i>double</i>:<br>
234
* - col+0.0 will return the easting for the western edge of the column.<br>
235
* - col+0.5 will return the easting for the center of the column.<br>
236
* - col+1.0 will return the easting for the eastern edge of the column.<br>
240
* \return east coordinate
243
double G_col_to_easting(double col, const struct Cell_head *window)
245
return window->west + col * window->ew_res;
250
* \brief Number of rows in active window.
252
* This routine returns the number of rows in the active module window.
253
* Before raster files can be read or written, it is necessary to
254
* known how many rows are in the active window. For example:<br>
258
nrows = G_window_rows( );
259
ncols = G_window_cols( );
260
for (row = 0; row < nrows; row++)
263
for (col = 0; col < ncols; col++)
270
* \return number of rows
273
int G_window_rows(void)
277
return G__.window.rows;
282
* \brief Number of columns in active window.
285
* routines return the number of rows and columns (respectively) in the active
286
* module region. Before raster maps can be read or written, it is necessary to
287
* known how many rows and columns are in the active region. For example:<br>
291
nrows = G_window_rows( );
292
ncols = G_window_cols( );
293
for (row = 0; row < nrows; row++)
296
for (col = 0; col < ncols; col++)
303
* \return number of columns
306
int G_window_cols(void)
310
return G__.window.cols;
315
* \brief Initialize window.
317
* \return always returns 0
320
int G__init_window(void)
322
if (!G__.window_set) {
324
G_get_window(&G__.window);
332
* \brief Loops rows until mismatch?.
334
* This routine works fine if the mask is not set. It may give incorrect
335
* results with a mask, since the mask row may have a different repeat
336
* value. The issue can be fixed by doing it for the mask as well and
337
* using the smaller value.
339
* \param[in] fd file descriptor
340
* \param[in] row starting row
341
* \return number of rows completed
344
int G_row_repeat_nomask(int fd, int row)
346
struct fileinfo *fcb = &G__.fileinfo[fd];
353
/* r1 is the row in the raster map itself.
354
* r2 is the next row(s) in the raster map
355
* see get_row.c for details on this calculation
357
f = row * fcb->C1 + fcb->C2;
362
while (++row < G__.window.rows) {
363
f = row * fcb->C1 + fcb->C2;
68
\brief Initialize window (region).
70
void G__init_window(void)
72
if (G_is_initialized(&G__.window_set))
75
G_get_window(&G__.window);
77
G_initialize_done(&G__.window_set);