This commit is contained in:
2025-09-12 07:32:32 -07:00
parent 4d5fca6a5e
commit 49208df277
2978 changed files with 421237 additions and 394 deletions

View File

@@ -0,0 +1,32 @@
name: develop-ci
on:
push:
branches:
- develop
pull_request:
branches:
- develop
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and test
run: |
npm ci
npm test
env:
CI: true

32
node_modules/gpxparser/.github/workflows/master-ci.yml generated vendored Normal file
View File

@@ -0,0 +1,32 @@
name: master-ci
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and test
run: |
npm ci
npm test
env:
CI: true

21
node_modules/gpxparser/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Lucas Trebouet Voisin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

164
node_modules/gpxparser/README.md generated vendored Normal file
View File

@@ -0,0 +1,164 @@
![GPXParser](https://raw.githubusercontent.com/Luuka/gpx-parser/feature/new-demo/demo/Logo.png)
# GPXParser.js
![](https://github.com/Luuka/gpx-parser/workflows/master-ci/badge.svg) ![](https://github.com/Luuka/gpx-parser/workflows/develop-ci/badge.svg)
*GPXParser.js* is a lightweight JS library wich parse .gpx file and get or compute various datas like
- GPX metadata
- total and cumulate distances
- min, max, average, positive and negative height différence
# GPX ? What is this ?
Wikipedia say :
> GPX, or GPS Exchange Format, is an XML schema designed as a common GPS data format for software applications.
gpx files are based on xml with specific tags and attributes
For more information about gpx format see http://www.topografix.com/gpx_manual.asp
# How to do
### Install from npm
`npm install --save gpxparser`
### Load JavaScript file
From an HTML document :
```html
<script src="./js/GPXParser.js"></script>
```
From a node.js script :
```js
let gpxParser = require('gpxparser');
```
### Create and parse file
```js
var gpx = new gpxParser(); //Create gpxParser Object
gpx.parse("<xml><gpx></gpx></xml>"); //parse gpx file from string data
```
### Use the gpx Object
```js
var totalDistance = gpx.tracks[0].distance.total;
```
### Export gpxParser Objecto to GeoJSON
```js
let geoJSON = gpx.toGeoJSON();
```
# Documentation
| Property | Type | Description|
| ------------- | ------------- | ------------- |
| xmlSource | XML | XML Object parsed from gpx string file |
| metadata | Metadata object | File metadata |
| waypoints | Array of Waypoint object | Array of waypoints |
| tracks | Array of Track object | Array of waypoints of tracks |
| routes | Array of Route object | Array of waypoints of routes |
## Metadata object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| name | String | File name |
| desc | String | Description |
| link | Link object | Web address |
| author | Float | Author object |
| time | DateTime | Time |
## Waypoint object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| name | String | Point name |
| cmt | String | Comment |
| desc | String | Point description |
| lat | Float | Point latitute |
| lon | Float | Point longitude |
| ele | Float | Point elevation |
| time | Date | Point time |
## Track object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| name | String | Point name |
| cmt | String | Comment |
| desc | String | Point description |
| src | String | Used device |
| number | String | Track identifier |
| link | String | Link to a web address |
| type | String | Track type |
| points | Array | Points object array |
| distance | Distance Object | Distance informations about the Route |
| elevation | Elevation Object | Elevation informations about the Route |
| slopes | Float Array | Slope of each sub-segment|
## Route object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| name | String | Point name |
| cmt | String | Comment |
| desc | String | Point description |
| src | String | Used device |
| number | String | Track identifier |
| link | String | Link to a web address |
| type | String | Route type |
| points | Array | Points object array |
| distance | Distance Object | Distance informations about the Route |
| elevation | Elevation Object | Elevation informations about the Route |
| slopes | Float Array | Slope of each sub-segment|
## Point object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| lat | Float | Point latitute |
| lon | Float | Point longitude |
| ele | Float | Point elevation |
| time | Date | Point time |
## Distance object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| total | Float | Total distance of the Route/Track |
| cumul | Float | Cumulative distance at each point of the Route/Track |
## Elevation object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| max | Float | Maximum elevation |
| min | Float | Minimum elevation |
| pos | Float | Positive elevation difference |
| neg | Float | Negative elevation difference |
| avg | Float | Average elevation |
## Author object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| name | String | Author name |
| email | Email object | Email address of the author |
| link | Link object | Web address |
## Email object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| id | String | Email id |
| domain | String | Email domain |
## Link object
| Property | Type | Description |
| -------- | ------ | ----------------- |
| href | String | Web address |
| text | String | Link text |
| type | String | Link type |

27
node_modules/gpxparser/gulpfile.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
var gulp = require('gulp'),
minify = require('gulp-minify'),
jsdoc = require('gulp-jsdoc3'),
mocha = require('gulp-mocha');
gulp.task('test', function() {
return gulp.src('./test/test.js', {read: false}).pipe(mocha({reporter: 'nyan'}))
});
gulp.task('minify', function(){
return gulp.src('./src/GPXParser.js')
.pipe(minify({
ext:{
min:'.min.js'
},
noSource: true
}))
.pipe(gulp.dest('./dist'));
});
gulp.task('doc', function (cb) {
var config = require('./jsdoc.json');
return gulp.src(['README.md', './src/GPXParser.js'], {read: false}).pipe(jsdoc(config, cb));
});
gulp.task('build', gulp.series('test', 'minify', 'doc'));

94
node_modules/gpxparser/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,94 @@
export type MetaData = {
name: string
desc: string
link: string
author: number
time: Date
}
export type Waypoint = {
name: string
cmt: string
desc: string
lat: number
lon: number
ele: number
time: Date
}
export type Track = {
name: string
cmt: string
desc: string
src: string
number: string
link: Link
type: string
points: Point[]
distance: Distance
elevation: Elevation
slopes: number[]
}
export type Route = {
name: string
cmt: string
desc: string
src: string
number: string
link: string
type: string
points: Point[]
distance: Distance
elevation: Elevation
slopes: number[]
}
export type Point = {
lat: number
lon: number
ele: number
time: Date
}
export type Distance = {
total: number
cumul: number
}
export type Elevation = {
max: number
min: number
pos: number
neg: number
avg: number
}
export type Author = {
name: string
email: Email
link: Link
}
export type Email = {
id: string
domain: string
}
export type Link = {
href: string
text: string
type: string
}
declare class GpxParser {
xmlSource: string
metadata: MetaData
waypoints: Waypoint[]
tracks: Track[]
routes: Route[]
parse(xml: string): any
getElementValue(element: Element, needle: string): any
}
export default GpxParser

136
node_modules/gpxparser/index.html generated vendored Normal file
View File

@@ -0,0 +1,136 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>GPXParser | OpenSource GPX format JavaScript parser</title>
<link rel="icon" type="image/png" sizes="32x32" href="demo/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="demo/favicon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="demo/favicon/favicon-16x16.png">
<link rel="stylesheet" href="./demo/style.css">
<script src="./src/GPXParser.js"></script>
<script src="demo/vue.js"></script>
<script src="./demo/script.js"></script>
<link href="https://fonts.googleapis.com/css?family=Merriweather:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js" integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="crossorigin=""></script>
<script src="demo/highlight/highlight.pack.js"></script>
<link rel="stylesheet" href="demo/highlight/styles/default.css">
<link rel="stylesheet" href="demo/highlight/styles/">
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>
<header class="header-main">
<a href="">
<img src="./demo/Logo.png" alt="">
</a>
<nav>
<ul>
<li><a href="https://github.com/Luuka/gpx-parser">GitHub</a></li>
<li><a href="./doc/">Documentation</a></li>
</ul>
</nav>
</header>
<section role="main">
<section class="introduction">
<h1>Introduction</h1>
<div class="cols">
<div>
<p>
GPXParser is a JavaScript library designed to help developers to parse and use data stored with the GPX format.
<br>
It allow you to retrieve every data stored in your GPX formatted file by producing an easy to use JavaScript object structure.
<br>
Moreover, GPXParser is more than a simple XML parser, it also compute data from positioning and elevation statements to useful numeric data.
</p>
</div>
<div>
<p>
<strong>GPX Parser retrieve and compute various data :</strong>
</p>
<ul>
<li>Tracks and routes geographic coordinates</li>
<li>Elevation : gain, lose, average, min, max</li>
<li>Distance : Total and partial</li>
</ul>
</div>
</div>
</section>
<section class="panel-blue demo" id="demo">
<h1>Start the demo</h1>
<form v-on:submit.prevent>
<label for="inputFile">{{ inputLabel }}</label>
<input type="file" v-on:change="onChooseGPX" id="inputFile">
<button id="demogpx" v-on:click="onLoadGPX">Start the demo</button>
<button id="demofilegpx" v-on:click="onLoadDemoGPX">Load a demo gpx file</button>
</form>
<div id="map"></div>
<section v-if="gpxParser != null" class="demo-content">
<h2 v-if="!isEmpty(gpxParser.metadata)">General metadata</h2>
<div class="cards">
<div class="card" v-if="!isEmpty(gpxParser.metadata)">
<h3 v-if="gpxParser.metadata.name != null">{{ gpxParser.metadata.name }}</h3>
<p v-if="gpxParser.metadata.desc != null">{{ gpxParser.metadata.desc }}</p>
<p v-if="gpxParser.metadata.time != null">{{ gpxParser.metadata.time }}</p>
</div>
<div class="card" v-if="gpxParser.metadata.author != null && !isEmpty(gpxParser.metadata.author)">
<h3>{{ gpxParser.metadata.author.name }}</h3>
<p>{{ gpxParser.metadata.author.email.id }}@{{ gpxParser.metadata.author.email.domain }}</p>
<p><a :href="gpxParser.metadata.author.link.href">{{ gpxParser.metadata.author.link.text }}</a></p>
</div>
</div>
<h2 v-if="gpxParser.waypoints.length > 0">Waypoints</h2>
<div class="cards">
<div class="card" v-for="waypoint in gpxParser.waypoints">
<h3>{{ waypoint.name }}</h3>
<p>Latitude : {{ waypoint.lat }}</p>
<p>Longitude : {{ waypoint.lon }}</p>
</div>
</div>
<h2 v-if="gpxParser.tracks.concat(gpxParser.routes).length > 0">Tracks and Routes</h2>
<div class="cards">
<div class="card" v-for="track in gpxParser.tracks.concat(gpxParser.routes)">
<h3>{{ track.name }}</h3>
<p>Distance : {{ Math.floor(track.distance.total/1000) }}km</p>
<p>Elevation :</p>
<ul>
<li>Avg : {{ Math.floor(track.elevation.avg) }}m</li>
<li>Max : {{ Math.floor(track.elevation.max) }}m</li>
<li>Min : {{ Math.floor(track.elevation.min) }}m</li>
<li>Positive : {{ Math.floor(track.elevation.pos) }}m</li>
<li>Negative : {{ Math.floor(track.elevation.neg) }}m</li>
</ul>
</div>
</div>
</section>
</section>
<section>
<h1>How to use ?</h1>
<h2>Load JavaScript file</h2>
<pre><code class="html">
&lt;script src="./js/GPXParser.js"&gt;&lt;/script&gt;
</code></pre>
<h2>Create and parse GPX</h2>
<pre><code class="javascript">
let gpx = new gpxParser(); //Create gpxParser Object
gpx.parse("&lt;xml&gt;&lt;gpx&gt;&lt;/gpx&gt;&lt;/xml&gt;"); //parse gpx file from string data
</code></pre>
<h2>Use the gpxParser Object</h2>
<pre><code class="javascript">
let totalDistance = gpx.tracks[0].distance.total;
gpx.tracks[0].points.push([lat, lon]);
</code></pre>
<h2>Export gpxParser Objecto to GEOJson</h2>
<pre><code class="javascript">
let geoJSON = gpx.toGeoJSON();
</code></pre>
</section>
<footer>
<p>Lucas Trebouet Voisin - <a href="https://github.com/Luuka/GPXParser.js/blob/master/LICENSE">MIT Licence</a> - <a href="https://github.com/Luuka/GPXParser.js">GitHub</a></p>
</footer>
</section>
</body>
</html>

5
node_modules/gpxparser/jsdoc.json generated vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"opts": {
"destination": "./doc/"
}
}

40
node_modules/gpxparser/package.json generated vendored Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "gpxparser",
"version": "3.0.8",
"description": "GPX file parser",
"main": "dist/GPXParser.min.js",
"scripts": {
"test": "nyc mocha"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Luuka/GPXParser.js.git"
},
"keywords": [
"gpx",
"parser",
"GPS",
"Positioning",
"GEOJson"
],
"author": "Lucas Trebouet Voisin",
"license": "MIT",
"bugs": {
"url": "https://github.com/Luuka/GPXParser.js/issues"
},
"homepage": "https://github.com/Luuka/GPXParser.js#readme",
"dependencies": {
"jsdom": "^15.2.1",
"jsdom-global": "^3.0.2"
},
"devDependencies": {
"gulp": "^4.0.2",
"gulp-jsdoc3": "^2.0.0",
"gulp-minify": "^3.1.0",
"gulp-mocha": "^7.0.2",
"jsdoc": "^3.6.3",
"jsdom": "^15.2.1",
"mocha": "^6.2.2",
"nyc": "^15.0.0"
}
}

465
node_modules/gpxparser/src/GPXParser.js generated vendored Normal file
View File

@@ -0,0 +1,465 @@
/**
* GPX file parser
*
* @constructor
*/
let gpxParser = function () {
this.xmlSource = "";
this.metadata = {};
this.waypoints = [];
this.tracks = [];
this.routes = [];
};
/**
* Parse a gpx formatted string to a GPXParser Object
*
* @param {string} gpxstring - A GPX formatted String
*
* @return {gpxParser} A GPXParser object
*/
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);
}
};
/**
* Get value from a XML DOM element
*
* @param {Element} parent - Parent DOM Element
* @param {string} needle - Name of the searched element
*
* @return {} The element value
*/
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;
};
/**
* Search the value of a direct child XML DOM element
*
* @param {Element} parent - Parent DOM Element
* @param {string} needle - Name of the searched element
*
* @return {} The element value
*/
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;
};
/**
* Calcul the Distance Object from an array of points
*
* @param {} points - An array of points with lat and lon properties
*
* @return {DistanceObject} An object with total distance and Cumulative distances
*/
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;
};
/**
* Calcul Distance between two points with lat and lon
*
* @param {} wpt1 - A geographic point with lat and lon properties
* @param {} wpt2 - A geographic point with lat and lon properties
*
* @returns {float} The distance between the two points
*/
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;
};
/**
* Generate Elevation Object from an array of points
*
* @param {} points - An array of points with ele property
*
* @returns {ElevationObject} An object with negative and positive height difference and average, max and min altitude data
*/
gpxParser.prototype.calcElevation = function (points) {
var dp = 0,
dm = 0,
ret = {};
for (var i = 0; i < points.length - 1; i++) {
let rawNextElevation = points[i + 1].ele;
let rawElevation = points[i].ele;
if(rawNextElevation !== null && rawElevation !== null) {
let diff = parseFloat(rawNextElevation) - parseFloat(rawElevation);
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++) {
let rawElevation = points[i].ele;
if(rawElevation !== null) {
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;
};
/**
* Generate slopes Object from an array of Points and an array of Cumulative distance
*
* @param {} points - An array of points with ele property
* @param {} cumul - An array of cumulative distance
*
* @returns {SlopeObject} An array of slopes
*/
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;
};
/**
* Export the GPX object to a GeoJSON formatted Object
*
* @returns {} a GeoJSON formatted Object
*/
gpxParser.prototype.toGeoJSON = function () {
var GeoJSON = {
"type": "FeatureCollection",
"features": [],
"properties": {
"name": this.metadata.name,
"desc": this.metadata.desc,
"time": this.metadata.time,
"author": this.metadata.author,
"link": this.metadata.link,
},
};
for(idx in this.tracks) {
let track = this.tracks[idx];
var feature = {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": []
},
"properties": {
}
};
feature.properties.name = track.name;
feature.properties.cmt = track.cmt;
feature.properties.desc = track.desc;
feature.properties.src = track.src;
feature.properties.number = track.number;
feature.properties.link = track.link;
feature.properties.type = track.type;
for(idx in track.points) {
let pt = track.points[idx];
var geoPt = [];
geoPt.push(pt.lon);
geoPt.push(pt.lat);
geoPt.push(pt.ele);
feature.geometry.coordinates.push(geoPt);
}
GeoJSON.features.push(feature);
}
for(idx in this.routes) {
let track = this.routes[idx];
var feature = {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": []
},
"properties": {
}
};
feature.properties.name = track.name;
feature.properties.cmt = track.cmt;
feature.properties.desc = track.desc;
feature.properties.src = track.src;
feature.properties.number = track.number;
feature.properties.link = track.link;
feature.properties.type = track.type;
for(idx in track.points) {
let pt = track.points[idx];
var geoPt = [];
geoPt.push(pt.lon);
geoPt.push(pt.lat);
geoPt.push(pt.ele);
feature.geometry.coordinates.push(geoPt);
}
GeoJSON.features.push(feature);
}
for(idx in this.waypoints) {
let pt = this.waypoints[idx];
var feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": []
},
"properties": {
}
};
feature.properties.name = pt.name;
feature.properties.sym = pt.sym;
feature.properties.cmt = pt.cmt;
feature.properties.desc = pt.desc;
feature.geometry.coordinates = [pt.lon, pt.lat, pt.ele];
GeoJSON.features.push(feature);
}
return GeoJSON;
};
if(typeof module !== 'undefined'){
require('jsdom-global')();
module.exports = gpxParser;
}

237
node_modules/gpxparser/test/test.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1708
node_modules/gpxparser/test/test.xml generated vendored Normal file

File diff suppressed because it is too large Load Diff