123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/glocale.h>
- #include "local_proto.h"
- #define DOT "." /* for determining data type -tw */
- #define INT "int"
- #define FLOAT "float"
- #define DOUBLE "double"
- #define TMPBUFSIZE 8192
- static int missing(int, char *);
- static int extract(int, char *, char *, void *, int, int (*)());
- static int scan_int(char *, int *, int);
- const char gs_ascii_flag[5] = { "DSAA" };
- int getgrdhead(FILE * fd, struct Cell_head *cellhd)
- {
- char grd_flag[6];
- int nc, nr;
- float xmin, xmax, ymin, ymax, zmin, zmax;
- /* make sure the input file is positioned at the beginning */
- rewind(fd);
- /* read and check the flag on the first line */
- fgets(grd_flag, sizeof(grd_flag), fd);
- if (strncmp(gs_ascii_flag, grd_flag, strlen(gs_ascii_flag))) {
- G_warning(_("input file is not a Surfer ascii grid file"));
- return 0;
- }
- /* read the row and column dimensions */
- if (fscanf(fd, "%d %d \n", &nc, &nr) != 2) {
- G_warning(_("error reading the column and row dimension from the Surfer grid file"));
- return 0;
- }
- /* read the range of x values */
- if (fscanf(fd, "%f %f \n", &xmin, &xmax) != 2) {
- G_warning(_("error reading the X range from the Surfer grid file"));
- return 0;
- }
- /* read the range of y values */
- if (fscanf(fd, "%f %f \n", &ymin, &ymax) != 2) {
- G_warning(_("error reading the Y range from the Surfer grid file"));
- return 0;
- }
- /* read the range of z values (not used) */
- if (fscanf(fd, "%f %f \n", &zmin, &zmax) != 2) {
- G_warning(_("error reading the Z range from the Surfer grid file"));
- return 0;
- }
- /* initialize the cell header */
- cellhd->zone = G_zone();
- cellhd->proj = G_projection();
- cellhd->rows = nr;
- cellhd->cols = nc;
- cellhd->ew_res = (double)(xmax - xmin) / (nc - 1);
- cellhd->ns_res = (double)(ymax - ymin) / (nr - 1);
- /* the Surfer grid specifies x,y locations of gridded points. The GRASS raster
- specifies an area covered by rectangular cells centerd at gridded points.
- That difference requires an adjustment */
- cellhd->north = ymax + cellhd->ns_res / 2.;
- cellhd->south = ymin - cellhd->ns_res / 2.;
- cellhd->east = xmax + cellhd->ew_res / 2.;
- cellhd->west = xmin - cellhd->ew_res / 2.;
- return 1;
- }
- int gethead(FILE * fd,
- struct Cell_head *cellhd,
- RASTER_MAP_TYPE * d_type, DCELL * mult, char **nval)
- {
- int n, s, e, w, r, c;
- char label[100], value[100];
- char buf[1024];
- int ret, len;
- /* rsb fix */
- fpos_t p;
- n = s = e = w = r = c = 0;
- cellhd->zone = G_zone();
- cellhd->proj = G_projection();
- /* while (n == 0 || s== 0 || e == 0 || w == 0 || r == 0 || c == 0) */
- while (1) {
- /* rsb fix */
- if (fgetpos(fd, &p) != 0)
- G_fatal_error(_("error getting file position"));
- if (!G_getl2(buf, sizeof(buf), fd))
- break;
- len = strlen(buf);
- *label = *value = '\0';
- if (NULL == strstr(buf, ":"))
- break;
- if (sscanf(buf, "%[^:]:%s", label, value) != 2)
- break;
- if (*label == '\0')
- continue; /* ignore blank lines */
- if (strcmp(label, "north") == 0) {
- extract(n++, label, value, &cellhd->north, cellhd->proj,
- G_scan_northing);
- continue;
- }
- if (strcmp(label, "south") == 0) {
- extract(s++, label, value, &cellhd->south, cellhd->proj,
- G_scan_northing);
- continue;
- }
- if (strcmp(label, "east") == 0) {
- extract(e++, label, value, &cellhd->east, cellhd->proj,
- G_scan_easting);
- continue;
- }
- if (strcmp(label, "west") == 0) {
- extract(w++, label, value, &cellhd->west, cellhd->proj,
- G_scan_easting);
- continue;
- }
- if (strcmp(label, "rows") == 0) {
- extract(r++, label, value, &cellhd->rows, cellhd->proj, scan_int);
- continue;
- }
- if (strcmp(label, "cols") == 0) {
- extract(c++, label, value, &cellhd->cols, cellhd->proj, scan_int);
- continue;
- }
- /* try to read optional header fields */
- if (strcmp(label, "type") == 0) { /* if not exist then the file scan */
- if (*d_type < 0) { /* if data type not set on command line */
- if (!strncmp(value, INT, strlen(INT)))
- *d_type = CELL_TYPE;
- else if (!strncmp(value, FLOAT, strlen(FLOAT)))
- *d_type = FCELL_TYPE;
- else if (!strncmp(value, DOUBLE, strlen(DOUBLE)))
- *d_type = DCELL_TYPE;
- else {
- G_warning(_("illegal type field: using type int"));
- *d_type = CELL_TYPE;
- }
- }
- else
- G_warning(_("ignoring type filed in header, type is set on command line"));
- continue;
- }
- if (strcmp(label, "multiplier") == 0) {
- if (Rast_is_d_null_value(mult)) { /* if mult not set on commant line */
- if (sscanf(value, "%lf", mult) != 1) {
- G_warning(_("illegal multiplier field: using 1.0"));
- *mult = 1.0;
- }
- }
- else
- G_warning(_("ignoring multiplier filed in header, multiplier is set on command line"));
- continue;
- }
- if (strcmp(label, "null") == 0) {
- if (!(*nval)) /* if null val string not set on command line */
- *nval = G_store(value);
- else
- G_warning(_("ignoring null filed in header, null string is set on command line"));
- continue;
- }
- } /* while */
- /* the line read was not a header line, but actually
- the first data line, so put it back on the stack and break */
- /* rsb fix */
- fsetpos(fd, &p);
- missing(n, "north");
- missing(s, "south");
- missing(e, "east");
- missing(w, "west");
- missing(r, "rows");
- missing(c, "cols");
- if (!(*nval))
- *nval = G_store("*");
- if (Rast_is_d_null_value(mult))
- *mult = 1.0;
- /* if data type is not set, then scan data to find out data type */
- if (*d_type < 0) {
- ret = file_scan(fd);
- if (!ret)
- *d_type = DCELL_TYPE;
- else if (ret == 1)
- *d_type = CELL_TYPE;
- else {
- G_warning(_("error in ascii data format"));
- return 0;
- }
- }
- G_adjust_Cell_head(cellhd, 1, 1);
- return 1;
- }
- static int scan_int(char *s, int *i, int proj)
- {
- char dummy[3];
- *dummy = 0;
- if (sscanf(s, "%d%1s", i, dummy) != 1)
- return 0;
- if (*dummy)
- return 0;
- if (*i <= 0)
- return 0;
- return 1;
- }
- static int extract(int count,
- char *label, char *value,
- void *data, int proj, int (*scanner) ())
- {
- if (count) {
- G_warning(_("Duplicate \"%s\" field in header"), label);
- return 0;
- }
- if (scanner(value, data, proj))
- return 1;
- G_warning(_("Illegal \"%s\" value in header: %s"), label, value);
- return 0;
- }
- static int missing(int count, char *label)
- {
- if (count)
- return 0;
- G_warning(_("\"%s\" field missing from header"), label);
- return 1;
- }
- /* file_scan(): determine data type in ascii format */
- int file_scan(FILE * fd)
- {
- long curpos;
- char tmpbuf[TMPBUFSIZE];
- size_t size = TMPBUFSIZE;
- if ((curpos = G_ftell(fd)) == -1)
- return -1;
- while (!feof(fd)) {
- if (size != fread(tmpbuf, sizeof(char), size, fd)) {
- if (!feof(fd))
- return -1;
- }
- if (strstr(tmpbuf, DOT) != NULL) {
- G_fseek(fd, curpos - 1L, SEEK_SET);
- return 0;
- }
- }
- G_fseek(fd, curpos - 1L, SEEK_SET);
- return 1;
- }
|