@raruto/leaflet-elevation 2.0.4 → 2.0.7

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.
@@ -0,0 +1,457 @@
1
+ /*
2
+ (c) 2017, iosphere GmbH
3
+ Leaflet.hotline, a Leaflet plugin for drawing gradients along polylines.
4
+ https://github.com/iosphere/Leaflet.hotline/
5
+ */
6
+
7
+ (function (root, plugin) {
8
+ /**
9
+ * UMD wrapper.
10
+ * When used directly in the Browser it expects Leaflet to be globally
11
+ * available as `L`. The plugin then adds itself to Leaflet.
12
+ * When used as a CommonJS module (e.g. with browserify) only the plugin
13
+ * factory gets exported, so one hast to call the factory manually and pass
14
+ * Leaflet as the only parameter.
15
+ * @see {@link https://github.com/umdjs/umd}
16
+ */
17
+ if (typeof define === 'function' && define.amd) {
18
+ define(['leaflet'], plugin);
19
+ } else if (typeof exports === 'object') {
20
+ module.exports = plugin;
21
+ } else {
22
+ plugin(root.L);
23
+ }
24
+ }(window, function (L) {
25
+ // Plugin is already added to Leaflet
26
+ if (L.Hotline) {
27
+ return L;
28
+ }
29
+
30
+ /**
31
+ * Core renderer.
32
+ * @constructor
33
+ * @param {HTMLElement | string} canvas - <canvas> element or its id
34
+ * to initialize the instance on.
35
+ */
36
+ var Hotline = function (canvas) {
37
+ if (!(this instanceof Hotline)) { return new Hotline(canvas); }
38
+
39
+ var defaultPalette = {
40
+ 0.0: 'green',
41
+ 0.5: 'yellow',
42
+ 1.0: 'red'
43
+ };
44
+
45
+ this._canvas = canvas = typeof canvas === 'string'
46
+ ? document.getElementById(canvas)
47
+ : canvas;
48
+
49
+ this._ctx = canvas.getContext('2d');
50
+ this._width = canvas.width;
51
+ this._height = canvas.height;
52
+
53
+ this._weight = 5;
54
+ this._outlineWidth = 1;
55
+ this._outlineColor = 'black';
56
+
57
+ this._min = 0;
58
+ this._max = 1;
59
+
60
+ this._data = [];
61
+
62
+ this.palette(defaultPalette);
63
+ };
64
+
65
+ Hotline.prototype = {
66
+ /**
67
+ * Sets the width of the canvas. Used when clearing the canvas.
68
+ * @param {number} width - Width of the canvas.
69
+ */
70
+ width: function (width) {
71
+ this._width = width;
72
+ return this;
73
+ },
74
+
75
+ /**
76
+ * Sets the height of the canvas. Used when clearing the canvas.
77
+ * @param {number} height - Height of the canvas.
78
+ */
79
+ height: function (height) {
80
+ this._height = height;
81
+ return this;
82
+ },
83
+
84
+ /**
85
+ * Sets the weight of the path.
86
+ * @param {number} weight - Weight of the path in px.
87
+ */
88
+ weight: function (weight) {
89
+ this._weight = weight;
90
+ return this;
91
+ },
92
+
93
+ /**
94
+ * Sets the width of the outline around the path.
95
+ * @param {number} outlineWidth - Width of the outline in px.
96
+ */
97
+ outlineWidth: function (outlineWidth) {
98
+ this._outlineWidth = outlineWidth;
99
+ return this;
100
+ },
101
+
102
+ /**
103
+ * Sets the color of the outline around the path.
104
+ * @param {string} outlineColor - A CSS color value.
105
+ */
106
+ outlineColor: function (outlineColor) {
107
+ this._outlineColor = outlineColor;
108
+ return this;
109
+ },
110
+
111
+ /**
112
+ * Sets the palette gradient.
113
+ * @param {Object.<number, string>} palette - Gradient definition.
114
+ * e.g. { 0.0: 'white', 1.0: 'black' }
115
+ */
116
+ palette: function (palette) {
117
+ var canvas = document.createElement('canvas'),
118
+ ctx = canvas.getContext('2d'),
119
+ gradient = ctx.createLinearGradient(0, 0, 0, 256);
120
+
121
+ canvas.width = 1;
122
+ canvas.height = 256;
123
+
124
+ for (var i in palette) {
125
+ gradient.addColorStop(i, palette[i]);
126
+ }
127
+
128
+ ctx.fillStyle = gradient;
129
+ ctx.fillRect(0, 0, 1, 256);
130
+
131
+ this._palette = ctx.getImageData(0, 0, 1, 256).data;
132
+
133
+ return this;
134
+ },
135
+
136
+ /**
137
+ * Sets the value used at the start of the palette gradient.
138
+ * @param {number} min
139
+ */
140
+ min: function (min) {
141
+ this._min = min;
142
+ return this;
143
+ },
144
+
145
+ /**
146
+ * Sets the value used at the end of the palette gradient.
147
+ * @param {number} max
148
+ */
149
+ max: function (max) {
150
+ this._max = max;
151
+ return this;
152
+ },
153
+
154
+ /**
155
+ * A path to rander as a hotline.
156
+ * @typedef Array.<{x:number, y:number, z:number}> Path - Array of x, y and z coordinates.
157
+ */
158
+
159
+ /**
160
+ * Sets the data that gets drawn on the canvas.
161
+ * @param {(Path|Path[])} data - A single path or an array of paths.
162
+ */
163
+ data: function (data) {
164
+ this._data = data;
165
+ return this;
166
+ },
167
+
168
+ /**
169
+ * Adds a path to the list of paths.
170
+ * @param {Path} path
171
+ */
172
+ add: function (path) {
173
+ this._data.push(path);
174
+ return this;
175
+ },
176
+
177
+ /**
178
+ * Draws the currently set paths.
179
+ */
180
+ draw: function () {
181
+ var ctx = this._ctx;
182
+
183
+ ctx.globalCompositeOperation = 'source-over';
184
+ ctx.lineCap = 'round';
185
+
186
+ this._drawOutline(ctx);
187
+ this._drawHotline(ctx);
188
+
189
+ return this;
190
+ },
191
+
192
+ /**
193
+ * Gets the RGB values of a given z value of the current palette.
194
+ * @param {number} value - Value to get the color for, should be between min and max.
195
+ * @returns {Array.<number>} The RGB values as an array [r, g, b]
196
+ */
197
+ getRGBForValue: function (value) {
198
+ var valueRelative = Math.min(Math.max((value - this._min) / (this._max - this._min), 0), 0.999);
199
+ var paletteIndex = Math.floor(valueRelative * 256) * 4;
200
+
201
+ return [
202
+ this._palette[paletteIndex],
203
+ this._palette[paletteIndex + 1],
204
+ this._palette[paletteIndex + 2]
205
+ ];
206
+ },
207
+
208
+ /**
209
+ * Draws the outline of the graphs.
210
+ * @private
211
+ */
212
+ _drawOutline: function (ctx) {
213
+ var i, j, dataLength, path, pathLength, pointStart, pointEnd;
214
+
215
+ if (this._outlineWidth) {
216
+ for (i = 0, dataLength = this._data.length; i < dataLength; i++) {
217
+ path = this._data[i];
218
+ ctx.lineWidth = this._weight + 2 * this._outlineWidth;
219
+
220
+ for (j = 1, pathLength = path.length; j < pathLength; j++) {
221
+ pointStart = path[j - 1];
222
+ pointEnd = path[j];
223
+
224
+ ctx.strokeStyle = this._outlineColor;
225
+ ctx.beginPath();
226
+ ctx.moveTo(pointStart.x, pointStart.y);
227
+ ctx.lineTo(pointEnd.x, pointEnd.y);
228
+ ctx.stroke();
229
+ }
230
+ }
231
+ }
232
+ },
233
+
234
+ /**
235
+ * Draws the color encoded hotline of the graphs.
236
+ * @private
237
+ */
238
+ _drawHotline: function (ctx) {
239
+ var i, j, dataLength, path, pathLength, pointStart, pointEnd,
240
+ gradient, gradientStartRGB, gradientEndRGB;
241
+
242
+ ctx.lineWidth = this._weight;
243
+
244
+ for (i = 0, dataLength = this._data.length; i < dataLength; i++) {
245
+ path = this._data[i];
246
+
247
+ for (j = 1, pathLength = path.length; j < pathLength; j++) {
248
+ pointStart = path[j - 1];
249
+ pointEnd = path[j];
250
+
251
+ // Create a gradient for each segment, pick start end end colors from palette gradient
252
+ gradient = ctx.createLinearGradient(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
253
+ gradientStartRGB = this.getRGBForValue(pointStart.z);
254
+ gradientEndRGB = this.getRGBForValue(pointEnd.z);
255
+ gradient.addColorStop(0, 'rgb(' + gradientStartRGB.join(',') + ')');
256
+ gradient.addColorStop(1, 'rgb(' + gradientEndRGB.join(',') + ')');
257
+
258
+ ctx.strokeStyle = gradient;
259
+ ctx.beginPath();
260
+ ctx.moveTo(pointStart.x, pointStart.y);
261
+ ctx.lineTo(pointEnd.x, pointEnd.y);
262
+ ctx.stroke();
263
+ }
264
+ }
265
+ }
266
+ };
267
+
268
+
269
+ var Renderer = L.Canvas.extend({
270
+ _initContainer: function () {
271
+ L.Canvas.prototype._initContainer.call(this);
272
+ this._hotline = new Hotline(this._container);
273
+ },
274
+
275
+ _update: function () {
276
+ L.Canvas.prototype._update.call(this);
277
+ this._hotline.width(this._container.width);
278
+ this._hotline.height(this._container.height);
279
+ },
280
+
281
+ _updatePoly: function (layer) {
282
+ if (!this._drawing) { return; }
283
+
284
+ var parts = layer._parts;
285
+
286
+ if (!parts.length) { return; }
287
+
288
+ this._updateOptions(layer);
289
+
290
+ this._hotline
291
+ .data(parts)
292
+ .draw();
293
+ },
294
+
295
+ _updateOptions: function (layer) {
296
+ if (layer.options.min != null) {
297
+ this._hotline.min(layer.options.min);
298
+ }
299
+ if (layer.options.max != null) {
300
+ this._hotline.max(layer.options.max);
301
+ }
302
+ if (layer.options.weight != null) {
303
+ this._hotline.weight(layer.options.weight);
304
+ }
305
+ if (layer.options.outlineWidth != null) {
306
+ this._hotline.outlineWidth(layer.options.outlineWidth);
307
+ }
308
+ if (layer.options.outlineColor != null) {
309
+ this._hotline.outlineColor(layer.options.outlineColor);
310
+ }
311
+ if (layer.options.palette) {
312
+ this._hotline.palette(layer.options.palette);
313
+ }
314
+ }
315
+ });
316
+
317
+ var renderer = function (options) {
318
+ return L.Browser.canvas ? new Renderer(options) : null;
319
+ };
320
+
321
+
322
+ var Util = {
323
+ /**
324
+ * This is just a copy of the original Leaflet version that support a third z coordinate.
325
+ * @see {@link http://leafletjs.com/reference.html#lineutil-clipsegment|Leaflet}
326
+ */
327
+ clipSegment: function (a, b, bounds, useLastCode, round) {
328
+ var codeA = useLastCode ? this._lastCode : L.LineUtil._getBitCode(a, bounds),
329
+ codeB = L.LineUtil._getBitCode(b, bounds),
330
+ codeOut, p, newCode;
331
+
332
+ // save 2nd code to avoid calculating it on the next segment
333
+ this._lastCode = codeB;
334
+
335
+ while (true) {
336
+ // if a,b is inside the clip window (trivial accept)
337
+ if (!(codeA | codeB)) {
338
+ return [a, b];
339
+ // if a,b is outside the clip window (trivial reject)
340
+ } else if (codeA & codeB) {
341
+ return false;
342
+ // other cases
343
+ } else {
344
+ codeOut = codeA || codeB;
345
+ p = L.LineUtil._getEdgeIntersection(a, b, codeOut, bounds, round);
346
+ newCode = L.LineUtil._getBitCode(p, bounds);
347
+
348
+ if (codeOut === codeA) {
349
+ p.z = a.z;
350
+ a = p;
351
+ codeA = newCode;
352
+ } else {
353
+ p.z = b.z;
354
+ b = p;
355
+ codeB = newCode;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ };
361
+
362
+
363
+ L.Hotline = L.Polyline.extend({
364
+ statics: {
365
+ Renderer: Renderer,
366
+ renderer: renderer
367
+ },
368
+
369
+ options: {
370
+ renderer: renderer(),
371
+ min: 0,
372
+ max: 1,
373
+ palette: {
374
+ 0.0: 'green',
375
+ 0.5: 'yellow',
376
+ 1.0: 'red'
377
+ },
378
+ weight: 5,
379
+ outlineColor: 'black',
380
+ outlineWidth: 1
381
+ },
382
+
383
+ getRGBForValue: function (value) {
384
+ return this._renderer._hotline.getRGBForValue(value);
385
+ },
386
+
387
+ /**
388
+ * Just like the Leaflet version, but with support for a z coordinate.
389
+ */
390
+ _projectLatlngs: function (latlngs, result, projectedBounds) {
391
+ var flat = latlngs[0] instanceof L.LatLng,
392
+ len = latlngs.length,
393
+ i, ring;
394
+
395
+ if (flat) {
396
+ ring = [];
397
+ for (i = 0; i < len; i++) {
398
+ ring[i] = this._map.latLngToLayerPoint(latlngs[i]);
399
+ // Add the altitude of the latLng as the z coordinate to the point
400
+ ring[i].z = latlngs[i].alt;
401
+ projectedBounds.extend(ring[i]);
402
+ }
403
+ result.push(ring);
404
+ } else {
405
+ for (i = 0; i < len; i++) {
406
+ this._projectLatlngs(latlngs[i], result, projectedBounds);
407
+ }
408
+ }
409
+ },
410
+
411
+ /**
412
+ * Just like the Leaflet version, but uses `Util.clipSegment()`.
413
+ */
414
+ _clipPoints: function () {
415
+ if (this.options.noClip) {
416
+ this._parts = this._rings;
417
+ return;
418
+ }
419
+
420
+ this._parts = [];
421
+
422
+ var parts = this._parts,
423
+ bounds = this._renderer._bounds,
424
+ i, j, k, len, len2, segment, points;
425
+
426
+ for (i = 0, k = 0, len = this._rings.length; i < len; i++) {
427
+ points = this._rings[i];
428
+
429
+ for (j = 0, len2 = points.length; j < len2 - 1; j++) {
430
+ segment = Util.clipSegment(points[j], points[j + 1], bounds, j, true);
431
+
432
+ if (!segment) { continue; }
433
+
434
+ parts[k] = parts[k] || [];
435
+ parts[k].push(segment[0]);
436
+
437
+ // if segment goes out of screen, or it's the last one, it's the end of the line part
438
+ if ((segment[1] !== points[j + 1]) || (j === len2 - 2)) {
439
+ parts[k].push(segment[1]);
440
+ k++;
441
+ }
442
+ }
443
+ }
444
+ },
445
+
446
+ _clickTolerance: function () {
447
+ return this.options.weight / 2 + this.options.outlineWidth + (L.Browser.touch ? 10 : 0);
448
+ }
449
+ });
450
+
451
+ L.hotline = function (latlngs, options) {
452
+ return new L.Hotline(latlngs, options);
453
+ };
454
+
455
+
456
+ return L;
457
+ }));
@@ -0,0 +1 @@
1
+ !function(root,plugin){"function"==typeof define&&define.amd?define(["leaflet"],plugin):"object"==typeof exports?module.exports=plugin:plugin(root.L)}(window,(function(L){if(L.Hotline)return L;var Hotline=function(canvas){if(!(this instanceof Hotline))return new Hotline(canvas);var defaultPalette={0:"green",.5:"yellow",1:"red"};this._canvas=canvas="string"==typeof canvas?document.getElementById(canvas):canvas,this._ctx=canvas.getContext("2d"),this._width=canvas.width,this._height=canvas.height,this._weight=5,this._outlineWidth=1,this._outlineColor="black",this._min=0,this._max=1,this._data=[],this.palette(defaultPalette)};Hotline.prototype={width:function(width){return this._width=width,this},height:function(height){return this._height=height,this},weight:function(weight){return this._weight=weight,this},outlineWidth:function(outlineWidth){return this._outlineWidth=outlineWidth,this},outlineColor:function(outlineColor){return this._outlineColor=outlineColor,this},palette:function(palette){var canvas=document.createElement("canvas"),ctx=canvas.getContext("2d"),gradient=ctx.createLinearGradient(0,0,0,256);for(var i in canvas.width=1,canvas.height=256,palette)gradient.addColorStop(i,palette[i]);return ctx.fillStyle=gradient,ctx.fillRect(0,0,1,256),this._palette=ctx.getImageData(0,0,1,256).data,this},min:function(min){return this._min=min,this},max:function(max){return this._max=max,this},data:function(data){return this._data=data,this},add:function(path){return this._data.push(path),this},draw:function(){var ctx=this._ctx;return ctx.globalCompositeOperation="source-over",ctx.lineCap="round",this._drawOutline(ctx),this._drawHotline(ctx),this},getRGBForValue:function(value){var valueRelative=Math.min(Math.max((value-this._min)/(this._max-this._min),0),.999),paletteIndex=4*Math.floor(256*valueRelative);return[this._palette[paletteIndex],this._palette[paletteIndex+1],this._palette[paletteIndex+2]]},_drawOutline:function(ctx){var i,j,dataLength,path,pathLength,pointStart,pointEnd;if(this._outlineWidth)for(i=0,dataLength=this._data.length;i<dataLength;i++)for(path=this._data[i],ctx.lineWidth=this._weight+2*this._outlineWidth,j=1,pathLength=path.length;j<pathLength;j++)pointStart=path[j-1],pointEnd=path[j],ctx.strokeStyle=this._outlineColor,ctx.beginPath(),ctx.moveTo(pointStart.x,pointStart.y),ctx.lineTo(pointEnd.x,pointEnd.y),ctx.stroke()},_drawHotline:function(ctx){var i,j,dataLength,path,pathLength,pointStart,pointEnd,gradient,gradientStartRGB,gradientEndRGB;for(ctx.lineWidth=this._weight,i=0,dataLength=this._data.length;i<dataLength;i++)for(j=1,pathLength=(path=this._data[i]).length;j<pathLength;j++)pointStart=path[j-1],pointEnd=path[j],gradient=ctx.createLinearGradient(pointStart.x,pointStart.y,pointEnd.x,pointEnd.y),gradientStartRGB=this.getRGBForValue(pointStart.z),gradientEndRGB=this.getRGBForValue(pointEnd.z),gradient.addColorStop(0,"rgb("+gradientStartRGB.join(",")+")"),gradient.addColorStop(1,"rgb("+gradientEndRGB.join(",")+")"),ctx.strokeStyle=gradient,ctx.beginPath(),ctx.moveTo(pointStart.x,pointStart.y),ctx.lineTo(pointEnd.x,pointEnd.y),ctx.stroke()}};var Renderer=L.Canvas.extend({_initContainer:function(){L.Canvas.prototype._initContainer.call(this),this._hotline=new Hotline(this._container)},_update:function(){L.Canvas.prototype._update.call(this),this._hotline.width(this._container.width),this._hotline.height(this._container.height)},_updatePoly:function(layer){if(this._drawing){var parts=layer._parts;parts.length&&(this._updateOptions(layer),this._hotline.data(parts).draw())}},_updateOptions:function(layer){null!=layer.options.min&&this._hotline.min(layer.options.min),null!=layer.options.max&&this._hotline.max(layer.options.max),null!=layer.options.weight&&this._hotline.weight(layer.options.weight),null!=layer.options.outlineWidth&&this._hotline.outlineWidth(layer.options.outlineWidth),null!=layer.options.outlineColor&&this._hotline.outlineColor(layer.options.outlineColor),layer.options.palette&&this._hotline.palette(layer.options.palette)}}),renderer=function(options){return L.Browser.canvas?new Renderer(options):null},Util={clipSegment:function(a,b,bounds,useLastCode,round){var codeA=useLastCode?this._lastCode:L.LineUtil._getBitCode(a,bounds),codeB=L.LineUtil._getBitCode(b,bounds),codeOut,p,newCode;for(this._lastCode=codeB;;){if(!(codeA|codeB))return[a,b];if(codeA&codeB)return!1;codeOut=codeA||codeB,p=L.LineUtil._getEdgeIntersection(a,b,codeOut,bounds,round),newCode=L.LineUtil._getBitCode(p,bounds),codeOut===codeA?(p.z=a.z,a=p,codeA=newCode):(p.z=b.z,b=p,codeB=newCode)}}};return L.Hotline=L.Polyline.extend({statics:{Renderer:Renderer,renderer:renderer},options:{renderer:renderer(),min:0,max:1,palette:{0:"green",.5:"yellow",1:"red"},weight:5,outlineColor:"black",outlineWidth:1},getRGBForValue:function(value){return this._renderer._hotline.getRGBForValue(value)},_projectLatlngs:function(latlngs,result,projectedBounds){var flat=latlngs[0]instanceof L.LatLng,len=latlngs.length,i,ring;if(flat){for(ring=[],i=0;i<len;i++)ring[i]=this._map.latLngToLayerPoint(latlngs[i]),ring[i].z=latlngs[i].alt,projectedBounds.extend(ring[i]);result.push(ring)}else for(i=0;i<len;i++)this._projectLatlngs(latlngs[i],result,projectedBounds)},_clipPoints:function(){if(this.options.noClip)this._parts=this._rings;else{this._parts=[];var parts=this._parts,bounds=this._renderer._bounds,i,j,k,len,len2,segment,points;for(i=0,k=0,len=this._rings.length;i<len;i++)for(j=0,len2=(points=this._rings[i]).length;j<len2-1;j++)(segment=Util.clipSegment(points[j],points[j+1],bounds,j,!0))&&(parts[k]=parts[k]||[],parts[k].push(segment[0]),segment[1]===points[j+1]&&j!==len2-2||(parts[k].push(segment[1]),k++))}},_clickTolerance:function(){return this.options.weight/2+this.options.outlineWidth+(L.Browser.touch?10:0)}}),L.hotline=function(latlngs,options){return new L.Hotline(latlngs,options)},L}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raruto/leaflet-elevation",
3
- "version": "2.0.4",
3
+ "version": "2.0.7",
4
4
  "description": "A Leaflet plugin that allows to add elevation profiles using d3js",
5
5
  "main": "dist/leaflet-elevation.min.js",
6
6
  "module": "src/index.js",
package/src/control.js CHANGED
@@ -13,6 +13,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
13
13
  __TOGEOJSON: 'https://unpkg.com/@tmcw/togeojson@4.6.0/dist/togeojson.umd.js',
14
14
  __LGEOMUTIL: 'https://unpkg.com/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.js',
15
15
  __LALMOSTOVER: 'https://unpkg.com/leaflet-almostover@1.0.1/src/leaflet.almostover.js',
16
+ __LHOTLINE: '../libs/leaflet-hotline.min.js',
16
17
  __LDISTANCEM: '../libs/leaflet-distance-marker.min.js',
17
18
  __LCHART: '../src/components/chart.js',
18
19
  __LMARKER: '../src/components/marker.js',
@@ -415,6 +416,41 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
415
416
  }
416
417
  },
417
418
 
419
+ _initHotLine: function(map, layer) {
420
+ this._hotline = L.featureGroup();
421
+ if (this.options.hotline) {
422
+ layer.on('add', () => {
423
+ this._hotline.eachLayer(line => {
424
+ this._hotline.addTo(layer._map);
425
+ if (line._renderer)
426
+ line._renderer._container.parentElement.insertBefore(line._renderer._container, line._renderer._container.parentElement.firstChild);
427
+ });
428
+ });
429
+ let prop = typeof this.options.hotline == 'string' ? this.options.hotline : 'elevation';
430
+ this.import(this.__LHOTLINE)
431
+ .then(() => {
432
+ layer.setStyle({opacity: 0});
433
+ layer.eachLayer((trkseg) => {
434
+ if(trkseg.feature.geometry.type != "Point") {
435
+ let geo = L.geoJson(trkseg.toGeoJSON(), { coordsToLatLng: (coords) => L.latLng(coords[0], coords[1], coords[2])});
436
+ let line = L.hotline(geo.toGeoJSON().features[0].geometry.coordinates, {
437
+ min: isFinite(this.track_info[prop + '_min']) ? this.track_info[prop + '_min'] : 0,
438
+ max: isFinite(this.track_info[prop + '_max']) ? this.track_info[prop + '_max'] : 1,
439
+ palette: {
440
+ 0.0: '#008800',
441
+ 0.5: '#ffff00',
442
+ 1.0: '#ff0000'
443
+ },
444
+ weight: 5,
445
+ outlineColor: '#000000',
446
+ outlineWidth: 1
447
+ }).addTo(this._hotline);
448
+ }
449
+ });
450
+ });
451
+ }
452
+ },
453
+
418
454
  /**
419
455
  * Initialize "L.AlmostOver" and "L.DistanceMarkers"
420
456
  */
@@ -428,6 +464,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
428
464
  control._circleMarkers.addTo(map);
429
465
  map.once('layeradd', (e) => control.options.autofitBounds && control.fitBounds(layer.getBounds()));
430
466
  if (!L.Browser.mobile) {
467
+ control._initHotLine(map, layer);
431
468
  control._initAlmostOverHandler(map, layer);
432
469
  control._initDistanceMarkers(map, layer);
433
470
  } else if (control.options.polyline) {
@@ -444,6 +481,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
444
481
  */
445
482
  _collapse: function() {
446
483
  _.replaceClass(this._container, 'elevation-expanded', 'elevation-collapsed');
484
+ if (this._map) this._map.invalidateSize();
447
485
  },
448
486
 
449
487
  /*
@@ -451,6 +489,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
451
489
  */
452
490
  _expand: function() {
453
491
  _.replaceClass(this._container, 'elevation-collapsed', 'elevation-expanded');
492
+ if (this._map) this._map.invalidateSize();
454
493
  },
455
494
 
456
495
  /**
@@ -1240,8 +1279,8 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
1240
1279
  }
1241
1280
  if (this.options.downloadLink && this._downloadURL) { // TODO: generate dynamically file content instead of using static file urls.
1242
1281
  this._summary._container.innerHTML += '<span class="download"><a href="#">' + L._('Download') + '</a></span>'
1243
- _.select('.download a', this._summary._container).onclick = ({preventDefault}) => {
1244
- preventDefault();
1282
+ _.select('.download a', this._summary._container).onclick = (e) => {
1283
+ e.preventDefault();
1245
1284
  let event = { downloadLink: this.options.downloadLink, confirm: _.saveFile.bind(this, this._downloadURL) };
1246
1285
  if (this.options.downloadLink == 'modal' && typeof CustomEvent === "function") {
1247
1286
  document.dispatchEvent(new CustomEvent("eletrack_download", { detail: event }));
package/src/options.js CHANGED
@@ -18,6 +18,7 @@ export var Options = {
18
18
  imperial: false,
19
19
  legend: true,
20
20
  handlers: [],
21
+ hotline: 'elevation',
21
22
  marker: 'elevation-line',
22
23
  markerIcon: L.divIcon({
23
24
  className: 'elevation-position-marker',