int main (int argc, char **argv) { int n_records, *year = NULL, k; int i, rec, n_read, n_files = 0, n_alloc = GMT_CHUNK, leg_year = 0, len; int T_INC = 60, fake_running_time = 0; int t_flag = FALSE, anom_offset = 0; GMT_LONG use_list = FALSE, set_agency = FALSE, mag_rewind = FALSE, greenwich = FALSE, give_synopsis_and_exit = FALSE; GMT_LONG error = FALSE; double cable_len = 0; char file[80], *mfile = NULL, *list = NULL, agency[10], *legfname = NULL, line[BUFSIZ], **mgd77 = NULL, **prefix = NULL; struct GMTMGG_TIME *gmt = NULL; struct GMTMGG_REC *record = NULL; FILE *fp = NULL, *fpo = NULL; argc = (int)GMT_begin (argc, argv); gmtmggpath_init(); legfname = list = mfile = CNULL; memset ((void *)agency, 0, (size_t)10); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case '\0': error = give_synopsis_and_exit = TRUE; break; case 'Y': leg_year = atoi (&argv[i][2]); break; case 'I': /* No time in data file, specify time increment between points */ T_INC = atoi (&argv[i][2]); t_flag = TRUE; /* fake time starts at 1/1/2000 @ 00:00:00 hr */ break; case 'H': /* No longer used, kept for nostalgic reasons */ break; case 'F': legfname = &argv[i][2]; break; case 'L': list = &argv[i][2]; use_list = TRUE; break; case 'A': strcpy (agency, &argv[i][2]); break; case 'T': /* Read Total field instead of anomaly and subtract a cte */ if (argv[i][2]) anom_offset = atoi (&argv[i][2]); else anom_offset = 40000; break; case 'G': greenwich = TRUE; break; case 'V': gmtdefs.verbose = TRUE; break; case 'W': if (argv[i][2]) cable_len = atof (&argv[i][2]); mag_rewind = TRUE; break; default: fprintf (stderr, "SYNTAX ERROR: Unrecognized option -%c\n", argv[i][1]); error = TRUE; break; } } else mfile = argv[i]; } if (!give_synopsis_and_exit) { if (use_list && !list) { fprintf (stderr, "SYNTAX ERROR -L option: Must specify list file\n"); error = TRUE; } if (use_list && (legfname || leg_year != 0)) { fprintf (stderr, "SYNTAX ERROR -L option: Specify -L or the combination -F, -Y\n"); error = TRUE; } if (!use_list && !mfile && !legfname) { fprintf (stderr, "SYNTAX ERROR -F option: When using standard input you must use -F option.\n"); error = TRUE; } } if (argc == 1 || error) { fprintf (stderr, "usage: mgd77togmt [mgd77file] [-F<filename>] -Y<leg_year> OR -L<leglist> [-A<10 char agency name>]\n"); fprintf (stderr, "\t[-G] [NGDC-file -I<time_increment>] [-V] [-T[<offset>]] [-W[<cable_length>]]\n\n"); if (give_synopsis_and_exit) exit (EXIT_FAILURE); fprintf (stderr, "\t-Y sets start year. If not provided and -L option not used, it tries to get\n"); fprintf (stderr, "\t it from header file. The header file must be in the same directory of the\n"); fprintf (stderr, "\t main file and must have a name equal to the main but with a .h77 extension.\n"); fprintf (stderr, "\t-L gives name of a list with several records of <mgd77file> <gmtprefix> <leg_year>\n"); fprintf (stderr, "\n\tOPTIONS:\n"); fprintf (stderr, "\t-A sets optional 10 char info for gmt header.\n"); fprintf (stderr, "\t-F sets gmtfilename prefix (e.g., without path or .gmt). If not given, it\n"); fprintf (stderr, "\t will be constructed from the mgd77file name plus the .gmt extension.\n"); fprintf (stderr, "\t-G force geographical longitudes (-180/+180) [Default is 0-360]\n"); fprintf (stderr, "\t-I sets fake timeincrement for files without time information\n"); fprintf (stderr, "\t-T Extracts Total field instead of anomaly. Since F does not hold in a 2 byte int var\n"); fprintf (stderr, "\t we subtract a constant [default = 40000] but you can provide another value in <offset>.\n"); fprintf (stderr, "\t-W Take into account that the magnetometer is not at ship's position.\n"); fprintf (stderr, "\t <cable> is magnetometer tow distance [default = 200 meters].\n"); fprintf (stderr, "\t If -W only is given (e.g., no <cable_length>) and like with the -Y option, we try\n"); fprintf (stderr, "\t to get the tow distance from the header file. Failing, defaults to 200 meters.\n"); fprintf (stderr, "\t Note that this option will throw away the first points whose accumulated.\n"); fprintf (stderr, "\t distance since the start of magnetic acquisition is less than cable.\n"); fprintf (stderr, "\t length, and likewise for the end of the mag profile.\n"); fprintf (stderr, "\t-V runs in verbose mode.\n"); exit (EXIT_FAILURE); } if (agency[0]) set_agency = TRUE; if (use_list) { if ((fp = fopen (list, "r")) == NULL) { fprintf (stderr, "mgd77togmt: Cannot open file %s!\n", list); exit (EXIT_FAILURE); } mgd77 = (char **) GMT_memory (VNULL, (size_t)n_alloc, sizeof (char *), "mgd77togmt"); prefix = (char **) GMT_memory (VNULL, (size_t)n_alloc, sizeof (char *), "mgd77togmt"); year = (int *) GMT_memory (VNULL, (size_t)n_alloc, sizeof (int), "mgd77togmt"); n_read = 0; while (fgets (line, BUFSIZ, fp)) { mgd77[n_read] = (char *) GMT_memory (VNULL, (size_t)80, sizeof (char), "mgd77togmt"); prefix[n_read] = (char *) GMT_memory (VNULL, (size_t)80, sizeof (char), "mgd77togmt"); if ((sscanf (line, "%s %s %d", mgd77[n_read], prefix[n_read], &year[n_read]) != (size_t)3)) { fprintf (stderr, "mgd77togmt: Trouble reading record # %d in list %s\n", n_read, list); exit (EXIT_FAILURE); } n_read++; if (n_read == n_alloc) { n_alloc <<= 1; mgd77 = (char **) GMT_memory ((void *)mgd77, (size_t)n_alloc, sizeof (char *), "mgd77togmt"); prefix = (char **) GMT_memory ((void *)prefix, (size_t)n_alloc, sizeof (char *), "mgd77togmt"); year = (int *) GMT_memory ((void *)year, (size_t)n_alloc, sizeof (int), "mgd77togmt"); } } n_files = n_read; fclose (fp); mgd77 = (char **) GMT_memory ((void *)mgd77, (size_t)n_files, sizeof (char *), "mgd77togmt"); prefix = (char **) GMT_memory ((void *)prefix, (size_t)n_files, sizeof (char *), "mgd77togmt"); year = (int *) GMT_memory ((void *)year, (size_t)n_files, sizeof (int), "mgd77togmt"); } else { int free_legfname = 0; char *ext; if (!legfname) { legfname = strdup(mfile); free_legfname = 1; GMT_chop_ext(legfname); } else { /* Make sure that the legname does not have the .gmt extension */ ext = GMT_chop_ext(legfname); if (ext && strcmp(ext,".gmt")) /* Hoops, removed a wrong extension */ strcat(legfname,ext); } mgd77 = (char **) GMT_memory (VNULL, (size_t)1, sizeof (char *), "mgd77togmt"); prefix = (char **) GMT_memory (VNULL, (size_t)1, sizeof (char *), "mgd77togmt"); year = (int *) GMT_memory (VNULL, (size_t)1, sizeof (int), "mgd77togmt"); mgd77[0] = (char *) GMT_memory (VNULL, (size_t)80, sizeof (char), "mgd77togmt"); prefix[0] = (char *) GMT_memory (VNULL, (size_t)80, sizeof (char), "mgd77togmt"); strcpy (mgd77[0], mfile); strcpy (prefix[0], legfname); year[0] = leg_year; n_files = 1; if (free_legfname) free ((void *)legfname); } n_alloc = GMT_CHUNK; for (i = 0; i < n_files; i++) { if (gmtdefs.verbose) fprintf (stderr, "mgd77togmt: Processing file %s\n", mgd77[i]); if (mgd77[i][0] == 0) { fp = stdin; } else if ((fp = fopen (mgd77[i], "r")) == NULL) { fprintf (stderr, "mgd77togmt: Unable to open file %s - skipping\n", mgd77[i]); GMT_free ((void *)mgd77[i]); GMT_free ((void *)prefix[i]); continue; } if (!set_agency) { /* Use legname as agency string */ strncpy ((void *)agency, prefix[i], (size_t)10); if (gmtdefs.verbose) fprintf (stderr, "mgd77togmt: Agency string set to %s\n", prefix[i]); } /* See if we have the header file arround and if yes try to get year and mag tow distance (if needed) */ if (!leg_year || (mag_rewind && !cable_len)) { char *hdr, s_yr[5]; FILE *fph; hdr = strdup(&mgd77[i][0]); GMT_chop_ext(hdr); strcat(hdr,".h77"); k = 0; if ((fph = fopen (hdr, "r")) != NULL) { while (fgets (line, BUFSIZ, fph) && k < 13) { k++; if (k == 4 && !leg_year) { strncpy (s_yr, &line[0], (size_t) 4); s_yr[4] = 0; year[i] = atoi (s_yr); if (gmtdefs.verbose) fprintf (stderr, "\tGot year %d from header file %s\n", year[i], hdr); if (!mag_rewind || cable_len > 0) k = 14; /* End reading header */ } else if (k == 13) { /* Seek for the magnetometer tow distance */ strncpy (s_yr, &line[5], (size_t) 4); s_yr[4] = 0; if (s_yr[0] == ' ' && s_yr[1] == ' ' && s_yr[2] == ' ' && s_yr[3] == ' ') cable_len = 200; /* The default tow distance */ else cable_len = atof (s_yr); if (cable_len > 500) cable_len = 200; /* This accounts also for 999 non-values in header */ if (gmtdefs.verbose) fprintf (stderr, "\tUsing magnetometer tow distance = %.0f\n", cable_len); } } fclose(fph); } else { if (!leg_year) { fprintf (stderr, "WARNING: Year not provided and companion header file not found. Jumping this file\n"); continue; } if (mag_rewind) cable_len = 200; } free ((void *) hdr); } gmt = gmtmgg_init (year[i]); record = (struct GMTMGG_REC *) GMT_memory (VNULL, (size_t)n_alloc, sizeof (struct GMTMGG_REC), "mgd77togmt"); rec = n_read = 0; while (fgets (line, BUFSIZ, fp)) { n_read++; if (!(line[0] == '3' || line[0] == '5')) continue; /* Only process data records */ if ((len = (int)strlen(line)) != 121) { fprintf (stderr, "mgd77togmt: Record # %d has incorrect length (%d), skipped\n", n_read, len); continue; } if (!gmtmgg_decode_MGD77 (line, t_flag, &record[rec], &gmt, anom_offset)) { if (t_flag) record[rec].time = (fake_running_time += T_INC); if (greenwich && record[rec].lon > 180000000) record[rec].lon -= 360000000; rec++; } else fprintf (stderr, "mgd77togmt: Trouble decoding record # %d (skipped)\n", n_read); if (rec == n_alloc) { n_alloc <<= 1; record = (struct GMTMGG_REC *) GMT_memory ((void *)record, (size_t)n_alloc, sizeof (struct GMTMGG_REC), "mgd77togmt"); } } if (fp != stdin) fclose (fp); GMT_free ((void *)gmt); n_records = rec; sprintf (file, "%s.gmt", prefix[i]); if ((fpo = fopen (file, "wb")) == NULL) { fprintf (stderr, "mgd77togmt: Could not create file %s\n", file); exit (EXIT_FAILURE); } if (fwrite ((void *)(&year[i]), (size_t)4, (size_t)1, fpo) != (size_t)1) { fprintf (stderr,"mgd77togmt: Error while writing first year\n"); exit (EXIT_FAILURE); } if (fwrite ((void *)(&n_records), (size_t)4, (size_t)1, fpo) != (size_t)1) { fprintf (stderr,"mgd77togmt: Error while writing no of records\n"); exit (EXIT_FAILURE); } if (fwrite ((void *)agency, (size_t)10, (size_t)1, fpo) != (size_t)1) { fprintf (stderr,"mgd77togmt: Error while writing info-header\n"); exit (EXIT_FAILURE); } if (!mag_rewind) { for (rec = 0; rec < n_records; rec++) { if (fwrite ((void *)(&record[rec]), (size_t)18, (size_t)1, fpo) != (size_t)1) { fprintf (stderr,"mgd77togmt: Error writing data record no %d\n",rec); exit (EXIT_FAILURE); } } } else { /* At ship's position we'll get the mag reading down the track that is closest to cable length */ int n, dlon, last_lon = 0, last_lat = 0, itmp; double *ds, dds, dx, dy; ds = (double *) GMT_memory (VNULL, (size_t)n_records, sizeof (double), "mgd77togmt"); for (rec = 0; rec < n_records; rec++) { if (rec == 0) { last_lon = record[0].lon; last_lat = record[0].lat; ds[0] = 0.0; } else { dlon = record[rec].lon - last_lon; dx = (double) dlon * cosd (0.5e-06*(double)(record[rec].lat+last_lat)); dy = (double) (record[rec].lat - last_lat); ds[rec] = ds[rec-1] + MPRDEG * hypot (dx, dy); last_lon = record[rec].lon; last_lat = record[rec].lat; } } for (rec = 0; rec < n_records; rec++) { dds = ds[rec] - cable_len; n = rec; if (dds < 0) { /* First points (of distance < cable_len) are lost */ record[rec].gmt[1] = GMTMGG_NODATA; } else { while ((ds[n] - dds) > 0) n--; } itmp = record[rec].gmt[1]; record[rec].gmt[1] = record[n].gmt[1]; if (fwrite ((void *)(&record[rec]), (size_t)18, (size_t)1, fpo) != (size_t)1) { fprintf (stderr,"mgd77togmt: Error writing data record no %d\n",rec); exit (EXIT_FAILURE); } record[rec].gmt[1] = itmp; /* Reset to original to be used when its turn arrives */ } } fclose (fpo); GMT_free ((void *)record); GMT_free ((void *)mgd77[i]); GMT_free ((void *)prefix[i]); } GMT_free ((void *)mgd77); GMT_free ((void *)prefix); GMT_free ((void *)year); gmtmgg_end (); GMT_end (argc, argv); exit (EXIT_SUCCESS); }
int GMT_is_esri_grid (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *header) { /* Determine if file is an ESRI Interchange ASCII file */ FILE *fp = NULL; char record[GMT_BUFSIZ]; if (!strcmp (header->name, "=")) return (GMT_GRDIO_PIPE_CODECHECK); /* Cannot check on pipes */ if ((fp = GMT_fopen (GMT, header->name, "r")) == NULL) return (GMT_GRDIO_OPEN_FAILED); if (fgets (record, GMT_BUFSIZ, fp) == NULL) { /* Just get first line. Not using GMT_fgets since we may be reading a binary file */ return (GMT_GRDIO_OPEN_FAILED); } GMT_fclose (GMT, fp); if (strncmp (record, "ncols ", 6) ) { /* Failed to find "ncols"; probably a binary file */ char *file = NULL; size_t name_len; /* If it got here, see if a companion .hdr file exists (must test upper & lower cases names) */ file = strdup (header->name); GMT_chop_ext (file); name_len = strlen (header->name); if (name_len < strlen(file) + 4) { /* The file extension had less than 3 chars, which means that 1) it's not an esri file. 2) would corrupt the heap with the later strcat (file, ".hdr"); On Win this would later cause a crash upon freeing 'file' */ free (file); return (-1); } if (isupper ((unsigned char) header->name[name_len - 1])) strcat (file, ".HDR"); else strcat (file, ".hdr"); if (!GMT_access (GMT, file, F_OK)) { /* Now, if first line has BYTEORDER or ncols keywords we are in the game */ if ((fp = GMT_fopen (GMT, file, "r")) == NULL) return (GMT_GRDIO_OPEN_FAILED); GMT_fgets (GMT, record, GMT_BUFSIZ, fp); /* Just get first line */ GMT_fclose (GMT, fp); if (!strncmp (record, "BYTEORDER", 4) ) { sscanf (record, "%*s %c", &header->flags[0]); /* Store the endianness flag here */ strncpy (header->title, file, GMT_GRID_TITLE_LEN80); } else if (!strncmp (record, "ncols ", 6) ) { /* Ah. A Arc/Info float binary file with a separate .hdr */ strncpy (header->title, file, GMT_GRID_TITLE_LEN80); header->flags[0] = 'L'; /* If is truly 'L' or 'B' we'll find only when parsing the whole header */ header->flags[1] = '2'; /* Flag to let us know the file type */ } else { /* Cannot do anything with this data */ free (file); return (-1); } free (file); } else { /* No header file; see if filename contains w/e/s/n information, as in W|ExxxN|Syy.dem * for GTOPO30 (e.g W020N90.DEM) or N|SyyW|Exxx.hgt for SRTM1|3 (e.g. N00E006.hgt) */ size_t len; while (GMT_chop_ext (file)); /* Remove all extensions so we know exactly where to look */ len = strlen (file); if ((file[len-3] == 'N' || file[len-3] == 'n' || file[len-3] == 'S' || file[len-3] == 's') && (file[len-7] == 'W' || file[len-7] == 'w' || file[len-7] == 'E' || file[len-7] == 'e')) { /* It is a GTOPO30 or SRTM30 source file without a .hdr companion. */ /* see http://dds.cr.usgs.gov/srtm/version1/SRTM30/GTOPO30_Documentation */ header->flags[0] = 'B'; /* GTOPO30 & SRTM30 are Big Endians */ header->flags[1] = '0'; /* Flag to let us know the file type */ /* Store the file name with all extensions removed. * We'll use this to create header from file name info */ strncpy (header->title, file, GMT_GRID_TITLE_LEN80); strcpy (header->remark, "Assumed to be a GTOPO30 or SRTM30 tile"); } else if (name_len > 3 && !(strncmp (&header->name[name_len-4], ".hgt", 4) && strncmp (&header->name[name_len-4], ".HGT", 4))) { /* Probably a SRTM1|3 file. In read_esri_info we'll check further if it is a 1 or 3 sec */ if ((file[len-4] == 'E' || file[len-4] == 'e' || file[len-4] == 'W' || file[len-4] == 'w') && (file[len-7] == 'N' || file[len-7] == 'n' || file[len-7] == 'S' || file[len-7] == 's')) { header->flags[0] = 'B'; /* SRTM1|3 are Big Endians */ header->flags[1] = '1'; /* Flag to let us know the file type */ /* Store the file name with all extensions removed. * We'll use this to create header from file name info */ strncpy (header->title, file, GMT_GRID_TITLE_LEN80); } } else { /* Cannot do anything with this data */ free (file); return (-1); /* Not this kind of file */ } } } header->type = GMT_GRID_IS_EI; return GMT_NOERROR; }