diff --git a/script/gaia_upload.js b/script/gaia_upload.js index 35c6fc0..0ce24fa 100644 --- a/script/gaia_upload.js +++ b/script/gaia_upload.js @@ -9,7 +9,9 @@ //Ctrl+Alt+Shift+I to open network tab on addon -var gpxParser = function () { +/* GPXParser - v3.0.6 - https://github.com/Luuka/GPXParser.js/blob/master/src/GPXParser.js */ +/* Personnal modifications have been applied, care on upgrade */ +let gpxParser = function () { this.xmlSource = ""; this.metadata = {}; this.waypoints = []; @@ -18,8 +20,9 @@ var gpxParser = function () { }; gpxParser.prototype.parse = function (gpxstring) { - var keepThis = this; - var domParser = new window.DOMParser(); + let keepThis = this; + + let domParser = new window.DOMParser(); this.xmlSource = domParser.parseFromString(gpxstring, 'text/xml'); metadata = this.xmlSource.querySelector('metadata'); @@ -70,13 +73,17 @@ gpxParser.prototype.parse = function (gpxstring) { pt.ele = parseFloat(keepThis.getElementValue(wpt, "ele")) || null; pt.cmt = keepThis.getElementValue(wpt, "cmt"); pt.desc = keepThis.getElementValue(wpt, "desc"); - pt.sym = keepThis.getElementValue(wpt, "sym"); + pt.sym = keepThis.getElementValue(wpt, "sym"); + + 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){ - var rte = rtes[idx]; + let rte = rtes[idx]; let route = {}; route.name = keepThis.getElementValue(rte, "name"); route.cmt = keepThis.getElementValue(rte, "cmt"); @@ -100,21 +107,29 @@ gpxParser.prototype.parse = function (gpxstring) { var rtepts = [].slice.call(rte.querySelectorAll('rtept')); for (let idxIn in rtepts){ - var rtept = rtepts[idxIn]; + let rtept = rtepts[idxIn]; let pt = {}; pt.lat = parseFloat(rtept.getAttribute("lat")); pt.lon = parseFloat(rtept.getAttribute("lon")); - pt.ele = parseFloat(keepThis.getElementValue(rtept, "ele")); + pt.ele = parseFloat(keepThis.getElementValue(rtept, "ele")) || null; + + 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){ - var trk = trks[idx]; + let trk = trks[idx]; let track = {}; track.name = keepThis.getElementValue(trk, "name"); @@ -125,6 +140,7 @@ gpxParser.prototype.parse = function (gpxstring) { track.color = keepThis.getElementValue(trk, "DisplayColor"); let type = keepThis.queryDirectSelector(trk, "type"); + track.type = type != null ? type.innerHTML : null; let link = {}; let linkElem = trk.querySelector('link'); @@ -136,15 +152,22 @@ gpxParser.prototype.parse = function (gpxstring) { track.link = link; let trackpoints = []; - var trkpts = [].slice.call(trk.querySelectorAll('trkpt')); + 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")); pt.ele = parseFloat(keepThis.getElementValue(trkpt, "ele")) || null; + + 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); @@ -179,6 +202,88 @@ gpxParser.prototype.queryDirectSelector = function(parent, needle) { } /* +gpxParser.prototype.calculDistance = function(points) { + let distance = {}; + let totalDistance = 0; + let cumulDistance = []; + for (var i = 0; i < points.length - 1; i++) { + totalDistance += this.calcDistanceBetween(points[i],points[i+1]); + cumulDistance[i] = totalDistance; + } + cumulDistance[points.length - 1] = totalDistance; + + distance.total = totalDistance; + distance.cumul = cumulDistance; + + return distance; +} + +gpxParser.prototype.calcDistanceBetween = function (wpt1, wpt2) { + let latlng1 = {}; + latlng1.lat = wpt1.lat; + latlng1.lon = wpt1.lon; + let latlng2 = {}; + latlng2.lat = wpt2.lat; + latlng2.lon = wpt2.lon; + var rad = Math.PI / 180, + lat1 = latlng1.lat * rad, + lat2 = latlng2.lat * rad, + sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2), + sinDLon = Math.sin((latlng2.lon - latlng1.lon) * rad / 2), + a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon, + c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return 6371000 * c; +} + +gpxParser.prototype.calcElevation = function (points) { + var dp = 0, + dm = 0, + ret = {}; + + for (var i = 0; i < points.length - 1; i++) { + var diff = parseFloat(points[i + 1].ele) - parseFloat(points[i].ele); + + if (diff < 0) { + dm += diff; + } else if (diff > 0) { + dp += diff; + } + } + + var elevation = []; + var sum = 0; + + for (var i = 0, len = points.length; i < len; i++) { + var ele = parseFloat(points[i].ele); + elevation.push(ele); + sum += ele; + } + + ret.max = Math.max.apply(null, elevation) || null; + ret.min = Math.min.apply(null, elevation) || null; + ret.pos = Math.abs(dp) || null; + ret.neg = Math.abs(dm) || null; + ret.avg = sum / elevation.length || null; + + return ret; +}; + +gpxParser.prototype.calculSlope = function(points, cumul) { + let slopes = []; + + for (var i = 0; i < points.length - 1; i++) { + let point = points[i]; + let nextPoint = points[i+1]; + let elevationDiff = nextPoint.ele - point.ele; + let distance = cumul[i+1] - cumul[i]; + + let slope = (elevationDiff * 100) / distance; + slopes.push(slope); + } + + return slopes; +} + gpxParser.prototype.toGeoJSON = function () { var GeoJSON = { "type": "FeatureCollection", @@ -287,7 +392,11 @@ gpxParser.prototype.toGeoJSON = function () { return GeoJSON; } -*/ + +if(typeof module !== 'undefined'){ + require('jsdom-global')(); + module.exports = gpxParser; +} gpxParser.prototype.getGPX = function(sName) { var sTrack = ''; @@ -315,6 +424,7 @@ gpxParser.prototype.getGPX = function(sName) { return sGPX; }; +*/ class Gaia { static get URL() { return 'https://www.gaiagps.com'; }