@raruto/leaflet-elevation 2.0.5 → 2.0.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/dist/leaflet-elevation.js +36 -0
- 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/libs/leaflet-hotline.js +457 -0
- package/libs/leaflet-hotline.min.js +1 -0
- package/package.json +1 -1
- package/src/control.js +35 -0
- package/src/options.js +1 -0
|
@@ -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
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,37 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
415
416
|
}
|
|
416
417
|
},
|
|
417
418
|
|
|
419
|
+
_initHotLine: function(map, layer) {
|
|
420
|
+
if (this.options.hotline) {
|
|
421
|
+
let prop = typeof this.options.hotline == 'string' ? this.options.hotline : 'elevation';
|
|
422
|
+
this.import(this.__LHOTLINE)
|
|
423
|
+
.then(() => {
|
|
424
|
+
this._hotline = L.featureGroup();
|
|
425
|
+
layer.setStyle({opacity: 0});
|
|
426
|
+
layer.eachLayer((trkseg) => {
|
|
427
|
+
if(trkseg.feature.geometry.type != "Point") {
|
|
428
|
+
let geo = L.geoJson(trkseg.toGeoJSON(), { coordsToLatLng: (coords) => L.latLng(coords[0], coords[1], coords[2])});
|
|
429
|
+
L.hotline(geo.toGeoJSON().features[0].geometry.coordinates, {
|
|
430
|
+
min: isFinite(this.track_info[prop + '_min']) ? this.track_info[prop + '_min'] : 0,
|
|
431
|
+
max: isFinite(this.track_info[prop + '_max']) ? this.track_info[prop + '_max'] : 1,
|
|
432
|
+
palette: {
|
|
433
|
+
0.0: '#008800',
|
|
434
|
+
0.5: '#ffff00',
|
|
435
|
+
1.0: '#ff0000'
|
|
436
|
+
},
|
|
437
|
+
weight: 5,
|
|
438
|
+
outlineColor: '#000000',
|
|
439
|
+
outlineWidth: 1
|
|
440
|
+
}).addTo(this._hotline);
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
if (map) {
|
|
444
|
+
this._hotline.addTo(map);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
|
|
418
450
|
/**
|
|
419
451
|
* Initialize "L.AlmostOver" and "L.DistanceMarkers"
|
|
420
452
|
*/
|
|
@@ -428,6 +460,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
428
460
|
control._circleMarkers.addTo(map);
|
|
429
461
|
map.once('layeradd', (e) => control.options.autofitBounds && control.fitBounds(layer.getBounds()));
|
|
430
462
|
if (!L.Browser.mobile) {
|
|
463
|
+
control._initHotLine(map, layer);
|
|
431
464
|
control._initAlmostOverHandler(map, layer);
|
|
432
465
|
control._initDistanceMarkers(map, layer);
|
|
433
466
|
} else if (control.options.polyline) {
|
|
@@ -444,6 +477,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
444
477
|
*/
|
|
445
478
|
_collapse: function() {
|
|
446
479
|
_.replaceClass(this._container, 'elevation-expanded', 'elevation-collapsed');
|
|
480
|
+
if (this._map) this._map.invalidateSize();
|
|
447
481
|
},
|
|
448
482
|
|
|
449
483
|
/*
|
|
@@ -451,6 +485,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
451
485
|
*/
|
|
452
486
|
_expand: function() {
|
|
453
487
|
_.replaceClass(this._container, 'elevation-collapsed', 'elevation-expanded');
|
|
488
|
+
if (this._map) this._map.invalidateSize();
|
|
454
489
|
},
|
|
455
490
|
|
|
456
491
|
/**
|