|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
GoPal tracklog patchHi list,
attached (I hope) you will find the files to patch gpsbabel to support the logging format of GoPal powered gps navigation devices. Any comments are welcome! Regards Juergen This is the first try to implement the GoPal track log format into gpsbabel. It was developed using MSVC2005, but was also tested on a Suse10.3 linux using gcc. The main reason to implement this easy format were 3 points: - I did'nt found a way to tell gpsbabel a starting date, from wich the internal timestamps count up - it would be better to leave the filename parsing do a program ... - in my logs are annoying position errors I want to sort out Questions & bug reports are welcome @ Juergen.Neumann (ät) online.com Good luck Jürgen /* Copyright (C) 2008 Jürgen Neumann, Juergen.Neumann@... Copyright (C) 2005 Robert Lipe, robertlipe@... (based on nmea.c) Copyright (C) 20XX probably many others from the gpsbabel development team ;-) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA ===================================================================================== This file allows gpsbabel to read and write the internal track log format used by GoPal navigation systems. They produce a simple line-oriented format with one point per second. Unfortunately the the data does not contain a valid date, only some kind of timetick, together with each point (perhaps by mistake ??). So we have to parse the filename for a valid starting date and add the timeoffset. Second problem (at least to me) was that irregularly stupid errors were in the data, i.e. only one data point shows a totally wrong longitude or latitude. Everything else in the dataset seems ok, so I needed a way to sort out these errors. My solution is to calculate the speed between successive points and drop points not between minspeed and maxspeed. This way I can sort out most of this annoying bugs, a side effect is that if a minimum speed > 0 is set points with the same coodinates are also dropped. Fileformat GoPal TICK; TIME UTC; LONG; LAT; HEIGHT; SPEED km/h; FIX; HDOP; SAT 3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 Filenames: trackYYYYMMDD_HHMMSS.trk A_YYYYMMDD_HHMMSS.trk with HHMMSS local time (not UTC) History 2008-07-18 initial release of Version 0.1 */ #include "defs.h" #include <ctype.h> #include "csv_util.h" #include <time.h> #include "strptime.h" #include "jeeps/gpsmath.h" #include "grtcirc.h" #define MYNAME "gopal" static gbfile *fin, *fout; static struct tm tm,filenamedate, trackdate; time_t tx; char tmp[64]; char routename[64]; static char *optdate=NULL; static char *optmaxspeed=NULL; static char *optminspeed=NULL; static char *optclean= NULL; static double minspeed,maxspeed; static struct tm opt_tm; /* converted "date" parameter */ static arglist_t gopal_args[] = { {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, {"maxspeed", &optmaxspeed, "The maximum speed traveling from waypoint to waypoint.", "200", ARGTYPE_INT, "1", "1000" }, {"minspeed", &optminspeed, "The minimum speed traveling from waypoint to waypoint.\nset >0 to remove duplicate waypoints", "0", ARGTYPE_INT, "0", "999" }, {"clean", &optclean, "Cleanup common errors in trackdata", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, ARG_TERMINATOR }; #define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL int gopal_check_line(char *line) { char *c = line; int i = 0; while ((c = strchr(c, ','))) { c++; i++; } if ((i != 8)&& (global_opts.debug_level > 1)) { snprintf(tmp,sizeof(tmp),MYNAME " Warning:\"%s\"\n",line); fprintf(stderr,tmp); } return i; } /******************************************************************************* * %%% global callbacks called by gpsbabel main process %%% * *******************************************************************************/ static void gopal_rd_init(const char *fname) {char buff[32]; char *ck; char filename[255]; char *delim; CHECK_BOOL(optclean); if (optminspeed) { minspeed=atof(optminspeed); if (global_opts.debug_level > 1) fprintf(stderr,"options from command line : gopal minspeed = %s\n",optminspeed); } else minspeed=0; if (optmaxspeed) { maxspeed=atof(optmaxspeed); if (global_opts.debug_level > 1) fprintf(stderr,"options from command line : gopal maxspeed = %s\n",optmaxspeed); } else maxspeed=200; if (global_opts.debug_level > 1) fprintf(stderr,"setting minspeed to %5.1lf km/h and maxspeed to %5.1lf km/h\n",minspeed,maxspeed); fin = gbfopen(fname, "r", MYNAME); memset(buff,0,sizeof(buff)); if (optdate) { memset(&opt_tm, 0, sizeof(opt_tm)); ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); else if (opt_tm.tm_year < 70) fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); tx = mkgmtime(&opt_tm); } else { /* remove path */ delim = strrchr(fname, '/'); delim = strrchr(fname, '\\'); if ((delim)&&(strlen(delim)>8) ) sprintf((char*)&filename, "%s", delim+1); //copy only filename without path else sprintf((char*)&filename, "%s", fname); // copy original filename (probably without path) if ((strncmp(filename,"track",5)==0)&&(strlen(filename)>13)) // we need at least 13 letters: trackYYYYMMDD... { strncpy(&buff[0],&filename[5],8); } else if ((strncmp(filename,"A_",2)==0)&&(strlen(filename)>10))// here we expect at least 10 letters: A_YYYYMMDD... { strncpy(&buff[0],&filename[2],8); } // in buff we should now have something wich looks like a valid date starting with YYYYMMDD ck = (char *)strptime(buff, "%Y%m%d", &filenamedate); if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"optdate\" switch!\n", buff); else if (filenamedate.tm_year < 70) fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); tx= mkgmtime(&filenamedate); } } static void gopal_rd_deinit(void) { gbfclose(fin); } static void gopal_read(void) { char *buff; char *str, *c; int column; long line; double hmsd,speed; int fix, hms; route_head *route; waypoint *wpt, *lastwpt=NULL; double long_old,lat_old; char tbuffer[64]; long_old=0;lat_old=0; strftime(routename,sizeof(routename),"Tracklog %c",localtime(&tx)); route = route_head_alloc(); route->rte_name=xstrdup(routename); route_add_head(route); line=0; while ((buff = gbfgetstr(fin))) { str = buff = lrtrim(buff); if (*buff == '\0') continue; if (gopal_check_line(buff)!=8)continue; wpt = waypt_new(); column = -1; // the format of gopal is quite simple. Unfortunately the developers forgot the date as the first element... //TICK; TIME; LONG; LAT; HEIGHT; SPEED; Fix; HDOP; SAT //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 c = csv_lineparse(str, ",", "", column++); while (c != NULL) { switch(column) { case 0: /* "-" */ /* unknown fields for the moment */ //sscanf(c, "%llu", &wpt->microseconds); break; case 1: /* Time UTC */ sscanf(c,"%lf",&hmsd); hms = (int) hmsd; tm.tm_sec = hms % 100; hms = hms / 100; tm.tm_min = hms % 100; hms = hms / 100; tm.tm_hour = hms % 100; tm.tm_year=trackdate.tm_year; tm.tm_mon=trackdate.tm_mon; tm.tm_mday=trackdate.tm_mday; wpt->creation_time = tx+((((time_t)tm.tm_hour * 60) + tm.tm_min) * 60) + tm.tm_sec; strftime(tbuffer, sizeof(tbuffer), "%H:%M:%S", gmtime(&wpt->creation_time)); break; case 2: /* longitude */ sscanf(c, "%lf", &wpt->longitude); break; case 3: /* latitude */ sscanf(c, "%lf", &wpt->latitude); break; case 4: /* altitude */ sscanf(c, "%lf", &wpt->altitude); break; case 5: /* speed */ //sscanf(c, "%lf", &wpt->speed); wpt->speed=atof(c); break; case 6: /* type of fix */ sscanf(c, "%d", &fix); //my device shows only 0 or 2 //should i guess from no of sats if 2d or 3d? switch (fix) { case 0: wpt->fix = fix_none;break; case 2: wpt->fix = fix_2d;break; //case 3: wpt->fix = fix_3d;break; //case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ //case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ default: wpt->fix = fix_unknown; break; } break; case 7: /* hdop */ wpt->hdop = atof(c); //sscanf(c, "%lf", &wpt->hdop); does not work ??? //wpt->vdop=0;wpt->hdop=0; break; case 8: /* number of sats */ sscanf(c, "%d", &wpt->sat); break; } c = csv_lineparse(NULL, ",", "", column++); } line++; if ((wpt->fix != fix_none)&&(lat_old==0)){ //first-time init lat_old=wpt->latitude; long_old=wpt->longitude; //route_add_wpt(route, wpt); lastwpt=wpt; } //calculate the speed to reach this waypoint from the last. This way I try to sort out invalid waypoints speed=0; if (lastwpt !=NULL) { speed=3.6*radtometers(gcdist(RAD(lastwpt->latitude), RAD(lastwpt->longitude), RAD(wpt->latitude), RAD(wpt->longitude))) / abs(wpt->creation_time - lastwpt->creation_time); //printf("speed line %d %lf \n",line,speed); } /* Error handling: in the tracklog of my device sometimes "jump" waypoints ;-) */ if ((optclean) && (((wpt->longitude==0.0)|| (wpt->latitude==0.0)||(abs(wpt->latitude)>90)||(abs(wpt->longitude)>180))|| ((speed>maxspeed)||(speed<minspeed))) ) { if (global_opts.debug_level > 1) fprintf(stderr,"Problem in or around line %5lu: \"%s\" %lf km/h\n",line,buff,speed); } else { if (global_opts.debug_level > 1) fprintf(stderr,"valid line %5lu: \"%s\" %lf km/h\n",line,buff,speed); lastwpt=wpt; long_old=wpt->longitude; lat_old=wpt->latitude; route_add_wpt(route,wpt); waypt_add(waypt_dupe( wpt)); } } } static void gopal_route_hdr(const route_head *route) { } static void gopal_route_tlr(const route_head *rte) { } static void gopal_write_waypt(const waypoint *wpt) { char tbuffer[64]; int fix=fix_unknown; //TICK; TIME; LONG; LAT; HEIGHT; SPEED; UN; HDOP; SAT //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 strftime(tbuffer, sizeof(tbuffer), "%H%M%S", gmtime(&wpt->creation_time)); if (wpt->fix!=fix_unknown) { switch (wpt->fix) { case fix_none: fix = 0; break; case fix_2d: fix = 2; break; default: fix = 0; break; } } gbfprintf(fout, "%llu, %s, %lf, %lf, %5.1lf, %5.4lf, %d, %lf, %d\n",wpt->creation_time,tbuffer, wpt->longitude, wpt->latitude,wpt->altitude, wpt->speed,fix,wpt->hdop,wpt->sat); } static void gopal_wr_init(const char *fname) { fout = gbfopen(fname, "w", MYNAME); } static void gopal_wr_deinit(void) { gbfclose(fout); } static void gopal_write(void) { //route_disp_all(gopal_route_hdr, gopal_route_tlr, gopal_write_waypt); if (global_opts.objective == wptdata) { waypt_disp_all(gopal_write_waypt); } else //if (global_opts.objective == rtedata) { route_disp_all(gopal_route_hdr, gopal_route_tlr, gopal_write_waypt); } } static void gopal_exit(void) /* optional */ { } /**************************************************************************/ // capabilities below means: we can only read and write waypoints // ff_vecs_t gopal_vecs = { ff_type_file, { ff_cap_read | ff_cap_write /* waypoints */, ff_cap_none /* tracks */, ff_cap_read | ff_cap_write /* routes */ }, gopal_rd_init, gopal_wr_init, gopal_rd_deinit, gopal_wr_deinit, gopal_read, gopal_write, gopal_exit, gopal_args, CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ Index: Makefile.in =================================================================== RCS file: /cvsroot/gpsbabel/gpsbabel/Makefile.in,v retrieving revision 1.120 diff -u -r1.120 Makefile.in --- Makefile.in 25 Jun 2008 04:03:32 -0000 1.120 +++ Makefile.in 20 Jul 2008 11:40:20 -0000 @@ -59,7 +59,7 @@ wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o alan.o vitovtt.o \ ggv_log.o g7towin.o garmin_gpi.o lmx.o random.o xol.o dg-100.o \ navilink.o mtk_logger.o ik3d.o osm.o destinator.o exif.o vidaone.o \ - igo8.o + igo8.o gopal.o FMTS=@FMTS@ Index: vecs.c =================================================================== RCS file: /cvsroot/gpsbabel/gpsbabel/vecs.c,v retrieving revision 1.172 diff -u -r1.172 vecs.c --- vecs.c 19 Jun 2008 02:26:30 -0000 1.172 +++ vecs.c 20 Jul 2008 11:41:00 -0000 @@ -140,6 +140,7 @@ extern ff_vecs_t destinator_itn_vecs; extern ff_vecs_t exif_vecs; extern ff_vecs_t vidaone_vecs; +extern ff_vecs_t gopal_vecs; static vecs_t vec_list[] = { @@ -795,6 +796,12 @@ "IGO8 .trk", "trk" }, + { + &gopal_vecs, + "gopal", + "GoPal GPS track log (.trk)", + "trk" + }, #endif // MAXIMAL_ENABLED { NULL, ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Gpsbabel-code mailing list http://www.gpsbabel.org Gpsbabel-code@... https://lists.sourceforge.net/lists/listinfo/gpsbabel-code |
|
|
Re: GoPal tracklog patchHello.
This basically looks pretty good to me. Can you please offer an entry for our test suite (testo) and some kind of doc on what a "GoPal" is and how one would use the resulting files with it? I'll commit this change once it's documented and testable. It looks like good stuff! Thanx, RJL On Sun, Jul 20, 2008 at 8:10 AM, "Dr. Jürgen Neumann" <Juergen.Neumann@...> wrote: Hi list, ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Gpsbabel-code mailing list http://www.gpsbabel.org Gpsbabel-code@... https://lists.sourceforge.net/lists/listinfo/gpsbabel-code |
| Free Forum Powered by Nabble | Forum Help |