GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
rd_cellhd.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/rd_cellhd.c
3
4 \brief GIS Library - Read cell header or window
5
6 (C) 1999-2011 by the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author USACERL and others
12*/
13
14#include <string.h>
15
16#include <grass/gis.h>
17#include <grass/glocale.h>
18
19#include "gis_local_proto.h"
20
21static int scan_item(const char *, char *, char *);
22static int scan_int(const char *, int *);
23static double scan_double(const char *, double *);
24
25#define F_PROJ 1
26#define F_ZONE 2
27#define F_NORTH 3
28#define F_SOUTH 4
29#define F_EAST 5
30#define F_WEST 6
31#define F_EWRES 7
32#define F_NSRES 8
33#define F_FORMAT 9
34#define F_COMP 10
35#define F_COLS 11
36#define F_ROWS 12
37
38#define F_EWRES3 13
39#define F_NSRES3 14
40#define F_COLS3 15
41#define F_ROWS3 16
42#define F_TOP 17
43#define F_BOTTOM 18
44#define F_TBRES 19
45#define F_DEPTHS 20
46
47#define SET(x) flags|=(1<<x)
48#define TEST(x) (flags&(1<<x))
49
50/*!
51 \brief Read cell header (for internal use only)
52
53 \param fp file descriptor
54 \param[out] cellhd pointer to Cell_head structure
55 \param is_cellhd ? (unused)
56*/
57void G__read_Cell_head(FILE * fd, struct Cell_head *cellhd, int is_cellhd)
58{
59 int count;
60 char **array;
61 char buf[1024];
62
63 G_debug(2, "G__read_Cell_head");
64
65 /* Count lines */
66 count = 0;
67 G_fseek(fd, 0L, 0);
68 while (G_getl(buf, sizeof(buf), fd))
69 count++;
70
71 array = (char **)G_calloc(count + 1, sizeof(char *));
72
73 count = 0;
74 G_fseek(fd, 0L, 0);
75 while (G_getl(buf, sizeof(buf), fd)) {
76 array[count] = G_store(buf);
77 count++;
78 }
79
80 G__read_Cell_head_array(array, cellhd, is_cellhd);
81
82 count = 0;
83 while (array[count]) {
84 G_free(array[count]);
85 count++;
86 }
87 G_free(array);
88}
89
90/*!
91 \brief Read window from NULL terminated array of strings (for internal use only)
92
93 \param array array of strings
94 \param[out] cellhd pointer to Cell_head structure
95 \param is_cellhd ? (unused)
96*/
97void G__read_Cell_head_array(char **array,
98 struct Cell_head *cellhd, int is_cellhd)
99{
100 char *buf;
101 char label[200];
102 char value[200];
103 int i, line;
104 int flags;
105
106 G_debug(2, "G__read_Cell_head_array");
107
108 flags = 0;
109
110 /* initialize the cell header */
111 cellhd->format = 0;
112 cellhd->rows = 0;
113 cellhd->rows3 = 0;
114 cellhd->cols = 0;
115 cellhd->cols3 = 0;
116 cellhd->depths = 1;
117 cellhd->proj = -1;
118 cellhd->zone = -1;
119 cellhd->compressed = -1;
120 cellhd->ew_res = 0.0;
121 cellhd->ew_res3 = 1.0;
122 cellhd->ns_res = 0.0;
123 cellhd->ns_res3 = 1.0;
124 cellhd->tb_res = 1.0;
125 cellhd->north = 0.0;
126 cellhd->south = 0.0;
127 cellhd->east = 0.0;
128 cellhd->west = 0.0;
129 cellhd->top = 1.0;
130 cellhd->bottom = 0.0;
131
132 /* determine projection, zone first */
133
134 i = 0;
135 for (line = 1; (buf = array[i++]); line++) {
136 if (TEST(F_PROJ) && TEST(F_ZONE))
137 break;
138
139 switch (scan_item(buf, label, value)) {
140 case -1:
141 G_fatal_error(_("Syntax error in cell header, line %d: %s"),
142 line, buf);
143 case 0:
144 continue;
145 case 1:
146 break;
147 }
148 if (strncmp(label, "proj", 4) == 0) {
149 if (TEST(F_PROJ))
150 G_fatal_error(_("Duplicate projection field"));
151
152 if (!scan_int(value, &cellhd->proj))
153 G_fatal_error(_("Invalid projection field: %s"), value);
154
155 SET(F_PROJ);
156 continue;
157 }
158 if (strncmp(label, "zone", 4) == 0) {
159 if (TEST(F_ZONE))
160 G_fatal_error(_("Duplicate zone field"));
161
162 if (!scan_int(value, &cellhd->zone))
163 G_fatal_error(_("Invalid zone field: %s"), value);
164
165 SET(F_ZONE);
166 continue;
167 }
168 }
169 if (!TEST(F_PROJ))
170 G_fatal_error(_("Field <%s> missing"), "projection");
171 if (!TEST(F_ZONE))
172 G_fatal_error(_("Field <%s> missing"), "zone");
173
174 /* read the other info */
175 i = 0;
176 for (line = 1; (buf = array[i++]); line++) {
177 G_debug(3, "region item: %s", buf);
178 switch (scan_item(buf, label, value)) {
179 case -1:
180 G_fatal_error(_("Syntax error in cell header, line %d: %s"),
181 line, buf);
182 case 0:
183 continue;
184 case 1:
185 break;
186 }
187
188 if (strncmp(label, "proj", 4) == 0)
189 continue;
190 if (strncmp(label, "zone", 4) == 0)
191 continue;
192
193 if (strncmp(label, "nort", 4) == 0) {
194 if (TEST(F_NORTH))
195 G_fatal_error(_("Duplicate north field"));
196 if (!G_scan_northing(value, &cellhd->north, cellhd->proj))
197 G_fatal_error(_("Invalid north field: %s"), value);
198 SET(F_NORTH);
199 continue;
200 }
201 if (strncmp(label, "sout", 4) == 0) {
202 if (TEST(F_SOUTH))
203 G_fatal_error(_("Duplicate south field"));
204 if (!G_scan_northing(value, &cellhd->south, cellhd->proj))
205 G_fatal_error(_("Invalid south field: %s"), value);
206 SET(F_SOUTH);
207 continue;
208 }
209 if (strncmp(label, "east", 4) == 0) {
210 if (TEST(F_EAST))
211 G_fatal_error(_("Duplicate east field"));
212 if (!G_scan_easting(value, &cellhd->east, cellhd->proj))
213 G_fatal_error(_("Invalid east field: %s"), value);
214 SET(F_EAST);
215 continue;
216 }
217 if (strncmp(label, "west", 4) == 0) {
218 if (TEST(F_WEST))
219 G_fatal_error(_("Duplicate west field"));
220 if (!G_scan_easting(value, &cellhd->west, cellhd->proj))
221 G_fatal_error(_("Invalid west field: %s"), value);
222 SET(F_WEST);
223 continue;
224 }
225 if (strncmp(label, "top", 3) == 0) {
226 if (TEST(F_TOP))
227 G_fatal_error(_("Duplicate top field"));
228 if (!scan_double(value, &cellhd->top))
229 G_fatal_error(_("Invalid top field: %s"), value);
230 SET(F_TOP);
231 continue;
232 }
233 if (strncmp(label, "bottom", 6) == 0) {
234 if (TEST(F_BOTTOM))
235 G_fatal_error(_("Duplicate bottom field"));
236 if (!scan_double(value, &cellhd->bottom))
237 G_fatal_error(_("Invalid bottom field: %s"), value);
238 SET(F_BOTTOM);
239 continue;
240 }
241 if (strncmp(label, "e-w ", 4) == 0 && strlen(label) == 9) {
242 if (TEST(F_EWRES))
243 G_fatal_error(_("Duplicate e-w resolution field"));
244 if (!G_scan_resolution(value, &cellhd->ew_res, cellhd->proj))
245 G_fatal_error(_("Invalid e-w resolution field: %s"), value);
246 if (cellhd->ew_res <= 0.0)
247 G_fatal_error(_("Invalid e-w resolution field: %s"), value);
248 SET(F_EWRES);
249 continue;
250 }
251 if (strncmp(label, "e-w resol3", 10) == 0) {
252 if (TEST(F_EWRES3))
253 G_fatal_error(_("Duplicate 3D e-w resolution field"));
254 if (!G_scan_resolution(value, &cellhd->ew_res3, cellhd->proj))
255 G_fatal_error(_("Invalid 3D e-w resolution field: %s"), value);
256 if (cellhd->ew_res3 <= 0.0)
257 G_fatal_error(_("Invalid 3D e-w resolution field: %s"), value);
258 SET(F_EWRES3);
259 continue;
260 }
261 if (strncmp(label, "n-s ", 4) == 0 && strlen(label) == 9) {
262 if (TEST(F_NSRES))
263 G_fatal_error(_("Duplicate n-s resolution field"));
264 if (!G_scan_resolution(value, &cellhd->ns_res, cellhd->proj))
265 G_fatal_error(_("Invalid n-s resolution field: %s"), value);
266 if (cellhd->ns_res <= 0.0)
267 G_fatal_error(_("Invalid n-s resolution field: %s"), value);
268 SET(F_NSRES);
269 continue;
270 }
271 if (strncmp(label, "n-s resol3", 10) == 0) {
272 if (TEST(F_NSRES3))
273 G_fatal_error(_("Duplicate 3D n-s resolution field"));
274 if (!G_scan_resolution(value, &cellhd->ns_res3, cellhd->proj))
275 G_fatal_error(_("Invalid 3D n-s resolution field: %s"), value);
276 if (cellhd->ns_res3 <= 0.0)
277 G_fatal_error(_("Invalid 3D n-s resolution field: %s"), value);
278 SET(F_NSRES3);
279 continue;
280 }
281 if (strncmp(label, "t-b ", 4) == 0) {
282 if (TEST(F_TBRES))
283 G_fatal_error(_("Duplicate t-b resolution field"));
284 if (!scan_double(value, &cellhd->tb_res))
285 G_fatal_error(_("Invalid t-b resolution field: %s"), value);
286 if (cellhd->tb_res <= 0.0)
287 G_fatal_error(_("Invalid t-b resolution field: %s"), value);
288 SET(F_TBRES);
289 continue;
290 }
291 if (strncmp(label, "rows", 4) == 0 && strlen(label) == 4) {
292 if (TEST(F_ROWS))
293 G_fatal_error(_("Duplicate rows field"));
294 if (!scan_int(value, &cellhd->rows))
295 G_fatal_error(_("Invalid rows field: %s"), value);
296 if (cellhd->rows <= 0)
297 G_fatal_error(_("Invalid rows field: %s"), value);
298 SET(F_ROWS);
299 continue;
300 }
301 if (strncmp(label, "rows3", 5) == 0) {
302 if (TEST(F_ROWS3))
303 G_fatal_error(_("Duplicate 3D rows field"));
304 if (!scan_int(value, &cellhd->rows3))
305 G_fatal_error(_("Invalid 3D rows field: %s"), value);
306 if (cellhd->rows3 <= 0)
307 G_fatal_error(_("Invalid 3D rows field: %s"), value);
308 SET(F_ROWS3);
309 continue;
310 }
311 if (strncmp(label, "cols", 4) == 0 && strlen(label) == 4) {
312 if (TEST(F_COLS))
313 G_fatal_error(_("Duplicate cols field"));
314 if (!scan_int(value, &cellhd->cols))
315 G_fatal_error(_("Invalid cols field: %s"), value);
316 if (cellhd->cols <= 0)
317 G_fatal_error(_("Invalid cols field: %s"), value);
318 SET(F_COLS);
319 continue;
320 }
321 if (strncmp(label, "cols3", 5) == 0) {
322 if (TEST(F_COLS3))
323 G_fatal_error(_("Duplicate 3D cols field"));
324 if (!scan_int(value, &cellhd->cols3))
325 G_fatal_error(_("Invalid 3D cols field: %s"), value);
326 if (cellhd->cols3 <= 0)
327 G_fatal_error(_("Invalid 3D cols field: %s"), value);
328 SET(F_COLS3);
329 continue;
330 }
331 if (strncmp(label, "depths", 6) == 0) {
332 if (TEST(F_DEPTHS))
333 G_fatal_error(_("Duplicate depths field"));
334 if (!scan_int(value, &cellhd->depths))
335 G_fatal_error(_("Invalid depths field: %s"), value);
336 if (cellhd->depths <= 0)
337 G_fatal_error(_("Invalid depths field: %s"), value);
338 SET(F_DEPTHS);
339 continue;
340 }
341 if (strncmp(label, "form", 4) == 0) {
342 if (TEST(F_FORMAT))
343 G_fatal_error(_("Duplicate format field"));
344 if (!scan_int(value, &cellhd->format))
345 G_fatal_error(_("Invalid format field: %s"), value);
346 SET(F_FORMAT);
347 continue;
348 }
349 if (strncmp(label, "comp", 4) == 0) {
350 if (TEST(F_COMP))
351 G_fatal_error(_("Duplicate compressed field"));
352 if (!scan_int(value, &cellhd->compressed))
353 G_fatal_error(_("Invalid compressed field: %s"), value);
354 SET(F_COMP);
355 continue;
356 }
357 G_fatal_error(_("Syntax error in cell header, line %d: %s"),
358 line, buf);
359 }
360
361 /* check some of the fields */
362 if (!TEST(F_NORTH))
363 G_fatal_error(_("Field <%s> missing"), "north");
364 if (!TEST(F_SOUTH))
365 G_fatal_error(_("Field <%s> missing"), "south");
366 if (!TEST(F_WEST))
367 G_fatal_error(_("Field <%s> missing"), "west");
368 if (!TEST(F_EAST))
369 G_fatal_error(_("Field <%s> missing"), "east");
370 if (!TEST(F_EWRES) && !TEST(F_COLS))
371 G_fatal_error(_("Field <%s> missing"), "cols");
372 if (!TEST(F_NSRES) && !TEST(F_ROWS))
373 G_fatal_error(_("Field <%s> missing"), "rows");
374 /* This next stmt is commented out to allow wr_cellhd.c to write
375 * headers that will be readable by GRASS 3.1
376 if ((TEST(F_ROWS) && TEST(F_NSRES))
377 || (TEST(F_COLS) && TEST(F_EWRES)))
378 ERROR ("row/col and resolution information can not both appear ",0);
379 */
380
381 /* 3D defined? */
382 if (TEST(F_EWRES3) || TEST(F_NSRES3) || TEST(F_COLS3) || TEST(F_ROWS3)) {
383 if (!TEST(F_EWRES3))
384 G_fatal_error(_("Field <%s> missing"), "ewres3");
385 if (!TEST(F_NSRES3))
386 G_fatal_error(_("Field <%s> missing"), "nsres3");
387 if (!TEST(F_COLS3))
388 G_fatal_error(_("Field <%s> missing"), "cols3");
389 if (!TEST(F_ROWS3))
390 G_fatal_error(_("Field <%s> missing"), "rows3");
391 }
392 else { /* use 2D */
393 cellhd->ew_res3 = cellhd->ew_res;
394 cellhd->ns_res3 = cellhd->ns_res;
395 cellhd->cols3 = cellhd->cols;
396 cellhd->rows3 = cellhd->rows;
397 }
398
399 /* Adjust and complete the cell header */
401}
402
403static int scan_item(const char *buf, char *label, char *value)
404{
405 /* skip blank lines */
406 if (sscanf(buf, "%1s", label) != 1)
407 return 0;
408
409 /* skip comment lines */
410 if (*label == '#')
411 return 0;
412
413 /* must be label: value */
414 if (sscanf(buf, "%[^:]:%[^\n]", label, value) != 2)
415 return -1;
416
417 G_strip(label);
418 G_strip(value);
419 return 1;
420}
421
422static int scan_int(const char *buf, int *n)
423{
424 char dummy[3];
425
426 *dummy = 0;
427 return (sscanf(buf, "%d%1s", n, dummy) == 1 && *dummy == 0);
428}
429
430static double scan_double(const char *buf, double *n)
431{
432 char dummy[3];
433
434 *dummy = 0;
435 return (sscanf(buf, "%lf%1s", n, dummy) == 1 && *dummy == 0);
436}
437
void G_adjust_Cell_head(struct Cell_head *cellhd, int row_flag, int col_flag)
Adjust cell header.
Definition: adj_cellhd.c:51
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
int G_getl(char *buf, int n, FILE *fd)
Gets a line of text from a file.
Definition: getl.c:31
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
void G_fseek(FILE *fp, off_t offset, int whence)
Change the file position of the stream.
Definition: gis/seek.c:50
int count
#define F_PROJ
Definition: rd_cellhd.c:25
#define F_ROWS3
Definition: rd_cellhd.c:41
#define F_NORTH
Definition: rd_cellhd.c:27
#define SET(x)
Definition: rd_cellhd.c:47
void G__read_Cell_head_array(char **array, struct Cell_head *cellhd, int is_cellhd)
Read window from NULL terminated array of strings (for internal use only)
Definition: rd_cellhd.c:97
#define F_TOP
Definition: rd_cellhd.c:42
#define F_EWRES3
Definition: rd_cellhd.c:38
#define F_NSRES3
Definition: rd_cellhd.c:39
#define TEST(x)
Definition: rd_cellhd.c:48
#define F_ROWS
Definition: rd_cellhd.c:36
#define F_SOUTH
Definition: rd_cellhd.c:28
#define F_EAST
Definition: rd_cellhd.c:29
#define F_FORMAT
Definition: rd_cellhd.c:33
#define F_COLS3
Definition: rd_cellhd.c:40
#define F_WEST
Definition: rd_cellhd.c:30
#define F_BOTTOM
Definition: rd_cellhd.c:43
#define F_NSRES
Definition: rd_cellhd.c:32
#define F_TBRES
Definition: rd_cellhd.c:44
#define F_DEPTHS
Definition: rd_cellhd.c:45
#define F_COMP
Definition: rd_cellhd.c:34
#define F_EWRES
Definition: rd_cellhd.c:31
#define F_ZONE
Definition: rd_cellhd.c:26
void G__read_Cell_head(FILE *fd, struct Cell_head *cellhd, int is_cellhd)
Read cell header (for internal use only)
Definition: rd_cellhd.c:57
#define F_COLS
Definition: rd_cellhd.c:35
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:87
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:300
int G_scan_resolution(const char *buf, double *res, int projection)
ASCII resolution to double.
Definition: wind_scan.c:100
int G_scan_northing(const char *buf, double *northing, int projection)
ASCII northing to double.
Definition: wind_scan.c:38
int G_scan_easting(const char *buf, double *easting, int projection)
ASCII easting to double.
Definition: wind_scan.c:69