GRASS Programmer's Manual 6.4.1(2011)
rd_cellhd.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines