/* read cell header, or window. returns NULL if ok, error message otherwise note: the error message can be freed using G_free (). */ #include #include #include #define ERROR(x,line) return error(x,line) static int scan_item(const char *, char *, char *); static int scan_int(const char *, int *); static double scan_double(const char *, double *); static char *error(const char *, int); #define F_PROJ 1 #define F_ZONE 2 #define F_NORTH 3 #define F_SOUTH 4 #define F_EAST 5 #define F_WEST 6 #define F_EWRES 7 #define F_NSRES 8 #define F_FORMAT 9 #define F_COMP 10 #define F_COLS 11 #define F_ROWS 12 #define F_EWRES3 13 #define F_NSRES3 14 #define F_COLS3 15 #define F_ROWS3 16 #define F_TOP 17 #define F_BOTTOM 18 #define F_TBRES 19 #define F_DEPTHS 20 #define SET(x) flags|=(1<format = 0; cellhd->rows = 0; cellhd->rows3 = 0; cellhd->cols = 0; cellhd->cols3 = 0; cellhd->depths = 1; cellhd->proj = -1; cellhd->zone = -1; cellhd->compressed = -1; cellhd->ew_res = 0.0; cellhd->ew_res3 = 1.0; cellhd->ns_res = 0.0; cellhd->ns_res3 = 1.0; cellhd->tb_res = 1.0; cellhd->north = 0.0; cellhd->south = 0.0; cellhd->east = 0.0; cellhd->west = 0.0; cellhd->top = 1.0; cellhd->bottom = 0.0; /* determine projection, zone first */ i = 0; for (line = 1; (buf = array[i++]); line++) { if (TEST(F_PROJ) && TEST(F_ZONE)) break; switch (scan_item(buf, label, value)) { case -1: ERROR(buf, line); case 0: continue; case 1: break; } if (strncmp(label, "proj", 4) == 0) { if (TEST(F_PROJ)) ERROR(_("duplicate projection field"), line); if (!scan_int(value, &cellhd->proj)) ERROR(buf, line); SET(F_PROJ); continue; } if (strncmp(label, "zone", 4) == 0) { if (TEST(F_ZONE)) ERROR(_("duplicate zone field"), line); if (!scan_int(value, &cellhd->zone)) ERROR(buf, line); SET(F_ZONE); continue; } } if (!TEST(F_PROJ)) ERROR(_("projection field missing"), 0); if (!TEST(F_ZONE)) ERROR(_("zone field missing"), 0); /* read the other info */ i = 0; for (line = 1; (buf = array[i++]); line++) { G_debug(3, "region item: %s", buf); switch (scan_item(buf, label, value)) { case -1: ERROR(buf, line); case 0: continue; case 1: break; } if (strncmp(label, "proj", 4) == 0) continue; if (strncmp(label, "zone", 4) == 0) continue; if (strncmp(label, "nort", 4) == 0) { if (TEST(F_NORTH)) ERROR(_("duplicate north field"), line); if (!G_scan_northing(value, &cellhd->north, cellhd->proj)) ERROR(buf, line); SET(F_NORTH); continue; } if (strncmp(label, "sout", 4) == 0) { if (TEST(F_SOUTH)) ERROR(_("duplicate south field"), line); if (!G_scan_northing(value, &cellhd->south, cellhd->proj)) ERROR(buf, line); SET(F_SOUTH); continue; } if (strncmp(label, "east", 4) == 0) { if (TEST(F_EAST)) ERROR(_("duplicate east field"), line); if (!G_scan_easting(value, &cellhd->east, cellhd->proj)) ERROR(buf, line); SET(F_EAST); continue; } if (strncmp(label, "west", 4) == 0) { if (TEST(F_WEST)) ERROR(_("duplicate west field"), line); if (!G_scan_easting(value, &cellhd->west, cellhd->proj)) ERROR(buf, line); SET(F_WEST); continue; } if (strncmp(label, "top", 3) == 0) { if (TEST(F_TOP)) ERROR(_("duplicate top field"), line); if (!scan_double(value, &cellhd->top)) ERROR(buf, line); SET(F_TOP); continue; } if (strncmp(label, "bottom", 6) == 0) { if (TEST(F_BOTTOM)) ERROR(_("duplicate bottom field"), line); if (!scan_double(value, &cellhd->bottom)) ERROR(buf, line); SET(F_BOTTOM); continue; } if (strncmp(label, "e-w ", 4) == 0 && strlen(label) == 9) { if (TEST(F_EWRES)) ERROR(_("duplicate e-w resolution field"), line); if (!G_scan_resolution(value, &cellhd->ew_res, cellhd->proj)) ERROR(buf, line); if (cellhd->ew_res <= 0.0) ERROR(buf, line); SET(F_EWRES); continue; } if (strncmp(label, "e-w resol3", 10) == 0) { if (TEST(F_EWRES3)) ERROR(_("duplicate 3D e-w resolution field"), line); if (!G_scan_resolution(value, &cellhd->ew_res3, cellhd->proj)) ERROR(buf, line); if (cellhd->ew_res3 <= 0.0) ERROR(buf, line); SET(F_EWRES3); continue; } if (strncmp(label, "n-s ", 4) == 0 && strlen(label) == 9) { if (TEST(F_NSRES)) ERROR(_("duplicate n-s resolution field"), line); if (!G_scan_resolution(value, &cellhd->ns_res, cellhd->proj)) ERROR(buf, line); if (cellhd->ns_res <= 0.0) ERROR(buf, line); SET(F_NSRES); continue; } if (strncmp(label, "n-s resol3", 10) == 0) { if (TEST(F_NSRES3)) ERROR(_("duplicate 3D n-s resolution field"), line); if (!G_scan_resolution(value, &cellhd->ns_res3, cellhd->proj)) ERROR(buf, line); if (cellhd->ns_res3 <= 0.0) ERROR(buf, line); SET(F_NSRES3); continue; } if (strncmp(label, "t-b ", 4) == 0) { if (TEST(F_TBRES)) ERROR(_("duplicate t-b resolution field"), line); if (!scan_double(value, &cellhd->tb_res)) ERROR(buf, line); if (cellhd->tb_res <= 0.0) ERROR(buf, line); SET(F_TBRES); continue; } if (strncmp(label, "rows", 4) == 0 && strlen(label) == 4) { if (TEST(F_ROWS)) ERROR(_("duplicate rows field"), line); if (!scan_int(value, &cellhd->rows)) ERROR(buf, line); if (cellhd->rows <= 0) ERROR(buf, line); SET(F_ROWS); continue; } if (strncmp(label, "rows3", 5) == 0) { if (TEST(F_ROWS3)) ERROR(_("duplicate 3D rows field"), line); if (!scan_int(value, &cellhd->rows3)) ERROR(buf, line); if (cellhd->rows3 <= 0) ERROR(buf, line); SET(F_ROWS3); continue; } if (strncmp(label, "cols", 4) == 0 && strlen(label) == 4) { if (TEST(F_COLS)) ERROR(_("duplicate cols field"), line); if (!scan_int(value, &cellhd->cols)) ERROR(buf, line); if (cellhd->cols <= 0) ERROR(buf, line); SET(F_COLS); continue; } if (strncmp(label, "cols3", 5) == 0) { if (TEST(F_COLS3)) ERROR(_("duplicate 3D cols field"), line); if (!scan_int(value, &cellhd->cols3)) ERROR(buf, line); if (cellhd->cols3 <= 0) ERROR(buf, line); SET(F_COLS3); continue; } if (strncmp(label, "depths", 6) == 0) { if (TEST(F_DEPTHS)) ERROR(_("duplicate depths field"), line); if (!scan_int(value, &cellhd->depths)) ERROR(buf, line); if (cellhd->depths <= 0) ERROR(buf, line); SET(F_DEPTHS); continue; } if (strncmp(label, "form", 4) == 0) { if (TEST(F_FORMAT)) ERROR(_("duplicate format field"), line); if (!scan_int(value, &cellhd->format)) ERROR(buf, line); SET(F_FORMAT); continue; } if (strncmp(label, "comp", 4) == 0) { if (TEST(F_COMP)) ERROR(_("duplicate compressed field"), line); if (!scan_int(value, &cellhd->compressed)) ERROR(buf, line); SET(F_COMP); continue; } ERROR(buf, line); } /* check some of the fields */ if (!TEST(F_NORTH)) ERROR(_("north field missing"), 0); if (!TEST(F_SOUTH)) ERROR(_("south field missing"), 0); if (!TEST(F_WEST)) ERROR(_("west field missing"), 0); if (!TEST(F_EAST)) ERROR(_("east field missing"), 0); if (!TEST(F_EWRES) && !TEST(F_COLS)) ERROR(_("cols field missing"), 0); if (!TEST(F_NSRES) && !TEST(F_ROWS)) ERROR(_("rows field missing"), 0); /* This next stmt is commented out to allow wr_cellhd.c to write * headers that will be readable by GRASS 3.1 if ((TEST(F_ROWS) && TEST(F_NSRES)) || (TEST(F_COLS) && TEST(F_EWRES))) ERROR ("row/col and resolution information can not both appear ",0); */ /* 3D defined? */ if (TEST(F_EWRES3) || TEST(F_NSRES3) || TEST(F_COLS3) || TEST(F_ROWS3)) { if (!TEST(F_EWRES3)) ERROR(_("ewres3 field missing"), 0); if (!TEST(F_NSRES3)) ERROR(_("nsres3 field missing"), 0); if (!TEST(F_COLS3)) ERROR(_("cols3 field missing"), 0); if (!TEST(F_ROWS3)) ERROR(_("rows3 field missing"), 0); } else { /* use 2D */ cellhd->ew_res3 = cellhd->ew_res; cellhd->ns_res3 = cellhd->ns_res; cellhd->cols3 = cellhd->cols; cellhd->rows3 = cellhd->rows; } /* Adjust and complete the cell header */ if ((err = G_adjust_Cell_head(cellhd, TEST(F_ROWS), TEST(F_COLS)))) ERROR(err, 0); return NULL; } static int scan_item(const char *buf, char *label, char *value) { /* skip blank lines */ if (sscanf(buf, "%1s", label) != 1) return 0; /* skip comment lines */ if (*label == '#') return 0; /* must be label: value */ if (sscanf(buf, "%[^:]:%[^\n]", label, value) != 2) return -1; G_strip(label); G_strip(value); return 1; } static int scan_int(const char *buf, int *n) { char dummy[3]; *dummy = 0; return (sscanf(buf, "%d%1s", n, dummy) == 1 && *dummy == 0); } static double scan_double(const char *buf, double *n) { char dummy[3]; *dummy = 0; return (sscanf(buf, "%lf%1s", n, dummy) == 1 && *dummy == 0); } static char *error(const char *msg, int line) { char buf[1024]; if (line) sprintf(buf, _("line %d: <%s>"), line, msg); else sprintf(buf, "<%s>", msg); return G_store(buf); }