Beispiel #1
0
static void
garmin_txt_read(void)
{
    char *buff;

    current_line = 0;

    while ((buff = gbfgetstr(fin))) {
        char *cin;

        if ((current_line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1);

        cin = lrtrim(buff);
        if (*cin == '\0') continue;

        cin = csv_lineparse(cin, "\t", "", 0);

        if (cin == NULL) continue;

        if (case_ignore_strcmp(cin, "Header") == 0) parse_header();
        else if (case_ignore_strcmp(cin, "Grid") == 0) parse_grid();
        else if (case_ignore_strcmp(cin, "Datum") == 0) parse_datum();
        else if (case_ignore_strcmp(cin, "Waypoint") == 0) parse_waypoint();
        else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) parse_route_waypoint();
        else if (case_ignore_strcmp(cin, "Trackpoint") == 0) parse_track_waypoint();
        else if (case_ignore_strcmp(cin, "Route") == 0) parse_route_header();
        else if (case_ignore_strcmp(cin, "Track") == 0) parse_track_header();
        else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ;
        else
            fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line);

        /* flush pending data */
        while (csv_lineparse(NULL, "\t", "", 0));
    }
}
Beispiel #2
0
static status_type
unicsv_parse_status(const char *str)
{
	if ((case_ignore_strcmp(str, "true") == 0) ||
	    (case_ignore_strcmp(str, "yes") == 0) ||
	    (*str == '1')) return status_true;
	else if ((case_ignore_strcmp(str, "false") == 0) ||
		 (case_ignore_strcmp(str, "no") == 0) ||
		 (*str == '0')) return status_false;
	else return status_unknown;
}
Beispiel #3
0
static void 
tef_header(const char *args, const char **attrv)
{
	const char **avp = &attrv[0];

	route = route_head_alloc();
	while (*avp) {
		if (case_ignore_strcmp(avp[0], "Name") == 0)
			route->rte_name = trimmed_strdup(avp[1]);
		else if (case_ignore_strcmp(avp[0], "Software") == 0)
			route->rte_desc = trimmed_strdup(avp[1]);
		avp+=2;
	}
	route_add_head(route);
}
Beispiel #4
0
static void
compegps_data_write(void)
{
	/* because of different file extensions we can only write one GPS data type at time */
	
	gbfprintf(fout, "G  WGS 84\n");
	gbfprintf(fout, "U  1\n");
	
	/* process options */
	
	target_index = 1;
	if (option_index != NULL)
		target_index = atoi(option_index);
		
	snlen = 0;
	if (global_opts.synthesize_shortnames != 0)
	{
		if (option_snlen != NULL)
			snlen = atoi(option_snlen);
		else
			snlen = SHORT_NAME_LENGTH;
		
		is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!");
		
		setshort_whitespace_ok(sh, 0);
		setshort_length(sh, snlen);
	}
	
	radius = -1;
	if (option_radius != 0)
	{
	    radius = atof(option_radius);
	    is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!");
	}
	
	if (option_icon != NULL)
	{
		if (*option_icon == '\0')
			option_icon = NULL;
		else if (case_ignore_strcmp(option_icon, "deficon") == 0)
			option_icon = NULL;
	}
	
	switch(global_opts.objective)
	{
		case wptdata:
			curr_index = target_index = 0;
			write_waypoints();
			break;
		case trkdata:
			write_track();
			break;
		case rtedata:
			write_route();
			break;
		case posndata:
			fatal(MYNAME ": Realtime positioning not supported.\n");
			break;
	}
}
Beispiel #5
0
static void
enum_waypt_cb(const waypoint *wpt)
{
    garmin_fs_p gmsd;
    int wpt_class;

    gmsd = GMSD_FIND(wpt);
    wpt_class = GMSD_GET(wpt_class, 0);
    if (wpt_class < 0x80)
    {
        int i;

        if (gtxt_flags.enum_waypoints)			/* enumerate only */
        {
            waypoints++;
            return;
        }
        for (i = 0; i < wpt_a_ct; i++) {		/* check for duplicates */
            waypoint *tmp = wpt_a[i];
            if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0)
            {
                wpt_a[i] = (waypoint *)wpt;
                waypoints--;
                return;

            }
        }
        wpt_a[wpt_a_ct++] = (waypoint *)wpt;
    }

}
Beispiel #6
0
int
lowranceusr_find_icon_number_from_desc(const char *desc)
{
	const lowranceusr_icon_mapping_t *i;
	int n;

	if (!desc) {
		return DEF_ICON;
	}

	/*
	 * If we were given a numeric icon number as a description 
	 * (i.e. 8255), just return that.
	 */
	n = atoi(desc);
	if (n)  {
		return n;
	}


	for (i = lowranceusr_icon_value_table; i->icon; i++) {
		if (case_ignore_strcmp(desc,i->icon) == 0) {
			return i->value;
		}
	}

	return DEF_ICON;
}
Beispiel #7
0
static void
humminbird_write_waypoint(const waypoint *wpt) {
	humminbird_waypt_t hum;
	double lat, north, east;
	int i;
	int num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]);
	char *name;

	be_write16(&hum.num, waypoint_num++);
	hum.zero   = 0;
	hum.status = 1;
	hum.icon   = 255;

	// Icon....
	if (wpt->icon_descr) {
		for (i = 0; i < num_icons; i++) {
			if (!case_ignore_strcmp(wpt->icon_descr, humminbird_icons[i])) {
				hum.icon = i;
				break;
			}
		}
		if (hum.icon == 255) {	/* no success, no try to find the item in a more comlex name */
			hum.icon = 0;	/* i.e. "Diamond" as part of "Diamond, Green" or "Green Diamond" */
			for (i = 0; i < num_icons; i++) {
				char *match;
				int j;
				xasprintf(&match, "*%s*", humminbird_icons[i]);
				j = case_ignore_str_match(wpt->icon_descr, match);
				xfree(match);
				if (j != 0) {
					hum.icon = i;
					break;
				}
			}
		}
	}

	hum.depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0);
	be_write16(&hum.depth, hum.depth);

	be_write32(&hum.time, wpt->creation_time);

	east = wpt->longitude / 180.0 * EAST_SCALE;
	be_write32(&hum.east, si_round((east)));

	lat = geodetic_to_geocentric_hwr(wpt->latitude);
	north = inverse_gudermannian_i1924(lat);
	be_write32(&hum.north, si_round(north));

	name = (global_opts.synthesize_shortnames) 
		? mkshort_from_wpt(wptname_sh, wpt) 
		: mkshort(wptname_sh, wpt->shortname);
	memset(&hum.name, 0, sizeof(hum.name));
	memcpy(&hum.name, name, strlen(name));
	xfree(name);

	gbfputuint32(WPT_MAGIC, fout);
	gbfwrite(&hum, sizeof(hum), 1, fout);
}
Beispiel #8
0
static int
sort_waypt_cb(const void *a, const void *b)
{
    const waypoint *wa = *(waypoint **)a;
    const waypoint *wb = *(waypoint **)b;

    return case_ignore_strcmp(wa->shortname, wb->shortname);
}
Beispiel #9
0
static void 
tef_item_start(const char *args, const char **attrv)
{
	const char **avp = &attrv[0];

	waypoints++;

	wpt_tmp = waypt_new();
	if ((waypoints == 1) || (waypoints == item_count))
		wpt_tmp->microseconds++;

	while (*avp) 
	{
		if (0 == case_ignore_strcmp(avp[0], "SegDescription"))
			wpt_tmp->shortname = trimmed_strdup(avp[1]);
		else if (0 == case_ignore_strcmp(avp[0], "PointDescription"))
			wpt_tmp->description = trimmed_strdup(avp[1]);
		else if ((0 == case_ignore_strcmp(avp[0], "ViaStation")) && 
			 (0 == case_ignore_strcmp(avp[1], "true")))
			wpt_tmp->microseconds = 1;		/* only a flag */

		/* new in TEF V2 */
		else if (0 == case_ignore_strcmp(avp[0], "Instruction"))
			wpt_tmp->description = trimmed_strdup(avp[1]);
		else if (0 == case_ignore_strcmp(avp[0], "Altitude"))
			wpt_tmp->altitude = atof(avp[1]);
		else if (0 == case_ignore_strcmp(avp[0], "TimeStamp"))
			{ /* nothing for the moment */ }

		avp+=2;
	}
}
Beispiel #10
0
void 
tef_start(const char *args, const char **attrv)
{
	int valid = 0;
	const char **avp = &attrv[0];

        while (*avp) {
		if (0 == case_ignore_strcmp(avp[0], "Comment")) {
			if (0 == case_ignore_strcmp(avp[1], "TourExchangeFormat"))
				valid = 1;
		}
		else if (0 == case_ignore_strcmp(avp[0], "Version"))
			version = atof(avp[1]);
		avp+=2;
	}
	if (!valid)
		fatal(MYNAME ": Error in source file.\n");
}
Beispiel #11
0
static void
garmin_txt_wr_init(const char *fname)
{
    char *grid_str;

    memset(&gtxt_flags, 0, sizeof(gtxt_flags));

    fout = gbfopen(fname, "wb", MYNAME);

    gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M');
    gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C');
    init_date_and_time_format();
    if (opt_precision) {
        precision = atoi(opt_precision);
        is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision);
    }

    datum_str = get_option_val(opt_datum, NULL);
    grid_str = get_option_val(opt_grid, NULL);

    grid_index = grid_lat_lon_dmm;
    if (grid_str != NULL) {
        int i;

        if (sscanf(grid_str, "%d", &i)) {
            grid_index = (grid_type) i;
            if ((grid_index < GRID_INDEX_MIN) || (grid_index > GRID_INDEX_MAX))
                fatal(MYNAME ": Grid index out of range (%d..%d)!",
                      (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX);
        }
        else grid_index = gt_lookup_grid_type(grid_str, MYNAME);
    }

    switch(grid_index) {
    case grid_bng: /* force datum to "Ord Srvy Grt Britn" */
        datum_index = DATUM_OSGB36;
        break;
    case grid_swiss: /* force datum to "Ord Srvy Grt Britn" */
        datum_index = DATUM_WGS84;
        break;
    default:
        datum_index = gt_lookup_datum_index(datum_str, MYNAME);
    }

    if (opt_utc != NULL) {
        if (case_ignore_strcmp(opt_utc, "utc") == 0)
            utc_offs = 0;
        else
            utc_offs = atoi(opt_utc);
        utc_offs *= (60 * 60);
        gtxt_flags.utc = 1;
    }
}
Beispiel #12
0
static
geocache_container
nc_mkcont(const char *t)
{
	int i;
	int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]);

	for (i = 0; i < sz; i++) {
		if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) {
			return nc_container_map[i].type;
		}
	}
	return gc_unknown;
}
Beispiel #13
0
static int
parse_display(const char *str, int *val)
{
    gt_display_modes_e i;

    if ((str == NULL) || (*str == '\0')) return 0;

    for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) {
        if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) {
            *val = i;
            return 1;
        }
    }
    warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line);
    return 0;
}
Beispiel #14
0
static void
data_write(void)
{
    if (Arg_dbname) {
	if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0)
	    fatal(MYNAME ": Reserved database name!\n");
	strncpy(file_out->name, Arg_dbname, PDB_DBNAMELEN);
    }
    else
	strncpy(file_out->name, FilenameOut, PDB_DBNAMELEN);
    file_out->name[PDB_DBNAMELEN-1] = 0;

    file_out->attr = PDB_FLAG_BACKUP;
    file_out->ctime = file_out->mtime = current_time() + (49*365 + 17*366) * (60*60*24);
    file_out->type = MYTYPE_ASC;
    file_out->creator = MYCREATOR; 
    file_out->version = 0;
    file_out->revision = 1;

    rec_ct = 0;
    ct = 0;
    waypt_disp_all(geoniche_writewpt);
}
Beispiel #15
0
static void
parse_waypoint(void)
{
    char *str;
    int column = -1;
    waypoint *wpt;
    garmin_fs_p gmsd = NULL;

    bind_fields(waypt_header);

    wpt = waypt_new();
    gmsd = garmin_fs_alloc(-1);
    fs_chain_add(&wpt->fs, (format_specific_data *) gmsd);

    while ((str = csv_lineparse(NULL, "\t", "", column++)))
    {
        int i, dynamic;
        double d;
        int field_no = header_fields[waypt_header][column];

        switch(field_no) {
        case  1:
            wpt->shortname = DUPSTR(str);
            break;
        case  2:
            wpt->notes = DUPSTR(str);
            break;
        case  3:
            for (i = 0; i <= gt_waypt_class_map_line; i++) {
                if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) {
                    GMSD_SET(wpt_class, i);
                    break;
                }
            }
            break;
        case  4:
            parse_coordinates(str, datum_index, grid_index,
                              &wpt->latitude, &wpt->longitude, MYNAME);
            break;
        case  5:
            if (parse_distance(str, &d, 1, MYNAME)) wpt->altitude = d;
            break;
        case  6:
            if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, depth, d);
            break;
        case  7:
            if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, proximity, d);
            break;
        case  8:
            if (parse_temperature(str, &d)) WAYPT_SET(wpt, temperature, d);
            break;
        case  9:
            if (parse_display(str, &i)) GMSD_SET(display, i);
            break;
        case 10:
            break;	/* skip color */
        case 11:
            i = gt_find_icon_number_from_desc(str, GDB);
            GMSD_SET(icon, i);
            wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic);
            wpt->wpt_flags.icon_descr_is_dynamic = dynamic;
            break;
        case 12:
            GMSD_SETSTR(facility, str);
            break;
        case 13:
            GMSD_SETSTR(city, str);
            break;
        case 14:
            GMSD_SETSTR(state, str);
            break;
        case 15:
            GMSD_SETSTR(country, str);
            GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname));
            break;
        case 16:
            parse_date_and_time(str, &wpt->creation_time);
            break;
        case 17:
            wpt->url = DUPSTR(str);
            break;
        case 18:
            GMSD_SET(category, parse_categories(str));
            break;
        default:
            break;
        }
    }
    waypt_add(wpt);
}
Beispiel #16
0
static void
unicsv_parse_one_line(char *ibuf)
{
	char *s;
	waypoint *wpt = NULL;
	int column;
	int  utm_zone = -9999;
	double utm_easting = 0;
	double utm_northing = 0;
	char utm_zc = 'N';
	char bng_zone[3] = "";
	double bng_easting = 0;
	double bng_northing = 0;
	double swiss_easting = unicsv_unknown;
	double swiss_northing = unicsv_unknown;
	int checked = 0;
	time_t date = -1, time = -1;
	int msec = -1;
	char is_localtime = 0;
	garmin_fs_t *gmsd;
	double d;
	struct tm ymd;
	int src_datum = unicsv_datum_idx;
	int ns = 1;
	int ew = 1;
#ifdef UNICSV_GC_READY
	geocache_data *gc_data = NULL;
#endif
	wpt = waypt_new();
	wpt->latitude = unicsv_unknown;
	wpt->longitude = unicsv_unknown;
	memset(&ymd, 0, sizeof(ymd));

	column = -1;
	while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) {

		if (column > unicsv_fields_tab_ct) break;	/* ignore extra fields on line */

		ibuf = NULL;

		column++;
		checked++;

		s = lrtrim(s);
		if (! *s) continue;	/* skip empty columns */
		switch(unicsv_fields_tab[column]) {

		case fld_time:
		case fld_date:
		case fld_datetime:
			/* switch column type if it looks like an iso time string */
			if (strchr(s, 'T'))
				unicsv_fields_tab[column] = fld_iso_time;
			break;
		default: ;
		}


		switch(unicsv_fields_tab[column]) {

		case fld_latitude:
			human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 );
			wpt->latitude = wpt->latitude * ns;
			break;

		case fld_longitude:
			human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 );
			wpt->longitude = wpt->longitude * ew;
			break;

		case fld_shortname:
			wpt->shortname = xstrdup(s);
			break;

		case fld_description:
			wpt->description = xstrdup(s);
			break;

		case fld_notes:
			wpt->notes = xstrdup(s);
			break;

		case fld_url:
			wpt->url = xstrdup(s);
			break;

		case fld_altitude:
			if (parse_distance(s, &d, unicsv_altscale, MYNAME)) {
				if (fabs(d) < fabs(unknown_alt))
					wpt->altitude = d;
			}
			break;

		case fld_utm_zone:
			utm_zone = atoi(s);
			break;

		case fld_utm_easting:
			utm_easting = atof(s);
			break;

		case fld_utm_northing:
			utm_northing = atof(s);
			break;

		case fld_utm_zone_char:
			utm_zc = toupper(s[0]);
			break;

		case fld_utm:
			parse_coordinates(s, unicsv_datum_idx, grid_utm,
				&wpt->latitude, &wpt->longitude, MYNAME);
			/* coordinates from parse_coordinates are in WGS84
			   don't convert a second time */
			src_datum = DATUM_WGS84;
			break;

		case fld_bng:
			parse_coordinates(s, DATUM_OSGB36, grid_bng,
				&wpt->latitude, &wpt->longitude, MYNAME);
			/* coordinates from parse_coordinates are in WGS84
			   don't convert a second time */
			src_datum = DATUM_WGS84;
			break;

		case fld_bng_zone:
			strncpy(bng_zone, s, sizeof(bng_zone));
			strupper(bng_zone);
			break;

		case fld_bng_northing:
			bng_northing = atof(s);
			break;

		case fld_bng_easting:
			bng_easting = atof(s);
			break;

		case fld_swiss:
			parse_coordinates(s, DATUM_WGS84, grid_swiss,
				&wpt->latitude, &wpt->longitude, MYNAME);
			/* coordinates from parse_coordinates are in WGS84
			   don't convert a second time */
			src_datum = DATUM_WGS84;
			break;

		case fld_swiss_easting:
			swiss_easting = atof(s);
			break;

		case fld_swiss_northing:
			swiss_northing = atof(s);
			break;

		case fld_hdop:
			wpt->hdop = atof(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_pdop:
			wpt->pdop = atof(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_vdop:
			wpt->vdop = atof(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_sat:
			wpt->sat = atoi(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_fix:
			if (unicsv_detect) unicsv_data_type = trkdata;
			if (case_ignore_strcmp(s, "none") == 0)
				wpt->fix = fix_none;
			else if (case_ignore_strcmp(s, "2d") == 0)
				wpt->fix = fix_2d;
			else if (case_ignore_strcmp(s, "3d") == 0)
				wpt->fix = fix_3d;
			else if (case_ignore_strcmp(s, "dgps") == 0)
				wpt->fix = fix_dgps;
			else if (case_ignore_strcmp(s, "pps") == 0)
				wpt->fix = fix_pps;
			else wpt->fix = fix_unknown;
			break;

		case fld_utc_date:
			if ((is_localtime < 2) && (date < 0)) {
				date = unicsv_parse_date(s, NULL);
				is_localtime = 0;
			}
			break;

		case fld_utc_time:
			if ((is_localtime < 2) && (time < 0)) {
				time = unicsv_parse_time(s, &msec, &date);
				is_localtime = 0;
			}
			break;

		case fld_speed:
			if (parse_speed(s, &d, 1.0, MYNAME)) {
				WAYPT_SET(wpt, speed, d);
				if (unicsv_detect)
					unicsv_data_type = trkdata;
			}
			break;

		case fld_course:
			WAYPT_SET(wpt, course, atof(s));
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_temperature:
			d = atof(s);
			if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, d);
			break;

		case fld_temperature_f:
			d = atof(s);
			if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, FAHRENHEIT_TO_CELSIUS(d));
			break;

		case fld_heartrate:
			wpt->heartrate = atoi(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_cadence:
			wpt->cadence = atoi(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_proximity:
			if (parse_distance(s, &d, unicsv_proximityscale, MYNAME))
				WAYPT_SET(wpt, proximity, d);
			break;

		case fld_depth:
			if (parse_distance(s, &d, unicsv_depthscale, MYNAME))
				WAYPT_SET(wpt, depth, d);
			break;

		case fld_symbol:
			wpt->icon_descr = xstrdup(s);
			wpt->wpt_flags.icon_descr_is_dynamic = 1;
			break;

		case fld_iso_time:
			is_localtime = 2;	/* fix result */
			wpt->creation_time = xml_parse_time(s, &wpt->microseconds);
			break;

		case fld_time:
			if ((is_localtime < 2) && (time < 0)) {
				time = unicsv_parse_time(s, &msec, &date);
				is_localtime = 1;
			}
			break;

		case fld_date:
			if ((is_localtime < 2) && (date < 0)) {
				date = unicsv_parse_date(s, NULL);
				is_localtime = 1;
			}
			break;

		case fld_year:
			ymd.tm_year = atoi(s);
			break;

		case fld_month:
			ymd.tm_mon = atoi(s);
			break;

		case fld_day:
			ymd.tm_mday = atoi(s);
			break;

		case fld_hour:
			ymd.tm_hour = atoi(s);
			break;

		case fld_min:
			ymd.tm_min = atoi(s);
			break;

		case fld_sec:
			ymd.tm_sec = atoi(s);
			break;

		case fld_datetime:
			if ((is_localtime < 2) && (date < 0) && (time < 0)) {
				time = unicsv_parse_time(s, &msec, &date);
				is_localtime = 1;
			}
			break;

		case fld_ns:
			ns = tolower(s[0]) == 'n' ? 1 : -1;
			wpt->latitude *= ns;
			break;

		case fld_ew:
			ew = tolower(s[0]) == 'e' ? 1 : -1;
			wpt->longitude *= ew;
			break;

		case fld_garmin_city:
		case fld_garmin_postal_code:
		case fld_garmin_state:
		case fld_garmin_country:
		case fld_garmin_addr:
		case fld_garmin_phone_nr:
		case fld_garmin_phone_nr2:
		case fld_garmin_fax_nr:
		case fld_garmin_email:
		case fld_garmin_facility:
			gmsd = GMSD_FIND(wpt);
			if (! gmsd) {
				gmsd = garmin_fs_alloc(-1);
				fs_chain_add(&wpt->fs, (format_specific_data *) gmsd);
			}
			switch(unicsv_fields_tab[column]) {
			case fld_garmin_city: GMSD_SETSTR(city, s); break;
			case fld_garmin_postal_code: GMSD_SETSTR(postal_code, s); break;
			case fld_garmin_state: GMSD_SETSTR(state, s); break;
			case fld_garmin_country: GMSD_SETSTR(country, s); break;
			case fld_garmin_addr: GMSD_SETSTR(addr, s); break;
			case fld_garmin_phone_nr: GMSD_SETSTR(phone_nr, s); break;
			case fld_garmin_phone_nr2: GMSD_SETSTR(phone_nr2, s); break;
			case fld_garmin_fax_nr: GMSD_SETSTR(fax_nr, s); break;
			case fld_garmin_email: GMSD_SETSTR(email, s); break;
			case fld_garmin_facility: GMSD_SETSTR(facility, s); break;
			default: break;
			}
			break;
#ifdef UNICSV_GC_READY
		case fld_gc_id:
		case fld_gc_type:
		case fld_gc_container:
		case fld_gc_terr:
		case fld_gc_diff:
		case fld_gc_is_archived:
		case fld_gc_is_available:
		case fld_gc_exported:
		case fld_gc_last_found:
		case fld_gc_placer:
		case fld_gc_placer_id:
		case fld_gc_hint:

			gc_data = waypt_alloc_gc_data(wpt);

			switch(unicsv_fields_tab[column]) {

			case fld_gc_id:
				gc_data->id = atoi(s);
				if (gc_data->id == 0) gc_data->id = unicsv_parse_gc_id(s);
				break;
			case fld_gc_type: gc_data->type = gs_mktype(s); break;
			case fld_gc_container: gc_data->container = gs_mkcont(s); break;
			case fld_gc_terr: gc_data->terr = atof(s) * 10; break;
			case fld_gc_diff: gc_data->diff = atof(s) * 10; break;
			case fld_gc_is_archived: gc_data->is_archived = unicsv_parse_status(s); break;
			case fld_gc_is_available: gc_data->is_available = unicsv_parse_status(s); break;
			case fld_gc_exported: {
				time_t time, date; int msec;
				time = unicsv_parse_time(s, &msec, &date);
				if (date || time) gc_data->exported = unicsv_adjust_time(time, &date);
				}
				break;
			case fld_gc_last_found: {
				time_t time, date;
				int msec;
				time = unicsv_parse_time(s, &msec, &date);
				if (date || time) gc_data->last_found = unicsv_adjust_time(time, &date);
				}
				break;
			case fld_gc_placer: gc_data->placer = xstrdup(s); break;
			case fld_gc_placer_id: gc_data->placer_id = atoi(s); break;
			case fld_gc_hint: gc_data->hint = xstrdup(s); break;

			default: break;
			}
			break;
#endif
		case fld_terminator: /* dummy */
			checked--;
			break;
		}
	}

	if (checked == 0) {
		waypt_free(wpt);
		return;
	}

	if (is_localtime < 2) {	/* not fixed */
		if ((time >= 0) && (date >= 0)) {
			time_t t = date + time;

			if (is_localtime) {
				struct tm tm;
				tm = *gmtime(&t);
				if (opt_utc)
					wpt->creation_time = mkgmtime(&tm);
				else
					wpt->creation_time = mklocaltime(&tm);
			}
			else
				wpt->creation_time = t;
		}
		else if (time >= 0)
			wpt->creation_time = time;
		else if (date >= 0)
			wpt->creation_time = date;
		else if (ymd.tm_year || ymd.tm_mon || ymd.tm_mday) {
			if (ymd.tm_year < 100) {
				if (ymd.tm_year <= 70) ymd.tm_year += 2000;
				else ymd.tm_year += 1900;
			}
			ymd.tm_year -= 1900;

			if (ymd.tm_mon == 0) ymd.tm_mon = 1;
			if (ymd.tm_mday == 0) ymd.tm_mday = 1;

			ymd.tm_mon--;
			if (opt_utc)
				wpt->creation_time = mkgmtime(&ymd);
			else
				wpt->creation_time = mklocaltime(&ymd);
		}
		else if (ymd.tm_hour || ymd.tm_min || ymd.tm_sec) {
			if (opt_utc)
				wpt->creation_time = mkgmtime(&ymd);
			else
				wpt->creation_time = mklocaltime(&ymd);
		}

		if (msec >= 0)
			wpt->microseconds = msec;

		if (opt_utc)
			wpt->creation_time += atoi(opt_utc) * SECONDS_PER_HOUR;
	}

	/* utm/bng/swiss can be optional */

	if ((wpt->latitude == unicsv_unknown) && (wpt->longitude == unicsv_unknown)) {
		if (utm_zone != -9999) {
			GPS_Math_UTM_EN_To_Known_Datum(&wpt->latitude, &wpt->longitude,
				utm_easting, utm_northing, utm_zone, utm_zc, unicsv_datum_idx);
		}
		else if (bng_zone[0]) {
			if (! GPS_Math_UKOSMap_To_WGS84_M(
				bng_zone, bng_easting, bng_northing,
				&wpt->latitude, &wpt->longitude))
			fatal(MYNAME ": Unable to convert BNG coordinates (%s %.f %.f)!\n",
				bng_zone, bng_easting, bng_northing);
			src_datum = DATUM_WGS84;	/* don't convert afterwards */
		}
		else if ((swiss_easting != unicsv_unknown) && (swiss_northing != unicsv_unknown)) {
			GPS_Math_Swiss_EN_To_WGS84(swiss_easting, swiss_northing,
				&wpt->latitude, &wpt->longitude);
			src_datum = DATUM_WGS84;	/* don't convert afterwards */
		}
	}

	if ((src_datum != DATUM_WGS84) &&
	    (wpt->latitude != unicsv_unknown) && (wpt->longitude != unicsv_unknown)) {
		double alt;
		GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0,
			&wpt->latitude, &wpt->longitude, &alt, src_datum);
	}

	switch(unicsv_data_type) {
	case rtedata:
		if (! unicsv_route) {
			unicsv_route = route_head_alloc();
			route_add_head(unicsv_route);
		}
		route_add_wpt(unicsv_route, wpt);
		break;
	case trkdata:
		if (! unicsv_track) {
			unicsv_track = route_head_alloc();
			track_add_head(unicsv_track);
		}
		track_add_wpt(unicsv_track, wpt);
		break;
	default:
		waypt_add(wpt);
	}
}