Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

gpx_merge cleanup and waypoint limit option

  • Loading branch information...
commit 013bd5e4619dae5ce2bf44889c1053581e85d37a 1 parent 259776d
Bernhard Tittelbach authored
Showing with 58 additions and 52 deletions.
  1. +8 −1 README.mediawiki
  2. +50 −51 gpx_merge.py
View
9 README.mediawiki
@@ -121,6 +121,9 @@ Suppose you generate multiple overlapping pocket-queries, you put them onto your
No more !!
Use gpx_merge.py to merge all <tt>*-wpts.gpx</tt> into one <tt>waypoints.gpx</tt> and: problem solved!
+Your waypoint files is larger than the maximum number of waypoints supported by your GPS ?
+Use the limit option <tt>-l</tt> to set a maximum number of waypoints to write into the output file.
+
==== Requirements ====
* python3
@@ -128,9 +131,13 @@ Use gpx_merge.py to merge all <tt>*-wpts.gpx</tt> into one <tt>waypoints.gpx</tt
==== Usage ====
+ Options:
+ -o <output-gpx-file>
+ -l <maximum number of waypoints in output-gpx-file>
+
Syntax:
./gpx_merge.py -o <output-gpx-file> <gpx-file1> [gpx-file2 [...]]
-
+
Example:
./gpx_merge.py -o london-wpts.gpx london1-wpts.gpx london2-wpts.gpx london3-wpts.gpx
View
101 gpx_merge.py
@@ -5,21 +5,17 @@
import sys
-import os
-import fnmatch
import getopt
-#import xml.etree.ElementTree as etree
from lxml import etree
-import re
-import urllib.request, urllib.parse, urllib.error
-import atexit
-import imghdr
import codecs
-from multiprocessing import Pool, Lock, RLock
+from itertools import *
def usage():
print("This tool will merge two GPX Files")
+ print("\nOptions:")
+ print(" -o <output-gpx-file>")
+ print(" -l <maximum number of waypoints in output-gpx-file>")
print("\nSyntax:")
print(" %s -o <output-gpx-file> <gpx-file1> [gpx-file2 [...]]" % (sys.argv[0]))
@@ -31,84 +27,78 @@ def guessEncodingFromBOM(filename):
return codec
return "utf_8"
+def calcBounds(wpt, bounds):
+ comp_func = {"max":max, "min":min}
+ for attrib in ["minlat", "minlon", "maxlat", "maxlon"]:
+ if not bounds.attrib.has_key(attrib):
+ bounds.set(attrib,wpt.get(attrib[-3:]))
+ else:
+ try:
+ cfun = comp_func[attrib[:3]]
+ bounds.attrib[attrib] = cfun(wpt.get(attrib[-3:]), bounds.get(attrib))
+ except KeyError:
+ pass
+
if __name__ == '__main__':
######### Global Vars ##########
- num_threads_=None #None means: use num_cpu threads
- imagemagick_available_=False
- geotag_images_=True
- delete_old_images_=False
- re_imgnamefilter_=None
- lat_offset_=0.00
- lon_offset_=0.00015
- img_save_path_="./"
- dir_lock_filename_="gc_spoiler_pics.lock"
- look_for_gcjpg_files_and_skip_gc_=False
- files_in_savedir_=None
- done_file_=None
- done_list_= []
- done_list_lock_=Lock()
- gc_in_gpx_list_=[]
- images_ext_=".jpg".lower()
- print_lock_=RLock()
+ output_file_ = None
+ wpt_limit_ = None
+
######### Parse Arguments ##########
try:
- opts, files = getopt.gnu_getopt(sys.argv[1:], "ho:", ["help","output="])
+ opts, files = getopt.gnu_getopt(sys.argv[1:], "ho:l:", ["help","output=","limit="])
except getopt.GetoptError as e:
- print("ERROR: Invalid Option: " +str(e))
+ print("ERROR: Invalid Option: " +str(e), file=sys.stderr)
usage()
sys.exit(1)
- output_file_ = None
-
for o, a in opts:
if o in ["-h","--help"]:
usage()
sys.exit()
elif o in ["-o","--output"]:
- output_file_=a
+ output_file_ = a
+ elif o in ["-l","--limit"]:
+ try:
+ wpt_limit_ = int(a)
+ except ValueError:
+ print("Warning: given limit is not an integer, ignoring it...",file=sys.stderr)
######### Main Program ##########
if len(files) <1 or output_file_ is None:
+ print("ERROR: no input files and/or no output file given",file=sys.stderr)
usage()
sys.exit()
-
wptdict = {}
gpxmetainfo = {}
nsmap = {}
bounds = etree.Element ( 'bounds' , nsmap = nsmap)
- comp_func = {"max":max, "min":min}
xml_parser = etree.XMLParser(encoding="utf-8")
for gpxfile in files:
fgpx = open(gpxfile, encoding=guessEncodingFromBOM(gpxfile))
try:
gpxtree = etree.parse(fgpx,xml_parser).getroot()
nsmap.update(gpxtree.nsmap) #get namespace info from gpx files
- except (etree.ParserError,etree.DocumentInvalid) as e:
- parprint("ERROR, could not parse %s" % (gpxfile))
- parprint("\tErrorMsg: %s" % (str(e)))
+ except (etree.ParserError,etree.DocumentInvalid,etree.XMLSyntaxError) as e:
+ print("Warning: could not parse %s" % (gpxfile), file=sys.stderr)
+ print("\tErrorMsg: %s" % (str(e)), file=sys.stderr)
continue
fgpx.close()
-
+
for wpt_elem in gpxtree:
- if wpt_elem.tag[-3:] == "wpt":
- for cache_elem in wpt_elem:
- if cache_elem.tag[-4:] == "name":
- wptname = cache_elem.text.strip()
+ if wpt_elem.tag == "wpt" or (wpt_elem.tag.startswith("{http://www.topografix.com/GPX/") and wpt_elem.tag.endswith("}wpt")):
+ calcBounds(wpt_elem, bounds)
+ for wpt_subelem in wpt_elem:
+ if wpt_subelem.tag == "name" or (wpt_subelem.tag.startswith("{http://www.topografix.com/GPX/") and wpt_subelem.tag.endswith("}name")):
+ wptname = wpt_subelem.text.strip()
wptdict[wptname] = wpt_elem
+ break
elif wpt_elem.tag[-6:] == "bounds":
- for attrib in ["minlat", "minlon", "maxlat", "maxlon"]:
- if not bounds.attrib.has_key(attrib):
- bounds.attrib[attrib] = wpt_elem.attrib[attrib]
- else:
- try:
- cfun = comp_func[attrib[0:3]]
- bounds.attrib[attrib] = cfun(wpt_elem.get(attrib), bounds.get(attrib))
- except KeyError:
- pass
+ pass
else:
gpxmetainfo[wpt_elem.tag] = wpt_elem
@@ -116,13 +106,22 @@ def guessEncodingFromBOM(filename):
newgpx.attrib["version"]="1.0"
newgpx.attrib["creator"]="GPX Merge Tool"
doc = etree.ElementTree ( newgpx)
+
+ if wpt_limit_ is None:
+ wpt_limit_ = len(wptdict)
+ else:
+ wpt_limit_ = min(wpt_limit_,len(wptdict))
for elem in gpxmetainfo.values():
newgpx.append(elem)
newgpx.append(bounds)
- for elem in wptdict.values():
+ for elem in islice(wptdict.values(),wpt_limit_):
newgpx.append(elem)
with open(output_file_, "wb") as nfh:
nfh.truncate()
- nfh.write(etree.tostring(doc,method="xml",xml_declaration=True,encoding="utf-8"))
+ nfh.write(etree.tostring(doc,method="xml",xml_declaration=True,encoding="utf-8"))
+ print ("%d waypoints merged into %s" % (wpt_limit_, output_file_))
+ if wpt_limit_ < len(wptdict):
+ print("Waypoint limit was exceeded and the following waypoints were dropped:")
+ print(", ".join(islice(wptdict.keys(),wpt_limit_,None)))
Please sign in to comment.
Something went wrong with that request. Please try again.