vincentneo / CoreGPX

A library for parsing and creation of GPX location files. Purely Swift.
https://www.vincent-neo.com
MIT License
261 stars 57 forks source link

System for easier use of extensions dependent on schema #58

Open edorphy opened 5 years ago

edorphy commented 5 years ago

Apple Health exports any workout routes as GPX as of iOS 13.1. It would be nice if this library supported generating files with the same extension fields on tracepoints. Specifically the other properties on CLLocation objects, speed, course, hAcc, vAcc.

Sample generated from watch/iPhone simulator and then exported.


<trkpt lon="-122.023202" lat="37.330198">
    <ele>0.000000</ele>
    <time>2019-10-25T14:39:48Z</time>
    <extensions>
        <speed>3.830000</speed>
        <course>95.680000</course>
        <hAcc>5.000000</hAcc>
        <vAcc>-1.000000</vAcc>
    </extensions>
</trkpt>

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="Apple Health Export" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
  <metadata>
    <time>2019-10-25T14:49:14Z</time>
  </metadata>
  <trk>
    <name>Route 2019-10-25 9:41am</name>
    <trkseg>
      <trkpt lon="-122.023291" lat="37.330206"><ele>0.000000</ele><time>2019-10-25T14:39:46Z</time><extensions><speed>3.760000</speed><course>89.690002</course><hAcc>5.000000</hAcc><vAcc>-1.000000</vAcc></extensions></trkpt>
      <trkpt lon="-122.023246" lat="37.330203"><ele>0.000000</ele><time>2019-10-25T14:39:47Z</time><extensions><speed>3.840000</speed><course>93.190002</course><hAcc>5.000000</hAcc><vAcc>-1.000000</vAcc></extensions></trkpt>
      <trkpt lon="-122.023202" lat="37.330198"><ele>0.000000</ele><time>2019-10-25T14:39:48Z</time><extensions><speed>3.830000</speed><course>95.680000</course><hAcc>5.000000</hAcc><vAcc>-1.000000</vAcc></extensions></trkpt>
    </trkseg>
  </trk>
</gpx>`
vincentneo commented 5 years ago

Hi @edorphy,

Technically, it is possible to read and write extensions data using GPXExtensions right now. Maybe you would want to try that out? It surely isn't as polished as a hard coded approach, but that is what it is for now. I am thinking that it maybe possible where I support some common extensions types like from Garmin, and this, etc.

Looking at the export though, I am surprised to see that Apple appears to be generating a rather non standard GPX file, considering that there is no extension schema provided in the gpx tag.

edorphy commented 5 years ago

@vincentneo

I did try using the extensions and extension elements. I was able to get it close to Apple, but it added the parent tag, as expected from the library.

When I was reading the gpx spec (web ref from topografix), I couldn't discern if the extensions type could be any xml nodes, or if they needed to be nested within a parent schema. Is this what you were referring to as apple being non-standard?

Thanks for the reply!

vincentneo commented 5 years ago

@edorphy

Did some codes, and found GPXExtensions rather defective at this point - i just didn't notice it. Using .append(parent: nil, contents: ["":""]) shouldn't generate a parent tag, but it did.

Will attempt to fix in a couple of days hopefully.

By the way, the reason why I said that Apple's approach seems non-standard is because of this:

<gpx
  version="1.1"
  creator="Runkeeper - http://www.runkeeper.com"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.topografix.com/GPX/1/1"
  xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
  xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1">

Normally, a schema will be appended to the gpx tag. The extensions in the whole file should follow what is listed in the schema, but Apple's approach in your example did not show that, which, meant that they may change something near future, without telling the user/app developer of what it should be.