From d3099acf2d5a10a1363ba2543603609751cdcb0c Mon Sep 17 00:00:00 2001 From: Vincent van der Wal Date: Thu, 28 Mar 2024 11:35:38 +0100 Subject: [PATCH 1/3] added support for trackpoint extensions --- src/GPXParser.js | 60 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/GPXParser.js b/src/GPXParser.js index 1034d51..db5ae90 100644 --- a/src/GPXParser.js +++ b/src/GPXParser.js @@ -64,7 +64,7 @@ gpxParser.prototype.parse = function (gpxstring) { var wpts = [].slice.call(this.xmlSource.querySelectorAll('wpt')); for (let idx in wpts){ - var wpt = wpts[idx]; + const wpt = wpts[idx]; let pt = {}; pt.name = keepThis.getElementValue(wpt, "name"); pt.sym = keepThis.getElementValue(wpt, "sym"); @@ -85,7 +85,7 @@ gpxParser.prototype.parse = function (gpxstring) { var rtes = [].slice.call(this.xmlSource.querySelectorAll('rte')); for (let idx in rtes){ - let rte = rtes[idx]; + const rte = rtes[idx]; let route = {}; route.name = keepThis.getElementValue(rte, "name"); route.cmt = keepThis.getElementValue(rte, "cmt"); @@ -93,11 +93,11 @@ gpxParser.prototype.parse = function (gpxstring) { route.src = keepThis.getElementValue(rte, "src"); route.number = keepThis.getElementValue(rte, "number"); - let type = keepThis.queryDirectSelector(rte, "type"); + const type = keepThis.queryDirectSelector(rte, "type"); route.type = type != null ? type.innerHTML : null; let link = {}; - let linkElem = rte.querySelector('link'); + const linkElem = rte.querySelector('link'); if(linkElem != null){ link.href = linkElem.getAttribute('href'); link.text = keepThis.getElementValue(linkElem, "text"); @@ -106,10 +106,10 @@ gpxParser.prototype.parse = function (gpxstring) { route.link = link; let routepoints = []; - var rtepts = [].slice.call(rte.querySelectorAll('rtept')); + const rtepts = [].slice.call(rte.querySelectorAll('rtept')); for (let idxIn in rtepts){ - let rtept = rtepts[idxIn]; + const rtept = rtepts[idxIn]; let pt = {}; pt.lat = parseFloat(rtept.getAttribute("lat")); pt.lon = parseFloat(rtept.getAttribute("lon")); @@ -131,9 +131,9 @@ gpxParser.prototype.parse = function (gpxstring) { keepThis.routes.push(route); } - var trks = [].slice.call(this.xmlSource.querySelectorAll('trk')); + const trks = [].slice.call(this.xmlSource.querySelectorAll('trk')); for (let idx in trks){ - let trk = trks[idx]; + const trk = trks[idx]; let track = {}; track.name = keepThis.getElementValue(trk, "name"); @@ -142,11 +142,11 @@ gpxParser.prototype.parse = function (gpxstring) { track.src = keepThis.getElementValue(trk, "src"); track.number = keepThis.getElementValue(trk, "number"); - let type = keepThis.queryDirectSelector(trk, "type"); + const type = keepThis.queryDirectSelector(trk, "type"); track.type = type != null ? type.innerHTML : null; let link = {}; - let linkElem = trk.querySelector('link'); + const linkElem = trk.querySelector('link'); if(linkElem != null){ link.href = linkElem.getAttribute('href'); link.text = keepThis.getElementValue(linkElem, "text"); @@ -155,19 +155,51 @@ gpxParser.prototype.parse = function (gpxstring) { track.link = link; let trackpoints = []; - let trkpts = [].slice.call(trk.querySelectorAll('trkpt')); + const trkpts = [].slice.call(trk.querySelectorAll('trkpt')); for (let idxIn in trkpts){ - var trkpt = trkpts[idxIn]; + const trkpt = trkpts[idxIn]; let pt = {}; pt.lat = parseFloat(trkpt.getAttribute("lat")); pt.lon = parseFloat(trkpt.getAttribute("lon")); - let floatValue = parseFloat(keepThis.getElementValue(trkpt, "ele")); + const floatValue = parseFloat(keepThis.getElementValue(trkpt, "ele")); pt.ele = isNaN(floatValue) ? null : floatValue; - let time = keepThis.getElementValue(trkpt, "time"); + const time = keepThis.getElementValue(trkpt, "time"); pt.time = time == null ? null : new Date(time); + if (keepThis.getElementValue(trkpt, "extensions")) { + const temp = keepThis.getElementValue(trkpt, "temp") + const hr = keepThis.getElementValue(trkpt, "hr") + const cad = keepThis.getElementValue(trkpt, "cad") + const course = keepThis.getElementValue(trkpt, "course") + const speed = keepThis.getElementValue(trkpt, "speed") + const roc = keepThis.getElementValue(trkpt, "roc") + const distance = keepThis.getElementValue(trkpt, "distance") + + if (temp !== null) { + pt.temp = parseFloat(temp) + } + if (hr !== null) { + pt.hr = parseFloat(hr) + } + if (cad !== null) { + pt.cad = parseFloat(cad) + } + if (course !== null) { + pt.course = parseFloat(course) + } + if (speed !== null) { + pt.speed = parseFloat(speed) + } + if (roc !== null) { + pt.roc = parseFloat(roc) + } + if (distance !== null) { + pt.distance = parseFloat(distance) + } + } + trackpoints.push(pt); } track.distance = keepThis.calculDistance(trackpoints); From 4279db981fd1a82e6d89a7f6459af6bb402f02a8 Mon Sep 17 00:00:00 2001 From: Vincent van der Wal Date: Thu, 28 Mar 2024 11:47:13 +0100 Subject: [PATCH 2/3] fix toGeoJSON --- dist/GPXParser.min.js | 2 +- src/GPXParser.js | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/dist/GPXParser.min.js b/dist/GPXParser.min.js index d6784c5..1bf0d63 100644 --- a/dist/GPXParser.min.js +++ b/dist/GPXParser.min.js @@ -1 +1 @@ -let gpxParser=function(){this.xmlSource="",this.metadata={},this.waypoints=[],this.tracks=[],this.routes=[]};gpxParser.prototype.parse=function(e){let t=this,l=new window.DOMParser;this.xmlSource=l.parseFromString(e,"text/xml");let r=this.xmlSource.querySelector("metadata");if(null!=r){this.metadata.name=this.getElementValue(r,"name"),this.metadata.desc=this.getElementValue(r,"desc"),this.metadata.time=this.getElementValue(r,"time");let e={},t=r.querySelector("author");if(null!=t){e.name=this.getElementValue(t,"name"),e.email={};let l=t.querySelector("email");null!=l&&(e.email.id=l.getAttribute("id"),e.email.domain=l.getAttribute("domain"));let r={},a=t.querySelector("link");null!=a&&(r.href=a.getAttribute("href"),r.text=this.getElementValue(a,"text"),r.type=this.getElementValue(a,"type")),e.link=r}this.metadata.author=e;let l={},a=this.queryDirectSelector(r,"link");null!=a&&(l.href=a.getAttribute("href"),l.text=this.getElementValue(a,"text"),l.type=this.getElementValue(a,"type"),this.metadata.link=l)}var a=[].slice.call(this.xmlSource.querySelectorAll("wpt"));for(let e in a){var n=a[e];let l={};l.name=t.getElementValue(n,"name"),l.sym=t.getElementValue(n,"sym"),l.lat=parseFloat(n.getAttribute("lat")),l.lon=parseFloat(n.getAttribute("lon"));let r=parseFloat(t.getElementValue(n,"ele"));l.ele=isNaN(r)?null:r,l.cmt=t.getElementValue(n,"cmt"),l.desc=t.getElementValue(n,"desc");let i=t.getElementValue(n,"time");l.time=null==i?null:new Date(i),t.waypoints.push(l)}var i=[].slice.call(this.xmlSource.querySelectorAll("rte"));for(let e in i){let l=i[e],r={};r.name=t.getElementValue(l,"name"),r.cmt=t.getElementValue(l,"cmt"),r.desc=t.getElementValue(l,"desc"),r.src=t.getElementValue(l,"src"),r.number=t.getElementValue(l,"number");let a=t.queryDirectSelector(l,"type");r.type=null!=a?a.innerHTML:null;let n={},o=l.querySelector("link");null!=o&&(n.href=o.getAttribute("href"),n.text=t.getElementValue(o,"text"),n.type=t.getElementValue(o,"type")),r.link=n;let u=[];var s=[].slice.call(l.querySelectorAll("rtept"));for(let e in s){let l=s[e],r={};r.lat=parseFloat(l.getAttribute("lat")),r.lon=parseFloat(l.getAttribute("lon"));let a=parseFloat(t.getElementValue(l,"ele"));r.ele=isNaN(a)?null:a;let n=t.getElementValue(l,"time");r.time=null==n?null:new Date(n),u.push(r)}r.distance=t.calculDistance(u),r.elevation=t.calcElevation(u),r.slopes=t.calculSlope(u,r.distance.cumul),r.points=u,t.routes.push(r)}var o=[].slice.call(this.xmlSource.querySelectorAll("trk"));for(let e in o){let l=o[e],r={};r.name=t.getElementValue(l,"name"),r.cmt=t.getElementValue(l,"cmt"),r.desc=t.getElementValue(l,"desc"),r.src=t.getElementValue(l,"src"),r.number=t.getElementValue(l,"number");let a=t.queryDirectSelector(l,"type");r.type=null!=a?a.innerHTML:null;let n={},i=l.querySelector("link");null!=i&&(n.href=i.getAttribute("href"),n.text=t.getElementValue(i,"text"),n.type=t.getElementValue(i,"type")),r.link=n;let s=[],p=[].slice.call(l.querySelectorAll("trkpt"));for(let e in p){var u=p[e];let l={};l.lat=parseFloat(u.getAttribute("lat")),l.lon=parseFloat(u.getAttribute("lon"));let r=parseFloat(t.getElementValue(u,"ele"));l.ele=isNaN(r)?null:r;let a=t.getElementValue(u,"time");l.time=null==a?null:new Date(a),s.push(l)}r.distance=t.calculDistance(s),r.elevation=t.calcElevation(s),r.slopes=t.calculSlope(s,r.distance.cumul),r.points=s,t.tracks.push(r)}},gpxParser.prototype.getElementValue=function(e,t){let l=e.querySelector(t);return null!=l?null!=l.innerHTML?l.innerHTML:l.childNodes[0].data:l},gpxParser.prototype.queryDirectSelector=function(e,t){let l=e.querySelectorAll(t),r=l[0];if(l.length>1){let l=e.childNodes;for(idx in l)elem=l[idx],elem.tagName===t&&(r=elem)}return r},gpxParser.prototype.calculDistance=function(e){let t={},l=0,r=[];for(var a=0;a0&&(t+=e)}}for(var n=[],i=0,s=(a=0,e.length);a1){let l=e.childNodes;for(idx in l)elem=l[idx],elem.tagName===t&&(a=elem)}return a},gpxParser.prototype.calculDistance=function(e){let t={},l=0,a=[];for(var r=0;r0&&(t+=e)}}for(var n=[],s=0,o=(r=0,e.length);r Date: Thu, 28 Mar 2024 12:09:57 +0100 Subject: [PATCH 3/3] update type definitions --- index.d.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index 1301898..ad2e677 100644 --- a/index.d.ts +++ b/index.d.ts @@ -49,11 +49,18 @@ export type Point = { lon: number ele: number time: Date + temp?: number + hr?: number + cad?: number + course?: number + speed?: number + roc?: number + distance?: number } export type Distance = { total: number - cumul: number + cumul: number[] } export type Elevation = {