@raruto/leaflet-elevation 2.2.5 → 2.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -674
- package/dist/leaflet-elevation.css +337 -337
- package/dist/leaflet-elevation.js +281 -280
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +1 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/images/elevation-position.svg +1 -1
- package/images/elevation-pushpin.svg +1 -1
- package/images/elevation.svg +1 -1
- package/libs/leaflet-distance-marker.css +8 -8
- package/libs/leaflet-distance-marker.js +314 -314
- package/package.json +71 -71
- package/src/components/chart.js +783 -783
- package/src/components/d3.js +641 -641
- package/src/components/marker.js +96 -96
- package/src/components/summary.js +43 -43
- package/src/control.js +3 -2
- package/src/handlers/acceleration.js +64 -64
- package/src/handlers/heart.js +52 -52
- package/src/handlers/pace.js +65 -65
- package/src/handlers/slope.js +79 -79
- package/src/handlers/speed.js +66 -66
- package/src/handlers/time.js +102 -102
- package/src/index.css +329 -329
- package/src/index.js +42 -42
- package/src/options.js +85 -85
- package/src/utils.js +158 -158
|
@@ -3,164 +3,164 @@
|
|
|
3
3
|
factory();
|
|
4
4
|
})((function () { 'use strict';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* TODO: exget computed styles of theese values from actual "CSS vars"
|
|
8
|
-
**/
|
|
9
|
-
const Colors = {
|
|
10
|
-
'lightblue': { area: '#3366CC', alpha: 0.45, stroke: '#3366CC' },
|
|
11
|
-
'magenta' : { area: '#FF005E' },
|
|
12
|
-
'yellow' : { area: '#FF0' },
|
|
13
|
-
'purple' : { area: '#732C7B' },
|
|
14
|
-
'steelblue': { area: '#4682B4' },
|
|
15
|
-
'red' : { area: '#F00' },
|
|
16
|
-
'lime' : { area: '#9CC222', line: '#566B13' }
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const SEC = 1000;
|
|
20
|
-
const MIN = SEC * 60;
|
|
21
|
-
const HOUR = MIN * 60;
|
|
22
|
-
const DAY = HOUR * 24;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Convert a time (millis) to a human readable duration string (%Dd %H:%M'%S")
|
|
26
|
-
*/
|
|
27
|
-
function formatTime(t) {
|
|
28
|
-
let d = Math.floor(t / DAY);
|
|
29
|
-
let h = Math.floor( (t - d * DAY) / HOUR);
|
|
30
|
-
let m = Math.floor( (t - d * DAY - h * HOUR) / MIN);
|
|
31
|
-
let s = Math.round( (t - d * DAY - h * HOUR - m * MIN) / SEC);
|
|
32
|
-
if ( s === 60 ) { m++; s = 0; }
|
|
33
|
-
if ( m === 60 ) { h++; m = 0; }
|
|
34
|
-
if ( h === 24 ) { d++; h = 0; }
|
|
35
|
-
return (d ? d + "d " : '') + h.toString().padStart(2, 0) + ':' + m.toString().padStart(2, 0) + "'" + s.toString().padStart(2, 0) + '"';
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Convert a time (millis) to human readable date string (dd-mm-yyyy hh:mm:ss)
|
|
40
|
-
*/
|
|
41
|
-
function formatDate(format) {
|
|
42
|
-
if (!format) {
|
|
43
|
-
return (time) => (new Date(time)).toLocaleString().replaceAll('/', '-').replaceAll(',', ' ');
|
|
44
|
-
} else if (format == 'time') {
|
|
45
|
-
return (time) => (new Date(time)).toLocaleTimeString();
|
|
46
|
-
} else if (format == 'date') {
|
|
47
|
-
return (time) => (new Date(time)).toLocaleDateString();
|
|
48
|
-
}
|
|
49
|
-
return (time) => format(time);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Generate download data event.
|
|
54
|
-
*/
|
|
55
|
-
function saveFile(dataURI, fileName) {
|
|
56
|
-
let a = create('a', '', { href: dataURI, target: '_new', download: fileName || "", style: "display:none;" });
|
|
57
|
-
let b = document.body;
|
|
58
|
-
b.appendChild(a);
|
|
59
|
-
a.click();
|
|
60
|
-
b.removeChild(a);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Convert SVG Path into Path2D and then update canvas
|
|
66
|
-
*/
|
|
67
|
-
function drawCanvas(ctx, path) {
|
|
68
|
-
path.classed('canvas-path', true);
|
|
69
|
-
|
|
70
|
-
ctx.beginPath();
|
|
71
|
-
ctx.moveTo(0, 0);
|
|
72
|
-
let p = new Path2D(path.attr('d'));
|
|
73
|
-
|
|
74
|
-
ctx.strokeStyle = path.attr('stroke');
|
|
75
|
-
ctx.fillStyle = path.attr('fill');
|
|
76
|
-
ctx.lineWidth = 1.25;
|
|
77
|
-
ctx.globalCompositeOperation = 'source-over';
|
|
78
|
-
|
|
79
|
-
// stroke opacity
|
|
80
|
-
ctx.globalAlpha = path.attr('stroke-opacity') || 0.3;
|
|
81
|
-
ctx.stroke(p);
|
|
82
|
-
|
|
83
|
-
// fill opacity
|
|
84
|
-
ctx.globalAlpha = path.attr('fill-opacity') || 0.45;
|
|
85
|
-
ctx.fill(p);
|
|
86
|
-
|
|
87
|
-
ctx.globalAlpha = 1;
|
|
88
|
-
|
|
89
|
-
ctx.closePath();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Loop and extract GPX Extensions handled by "@tmcw/toGeoJSON" (eg. "coordinateProperties" > "times")
|
|
94
|
-
*/
|
|
95
|
-
function coordPropsToMeta(coordProps, name, parser) {
|
|
96
|
-
return coordProps && (({props, point, id, isMulti }) => {
|
|
97
|
-
if (props) {
|
|
98
|
-
for (const key of coordProps) {
|
|
99
|
-
if (key in props) {
|
|
100
|
-
point.meta[name] = (parser || parseNumeric).call(this, (isMulti ? props[key][isMulti] : props[key]), id);
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Extract numeric property (id) from GeoJSON object
|
|
110
|
-
*/
|
|
111
|
-
const parseNumeric = (property, id) => parseInt((typeof property === 'object' ? property[id] : property));
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Extract datetime property (id) from GeoJSON object
|
|
115
|
-
*/
|
|
116
|
-
const parseDate = (property, id) => new Date(Date.parse((typeof property === 'object' ? property[id] : property)));
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* A little bit shorter than L.DomUtil
|
|
120
|
-
*/
|
|
121
|
-
const addClass = (n, str) => n && str.split(" ").every(s => s && L.DomUtil.addClass(n, s));
|
|
122
|
-
const removeClass = (n, str) => n && str.split(" ").every(s => s && L.DomUtil.removeClass(n, s));
|
|
123
|
-
const toggleClass = (n, str, cond) => (cond ? addClass : removeClass)(n, str);
|
|
124
|
-
const replaceClass = (n, rem, add) => (rem && removeClass(n, rem)) || (add && addClass(n, add));
|
|
125
|
-
const style = (n, k, v) => (typeof v === "undefined" && L.DomUtil.getStyle(n, k)) || n.style.setProperty(k, v);
|
|
126
|
-
const toggleStyle = (n, k, v, cond) => style(n, k, cond ? v : '');
|
|
127
|
-
const setAttributes = (n, attrs) => { for (let k in attrs) { n.setAttribute(k, attrs[k]); } };
|
|
128
|
-
const toggleEvent = (el, e, fn, cond) => el[cond ? 'on' : 'off'](e, fn);
|
|
129
|
-
const create = (tag, str, attrs, n) => { let elem = L.DomUtil.create(tag, str || ""); if (attrs) setAttributes(elem, attrs); if (n) append(n, elem); return elem; };
|
|
130
|
-
const append = (n, c) => n.appendChild(c);
|
|
131
|
-
const insert = (n, c, pos) => n.insertAdjacentElement(pos, c);
|
|
132
|
-
const select = (str, n) => (n || document).querySelector(str);
|
|
133
|
-
const each = (obj, fn) => { for (let i in obj) fn(obj[i], i); };
|
|
134
|
-
const randomId = () => Math.random().toString(36).substr(2, 9);
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* TODO: use generators instead? (ie. "yield")
|
|
138
|
-
*/
|
|
139
|
-
const iMax = (iVal, max = -Infinity) => (iVal > max ? iVal : max);
|
|
140
|
-
const iMin = (iVal, min = +Infinity) => (iVal < min ? iVal : min);
|
|
141
|
-
const iAvg = (iVal, avg = 0, idx = 1) => (iVal + avg * (idx - 1)) / idx;
|
|
142
|
-
const iSum = (iVal, sum = 0) => iVal + sum;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Alias for some leaflet core functions
|
|
146
|
-
*/
|
|
147
|
-
const { on, off } = L.DomEvent;
|
|
148
|
-
const { throttle, wrapNum } = L.Util;
|
|
149
|
-
const { hasClass } = L.DomUtil;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Limit floating point precision
|
|
153
|
-
*/
|
|
154
|
-
const round = L.Util.formatNum;
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Limit a number between min / max values
|
|
158
|
-
*/
|
|
159
|
-
const clamp = (val, range) => range ? (val < range[0] ? range[0] : val > range[1] ? range[1] : val) : val;
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Limit a delta difference between two values
|
|
163
|
-
*/
|
|
6
|
+
/**
|
|
7
|
+
* TODO: exget computed styles of theese values from actual "CSS vars"
|
|
8
|
+
**/
|
|
9
|
+
const Colors = {
|
|
10
|
+
'lightblue': { area: '#3366CC', alpha: 0.45, stroke: '#3366CC' },
|
|
11
|
+
'magenta' : { area: '#FF005E' },
|
|
12
|
+
'yellow' : { area: '#FF0' },
|
|
13
|
+
'purple' : { area: '#732C7B' },
|
|
14
|
+
'steelblue': { area: '#4682B4' },
|
|
15
|
+
'red' : { area: '#F00' },
|
|
16
|
+
'lime' : { area: '#9CC222', line: '#566B13' }
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const SEC = 1000;
|
|
20
|
+
const MIN = SEC * 60;
|
|
21
|
+
const HOUR = MIN * 60;
|
|
22
|
+
const DAY = HOUR * 24;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Convert a time (millis) to a human readable duration string (%Dd %H:%M'%S")
|
|
26
|
+
*/
|
|
27
|
+
function formatTime(t) {
|
|
28
|
+
let d = Math.floor(t / DAY);
|
|
29
|
+
let h = Math.floor( (t - d * DAY) / HOUR);
|
|
30
|
+
let m = Math.floor( (t - d * DAY - h * HOUR) / MIN);
|
|
31
|
+
let s = Math.round( (t - d * DAY - h * HOUR - m * MIN) / SEC);
|
|
32
|
+
if ( s === 60 ) { m++; s = 0; }
|
|
33
|
+
if ( m === 60 ) { h++; m = 0; }
|
|
34
|
+
if ( h === 24 ) { d++; h = 0; }
|
|
35
|
+
return (d ? d + "d " : '') + h.toString().padStart(2, 0) + ':' + m.toString().padStart(2, 0) + "'" + s.toString().padStart(2, 0) + '"';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Convert a time (millis) to human readable date string (dd-mm-yyyy hh:mm:ss)
|
|
40
|
+
*/
|
|
41
|
+
function formatDate(format) {
|
|
42
|
+
if (!format) {
|
|
43
|
+
return (time) => (new Date(time)).toLocaleString().replaceAll('/', '-').replaceAll(',', ' ');
|
|
44
|
+
} else if (format == 'time') {
|
|
45
|
+
return (time) => (new Date(time)).toLocaleTimeString();
|
|
46
|
+
} else if (format == 'date') {
|
|
47
|
+
return (time) => (new Date(time)).toLocaleDateString();
|
|
48
|
+
}
|
|
49
|
+
return (time) => format(time);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Generate download data event.
|
|
54
|
+
*/
|
|
55
|
+
function saveFile(dataURI, fileName) {
|
|
56
|
+
let a = create('a', '', { href: dataURI, target: '_new', download: fileName || "", style: "display:none;" });
|
|
57
|
+
let b = document.body;
|
|
58
|
+
b.appendChild(a);
|
|
59
|
+
a.click();
|
|
60
|
+
b.removeChild(a);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Convert SVG Path into Path2D and then update canvas
|
|
66
|
+
*/
|
|
67
|
+
function drawCanvas(ctx, path) {
|
|
68
|
+
path.classed('canvas-path', true);
|
|
69
|
+
|
|
70
|
+
ctx.beginPath();
|
|
71
|
+
ctx.moveTo(0, 0);
|
|
72
|
+
let p = new Path2D(path.attr('d'));
|
|
73
|
+
|
|
74
|
+
ctx.strokeStyle = path.attr('stroke');
|
|
75
|
+
ctx.fillStyle = path.attr('fill');
|
|
76
|
+
ctx.lineWidth = 1.25;
|
|
77
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
78
|
+
|
|
79
|
+
// stroke opacity
|
|
80
|
+
ctx.globalAlpha = path.attr('stroke-opacity') || 0.3;
|
|
81
|
+
ctx.stroke(p);
|
|
82
|
+
|
|
83
|
+
// fill opacity
|
|
84
|
+
ctx.globalAlpha = path.attr('fill-opacity') || 0.45;
|
|
85
|
+
ctx.fill(p);
|
|
86
|
+
|
|
87
|
+
ctx.globalAlpha = 1;
|
|
88
|
+
|
|
89
|
+
ctx.closePath();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Loop and extract GPX Extensions handled by "@tmcw/toGeoJSON" (eg. "coordinateProperties" > "times")
|
|
94
|
+
*/
|
|
95
|
+
function coordPropsToMeta(coordProps, name, parser) {
|
|
96
|
+
return coordProps && (({props, point, id, isMulti }) => {
|
|
97
|
+
if (props) {
|
|
98
|
+
for (const key of coordProps) {
|
|
99
|
+
if (key in props) {
|
|
100
|
+
point.meta[name] = (parser || parseNumeric).call(this, (isMulti ? props[key][isMulti] : props[key]), id);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Extract numeric property (id) from GeoJSON object
|
|
110
|
+
*/
|
|
111
|
+
const parseNumeric = (property, id) => parseInt((typeof property === 'object' ? property[id] : property));
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Extract datetime property (id) from GeoJSON object
|
|
115
|
+
*/
|
|
116
|
+
const parseDate = (property, id) => new Date(Date.parse((typeof property === 'object' ? property[id] : property)));
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* A little bit shorter than L.DomUtil
|
|
120
|
+
*/
|
|
121
|
+
const addClass = (n, str) => n && str.split(" ").every(s => s && L.DomUtil.addClass(n, s));
|
|
122
|
+
const removeClass = (n, str) => n && str.split(" ").every(s => s && L.DomUtil.removeClass(n, s));
|
|
123
|
+
const toggleClass = (n, str, cond) => (cond ? addClass : removeClass)(n, str);
|
|
124
|
+
const replaceClass = (n, rem, add) => (rem && removeClass(n, rem)) || (add && addClass(n, add));
|
|
125
|
+
const style = (n, k, v) => (typeof v === "undefined" && L.DomUtil.getStyle(n, k)) || n.style.setProperty(k, v);
|
|
126
|
+
const toggleStyle = (n, k, v, cond) => style(n, k, cond ? v : '');
|
|
127
|
+
const setAttributes = (n, attrs) => { for (let k in attrs) { n.setAttribute(k, attrs[k]); } };
|
|
128
|
+
const toggleEvent = (el, e, fn, cond) => el[cond ? 'on' : 'off'](e, fn);
|
|
129
|
+
const create = (tag, str, attrs, n) => { let elem = L.DomUtil.create(tag, str || ""); if (attrs) setAttributes(elem, attrs); if (n) append(n, elem); return elem; };
|
|
130
|
+
const append = (n, c) => n.appendChild(c);
|
|
131
|
+
const insert = (n, c, pos) => n.insertAdjacentElement(pos, c);
|
|
132
|
+
const select = (str, n) => (n || document).querySelector(str);
|
|
133
|
+
const each = (obj, fn) => { for (let i in obj) fn(obj[i], i); };
|
|
134
|
+
const randomId = () => Math.random().toString(36).substr(2, 9);
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* TODO: use generators instead? (ie. "yield")
|
|
138
|
+
*/
|
|
139
|
+
const iMax = (iVal, max = -Infinity) => (iVal > max ? iVal : max);
|
|
140
|
+
const iMin = (iVal, min = +Infinity) => (iVal < min ? iVal : min);
|
|
141
|
+
const iAvg = (iVal, avg = 0, idx = 1) => (iVal + avg * (idx - 1)) / idx;
|
|
142
|
+
const iSum = (iVal, sum = 0) => iVal + sum;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Alias for some leaflet core functions
|
|
146
|
+
*/
|
|
147
|
+
const { on, off } = L.DomEvent;
|
|
148
|
+
const { throttle, wrapNum } = L.Util;
|
|
149
|
+
const { hasClass } = L.DomUtil;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Limit floating point precision
|
|
153
|
+
*/
|
|
154
|
+
const round = L.Util.formatNum;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Limit a number between min / max values
|
|
158
|
+
*/
|
|
159
|
+
const clamp = (val, range) => range ? (val < range[0] ? range[0] : val > range[1] ? range[1] : val) : val;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Limit a delta difference between two values
|
|
163
|
+
*/
|
|
164
164
|
const wrapDelta = (curr, prev, deltaMax) => Math.abs(curr - prev) > deltaMax ? prev + deltaMax * Math.sign(curr - prev) : curr;
|
|
165
165
|
|
|
166
166
|
var _ = /*#__PURE__*/Object.freeze({
|
|
@@ -201,88 +201,88 @@
|
|
|
201
201
|
wrapDelta: wrapDelta
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
-
var Options = {
|
|
205
|
-
autofitBounds: true,
|
|
206
|
-
autohide: false,
|
|
207
|
-
autohideMarker: true,
|
|
208
|
-
almostover: true,
|
|
209
|
-
altitude: true,
|
|
210
|
-
closeBtn: true,
|
|
211
|
-
collapsed: false,
|
|
212
|
-
detached: true,
|
|
213
|
-
distance: true,
|
|
214
|
-
distanceMarkers: { lazy: true, distance: true, direction: true },
|
|
215
|
-
dragging: !L.Browser.mobile,
|
|
216
|
-
downloadLink: 'link',
|
|
217
|
-
elevationDiv: "#elevation-div",
|
|
218
|
-
followMarker: true,
|
|
219
|
-
imperial: false,
|
|
220
|
-
legend: true,
|
|
221
|
-
handlers: ["Distance", "Time", "Altitude", "Slope", "Speed", "Acceleration"],
|
|
222
|
-
hotline: 'elevation',
|
|
223
|
-
marker: 'elevation-line',
|
|
224
|
-
markerIcon: L.divIcon({
|
|
225
|
-
className: 'elevation-position-marker',
|
|
226
|
-
html: '<i class="elevation-position-icon"></i>',
|
|
227
|
-
iconSize: [32, 32],
|
|
228
|
-
iconAnchor: [16, 16],
|
|
229
|
-
}),
|
|
230
|
-
position: "topright",
|
|
231
|
-
polyline: {
|
|
232
|
-
className: 'elevation-polyline',
|
|
233
|
-
color: '#000',
|
|
234
|
-
opacity: 0.75,
|
|
235
|
-
weight: 5,
|
|
236
|
-
lineCap: 'round'
|
|
237
|
-
},
|
|
238
|
-
polylineSegments: {
|
|
239
|
-
className: 'elevation-polyline-segments',
|
|
240
|
-
color: '#F00',
|
|
241
|
-
interactive: false,
|
|
242
|
-
},
|
|
243
|
-
preferCanvas: false,
|
|
244
|
-
reverseCoords: false,
|
|
245
|
-
ruler: true,
|
|
246
|
-
theme: "lightblue-theme",
|
|
247
|
-
summary: 'inline',
|
|
248
|
-
slope: false,
|
|
249
|
-
speed: false,
|
|
250
|
-
time: true,
|
|
251
|
-
timeFactor: 3600,
|
|
252
|
-
timestamps: false,
|
|
253
|
-
trkStart:
|
|
254
|
-
trkEnd:
|
|
255
|
-
waypoints: true,
|
|
256
|
-
wptIcons: {
|
|
257
|
-
'': L.divIcon({
|
|
258
|
-
className: 'elevation-waypoint-marker',
|
|
259
|
-
html: '<i class="elevation-waypoint-icon default"></i>',
|
|
260
|
-
iconSize: [30, 30],
|
|
261
|
-
iconAnchor: [8, 30],
|
|
262
|
-
}),
|
|
263
|
-
},
|
|
264
|
-
wptLabels: true,
|
|
265
|
-
xAttr: "dist",
|
|
266
|
-
xLabel: "km",
|
|
267
|
-
yAttr: "z",
|
|
268
|
-
yLabel: "m",
|
|
269
|
-
zFollow: false,
|
|
270
|
-
zooming: !L.Browser.Mobile,
|
|
271
|
-
|
|
272
|
-
// Quite uncommon and undocumented options
|
|
273
|
-
margins: { top: 30, right: 30, bottom: 30, left: 40 },
|
|
274
|
-
height: (screen.height * 0.3) || 200,
|
|
275
|
-
width: (screen.width * 0.6) || 600,
|
|
276
|
-
xTicks: undefined,
|
|
277
|
-
yTicks: undefined,
|
|
278
|
-
|
|
279
|
-
decimalsX: 2,
|
|
280
|
-
decimalsY: 0,
|
|
281
|
-
forceAxisBounds: false,
|
|
282
|
-
interpolation: "curveLinear",
|
|
283
|
-
skipNullZCoords: false,
|
|
284
|
-
yAxisMax: undefined,
|
|
285
|
-
yAxisMin: undefined,
|
|
204
|
+
var Options = {
|
|
205
|
+
autofitBounds: true,
|
|
206
|
+
autohide: false,
|
|
207
|
+
autohideMarker: true,
|
|
208
|
+
almostover: true,
|
|
209
|
+
altitude: true,
|
|
210
|
+
closeBtn: true,
|
|
211
|
+
collapsed: false,
|
|
212
|
+
detached: true,
|
|
213
|
+
distance: true,
|
|
214
|
+
distanceMarkers: { lazy: true, distance: true, direction: true },
|
|
215
|
+
dragging: !L.Browser.mobile,
|
|
216
|
+
downloadLink: 'link',
|
|
217
|
+
elevationDiv: "#elevation-div",
|
|
218
|
+
followMarker: true,
|
|
219
|
+
imperial: false,
|
|
220
|
+
legend: true,
|
|
221
|
+
handlers: ["Distance", "Time", "Altitude", "Slope", "Speed", "Acceleration"],
|
|
222
|
+
hotline: 'elevation',
|
|
223
|
+
marker: 'elevation-line',
|
|
224
|
+
markerIcon: L.divIcon({
|
|
225
|
+
className: 'elevation-position-marker',
|
|
226
|
+
html: '<i class="elevation-position-icon"></i>',
|
|
227
|
+
iconSize: [32, 32],
|
|
228
|
+
iconAnchor: [16, 16],
|
|
229
|
+
}),
|
|
230
|
+
position: "topright",
|
|
231
|
+
polyline: {
|
|
232
|
+
className: 'elevation-polyline',
|
|
233
|
+
color: '#000',
|
|
234
|
+
opacity: 0.75,
|
|
235
|
+
weight: 5,
|
|
236
|
+
lineCap: 'round'
|
|
237
|
+
},
|
|
238
|
+
polylineSegments: {
|
|
239
|
+
className: 'elevation-polyline-segments',
|
|
240
|
+
color: '#F00',
|
|
241
|
+
interactive: false,
|
|
242
|
+
},
|
|
243
|
+
preferCanvas: false,
|
|
244
|
+
reverseCoords: false,
|
|
245
|
+
ruler: true,
|
|
246
|
+
theme: "lightblue-theme",
|
|
247
|
+
summary: 'inline',
|
|
248
|
+
slope: false,
|
|
249
|
+
speed: false,
|
|
250
|
+
time: true,
|
|
251
|
+
timeFactor: 3600,
|
|
252
|
+
timestamps: false,
|
|
253
|
+
trkStart: { className: 'start-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#00d800', fillOpacity: 1, interactive: false },
|
|
254
|
+
trkEnd: { className: 'end-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#ff0606', fillOpacity: 1, interactive: false },
|
|
255
|
+
waypoints: true,
|
|
256
|
+
wptIcons: {
|
|
257
|
+
'': L.divIcon({
|
|
258
|
+
className: 'elevation-waypoint-marker',
|
|
259
|
+
html: '<i class="elevation-waypoint-icon default"></i>',
|
|
260
|
+
iconSize: [30, 30],
|
|
261
|
+
iconAnchor: [8, 30],
|
|
262
|
+
}),
|
|
263
|
+
},
|
|
264
|
+
wptLabels: true,
|
|
265
|
+
xAttr: "dist",
|
|
266
|
+
xLabel: "km",
|
|
267
|
+
yAttr: "z",
|
|
268
|
+
yLabel: "m",
|
|
269
|
+
zFollow: false,
|
|
270
|
+
zooming: !L.Browser.Mobile,
|
|
271
|
+
|
|
272
|
+
// Quite uncommon and undocumented options
|
|
273
|
+
margins: { top: 30, right: 30, bottom: 30, left: 40 },
|
|
274
|
+
height: (screen.height * 0.3) || 200,
|
|
275
|
+
width: (screen.width * 0.6) || 600,
|
|
276
|
+
xTicks: undefined,
|
|
277
|
+
yTicks: undefined,
|
|
278
|
+
|
|
279
|
+
decimalsX: 2,
|
|
280
|
+
decimalsY: 0,
|
|
281
|
+
forceAxisBounds: false,
|
|
282
|
+
interpolation: "curveLinear",
|
|
283
|
+
skipNullZCoords: false,
|
|
284
|
+
yAxisMax: undefined,
|
|
285
|
+
yAxisMin: undefined,
|
|
286
286
|
};
|
|
287
287
|
|
|
288
288
|
// "leaflet-i18n" fallback
|
|
@@ -465,8 +465,8 @@
|
|
|
465
465
|
this._hotline = L.featureGroup();
|
|
466
466
|
this._circleMarkers = L.featureGroup();
|
|
467
467
|
this._markedSegments = L.polyline([]);
|
|
468
|
-
this._start = (opts.trkStart || Options.trkStart);
|
|
469
|
-
this._end = (opts.trkEnd || Options.trkEnd);
|
|
468
|
+
this._start = L.circleMarker([0,0], (opts.trkStart || Options.trkStart));
|
|
469
|
+
this._end = L.circleMarker([0,0], (opts.trkEnd || Options.trkEnd));
|
|
470
470
|
this._chartEnabled = true;
|
|
471
471
|
this._yCoordMax = -Infinity;
|
|
472
472
|
this.track_info = {};
|
|
@@ -712,6 +712,7 @@
|
|
|
712
712
|
if(trkseg.feature.geometry.type != "Point") {
|
|
713
713
|
let geo = L.geoJson(trkseg.toGeoJSON(), { coordsToLatLng: (coords) => L.latLng(coords[0], coords[1], coords[2] * (this.options.altitudeFactor || 1))});
|
|
714
714
|
let line = L.hotline(geo.toGeoJSON().features[0].geometry.coordinates, {
|
|
715
|
+
renderer: L.Hotline.renderer(),
|
|
715
716
|
min: isFinite(this.track_info[prop + '_min']) ? this.track_info[prop + '_min'] : 0,
|
|
716
717
|
max: isFinite(this.track_info[prop + '_max']) ? this.track_info[prop + '_max'] : 1,
|
|
717
718
|
palette: {
|
|
@@ -1594,44 +1595,44 @@
|
|
|
1594
1595
|
|
|
1595
1596
|
});
|
|
1596
1597
|
|
|
1597
|
-
/*
|
|
1598
|
-
* Copyright (c) 2019, GPL-3.0+ Project, Raruto
|
|
1599
|
-
*
|
|
1600
|
-
* This file is free software: you may copy, redistribute and/or modify it
|
|
1601
|
-
* under the terms of the GNU General Public License as published by the
|
|
1602
|
-
* Free Software Foundation, either version 2 of the License, or (at your
|
|
1603
|
-
* option) any later version.
|
|
1604
|
-
*
|
|
1605
|
-
* This file is distributed in the hope that it will be useful, but
|
|
1606
|
-
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
1607
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
1608
|
-
* General Public License for more details.
|
|
1609
|
-
*
|
|
1610
|
-
* You should have received a copy of the GNU General Public License
|
|
1611
|
-
* along with this program. If not, see .
|
|
1612
|
-
*
|
|
1613
|
-
* This file incorporates work covered by the following copyright and
|
|
1614
|
-
* permission notice:
|
|
1615
|
-
*
|
|
1616
|
-
* Copyright (c) 2013-2016, MIT License, Felix “MrMufflon” Bache
|
|
1617
|
-
*
|
|
1618
|
-
* Permission to use, copy, modify, and/or distribute this software
|
|
1619
|
-
* for any purpose with or without fee is hereby granted, provided
|
|
1620
|
-
* that the above copyright notice and this permission notice appear
|
|
1621
|
-
* in all copies.
|
|
1622
|
-
*
|
|
1623
|
-
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
1624
|
-
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
1625
|
-
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
1626
|
-
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
|
1627
|
-
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
1628
|
-
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
1629
|
-
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
1630
|
-
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
1631
|
-
*/
|
|
1632
|
-
|
|
1633
|
-
Elevation.Utils = _;
|
|
1634
|
-
|
|
1598
|
+
/*
|
|
1599
|
+
* Copyright (c) 2019, GPL-3.0+ Project, Raruto
|
|
1600
|
+
*
|
|
1601
|
+
* This file is free software: you may copy, redistribute and/or modify it
|
|
1602
|
+
* under the terms of the GNU General Public License as published by the
|
|
1603
|
+
* Free Software Foundation, either version 2 of the License, or (at your
|
|
1604
|
+
* option) any later version.
|
|
1605
|
+
*
|
|
1606
|
+
* This file is distributed in the hope that it will be useful, but
|
|
1607
|
+
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
1608
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
1609
|
+
* General Public License for more details.
|
|
1610
|
+
*
|
|
1611
|
+
* You should have received a copy of the GNU General Public License
|
|
1612
|
+
* along with this program. If not, see .
|
|
1613
|
+
*
|
|
1614
|
+
* This file incorporates work covered by the following copyright and
|
|
1615
|
+
* permission notice:
|
|
1616
|
+
*
|
|
1617
|
+
* Copyright (c) 2013-2016, MIT License, Felix “MrMufflon” Bache
|
|
1618
|
+
*
|
|
1619
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
1620
|
+
* for any purpose with or without fee is hereby granted, provided
|
|
1621
|
+
* that the above copyright notice and this permission notice appear
|
|
1622
|
+
* in all copies.
|
|
1623
|
+
*
|
|
1624
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
1625
|
+
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
1626
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
1627
|
+
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
|
1628
|
+
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
1629
|
+
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
1630
|
+
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
1631
|
+
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
1632
|
+
*/
|
|
1633
|
+
|
|
1634
|
+
Elevation.Utils = _;
|
|
1635
|
+
|
|
1635
1636
|
L.control.elevation = (options) => new Elevation(options);
|
|
1636
1637
|
|
|
1637
1638
|
}));
|