@raruto/leaflet-elevation 1.7.4 → 1.8.0
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/README.md +19 -2
- package/dist/leaflet-elevation.js +637 -847
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +3 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/package.json +1 -1
- package/src/acceleration.js +11 -21
- package/src/altitude.js +21 -22
- package/src/chart.js +55 -175
- package/src/components.js +159 -111
- package/src/control.js +115 -209
- package/src/distance.js +15 -13
- package/src/index.js +12 -1
- package/src/marker.js +38 -98
- package/src/options.js +1 -8
- package/src/slope.js +9 -18
- package/src/speed.js +11 -21
- package/src/time.js +15 -10
- package/src/utils.js +113 -137
package/src/utils.js
CHANGED
|
@@ -22,29 +22,6 @@ export function deepMerge(target, ...sources) {
|
|
|
22
22
|
return deepMerge(target, ...sources);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/**
|
|
26
|
-
* Wait for document load before execute function.
|
|
27
|
-
*/
|
|
28
|
-
export function deferFunc(f) {
|
|
29
|
-
if (document.readyState !== 'complete') window.addEventListener("load", f, { once: true });
|
|
30
|
-
else f();
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Debounce function to limit events are being fired.
|
|
34
|
-
*/
|
|
35
|
-
export function debounce(func, wait, context, immediate) {
|
|
36
|
-
var timeout;
|
|
37
|
-
return function() {
|
|
38
|
-
var args = arguments;
|
|
39
|
-
clearTimeout(timeout);
|
|
40
|
-
timeout = setTimeout(function() {
|
|
41
|
-
timeout = null;
|
|
42
|
-
if (!immediate) func.apply(context, args);
|
|
43
|
-
}, wait);
|
|
44
|
-
if (immediate && !timeout) func.apply(context, args);
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
25
|
const SEC = 1000;
|
|
49
26
|
const MIN = SEC * 60;
|
|
50
27
|
const HOUR = MIN * 60;
|
|
@@ -73,14 +50,13 @@ export function GeoJSONLoader(data, control) {
|
|
|
73
50
|
}
|
|
74
51
|
control = control || this;
|
|
75
52
|
|
|
76
|
-
|
|
53
|
+
let distanceMarkers = (
|
|
77
54
|
control.options.distanceMarkers === true
|
|
78
55
|
? { lazy: true }
|
|
79
56
|
: L.extend({ lazy: true }, control.options.distanceMarkers)
|
|
80
57
|
);
|
|
81
58
|
|
|
82
|
-
|
|
83
|
-
let wptLabels = control.options.wptLabels;
|
|
59
|
+
let { wptIcons, wptLabels } = control.options;
|
|
84
60
|
|
|
85
61
|
let layer = L.geoJson(data, {
|
|
86
62
|
distanceMarkers: distanceMarkers,
|
|
@@ -99,33 +75,32 @@ export function GeoJSONLoader(data, control) {
|
|
|
99
75
|
let name = prop.name ?? '';
|
|
100
76
|
let sym = (prop.sym ?? name).replace(' ', '-').replace('"', '').replace("'", '').toLowerCase();
|
|
101
77
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
78
|
+
// Handle chart waypoints (dots)
|
|
79
|
+
if ([true, 'dots'].includes(control.options.waypoints)) {
|
|
80
|
+
control._registerCheckPoint({
|
|
81
|
+
latlng: latlng,
|
|
82
|
+
label: ([true, 'dots'].includes(wptLabels) ? name : '')
|
|
83
|
+
},
|
|
84
|
+
true
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Handle map waypoints (markers)
|
|
89
|
+
if ([true, 'markers'].includes(control.options.waypoints) && wptIcons != false) {
|
|
90
|
+
// generate and cache appropriate icon symbol
|
|
91
|
+
if (!wptIcons.hasOwnProperty(sym)) {
|
|
92
|
+
wptIcons[sym] = L.divIcon(
|
|
93
|
+
L.extend({}, wptIcons[""].options, { html: '<i class="elevation-waypoint-icon ' + sym + '"></i>' } )
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
let marker = L.marker(latlng, { icon: wptIcons[sym] });
|
|
97
|
+
if ([true, 'markers'].includes(wptLabels) && (name || desc)) {
|
|
98
|
+
marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
|
|
99
|
+
}
|
|
100
|
+
control._addMarker(marker);
|
|
101
|
+
control.fire('waypoint_added', { point: marker, element: latlng, properties: prop });
|
|
102
|
+
return marker;
|
|
103
|
+
}
|
|
129
104
|
},
|
|
130
105
|
onEachFeature: (feature, layer) => {
|
|
131
106
|
if (feature.geometry && feature.geometry.type == 'Point') return;
|
|
@@ -152,12 +127,12 @@ export function GeoJSONLoader(data, control) {
|
|
|
152
127
|
|
|
153
128
|
// Postpone adding the distance markers (lazy: true)
|
|
154
129
|
if(control.options.distanceMarkers && distanceMarkers.lazy) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
130
|
+
layer.on('add remove', (e) => {
|
|
131
|
+
let path = e.target;
|
|
132
|
+
if (L.DistanceMarkers && path instanceof L.Polyline) {
|
|
158
133
|
path[e.type + 'DistanceMarkers']();
|
|
159
|
-
|
|
160
|
-
|
|
134
|
+
}
|
|
135
|
+
});
|
|
161
136
|
}
|
|
162
137
|
|
|
163
138
|
control.track_info = L.extend({}, control.track_info, { type: "geojson", name: data.name });
|
|
@@ -171,13 +146,6 @@ export function GeoJSONLoader(data, control) {
|
|
|
171
146
|
return layer;
|
|
172
147
|
}
|
|
173
148
|
|
|
174
|
-
/**
|
|
175
|
-
* Check DOM element visibility.
|
|
176
|
-
*/
|
|
177
|
-
export function isDomVisible(elem) {
|
|
178
|
-
return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
149
|
/**
|
|
182
150
|
* Check object type.
|
|
183
151
|
*/
|
|
@@ -185,47 +153,6 @@ export function isObject(item) {
|
|
|
185
153
|
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
186
154
|
}
|
|
187
155
|
|
|
188
|
-
/**
|
|
189
|
-
* Check DOM element viewport visibility.
|
|
190
|
-
*/
|
|
191
|
-
export function isVisible(elem) {
|
|
192
|
-
if (!elem) return false;
|
|
193
|
-
|
|
194
|
-
let styles = window.getComputedStyle(elem);
|
|
195
|
-
|
|
196
|
-
function isVisibleByStyles(elem, styles) {
|
|
197
|
-
return styles.visibility !== 'hidden' && styles.display !== 'none';
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function isAboveOtherElements(elem, styles) {
|
|
201
|
-
let boundingRect = elem.getBoundingClientRect();
|
|
202
|
-
let left = boundingRect.left + 1;
|
|
203
|
-
let right = boundingRect.right - 1;
|
|
204
|
-
let top = boundingRect.top + 1;
|
|
205
|
-
let bottom = boundingRect.bottom - 1;
|
|
206
|
-
let above = true;
|
|
207
|
-
|
|
208
|
-
let pointerEvents = elem.style.pointerEvents;
|
|
209
|
-
|
|
210
|
-
if (styles['pointer-events'] == 'none') elem.style.pointerEvents = 'auto';
|
|
211
|
-
|
|
212
|
-
if (document.elementFromPoint(left, top) !== elem) above = false;
|
|
213
|
-
if (document.elementFromPoint(right, top) !== elem) above = false;
|
|
214
|
-
|
|
215
|
-
// Only for completely visible elements
|
|
216
|
-
// if (document.elementFromPoint(left, bottom) !== elem) above = false;
|
|
217
|
-
// if (document.elementFromPoint(right, bottom) !== elem) above = false;
|
|
218
|
-
|
|
219
|
-
elem.style.pointerEvents = pointerEvents;
|
|
220
|
-
|
|
221
|
-
return above;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (!isVisibleByStyles(elem, styles)) return false;
|
|
225
|
-
if (!isAboveOtherElements(elem, styles)) return false;
|
|
226
|
-
return true;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
156
|
/**
|
|
230
157
|
* Check JSON object type.
|
|
231
158
|
*/
|
|
@@ -260,6 +187,17 @@ export function isXMLDoc(doc, lazy) {
|
|
|
260
187
|
}
|
|
261
188
|
}
|
|
262
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Generate download data event.
|
|
192
|
+
*/
|
|
193
|
+
export function saveFile(dataURI, fileName) {
|
|
194
|
+
let a = create('a', '', { href: dataURI, target: '_new', download: fileName || "", style: "display:none;" });
|
|
195
|
+
let b = document.body;
|
|
196
|
+
b.appendChild(a);
|
|
197
|
+
a.click();
|
|
198
|
+
b.removeChild(a);
|
|
199
|
+
}
|
|
200
|
+
|
|
263
201
|
/**
|
|
264
202
|
* Async JS script download.
|
|
265
203
|
*/
|
|
@@ -278,39 +216,71 @@ export function lazyLoader(url, skip, loader) {
|
|
|
278
216
|
});
|
|
279
217
|
}
|
|
280
218
|
|
|
219
|
+
export function lazyLoad(src, control) {
|
|
220
|
+
if (!control.options.lazyLoadJS) return Promise.resolve();
|
|
221
|
+
|
|
222
|
+
const Elevation = L.Control.Elevation;
|
|
223
|
+
let loader = '';
|
|
224
|
+
let condition = false;
|
|
225
|
+
|
|
226
|
+
switch(src) {
|
|
227
|
+
case control.__D3:
|
|
228
|
+
loader = '_d3LazyLoader';
|
|
229
|
+
condition = typeof d3 !== 'object';
|
|
230
|
+
break;
|
|
231
|
+
case control.__TOGEOJSON:
|
|
232
|
+
loader = '_togeojsonLazyLoader';
|
|
233
|
+
condition = typeof toGeoJSON !== 'object';
|
|
234
|
+
break;
|
|
235
|
+
case control.__LGEOMUTIL:
|
|
236
|
+
loader = '_geomutilLazyLoader';
|
|
237
|
+
condition = typeof L.GeometryUtil !== 'object';
|
|
238
|
+
case control.__LALMOSTOVER:
|
|
239
|
+
loader = '_almostoverLazyLoader';
|
|
240
|
+
condition = typeof L.Handler.AlmostOver !== 'function ';
|
|
241
|
+
break;
|
|
242
|
+
case control.__LDISTANCEM:
|
|
243
|
+
loader = '_distanceMarkersLazyLoader';
|
|
244
|
+
condition = typeof L.DistanceMarkers !== 'function';
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
return Elevation[loader] = lazyLoader(src, condition, Elevation[loader]);
|
|
248
|
+
}
|
|
249
|
+
|
|
281
250
|
/**
|
|
282
|
-
*
|
|
251
|
+
* Convert SVG Path into Path2D and then update canvas
|
|
283
252
|
*/
|
|
284
|
-
export function
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
253
|
+
export function drawCanvas(ctx, path) {
|
|
254
|
+
path.classed('canvas-path', true);
|
|
255
|
+
|
|
256
|
+
ctx.beginPath();
|
|
257
|
+
ctx.moveTo(0, 0);
|
|
258
|
+
let p = new Path2D(path.attr('d'));
|
|
259
|
+
|
|
260
|
+
ctx.strokeStyle = path.attr('stroke');
|
|
261
|
+
ctx.fillStyle = path.attr('fill');
|
|
262
|
+
ctx.lineWidth = 1.25;
|
|
263
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
264
|
+
|
|
265
|
+
// stroke opacity
|
|
266
|
+
ctx.globalAlpha = path.attr('stroke-opacity') || 0.3;
|
|
267
|
+
ctx.stroke(p);
|
|
268
|
+
|
|
269
|
+
// fill opacity
|
|
270
|
+
ctx.globalAlpha = path.attr('fill-opacity') || 0.45;
|
|
271
|
+
ctx.fill(p);
|
|
272
|
+
|
|
273
|
+
ctx.globalAlpha = 1;
|
|
274
|
+
|
|
275
|
+
ctx.closePath();
|
|
290
276
|
}
|
|
291
277
|
|
|
292
278
|
/**
|
|
293
|
-
*
|
|
279
|
+
* Limit a number between min / max values
|
|
294
280
|
*/
|
|
295
|
-
export function
|
|
296
|
-
return
|
|
297
|
-
|
|
298
|
-
let scrollFn = () => {
|
|
299
|
-
if (!ticking) {
|
|
300
|
-
L.Util.requestAnimFrame(() => {
|
|
301
|
-
if (isVisible(elem)) {
|
|
302
|
-
window.removeEventListener('scroll', scrollFn);
|
|
303
|
-
resolve();
|
|
304
|
-
}
|
|
305
|
-
ticking = false;
|
|
306
|
-
});
|
|
307
|
-
ticking = true;
|
|
308
|
-
}
|
|
309
|
-
};
|
|
310
|
-
window.addEventListener('scroll', scrollFn);
|
|
311
|
-
if (elem) elem.addEventListener('mouseenter', scrollFn, { once: true });
|
|
312
|
-
scrollFn();
|
|
313
|
-
});
|
|
281
|
+
export function clamp(val, range) {
|
|
282
|
+
if (range) return val < range[0] ? range[0] : val > range[1] ? range[1] : val;
|
|
283
|
+
return val;
|
|
314
284
|
}
|
|
315
285
|
|
|
316
286
|
/**
|
|
@@ -332,8 +302,8 @@ export function toggleClass(targetNode, className, conditional) {
|
|
|
332
302
|
}
|
|
333
303
|
|
|
334
304
|
export function replaceClass(targetNode, removeClassName, addClassName) {
|
|
335
|
-
|
|
336
|
-
|
|
305
|
+
if (removeClassName) removeClass(targetNode, removeClassName);
|
|
306
|
+
if (addClassName) addClass(targetNode, addClassName);
|
|
337
307
|
}
|
|
338
308
|
|
|
339
309
|
export function style(targetNode, name, value) {
|
|
@@ -342,7 +312,7 @@ export function style(targetNode, name, value) {
|
|
|
342
312
|
}
|
|
343
313
|
|
|
344
314
|
export function toggleStyle(targetNode, name, value, conditional) {
|
|
345
|
-
|
|
315
|
+
return style(targetNode, name, conditional ? value : '');
|
|
346
316
|
}
|
|
347
317
|
|
|
348
318
|
export function toggleEvent(leafletElement, eventName, handler, conditional) {
|
|
@@ -403,10 +373,16 @@ export const off = L.DomEvent.off;
|
|
|
403
373
|
export const hasClass = L.DomUtil.hasClass;
|
|
404
374
|
|
|
405
375
|
|
|
376
|
+
/**
|
|
377
|
+
* Generate a random string
|
|
378
|
+
*/
|
|
406
379
|
export function randomId() {
|
|
407
380
|
return Math.random().toString(36).substr(2, 9);
|
|
408
381
|
}
|
|
409
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Execute a function foreach element in object
|
|
385
|
+
*/
|
|
410
386
|
export function each(obj, fn) {
|
|
411
387
|
for (let i in obj) fn(obj[i], i);
|
|
412
|
-
}
|
|
388
|
+
}
|