@raruto/leaflet-elevation 2.3.4 → 2.5.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.
@@ -1,457 +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 = ('string' === typeof canvas)
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;
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 - &lt;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 = ('string' === typeof canvas)
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
457
  }));