/* https://github.com/Luuka/GPXParser.js GPXParser.js v3.0.8 07/07/2024 Copyright (c) 2018 Lucas Trebouet Voisin */ let gpxParser=function(){this.xmlSource="";this.metadata={};this.waypoints=[];this.tracks=[];this.routes=[]};gpxParser.prototype.parse=function(gpxstring){let keepThis=this;let domParser=new window.DOMParser();this.xmlSource=domParser.parseFromString(gpxstring,'text/xml');let metadata=this.xmlSource.querySelector('metadata');if(metadata!=null){this.metadata.name=this.getElementValue(metadata,"name");this.metadata.desc=this.getElementValue(metadata,"desc");this.metadata.time=this.getElementValue(metadata,"time");let author={};let authorElem=metadata.querySelector('author');if(authorElem!=null){author.name=this.getElementValue(authorElem,"name");author.email={};let emailElem=authorElem.querySelector('email');if(emailElem!=null){author.email.id=emailElem.getAttribute("id");author.email.domain=emailElem.getAttribute("domain")}let link={};let linkElem=authorElem.querySelector('link');if(linkElem!=null){link.href=linkElem.getAttribute('href');link.text=this.getElementValue(linkElem,"text");link.type=this.getElementValue(linkElem,"type")}author.link=link}this.metadata.author=author;let link={};let linkElem=this.queryDirectSelector(metadata,'link');if(linkElem!=null){link.href=linkElem.getAttribute('href');link.text=this.getElementValue(linkElem,"text");link.type=this.getElementValue(linkElem,"type");this.metadata.link=link}}var wpts=[].slice.call(this.xmlSource.querySelectorAll('wpt'));for(let idx in wpts){var wpt=wpts[idx];let pt={};pt.name=keepThis.getElementValue(wpt,"name");pt.sym=keepThis.getElementValue(wpt,"sym");pt.lat=parseFloat(wpt.getAttribute("lat"));pt.lon=parseFloat(wpt.getAttribute("lon"));let floatValue=parseFloat(keepThis.getElementValue(wpt,"ele"));pt.ele=isNaN(floatValue)?null:floatValue;pt.cmt=keepThis.getElementValue(wpt,"cmt");pt.desc=keepThis.getElementValue(wpt,"desc");let time=keepThis.getElementValue(wpt,"time");pt.time=time==null?null:new Date(time);keepThis.waypoints.push(pt)}var rtes=[].slice.call(this.xmlSource.querySelectorAll('rte'));for(let idx in rtes){let rte=rtes[idx];let route={};route.name=keepThis.getElementValue(rte,"name");route.cmt=keepThis.getElementValue(rte,"cmt");route.desc=keepThis.getElementValue(rte,"desc");route.src=keepThis.getElementValue(rte,"src");route.number=keepThis.getElementValue(rte,"number");let type=keepThis.queryDirectSelector(rte,"type");route.type=type!=null?type.innerHTML:null;let link={};let linkElem=rte.querySelector('link');if(linkElem!=null){link.href=linkElem.getAttribute('href');link.text=keepThis.getElementValue(linkElem,"text");link.type=keepThis.getElementValue(linkElem,"type")}route.link=link;let routepoints=[];var rtepts=[].slice.call(rte.querySelectorAll('rtept'));for(let idxIn in rtepts){let rtept=rtepts[idxIn];let pt={};pt.lat=parseFloat(rtept.getAttribute("lat"));pt.lon=parseFloat(rtept.getAttribute("lon"));let floatValue=parseFloat(keepThis.getElementValue(rtept,"ele"));pt.ele=isNaN(floatValue)?null:floatValue;let time=keepThis.getElementValue(rtept,"time");pt.time=time==null?null:new Date(time);routepoints.push(pt)}route.distance=keepThis.calculDistance(routepoints);route.elevation=keepThis.calcElevation(routepoints);route.slopes=keepThis.calculSlope(routepoints,route.distance.cumul);route.points=routepoints;keepThis.routes.push(route)}var trks=[].slice.call(this.xmlSource.querySelectorAll('trk'));for(let idx in trks){let trk=trks[idx];let track={};track.name=keepThis.getElementValue(trk,"name");track.cmt=keepThis.getElementValue(trk,"cmt");track.desc=keepThis.getElementValue(trk,"desc");track.src=keepThis.getElementValue(trk,"src");track.number=keepThis.getElementValue(trk,"number");let type=keepThis.queryDirectSelector(trk,"type");track.type=type!=null?type.innerHTML:null;let link={};let linkElem=trk.querySelector('link');if(linkElem!=null){link.href=linkElem.getAttribute('href');link.text=keepThis.getElementValue(linkElem,"text");link.type=keepThis.getElementValue(linkElem,"type")}track.link=link;let trackpoints=[];let trkpts=[].slice.call(trk.querySelectorAll('trkpt'));for(let idxIn in trkpts){var trkpt=trkpts[idxIn];let pt={};pt.lat=parseFloat(trkpt.getAttribute("lat"));pt.lon=parseFloat(trkpt.getAttribute("lon"));let floatValue=parseFloat(keepThis.getElementValue(trkpt,"ele"));pt.ele=isNaN(floatValue)?null:floatValue;let time=keepThis.getElementValue(trkpt,"time");pt.time=time==null?null:new Date(time);trackpoints.push(pt)}track.distance=keepThis.calculDistance(trackpoints);track.elevation=keepThis.calcElevation(trackpoints);track.slopes=keepThis.calculSlope(trackpoints,track.distance.cumul);track.points=trackpoints;keepThis.tracks.push(track)}};gpxParser.prototype.getElementValue=function(parent,needle){let elem=parent.querySelector(needle);if(elem!=null){return elem.innerHTML!=undefined?elem.innerHTML:elem.childNodes[0].data}return elem};gpxParser.prototype.queryDirectSelector=function(parent,needle){let elements=parent.querySelectorAll(needle);let finalElem=elements[0];if(elements.length>1){let directChilds=parent.childNodes;for(idx in directChilds){elem=directChilds[idx];if(elem.tagName===needle){finalElem=elem}}}return finalElem};gpxParser.prototype.calculDistance=function(points){let distance={};let totalDistance=0;let cumulDistance=[];for(var i=0;i0){dp+=diff}}}var elevation=[];var sum=0;for(var i=0,len=points.length;i