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