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