[Gpsbabel-code] more sort filter options
Brought to you by:
robertl
From: Paul F. <pg...@fo...> - 2006-08-14 22:10:04
|
hello -- today i needed to sort a list of waypoints by lat/lon, and was a little surprised that gpsbabel doesn't already do this. (unless i missed it. i hope not.) this patch implements sorting by latitude major, longitude minor, or vice versa. since my reason for sorting was also to eliminated duplicate waypoints, i also implemented the effective equivalent of "sort -u" -- if the "unique" option is present along with a sort mode, then items will be made unique vis a vis that "key", after sorting. this is against 1.3.0 -- my cvs repository no longer works, and i think i recall hearing that gpsbabel has switched to svn. hopefully sort.c hasn't changed much. of course, this also means i didn't have source for the doc to update. feel free to tell me to resubmit properly, if you're so inclined... :-) paul diff -ru gpsbabel-1.3.0.orig/sort.c gpsbabel-1.3.0/sort.c --- gpsbabel-1.3.0.orig/sort.c Fri May 12 17:43:07 2006 +++ gpsbabel-1.3.0/sort.c Mon Aug 14 17:57:12 2006 @@ -28,12 +28,15 @@ sm_gcid, sm_shortname, sm_description, - sm_time + sm_time, + sm_latlon, + sm_lonlat } sort_mode_; sort_mode_ sort_mode = sm_shortname; /* How are we sorting these? */ static char *opt_sm_gcid, *opt_sm_shortname, *opt_sm_description, *opt_sm_time; +static char *opt_sm_latlon, *opt_sm_lonlat, *opt_sm_uniq; static arglist_t sort_args[] = { @@ -45,6 +48,12 @@ NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"time", &opt_sm_time, "Sort by time", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"latlon", &opt_sm_latlon, "Sort by latitude and longitude", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"lonlat", &opt_sm_lonlat, "Sort by longitude and latitude", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"unique", &opt_sm_uniq, "After sorting, eliminate duplicates", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, ARG_TERMINATOR }; @@ -54,11 +63,31 @@ const waypoint *x1 = *(waypoint **)a; const waypoint *x2 = *(waypoint **)b; + switch (sort_mode) { - case sm_gcid: return x1->gc_data.id > x2->gc_data.id; + case sm_gcid: return x1->gc_data.id - x2->gc_data.id; case sm_shortname: return strcmp (x1->shortname, x2->shortname); case sm_description: return strcmp (x1->description, x2->description); - case sm_time: return x1->creation_time > x2->creation_time; + case sm_time: return x1->creation_time - x2->creation_time; + case sm_latlon: + if (x1->latitude == x2->latitude) { + if (x1->longitude == x2->longitude) return 0; + else if (x1->longitude < x2->longitude) return -1; + else return 1; + } + else if (x1->latitude < x2->latitude) return -1; + else return 1; + break; + + case sm_lonlat: + if (x1->longitude == x2->longitude) { + if (x1->latitude == x2->latitude) return 0; + else if (x1->latitude < x2->latitude) return -1; + else return 1; + } + else if (x1->longitude < x2->longitude) return -1; + else return 1; + break; default: abort(); return 0; /* Internal caller error. */ } } @@ -68,6 +97,7 @@ { queue * elem, * tmp; waypoint ** comp; + waypoint *wprev = 0; int i = 0, wc; wc = waypt_count(); @@ -91,6 +121,22 @@ if (comp) xfree(comp); + + if (!opt_sm_uniq) + return; + + /* find duplicate neighbors */ + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + if (!wprev) { + wprev = (waypoint *)elem; + continue; + } + if (sort_comp(&wprev, &elem) == 0) { + waypt_del((waypoint *)elem); + } else { + wprev = (waypoint *)elem; + } + } } void @@ -104,6 +150,11 @@ sort_mode = sm_description; if (opt_sm_time) sort_mode = sm_time; + if (opt_sm_latlon) + sort_mode = sm_latlon; + if (opt_sm_lonlat) + sort_mode = sm_lonlat; + } filter_vecs_t sort_vecs = { =--------------------- paul fox, pg...@fo... (arlington, ma, where it's 74.7 degrees) |