tkrajina / gpxpy

gpx-py is a python GPX parser. GPX (GPS eXchange Format) is an XML based file format for GPS tracks.
Apache License 2.0
987 stars 223 forks source link

Save nsmap of GPX in GPXTrack, GPXTrackSegment and GPXTrackPoint #260

Open BobbyCephy opened 1 year ago

BobbyCephy commented 1 year ago

When adding GPXTrack, GPXTrackSegment and GPXTrackPoint objects to a GPX object from parsed gpx files with custom namespaces, the exported XML file can be malformed.

Might the nsmap of a source GPX be saved in its GPXTrack, GPXTrackSegment and GPXTrackPoint objects?

The nsmap of another GPX could then be updated by the nsmap of the added GPXTrack, GPXTrackSegment and GPXTrackPoint objects.

The following script merges the points of tracks 1.txt and 2.txt recorded with Geo Tracker into a new track. Its xml is exported without as bad.txt and with updated nsmap as good.txt and then parsed again:

import gpxpy
from gpxpy import parse

points = []
nsmap = {}

for filename in ["1.txt", "2.txt"]:
    with open(filename, "r") as file:
        gpx = parse(file)
        nsmap.update(gpx.nsmap)

        for track in gpx.tracks:
            for segment in track.segments:
                points.extend(segment.points)

gpx = gpxpy.gpx.GPX()

track = gpxpy.gpx.GPXTrack()
gpx.tracks.append(track)

segment = gpxpy.gpx.GPXTrackSegment()
track.segments.append(segment)

segment.points.extend(points)

filenames = ["bad.txt", "good.txt"]

for update_nsmap in range(2):
    if update_nsmap:
        gpx.nsmap.update(nsmap)

    xml = gpx.to_xml()

    with open(filenames[update_nsmap], "w") as file:
        file.write(xml)

for filename in reversed(filenames):
    with open(filename, "r") as file:
        print("Parsing", filename, end=" ")
        gpx = parse(file)
        print("done\n")

1.txt 2.txt bad.txt good.txt