GRASS Programmer's Manual
6.4.1(2011)
|
00001 /* read cell header, or window. 00002 returns NULL if ok, error message otherwise 00003 note: the error message can be freed using G_free (). 00004 */ 00005 00006 #include <grass/gis.h> 00007 #include <grass/glocale.h> 00008 #include <string.h> 00009 00010 #define ERROR(x,line) return error(x,line) 00011 static int scan_item(const char *, char *, char *); 00012 static int scan_int(const char *, int *); 00013 static double scan_double(const char *, double *); 00014 static char *error(const char *, int); 00015 00016 #define F_PROJ 1 00017 #define F_ZONE 2 00018 #define F_NORTH 3 00019 #define F_SOUTH 4 00020 #define F_EAST 5 00021 #define F_WEST 6 00022 #define F_EWRES 7 00023 #define F_NSRES 8 00024 #define F_FORMAT 9 00025 #define F_COMP 10 00026 #define F_COLS 11 00027 #define F_ROWS 12 00028 00029 #define F_EWRES3 13 00030 #define F_NSRES3 14 00031 #define F_COLS3 15 00032 #define F_ROWS3 16 00033 #define F_TOP 17 00034 #define F_BOTTOM 18 00035 #define F_TBRES 19 00036 #define F_DEPTHS 20 00037 00038 #define SET(x) flags|=(1<<x) 00039 #define TEST(x) (flags&(1<<x)) 00040 00041 char *G__read_Cell_head_array(char **array, 00042 struct Cell_head *cellhd, int is_cellhd); 00043 00044 char *G__read_Cell_head(FILE * fd, struct Cell_head *cellhd, int is_cellhd) 00045 { 00046 int count; 00047 char *result, **array; 00048 char buf[1024]; 00049 00050 G_debug(2, "G__read_Cell_head"); 00051 00052 /* Count lines */ 00053 count = 0; 00054 fseek(fd, 0L, 0); 00055 while (G_getl(buf, sizeof(buf), fd)) 00056 count++; 00057 00058 array = (char **)G_calloc(count + 1, sizeof(char **)); 00059 00060 count = 0; 00061 fseek(fd, 0L, 0); 00062 while (G_getl(buf, sizeof(buf), fd)) { 00063 array[count] = G_store(buf); 00064 count++; 00065 } 00066 00067 result = G__read_Cell_head_array(array, cellhd, is_cellhd); 00068 00069 count = 0; 00070 while (array[count]) { 00071 G_free(array[count]); 00072 count++; 00073 } 00074 G_free(array); 00075 00076 return result; 00077 } 00078 00079 /* Read window from NULL terminated array of strings */ 00080 char *G__read_Cell_head_array(char **array, 00081 struct Cell_head *cellhd, int is_cellhd) 00082 { 00083 char *buf; 00084 char label[200]; 00085 char value[200]; 00086 int i, line; 00087 int flags; 00088 char *G_adjust_Cell_head(); 00089 char *err; 00090 00091 G_debug(2, "G__read_Cell_head_array"); 00092 00093 flags = 0; 00094 00095 /* initialize the cell header */ 00096 cellhd->format = 0; 00097 cellhd->rows = 0; 00098 cellhd->rows3 = 0; 00099 cellhd->cols = 0; 00100 cellhd->cols3 = 0; 00101 cellhd->depths = 1; 00102 cellhd->proj = -1; 00103 cellhd->zone = -1; 00104 cellhd->compressed = -1; 00105 cellhd->ew_res = 0.0; 00106 cellhd->ew_res3 = 1.0; 00107 cellhd->ns_res = 0.0; 00108 cellhd->ns_res3 = 1.0; 00109 cellhd->tb_res = 1.0; 00110 cellhd->north = 0.0; 00111 cellhd->south = 0.0; 00112 cellhd->east = 0.0; 00113 cellhd->west = 0.0; 00114 cellhd->top = 1.0; 00115 cellhd->bottom = 0.0; 00116 00117 /* determine projection, zone first */ 00118 00119 i = 0; 00120 for (line = 1; (buf = array[i++]); line++) { 00121 if (TEST(F_PROJ) && TEST(F_ZONE)) 00122 break; 00123 00124 switch (scan_item(buf, label, value)) { 00125 case -1: 00126 ERROR(buf, line); 00127 case 0: 00128 continue; 00129 case 1: 00130 break; 00131 } 00132 if (strncmp(label, "proj", 4) == 0) { 00133 if (TEST(F_PROJ)) 00134 ERROR(_("duplicate projection field"), line); 00135 00136 if (!scan_int(value, &cellhd->proj)) 00137 ERROR(buf, line); 00138 00139 SET(F_PROJ); 00140 continue; 00141 } 00142 if (strncmp(label, "zone", 4) == 0) { 00143 if (TEST(F_ZONE)) 00144 ERROR(_("duplicate zone field"), line); 00145 00146 if (!scan_int(value, &cellhd->zone)) 00147 ERROR(buf, line); 00148 00149 SET(F_ZONE); 00150 continue; 00151 } 00152 } 00153 if (!TEST(F_PROJ)) 00154 ERROR(_("projection field missing"), 0); 00155 if (!TEST(F_ZONE)) 00156 ERROR(_("zone field missing"), 0); 00157 00158 /* read the other info */ 00159 i = 0; 00160 for (line = 1; (buf = array[i++]); line++) { 00161 G_debug(3, "region item: %s", buf); 00162 switch (scan_item(buf, label, value)) { 00163 case -1: 00164 ERROR(buf, line); 00165 case 0: 00166 continue; 00167 case 1: 00168 break; 00169 } 00170 00171 if (strncmp(label, "proj", 4) == 0) 00172 continue; 00173 if (strncmp(label, "zone", 4) == 0) 00174 continue; 00175 00176 if (strncmp(label, "nort", 4) == 0) { 00177 if (TEST(F_NORTH)) 00178 ERROR(_("duplicate north field"), line); 00179 if (!G_scan_northing(value, &cellhd->north, cellhd->proj)) 00180 ERROR(buf, line); 00181 SET(F_NORTH); 00182 continue; 00183 } 00184 if (strncmp(label, "sout", 4) == 0) { 00185 if (TEST(F_SOUTH)) 00186 ERROR(_("duplicate south field"), line); 00187 if (!G_scan_northing(value, &cellhd->south, cellhd->proj)) 00188 ERROR(buf, line); 00189 SET(F_SOUTH); 00190 continue; 00191 } 00192 if (strncmp(label, "east", 4) == 0) { 00193 if (TEST(F_EAST)) 00194 ERROR(_("duplicate east field"), line); 00195 if (!G_scan_easting(value, &cellhd->east, cellhd->proj)) 00196 ERROR(buf, line); 00197 SET(F_EAST); 00198 continue; 00199 } 00200 if (strncmp(label, "west", 4) == 0) { 00201 if (TEST(F_WEST)) 00202 ERROR(_("duplicate west field"), line); 00203 if (!G_scan_easting(value, &cellhd->west, cellhd->proj)) 00204 ERROR(buf, line); 00205 SET(F_WEST); 00206 continue; 00207 } 00208 if (strncmp(label, "top", 3) == 0) { 00209 if (TEST(F_TOP)) 00210 ERROR(_("duplicate top field"), line); 00211 if (!scan_double(value, &cellhd->top)) 00212 ERROR(buf, line); 00213 SET(F_TOP); 00214 continue; 00215 } 00216 if (strncmp(label, "bottom", 6) == 0) { 00217 if (TEST(F_BOTTOM)) 00218 ERROR(_("duplicate bottom field"), line); 00219 if (!scan_double(value, &cellhd->bottom)) 00220 ERROR(buf, line); 00221 SET(F_BOTTOM); 00222 continue; 00223 } 00224 if (strncmp(label, "e-w ", 4) == 0 && strlen(label) == 9) { 00225 if (TEST(F_EWRES)) 00226 ERROR(_("duplicate e-w resolution field"), line); 00227 if (!G_scan_resolution(value, &cellhd->ew_res, cellhd->proj)) 00228 ERROR(buf, line); 00229 if (cellhd->ew_res <= 0.0) 00230 ERROR(buf, line); 00231 SET(F_EWRES); 00232 continue; 00233 } 00234 if (strncmp(label, "e-w resol3", 10) == 0) { 00235 if (TEST(F_EWRES3)) 00236 ERROR(_("duplicate 3D e-w resolution field"), line); 00237 if (!G_scan_resolution(value, &cellhd->ew_res3, cellhd->proj)) 00238 ERROR(buf, line); 00239 if (cellhd->ew_res3 <= 0.0) 00240 ERROR(buf, line); 00241 SET(F_EWRES3); 00242 continue; 00243 } 00244 if (strncmp(label, "n-s ", 4) == 0 && strlen(label) == 9) { 00245 if (TEST(F_NSRES)) 00246 ERROR(_("duplicate n-s resolution field"), line); 00247 if (!G_scan_resolution(value, &cellhd->ns_res, cellhd->proj)) 00248 ERROR(buf, line); 00249 if (cellhd->ns_res <= 0.0) 00250 ERROR(buf, line); 00251 SET(F_NSRES); 00252 continue; 00253 } 00254 if (strncmp(label, "n-s resol3", 10) == 0) { 00255 if (TEST(F_NSRES3)) 00256 ERROR(_("duplicate 3D n-s resolution field"), line); 00257 if (!G_scan_resolution(value, &cellhd->ns_res3, cellhd->proj)) 00258 ERROR(buf, line); 00259 if (cellhd->ns_res3 <= 0.0) 00260 ERROR(buf, line); 00261 SET(F_NSRES3); 00262 continue; 00263 } 00264 if (strncmp(label, "t-b ", 4) == 0) { 00265 if (TEST(F_TBRES)) 00266 ERROR(_("duplicate t-b resolution field"), line); 00267 if (!scan_double(value, &cellhd->tb_res)) 00268 ERROR(buf, line); 00269 if (cellhd->tb_res <= 0.0) 00270 ERROR(buf, line); 00271 SET(F_TBRES); 00272 continue; 00273 } 00274 if (strncmp(label, "rows", 4) == 0 && strlen(label) == 4) { 00275 if (TEST(F_ROWS)) 00276 ERROR(_("duplicate rows field"), line); 00277 if (!scan_int(value, &cellhd->rows)) 00278 ERROR(buf, line); 00279 if (cellhd->rows <= 0) 00280 ERROR(buf, line); 00281 SET(F_ROWS); 00282 continue; 00283 } 00284 if (strncmp(label, "rows3", 5) == 0) { 00285 if (TEST(F_ROWS3)) 00286 ERROR(_("duplicate 3D rows field"), line); 00287 if (!scan_int(value, &cellhd->rows3)) 00288 ERROR(buf, line); 00289 if (cellhd->rows3 <= 0) 00290 ERROR(buf, line); 00291 SET(F_ROWS3); 00292 continue; 00293 } 00294 if (strncmp(label, "cols", 4) == 0 && strlen(label) == 4) { 00295 if (TEST(F_COLS)) 00296 ERROR(_("duplicate cols field"), line); 00297 if (!scan_int(value, &cellhd->cols)) 00298 ERROR(buf, line); 00299 if (cellhd->cols <= 0) 00300 ERROR(buf, line); 00301 SET(F_COLS); 00302 continue; 00303 } 00304 if (strncmp(label, "cols3", 5) == 0) { 00305 if (TEST(F_COLS3)) 00306 ERROR(_("duplicate 3D cols field"), line); 00307 if (!scan_int(value, &cellhd->cols3)) 00308 ERROR(buf, line); 00309 if (cellhd->cols3 <= 0) 00310 ERROR(buf, line); 00311 SET(F_COLS3); 00312 continue; 00313 } 00314 if (strncmp(label, "depths", 6) == 0) { 00315 if (TEST(F_DEPTHS)) 00316 ERROR(_("duplicate depths field"), line); 00317 if (!scan_int(value, &cellhd->depths)) 00318 ERROR(buf, line); 00319 if (cellhd->depths <= 0) 00320 ERROR(buf, line); 00321 SET(F_DEPTHS); 00322 continue; 00323 } 00324 if (strncmp(label, "form", 4) == 0) { 00325 if (TEST(F_FORMAT)) 00326 ERROR(_("duplicate format field"), line); 00327 if (!scan_int(value, &cellhd->format)) 00328 ERROR(buf, line); 00329 SET(F_FORMAT); 00330 continue; 00331 } 00332 if (strncmp(label, "comp", 4) == 0) { 00333 if (TEST(F_COMP)) 00334 ERROR(_("duplicate compressed field"), line); 00335 if (!scan_int(value, &cellhd->compressed)) 00336 ERROR(buf, line); 00337 SET(F_COMP); 00338 continue; 00339 } 00340 ERROR(buf, line); 00341 } 00342 00343 /* check some of the fields */ 00344 if (!TEST(F_NORTH)) 00345 ERROR(_("north field missing"), 0); 00346 if (!TEST(F_SOUTH)) 00347 ERROR(_("south field missing"), 0); 00348 if (!TEST(F_WEST)) 00349 ERROR(_("west field missing"), 0); 00350 if (!TEST(F_EAST)) 00351 ERROR(_("east field missing"), 0); 00352 if (!TEST(F_EWRES) && !TEST(F_COLS)) 00353 ERROR(_("cols field missing"), 0); 00354 if (!TEST(F_NSRES) && !TEST(F_ROWS)) 00355 ERROR(_("rows field missing"), 0); 00356 /* This next stmt is commented out to allow wr_cellhd.c to write 00357 * headers that will be readable by GRASS 3.1 00358 if ((TEST(F_ROWS) && TEST(F_NSRES)) 00359 || (TEST(F_COLS) && TEST(F_EWRES))) 00360 ERROR ("row/col and resolution information can not both appear ",0); 00361 */ 00362 00363 /* 3D defined? */ 00364 if (TEST(F_EWRES3) || TEST(F_NSRES3) || TEST(F_COLS3) || TEST(F_ROWS3)) { 00365 if (!TEST(F_EWRES3)) 00366 ERROR(_("ewres3 field missing"), 0); 00367 if (!TEST(F_NSRES3)) 00368 ERROR(_("nsres3 field missing"), 0); 00369 if (!TEST(F_COLS3)) 00370 ERROR(_("cols3 field missing"), 0); 00371 if (!TEST(F_ROWS3)) 00372 ERROR(_("rows3 field missing"), 0); 00373 } 00374 else { /* use 2D */ 00375 cellhd->ew_res3 = cellhd->ew_res; 00376 cellhd->ns_res3 = cellhd->ns_res; 00377 cellhd->cols3 = cellhd->cols; 00378 cellhd->rows3 = cellhd->rows; 00379 } 00380 00381 /* Adjust and complete the cell header */ 00382 if ((err = G_adjust_Cell_head(cellhd, TEST(F_ROWS), TEST(F_COLS)))) 00383 ERROR(err, 0); 00384 00385 00386 return NULL; 00387 } 00388 00389 static int scan_item(const char *buf, char *label, char *value) 00390 { 00391 /* skip blank lines */ 00392 if (sscanf(buf, "%1s", label) != 1) 00393 return 0; 00394 00395 /* skip comment lines */ 00396 if (*label == '#') 00397 return 0; 00398 00399 /* must be label: value */ 00400 if (sscanf(buf, "%[^:]:%[^\n]", label, value) != 2) 00401 return -1; 00402 00403 G_strip(label); 00404 G_strip(value); 00405 return 1; 00406 } 00407 00408 static int scan_int(const char *buf, int *n) 00409 { 00410 char dummy[3]; 00411 00412 *dummy = 0; 00413 return (sscanf(buf, "%d%1s", n, dummy) == 1 && *dummy == 0); 00414 } 00415 00416 static double scan_double(const char *buf, double *n) 00417 { 00418 char dummy[3]; 00419 00420 *dummy = 0; 00421 return (sscanf(buf, "%lf%1s", n, dummy) == 1 && *dummy == 0); 00422 } 00423 00424 static char *error(const char *msg, int line) 00425 { 00426 char buf[1024]; 00427 00428 if (line) 00429 sprintf(buf, _("line %d: <%s>"), line, msg); 00430 else 00431 sprintf(buf, "<%s>", msg); 00432 00433 return G_store(buf); 00434 }