@arunawalpola/leaflet.polylinemeasure 1.0.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/LICENSE.txt +26 -0
- package/Leaflet.PolylineMeasure.css +59 -0
- package/Leaflet.PolylineMeasure.js +1519 -0
- package/README.md +165 -0
- package/_config.yml +1 -0
- package/demo1.html +41 -0
- package/demo2.html +26 -0
- package/demo3.html +26 -0
- package/demo4.html +32 -0
- package/demo5.html +43 -0
- package/package.json +19 -0
- package/screenshot.jpg +0 -0
|
@@ -0,0 +1,1519 @@
|
|
|
1
|
+
/*********************************************************
|
|
2
|
+
** **
|
|
3
|
+
** Leaflet Plugin "Leaflet.PolylineMeasure" **
|
|
4
|
+
** File "Leaflet.PolylineMeasure.js" **
|
|
5
|
+
** Date: 2023-11-07 **
|
|
6
|
+
** **
|
|
7
|
+
*********************************************************/
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
(function (factory) {
|
|
11
|
+
if (typeof define === 'function' && define.amd) {
|
|
12
|
+
// AMD
|
|
13
|
+
define(['leaflet'], factory);
|
|
14
|
+
} else if (typeof module !== 'undefined') {
|
|
15
|
+
// Node/CommonJS
|
|
16
|
+
module.exports = factory(require('leaflet'));
|
|
17
|
+
} else {
|
|
18
|
+
// Browser globals
|
|
19
|
+
if (typeof window.L === 'undefined') {
|
|
20
|
+
throw new Error('Leaflet must be loaded first');
|
|
21
|
+
}
|
|
22
|
+
factory(window.L);
|
|
23
|
+
}
|
|
24
|
+
}(function (L) {
|
|
25
|
+
var _measureControlId = 'polyline-measure-control';
|
|
26
|
+
var _unicodeClass = 'polyline-measure-unicode-icon';
|
|
27
|
+
var isMacOS = navigator.platform === 'MacIntel';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Polyline Measure class
|
|
31
|
+
* @extends L.Control
|
|
32
|
+
*/
|
|
33
|
+
L.Control.PolylineMeasure = L.Control.extend({
|
|
34
|
+
/**
|
|
35
|
+
* Default options for the tool
|
|
36
|
+
* @type {Object}
|
|
37
|
+
*/
|
|
38
|
+
options: {
|
|
39
|
+
/**
|
|
40
|
+
* Position to show the control. Possible values are: 'topright', 'topleft', 'bottomright', 'bottomleft'
|
|
41
|
+
* @type {String}
|
|
42
|
+
* @default
|
|
43
|
+
*/
|
|
44
|
+
position: 'topleft',
|
|
45
|
+
/**
|
|
46
|
+
* Default unit the distances are displayed in. Possible values are: 'kilometres', 'landmiles', 'nauticalmiles'
|
|
47
|
+
* @type {String}
|
|
48
|
+
* @default
|
|
49
|
+
*/
|
|
50
|
+
unit: 'kilometres',
|
|
51
|
+
/**
|
|
52
|
+
* Use subunits (metres/feet) in tooltips in case of distances less then 1 kilometre/landmile
|
|
53
|
+
* @type {Boolean}
|
|
54
|
+
* @default
|
|
55
|
+
*/
|
|
56
|
+
useSubunits: true,
|
|
57
|
+
/**
|
|
58
|
+
* Clear all measurements when Measure Control is switched off
|
|
59
|
+
* @type {Boolean}
|
|
60
|
+
* @default
|
|
61
|
+
*/
|
|
62
|
+
clearMeasurementsOnStop: true,
|
|
63
|
+
/**
|
|
64
|
+
* Whether bearings are displayed within the tooltips
|
|
65
|
+
* @type {Boolean}
|
|
66
|
+
* @default
|
|
67
|
+
*/
|
|
68
|
+
showBearings: false,
|
|
69
|
+
/**
|
|
70
|
+
* Text for the bearing In
|
|
71
|
+
* @type {String}
|
|
72
|
+
* @default
|
|
73
|
+
*/
|
|
74
|
+
bearingTextIn: 'In',
|
|
75
|
+
/**
|
|
76
|
+
* Text for the bearing Out
|
|
77
|
+
* @type {String}
|
|
78
|
+
* @default
|
|
79
|
+
*/
|
|
80
|
+
bearingTextOut: 'Out',
|
|
81
|
+
/**
|
|
82
|
+
* Text for last point's tooltip
|
|
83
|
+
* @type {String}
|
|
84
|
+
* @default
|
|
85
|
+
*/
|
|
86
|
+
tooltipTextFinish: 'Click to <b>finish line</b><br>',
|
|
87
|
+
tooltipTextDelete: 'Press SHIFT-key and click to <b>delete point</b>',
|
|
88
|
+
tooltipTextMove: 'Click and drag to <b>move point</b><br>',
|
|
89
|
+
tooltipTextResume: '<br>Press ' + (isMacOS ? '⌘' : 'CTRL-key') + ' and click to <b>resume line</b>',
|
|
90
|
+
tooltipTextAdd: 'Press ' + (isMacOS ? '⌘' : 'CTRL-key') + ' and click to <b>add point</b>',
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Title for the control going to be switched on
|
|
94
|
+
* @type {String}
|
|
95
|
+
* @default
|
|
96
|
+
*/
|
|
97
|
+
measureControlTitleOn: "Turn on PolylineMeasure",
|
|
98
|
+
/**
|
|
99
|
+
* Title for the control going to be switched off
|
|
100
|
+
* @type {String}
|
|
101
|
+
* @default
|
|
102
|
+
*/
|
|
103
|
+
measureControlTitleOff: "Turn off PolylineMeasure",
|
|
104
|
+
/**
|
|
105
|
+
* Label of the Measure control (maybe a unicode symbol)
|
|
106
|
+
* @type {String}
|
|
107
|
+
* @default
|
|
108
|
+
*/
|
|
109
|
+
measureControlLabel: '↦',
|
|
110
|
+
/**
|
|
111
|
+
* Classes to apply to the Measure control
|
|
112
|
+
* @type {Array}
|
|
113
|
+
* @default
|
|
114
|
+
*/
|
|
115
|
+
measureControlClasses: [],
|
|
116
|
+
/**
|
|
117
|
+
* Show a control to clear all the measurements
|
|
118
|
+
* @type {Boolean}
|
|
119
|
+
* @default
|
|
120
|
+
*/
|
|
121
|
+
showClearControl: false,
|
|
122
|
+
/**
|
|
123
|
+
* Title text to show on the Clear measurements control button
|
|
124
|
+
* @type {String}
|
|
125
|
+
* @default
|
|
126
|
+
*/
|
|
127
|
+
clearControlTitle: 'Clear Measurements',
|
|
128
|
+
/**
|
|
129
|
+
* Label of the Clear control (maybe a unicode symbol)
|
|
130
|
+
* @type {String}
|
|
131
|
+
* @default
|
|
132
|
+
*/
|
|
133
|
+
clearControlLabel: '×',
|
|
134
|
+
/**
|
|
135
|
+
* Classes to apply to Clear control button
|
|
136
|
+
* @type {Array}
|
|
137
|
+
* @default
|
|
138
|
+
*/
|
|
139
|
+
clearControlClasses: [],
|
|
140
|
+
/**
|
|
141
|
+
* Show a control to change the units of measurements
|
|
142
|
+
* @type {Boolean}
|
|
143
|
+
* @default
|
|
144
|
+
*/
|
|
145
|
+
showUnitControl: false,
|
|
146
|
+
/**
|
|
147
|
+
* The measurement units that can be cycled through by using the Unit Control button
|
|
148
|
+
* @type {Array}
|
|
149
|
+
* @default
|
|
150
|
+
*/
|
|
151
|
+
unitControlUnits: ["kilometres" , "landmiles", "nauticalmiles"],
|
|
152
|
+
/**
|
|
153
|
+
* Title texts to show on the Unit Control button
|
|
154
|
+
* @type {Object}
|
|
155
|
+
* @default
|
|
156
|
+
*/
|
|
157
|
+
unitControlTitle: {
|
|
158
|
+
text: 'Change Units',
|
|
159
|
+
kilometres: 'kilometres',
|
|
160
|
+
landmiles: 'land miles',
|
|
161
|
+
nauticalmiles: 'nautical miles'
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* Unit symbols to show in the Unit Control button and measurement labels
|
|
165
|
+
* @type {Object}
|
|
166
|
+
* @default
|
|
167
|
+
*/
|
|
168
|
+
unitControlLabel: {
|
|
169
|
+
metres: 'm',
|
|
170
|
+
kilometres: 'km',
|
|
171
|
+
feet: 'ft',
|
|
172
|
+
landmiles: 'mi',
|
|
173
|
+
nauticalmiles: 'nm'
|
|
174
|
+
},
|
|
175
|
+
/**
|
|
176
|
+
* Classes to apply to the Unit control
|
|
177
|
+
* @type {Array}
|
|
178
|
+
* @default
|
|
179
|
+
*/
|
|
180
|
+
unitControlClasses: [],
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Styling settings for the temporary dashed rubberline
|
|
184
|
+
* @type {Object}
|
|
185
|
+
*/
|
|
186
|
+
tempLine: {
|
|
187
|
+
/**
|
|
188
|
+
* Dashed line color
|
|
189
|
+
* @type {String}
|
|
190
|
+
* @default
|
|
191
|
+
*/
|
|
192
|
+
color: '#00f',
|
|
193
|
+
/**
|
|
194
|
+
* Dashed line weight
|
|
195
|
+
* @type {Number}
|
|
196
|
+
* @default
|
|
197
|
+
*/
|
|
198
|
+
weight: 2
|
|
199
|
+
},
|
|
200
|
+
/**
|
|
201
|
+
* Styling for the fixed polyline
|
|
202
|
+
* @type {Object}
|
|
203
|
+
*/
|
|
204
|
+
fixedLine: {
|
|
205
|
+
/**
|
|
206
|
+
* Solid line color
|
|
207
|
+
* @type {String}
|
|
208
|
+
* @default
|
|
209
|
+
*/
|
|
210
|
+
color: '#006',
|
|
211
|
+
/**
|
|
212
|
+
* Solid line weight
|
|
213
|
+
* @type {Number}
|
|
214
|
+
* @default
|
|
215
|
+
*/
|
|
216
|
+
weight: 2
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* Styling of the midway arrow
|
|
220
|
+
* @type {Object}
|
|
221
|
+
*/
|
|
222
|
+
arrow: {
|
|
223
|
+
/**
|
|
224
|
+
* Color of the arrow
|
|
225
|
+
* @type {String}
|
|
226
|
+
* @default
|
|
227
|
+
*/
|
|
228
|
+
color: '#000'
|
|
229
|
+
},
|
|
230
|
+
/**
|
|
231
|
+
* Style settings for circle marker indicating the starting point of the polyline
|
|
232
|
+
* @type {Object}
|
|
233
|
+
*/
|
|
234
|
+
startCircle: {
|
|
235
|
+
/**
|
|
236
|
+
* Color of the border of the circle
|
|
237
|
+
* @type {String}
|
|
238
|
+
* @default
|
|
239
|
+
*/
|
|
240
|
+
color: '#000',
|
|
241
|
+
/**
|
|
242
|
+
* Weight of the circle
|
|
243
|
+
* @type {Number}
|
|
244
|
+
* @default
|
|
245
|
+
*/
|
|
246
|
+
weight: 1,
|
|
247
|
+
/**
|
|
248
|
+
* Fill color of the circle
|
|
249
|
+
* @type {String}
|
|
250
|
+
* @default
|
|
251
|
+
*/
|
|
252
|
+
fillColor: '#0f0',
|
|
253
|
+
/**
|
|
254
|
+
* Fill opacity of the circle
|
|
255
|
+
* @type {Number}
|
|
256
|
+
* @default
|
|
257
|
+
*/
|
|
258
|
+
fillOpacity: 1,
|
|
259
|
+
/**
|
|
260
|
+
* Radius of the circle
|
|
261
|
+
* @type {Number}
|
|
262
|
+
* @default
|
|
263
|
+
*/
|
|
264
|
+
radius: 3
|
|
265
|
+
},
|
|
266
|
+
/**
|
|
267
|
+
* Style settings for all circle markers between startCircle and endCircle
|
|
268
|
+
* @type {Object}
|
|
269
|
+
*/
|
|
270
|
+
intermedCircle: {
|
|
271
|
+
/**
|
|
272
|
+
* Color of the border of the circle
|
|
273
|
+
* @type {String}
|
|
274
|
+
* @default
|
|
275
|
+
*/
|
|
276
|
+
color: '#000',
|
|
277
|
+
/**
|
|
278
|
+
* Weight of the circle
|
|
279
|
+
* @type {Number}
|
|
280
|
+
* @default
|
|
281
|
+
*/
|
|
282
|
+
weight: 1,
|
|
283
|
+
/**
|
|
284
|
+
* Fill color of the circle
|
|
285
|
+
* @type {String}
|
|
286
|
+
* @default
|
|
287
|
+
*/
|
|
288
|
+
fillColor: '#ff0',
|
|
289
|
+
/**
|
|
290
|
+
* Fill opacity of the circle
|
|
291
|
+
* @type {Number}
|
|
292
|
+
* @default
|
|
293
|
+
*/
|
|
294
|
+
fillOpacity: 1,
|
|
295
|
+
/**
|
|
296
|
+
* Radius of the circle
|
|
297
|
+
* @type {Number}
|
|
298
|
+
* @default
|
|
299
|
+
*/
|
|
300
|
+
radius: 3
|
|
301
|
+
},
|
|
302
|
+
/**
|
|
303
|
+
* Style settings for circle marker indicating the latest point of the polyline during drawing a line
|
|
304
|
+
* @type {Object}
|
|
305
|
+
*/
|
|
306
|
+
currentCircle: {
|
|
307
|
+
/**
|
|
308
|
+
* Color of the border of the circle
|
|
309
|
+
* @type {String}
|
|
310
|
+
* @default
|
|
311
|
+
*/
|
|
312
|
+
color: '#000',
|
|
313
|
+
/**
|
|
314
|
+
* Weight of the circle
|
|
315
|
+
* @type {Number}
|
|
316
|
+
* @default
|
|
317
|
+
*/
|
|
318
|
+
weight: 1,
|
|
319
|
+
/**
|
|
320
|
+
* Fill color of the circle
|
|
321
|
+
* @type {String}
|
|
322
|
+
* @default
|
|
323
|
+
*/
|
|
324
|
+
fillColor: '#f0f',
|
|
325
|
+
/**
|
|
326
|
+
* Fill opacity of the circle
|
|
327
|
+
* @type {Number}
|
|
328
|
+
* @default
|
|
329
|
+
*/
|
|
330
|
+
fillOpacity: 1,
|
|
331
|
+
/**
|
|
332
|
+
* Radius of the circle
|
|
333
|
+
* @type {Number}
|
|
334
|
+
* @default
|
|
335
|
+
*/
|
|
336
|
+
radius: 6
|
|
337
|
+
},
|
|
338
|
+
/**
|
|
339
|
+
* Style settings for circle marker indicating the end point of the polyline
|
|
340
|
+
* @type {Object}
|
|
341
|
+
*/
|
|
342
|
+
endCircle: {
|
|
343
|
+
/**
|
|
344
|
+
* Color of the border of the circle
|
|
345
|
+
* @type {String}
|
|
346
|
+
* @default
|
|
347
|
+
*/
|
|
348
|
+
color: '#000',
|
|
349
|
+
/**
|
|
350
|
+
* Weight of the circle
|
|
351
|
+
* @type {Number}
|
|
352
|
+
* @default
|
|
353
|
+
*/
|
|
354
|
+
weight: 1,
|
|
355
|
+
/**
|
|
356
|
+
* Fill color of the circle
|
|
357
|
+
* @type {String}
|
|
358
|
+
* @default
|
|
359
|
+
*/
|
|
360
|
+
fillColor: '#f00',
|
|
361
|
+
/**
|
|
362
|
+
* Fill opacity of the circle
|
|
363
|
+
* @type {Number}
|
|
364
|
+
* @default
|
|
365
|
+
*/
|
|
366
|
+
fillOpacity: 1,
|
|
367
|
+
/**
|
|
368
|
+
* Radius of the circle
|
|
369
|
+
* @type {Number}
|
|
370
|
+
* @default
|
|
371
|
+
*/
|
|
372
|
+
radius: 3
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
_arcpoints: 99, // 99 points = 98 line segments. lower value to make arc less accurate or increase value to make it more accurate.
|
|
377
|
+
_circleNr: -1,
|
|
378
|
+
_lineNr: -1,
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Create a control button
|
|
382
|
+
* @param {String} label Label to add
|
|
383
|
+
* @param {String} title Title to show on hover
|
|
384
|
+
* @param {Array} classesToAdd Collection of classes to add
|
|
385
|
+
* @param {Element} container Parent element
|
|
386
|
+
* @param {Function} fn Callback function to run
|
|
387
|
+
* @param {Object} context Context
|
|
388
|
+
* @returns {Element} Created element
|
|
389
|
+
* @private
|
|
390
|
+
*/
|
|
391
|
+
_createControl: function (label, title, classesToAdd, container, fn, context) {
|
|
392
|
+
var anchor = document.createElement('a');
|
|
393
|
+
anchor.innerHTML = label;
|
|
394
|
+
anchor.setAttribute('title', title);
|
|
395
|
+
classesToAdd.forEach(function(c) {
|
|
396
|
+
anchor.classList.add(c);
|
|
397
|
+
});
|
|
398
|
+
L.DomEvent.on (anchor, 'click', fn, context);
|
|
399
|
+
container.appendChild(anchor);
|
|
400
|
+
return anchor;
|
|
401
|
+
},
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Method to fire on add to map
|
|
405
|
+
* @param {Object} map Map object
|
|
406
|
+
* @returns {Element} Containing element
|
|
407
|
+
*/
|
|
408
|
+
onAdd: function(map) {
|
|
409
|
+
var self = this
|
|
410
|
+
// needed to avoid creating points by mouseclick during dragging the map
|
|
411
|
+
map.on('movestart ', function() {
|
|
412
|
+
self._mapdragging = true
|
|
413
|
+
})
|
|
414
|
+
this._container = document.createElement('div');
|
|
415
|
+
this._container.classList.add('leaflet-bar');
|
|
416
|
+
L.DomEvent.disableClickPropagation(this._container); // otherwise drawing process would instantly start at controls' container or double click would zoom-in map
|
|
417
|
+
var title = this.options.measureControlTitleOn;
|
|
418
|
+
var label = this.options.measureControlLabel;
|
|
419
|
+
var classes = this.options.measureControlClasses;
|
|
420
|
+
if (label.indexOf('&') != -1) {
|
|
421
|
+
classes.push(_unicodeClass);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// initialize state
|
|
425
|
+
this._arrPolylines = [];
|
|
426
|
+
this._measureControl = this._createControl (label, title, classes, this._container, this._toggleMeasure, this);
|
|
427
|
+
this._defaultControlBgColor = this._measureControl.style.backgroundColor;
|
|
428
|
+
this._measureControl.setAttribute('id', _measureControlId);
|
|
429
|
+
if (this.options.showClearControl) {
|
|
430
|
+
var title = this.options.clearControlTitle;
|
|
431
|
+
var label = this.options.clearControlLabel;
|
|
432
|
+
var classes = this.options.clearControlClasses;
|
|
433
|
+
if (label.indexOf('&') != -1) {
|
|
434
|
+
classes.push(_unicodeClass);
|
|
435
|
+
}
|
|
436
|
+
this._clearMeasureControl = this._createControl (label, title, classes, this._container, this._clearAllMeasurements, this);
|
|
437
|
+
this._clearMeasureControl.classList.add('polyline-measure-clearControl')
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// There is no point in using the unitControl if there are no units to choose from.
|
|
441
|
+
if (this.options.showUnitControl && this.options.unitControlUnits.length > 1) {
|
|
442
|
+
var label = this.options.unitControlLabel[this.options.unit];
|
|
443
|
+
var title = this.options.unitControlTitle.text + " [" + this.options.unitControlTitle[this.options.unit] + "]";
|
|
444
|
+
|
|
445
|
+
var classes = this.options.unitControlClasses;
|
|
446
|
+
this._unitControl = this._createControl (label, title, classes, this._container, this._changeUnit, this);
|
|
447
|
+
this._unitControl.setAttribute ('id', 'unitControlId');
|
|
448
|
+
}
|
|
449
|
+
return this._container;
|
|
450
|
+
},
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Method to fire on remove from map
|
|
454
|
+
*/
|
|
455
|
+
onRemove: function () {
|
|
456
|
+
if (this._measuring) {
|
|
457
|
+
this._toggleMeasure();
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
|
|
461
|
+
// turn off all Leaflet-own events of markers (popups, tooltips). Needed to allow creating points on top of markers
|
|
462
|
+
_saveNonpolylineEvents: function () {
|
|
463
|
+
this._nonpolylineTargets = this._map._targets;
|
|
464
|
+
if (typeof this._polylineTargets !== 'undefined') {
|
|
465
|
+
this._map._targets = this._polylineTargets;
|
|
466
|
+
} else {
|
|
467
|
+
this._map._targets ={};
|
|
468
|
+
}
|
|
469
|
+
},
|
|
470
|
+
|
|
471
|
+
// on disabling the measure add-on, save Polyline-measure events and enable the former Leaflet-own events again
|
|
472
|
+
_savePolylineEvents: function () {
|
|
473
|
+
this._polylineTargets = this._map._targets;
|
|
474
|
+
this._map._targets = this._nonpolylineTargets;
|
|
475
|
+
},
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Toggle the measure functionality on or off
|
|
479
|
+
* @private
|
|
480
|
+
*/
|
|
481
|
+
_toggleMeasure: function () {
|
|
482
|
+
this._measuring = !this._measuring;
|
|
483
|
+
if (this._measuring) { // if measuring is going to be switched on
|
|
484
|
+
this._mapdragging = false;
|
|
485
|
+
this._saveNonpolylineEvents ();
|
|
486
|
+
this._measureControl.classList.add ('polyline-measure-controlOnBgColor');
|
|
487
|
+
this._measureControl.style.backgroundColor = this.options.backgroundColor;
|
|
488
|
+
this._measureControl.title = this.options.measureControlTitleOff;
|
|
489
|
+
this._oldCursor = this._map._container.style.cursor; // save former cursor type
|
|
490
|
+
this._map._container.style.cursor = 'crosshair';
|
|
491
|
+
this._doubleClickZoom = this._map.doubleClickZoom.enabled(); // save former status of doubleClickZoom
|
|
492
|
+
this._map.doubleClickZoom.disable();
|
|
493
|
+
// create LayerGroup "layerPaint" (only) the first time Measure Control is switched on
|
|
494
|
+
if (!this._layerPaint) {
|
|
495
|
+
this._layerPaint = L.layerGroup().addTo(this._map);
|
|
496
|
+
}
|
|
497
|
+
this._map.on ('mousemove', this._mouseMove, this); // enable listing to 'mousemove', 'click', 'keydown' events
|
|
498
|
+
this._map.on ('click', this._mouseClick, this);
|
|
499
|
+
L.DomEvent.on (document, 'keydown', this._onKeyDown, this);
|
|
500
|
+
this._resetPathVariables();
|
|
501
|
+
} else { // if measuring is going to be switched off
|
|
502
|
+
this._savePolylineEvents ();
|
|
503
|
+
this._measureControl.classList.remove ('polyline-measure-controlOnBgColor');
|
|
504
|
+
this._measureControl.style.backgroundColor = this._defaultControlBgColor;
|
|
505
|
+
this._measureControl.title = this.options.measureControlTitleOn;
|
|
506
|
+
this._map._container.style.cursor = this._oldCursor;
|
|
507
|
+
this._map.off ('mousemove', this._mouseMove, this);
|
|
508
|
+
this._map.off ('click', this._mouseClick, this);
|
|
509
|
+
this._map.off ('mousemove', this._resumeFirstpointMousemove, this);
|
|
510
|
+
this._map.off ('click', this._resumeFirstpointClick, this);
|
|
511
|
+
this._map.off ('mousemove', this._dragCircleMousemove, this);
|
|
512
|
+
this._map.off ('mouseup', this._dragCircleMouseup, this);
|
|
513
|
+
L.DomEvent.off (document, 'keydown', this._onKeyDown, this);
|
|
514
|
+
if(this._doubleClickZoom) {
|
|
515
|
+
this._map.doubleClickZoom.enable();
|
|
516
|
+
}
|
|
517
|
+
if(this.options.clearMeasurementsOnStop && this._layerPaint) {
|
|
518
|
+
this._clearAllMeasurements();
|
|
519
|
+
}
|
|
520
|
+
// to remove temp. Line if line at the moment is being drawn and not finished while clicking the control
|
|
521
|
+
if (this._cntCircle !== 0) {
|
|
522
|
+
this._finishPolylinePath();
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
// allow easy to connect the measure control to the app, f.e. to disable the selection on the map when the measurement is turned on
|
|
526
|
+
this._map.fire('polylinemeasure:toggle', { status: this._measuring });
|
|
527
|
+
},
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Clear all measurements from the map
|
|
531
|
+
*/
|
|
532
|
+
_clearAllMeasurements: function() {
|
|
533
|
+
if ((this._cntCircle !== undefined) && (this._cntCircle !== 0)) {
|
|
534
|
+
this._finishPolylinePath();
|
|
535
|
+
}
|
|
536
|
+
if (this._layerPaint) {
|
|
537
|
+
this._layerPaint.clearLayers();
|
|
538
|
+
}
|
|
539
|
+
this._arrPolylines = [];
|
|
540
|
+
this._map.fire('polylinemeasure:clear');
|
|
541
|
+
},
|
|
542
|
+
|
|
543
|
+
_changeUnit: function() {
|
|
544
|
+
// Retrieve the index of the next available unit of measurement.
|
|
545
|
+
let indexCurrUnit = this.options.unitControlUnits.indexOf(this.options.unit);
|
|
546
|
+
let indexNextUnit = (indexCurrUnit+1)%this.options.unitControlUnits.length;
|
|
547
|
+
|
|
548
|
+
// Update the unit of measurement.
|
|
549
|
+
this.options.unit = this.options.unitControlUnits[indexNextUnit];
|
|
550
|
+
this._unitControl.innerHTML = this.options.unitControlLabel[this.options.unit];
|
|
551
|
+
this._unitControl.title = this.options.unitControlTitle.text +" [" + this.options.unitControlTitle[this.options.unit] + "]";
|
|
552
|
+
|
|
553
|
+
if (this._currentLine) {
|
|
554
|
+
this._computeDistance(this._currentLine);
|
|
555
|
+
}
|
|
556
|
+
this._arrPolylines.map (this._computeDistance.bind(this));
|
|
557
|
+
},
|
|
558
|
+
|
|
559
|
+
_computeDistance: function(line) {
|
|
560
|
+
var totalDistance = 0;
|
|
561
|
+
line.circleCoords.map (function(point, point_index) {
|
|
562
|
+
if (point_index >= 1) {
|
|
563
|
+
var distance = line.circleCoords [point_index - 1].distanceTo (line.circleCoords [point_index]);
|
|
564
|
+
totalDistance += distance;
|
|
565
|
+
this._updateTooltip (line.tooltips [point_index], line.tooltips [point_index - 1], totalDistance, distance, line.circleCoords [point_index - 1], line.circleCoords [point_index]);
|
|
566
|
+
}
|
|
567
|
+
}.bind(this));
|
|
568
|
+
},
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Event to fire when a keyboard key is depressed.
|
|
572
|
+
* Currently only watching for ESC key (= keyCode 27). 1st press finishes line, 2nd press turns Measuring off.
|
|
573
|
+
* @param {Object} e Event
|
|
574
|
+
* @private
|
|
575
|
+
*/
|
|
576
|
+
_onKeyDown: function (e) {
|
|
577
|
+
if (e.keyCode === 27) {
|
|
578
|
+
// if resuming a line at its first point is active
|
|
579
|
+
if (this._resumeFirstpointFlag === true) {
|
|
580
|
+
this._resumeFirstpointFlag = false;
|
|
581
|
+
var lineNr = this._lineNr;
|
|
582
|
+
this._map.off ('mousemove', this._resumeFirstpointMousemove, this);
|
|
583
|
+
this._map.off ('click', this._resumeFirstpointClick, this);
|
|
584
|
+
this._layerPaint.removeLayer (this._rubberlinePath2);
|
|
585
|
+
this._layerPaint.removeLayer (this._tooltipNew);
|
|
586
|
+
this._arrPolylines[lineNr].circleMarkers [0].setStyle (this.options.startCircle);
|
|
587
|
+
var text = '';
|
|
588
|
+
var totalDistance = 0;
|
|
589
|
+
if (this.options.showBearings === true) {
|
|
590
|
+
text = this.options.bearingTextIn+':---°<br>'+this.options.bearingTextOut+':---°';
|
|
591
|
+
}
|
|
592
|
+
text = text + '<div class="polyline-measure-tooltip-difference">+' + '0</div>';
|
|
593
|
+
text = text + '<div class="polyline-measure-tooltip-total">' + '0</div>';
|
|
594
|
+
this._arrPolylines[lineNr].tooltips [0]._icon.innerHTML = text;
|
|
595
|
+
this._arrPolylines[lineNr].tooltips.map (function (item, index) {
|
|
596
|
+
if (index >= 1) {
|
|
597
|
+
var distance = this._arrPolylines[lineNr].circleCoords[index-1].distanceTo (this._arrPolylines[lineNr].circleCoords[index]);
|
|
598
|
+
var lastCircleCoords = this._arrPolylines[lineNr].circleCoords[index - 1];
|
|
599
|
+
var mouseCoords = this._arrPolylines[lineNr].circleCoords[index];
|
|
600
|
+
totalDistance += distance;
|
|
601
|
+
var prevTooltip = this._arrPolylines[lineNr].tooltips[index-1]
|
|
602
|
+
this._updateTooltip (item, prevTooltip, totalDistance, distance, lastCircleCoords, mouseCoords);
|
|
603
|
+
}
|
|
604
|
+
}.bind (this));
|
|
605
|
+
this._map.on ('mousemove', this._mouseMove, this);
|
|
606
|
+
return
|
|
607
|
+
}
|
|
608
|
+
if (!this._currentLine) { // if NOT drawing a line, ESC will directly switch of measuring
|
|
609
|
+
this._toggleMeasure();
|
|
610
|
+
} else { // if drawing a line, ESC will finish the current line
|
|
611
|
+
this._finishPolylinePath(e);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Get the distance in the format specified in the options
|
|
618
|
+
* @param {Number} distance Distance to convert
|
|
619
|
+
* @returns {{value: *, unit: *}}
|
|
620
|
+
* @private
|
|
621
|
+
*/
|
|
622
|
+
_getDistance: function (distance) {
|
|
623
|
+
var dist = distance;
|
|
624
|
+
var unit;
|
|
625
|
+
if (this.options.unit === 'nauticalmiles') {
|
|
626
|
+
unit = this.options.unitControlLabel.nauticalmiles;
|
|
627
|
+
if (dist >= 185200) {
|
|
628
|
+
dist = (dist/1852).toFixed(0);
|
|
629
|
+
} else if (dist >= 18520) {
|
|
630
|
+
dist = (dist/1852).toFixed(1);
|
|
631
|
+
} else if (dist >= 1852) {
|
|
632
|
+
dist = (dist/1852).toFixed(2);
|
|
633
|
+
} else {
|
|
634
|
+
dist = (dist/1852).toFixed(3); // there's no subunit of Nautical Miles for horizontal length measurements. "Cable length" (1/10th of 1 nm) is rarely used
|
|
635
|
+
}
|
|
636
|
+
} else if (this.options.unit === 'landmiles') {
|
|
637
|
+
unit = this.options.unitControlLabel.landmiles;
|
|
638
|
+
if (dist >= 160934.4) {
|
|
639
|
+
dist = (dist/1609.344).toFixed(0);
|
|
640
|
+
} else if (dist >= 16093.44) {
|
|
641
|
+
dist = (dist/1609.344).toFixed(1);
|
|
642
|
+
} else if (dist >= 1609.344) {
|
|
643
|
+
dist = (dist/1609.344).toFixed(2);
|
|
644
|
+
} else {
|
|
645
|
+
if (!this.options.useSubunits) {
|
|
646
|
+
dist = (dist/1609.344).toFixed(4);
|
|
647
|
+
} else {
|
|
648
|
+
dist = (dist/0.3048).toFixed(0);
|
|
649
|
+
unit = this.options.unitControlLabel.feet;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
unit = this.options.unitControlLabel.kilometres;
|
|
655
|
+
if (dist >= 100000) {
|
|
656
|
+
dist = (dist/1000).toFixed(0);
|
|
657
|
+
} else if (dist >= 10000) {
|
|
658
|
+
dist = (dist/1000).toFixed(1);
|
|
659
|
+
} else if (dist >= 1000) {
|
|
660
|
+
dist = (dist/1000).toFixed(2);
|
|
661
|
+
} else {
|
|
662
|
+
if (!this.options.useSubunits) {
|
|
663
|
+
dist = (dist/1000).toFixed(4);
|
|
664
|
+
} else {
|
|
665
|
+
dist = (dist).toFixed(1);
|
|
666
|
+
unit = this.options.unitControlLabel.metres;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return {value:dist, unit:unit};
|
|
671
|
+
},
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Calculate Great-circle Arc (= shortest distance on a sphere like the Earth) between two coordinates
|
|
675
|
+
* formulas: http://www.edwilliams.org/avform.htm
|
|
676
|
+
* @private
|
|
677
|
+
*/
|
|
678
|
+
_polylineArc: function (_from, _to) {
|
|
679
|
+
|
|
680
|
+
function _GCinterpolate (f) {
|
|
681
|
+
var A = Math.sin((1 - f) * d) / Math.sin(d);
|
|
682
|
+
var B = Math.sin(f * d) / Math.sin(d);
|
|
683
|
+
var x = A * Math.cos(fromLat) * Math.cos(fromLng) + B * Math.cos(toLat) * Math.cos(toLng);
|
|
684
|
+
var y = A * Math.cos(fromLat) * Math.sin(fromLng) + B * Math.cos(toLat) * Math.sin(toLng);
|
|
685
|
+
var z = A * Math.sin(fromLat) + B * Math.sin(toLat);
|
|
686
|
+
// atan2 better than atan-function cause results are from -pi to +pi
|
|
687
|
+
// => results of latInterpol, lngInterpol always within range -180° ... +180° => conversion into values < -180° or > + 180° has to be done afterwards
|
|
688
|
+
var latInterpol = 180 / Math.PI * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
|
|
689
|
+
var lngInterpol = 180 / Math.PI * Math.atan2(y, x);
|
|
690
|
+
// don't split polyline if it crosses dateline ( -180° or +180°). Without the polyline would look like: +179° ==> +180° ==> -180° ==> -179°...
|
|
691
|
+
// algo: if difference lngInterpol-from.lng is > 180° there's been an unwanted split from +180 to -180 cause an arc can never span >180°
|
|
692
|
+
var diff = lngInterpol-fromLng*180/Math.PI;
|
|
693
|
+
function trunc(n) { return Math[n > 0 ? "floor" : "ceil"](n); } // alternatively we could use the new Math.trunc method, but Internet Explorer doesn't know it
|
|
694
|
+
if (diff < 0) {
|
|
695
|
+
lngInterpol = lngInterpol - trunc ((diff - 180)/ 360) * 360;
|
|
696
|
+
} else {
|
|
697
|
+
lngInterpol = lngInterpol - trunc ((diff +180)/ 360) * 360;
|
|
698
|
+
}
|
|
699
|
+
return [latInterpol, lngInterpol];
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function _GCarc (npoints) {
|
|
703
|
+
var arrArcCoords = [];
|
|
704
|
+
var delta = 1.0 / (npoints-1 );
|
|
705
|
+
// first point of Arc should NOT be returned
|
|
706
|
+
for (var i = 0; i < npoints; i++) {
|
|
707
|
+
var step = delta * i;
|
|
708
|
+
var coordPair = _GCinterpolate (step);
|
|
709
|
+
arrArcCoords.push (coordPair);
|
|
710
|
+
}
|
|
711
|
+
return arrArcCoords;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
var fromLat = _from.lat; // work with with copies of object's elements _from.lat and _from.lng, otherwise they would get modiefied due to call-by-reference on Objects in Javascript
|
|
715
|
+
var fromLng = _from.lng;
|
|
716
|
+
var toLat = _to.lat;
|
|
717
|
+
var toLng = _to.lng;
|
|
718
|
+
fromLat=fromLat * Math.PI / 180;
|
|
719
|
+
fromLng=fromLng * Math.PI / 180;
|
|
720
|
+
toLat=toLat * Math.PI / 180;
|
|
721
|
+
toLng=toLng * Math.PI / 180;
|
|
722
|
+
var d = 2.0 * Math.asin(Math.sqrt(Math.pow (Math.sin((fromLat - toLat) / 2.0), 2) + Math.cos(fromLat) * Math.cos(toLat) * Math.pow(Math.sin((fromLng - toLng) / 2.0), 2)));
|
|
723
|
+
var arrLatLngs;
|
|
724
|
+
if (d === 0) {
|
|
725
|
+
arrLatLngs = [[fromLat, fromLng]];
|
|
726
|
+
} else {
|
|
727
|
+
arrLatLngs = _GCarc(this._arcpoints);
|
|
728
|
+
}
|
|
729
|
+
return arrLatLngs;
|
|
730
|
+
},
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Update the tooltip distance
|
|
734
|
+
* @param {Number} total Total distance
|
|
735
|
+
* @param {Number} difference Difference in distance between 2 points
|
|
736
|
+
* @private
|
|
737
|
+
*/
|
|
738
|
+
_updateTooltip: function (currentTooltip, prevTooltip, total, difference, lastCircleCoords, mouseCoords) {
|
|
739
|
+
// Explanation of formula: http://www.movable-type.co.uk/scripts/latlong.html
|
|
740
|
+
var calcAngle = function (p1, p2, direction) {
|
|
741
|
+
var lat1 = p1.lat / 180 * Math.PI;
|
|
742
|
+
var lat2 = p2.lat / 180 * Math.PI;
|
|
743
|
+
var lng1 = p1.lng / 180 * Math.PI;
|
|
744
|
+
var lng2 = p2.lng / 180 * Math.PI;
|
|
745
|
+
var y = Math.sin(lng2-lng1) * Math.cos(lat2);
|
|
746
|
+
var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(lng2-lng1);
|
|
747
|
+
if (direction === "inbound") {
|
|
748
|
+
var brng = (Math.atan2(y, x) * 180 / Math.PI + 180).toFixed(0);
|
|
749
|
+
} else {
|
|
750
|
+
var brng = (Math.atan2(y, x) * 180 / Math.PI + 360).toFixed(0);
|
|
751
|
+
}
|
|
752
|
+
return (brng % 360);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
var angleIn = calcAngle (mouseCoords, lastCircleCoords, "inbound");
|
|
756
|
+
var angleOut = calcAngle (lastCircleCoords, mouseCoords, "outbound");
|
|
757
|
+
var totalRound = this._getDistance (total);
|
|
758
|
+
var differenceRound = this._getDistance (difference);
|
|
759
|
+
var textCurrent = '';
|
|
760
|
+
if (differenceRound.value > 0 ) {
|
|
761
|
+
if (this.options.showBearings === true) {
|
|
762
|
+
textCurrent = this.options.bearingTextIn + ': ' + angleIn + '°<br>'+this.options.bearingTextOut+':---°';
|
|
763
|
+
}
|
|
764
|
+
textCurrent += '<div class="polyline-measure-tooltip-difference">+' + differenceRound.value + ' ' + differenceRound.unit + '</div>';
|
|
765
|
+
}
|
|
766
|
+
textCurrent += '<div class="polyline-measure-tooltip-total">' + totalRound.value + ' ' + totalRound.unit + '</div>';
|
|
767
|
+
currentTooltip._icon.innerHTML = textCurrent;
|
|
768
|
+
if ((this.options.showBearings === true) && (prevTooltip)) {
|
|
769
|
+
var textPrev = prevTooltip._icon.innerHTML;
|
|
770
|
+
var regExp = new RegExp(this.options.bearingTextOut + '.*\°');
|
|
771
|
+
var textReplace = textPrev.replace(regExp, this.options.bearingTextOut + ': ' + angleOut + "°");
|
|
772
|
+
prevTooltip._icon.innerHTML = textReplace;
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
|
|
776
|
+
_drawArrow: function (arcLine) {
|
|
777
|
+
// center of Great-circle distance, NOT of the arc on a Mercator map! reason: a) to complicated b) map not always Mercator c) good optical feature to see where real center of distance is not the "virtual" warped arc center due to Mercator projection
|
|
778
|
+
// differ between even and odd pointed Arcs. If even the arrow is in the center of the middle line-segment, if odd it is on the middle point
|
|
779
|
+
var midpoint = Math.trunc(arcLine.length/2);
|
|
780
|
+
if (arcLine.length % 2 == 0) {
|
|
781
|
+
var P1 = arcLine[midpoint-1];
|
|
782
|
+
var P2 = arcLine[midpoint];
|
|
783
|
+
var diffLng12 = P2[1] - P1[1];
|
|
784
|
+
var diffLat12 = P2[0] - P1[0];
|
|
785
|
+
var center = [P1[0] + diffLat12/2, P1[1] + diffLng12/2];
|
|
786
|
+
} else {
|
|
787
|
+
var P1 = arcLine[midpoint-1];
|
|
788
|
+
var P2 = arcLine[midpoint+1];
|
|
789
|
+
var diffLng12 = P2[1] - P1[1];
|
|
790
|
+
var diffLat12 = P2[0] - P1[0];
|
|
791
|
+
var center = arcLine[midpoint];
|
|
792
|
+
}
|
|
793
|
+
// angle just an aprroximation, which could be somewhat off if Line runs near high latitudes. Use of *geographical coords* for line segment P1 to P2 is best method. Use of *Pixel coords* for just one arc segement P1 to P2 could create for short lines unexact rotation angles, and the use Use of Pixel coords between endpoints [0] to [98] (in case of 99-point-arc) results in even more rotation difference for high latitudes as with geogrpaphical coords-method
|
|
794
|
+
var cssAngle = -Math.atan2(diffLat12, diffLng12)*57.29578 // convert radiant to degree as needed for use as CSS value; cssAngle is opposite to mathematical angle.
|
|
795
|
+
var iconArrow = L.divIcon ({
|
|
796
|
+
className: "", // to avoid getting a default class with paddings and borders assigned by Leaflet
|
|
797
|
+
iconSize: [16, 16],
|
|
798
|
+
iconAnchor: [8, 8],
|
|
799
|
+
// html : "<img src='iconArrow.png' style='background:green; height:100%; vertical-align:top; transform:rotate("+ cssAngle +"deg)'>" <<=== alternative method by the use of an image instead of a Unicode symbol.
|
|
800
|
+
html : "<div style = 'color:" + this.options.arrow.color + "; font-size: 16px; line-height: 16px; vertical-align:top; transform: rotate("+ cssAngle +"deg)'>➤</div>" // best results if iconSize = font-size = line-height and iconAnchor font-size/2 .both values needed to position symbol in center of L.divIcon for all font-sizes.
|
|
801
|
+
});
|
|
802
|
+
var newArrowMarker = L.marker (center, {icon: iconArrow, zIndexOffset:-50}).addTo(this._layerPaint); // zIndexOffset to draw arrows below tooltips
|
|
803
|
+
if (!this._currentLine){ // just bind tooltip if not drawing line anymore, cause following the instruction of tooltip is just possible when not drawing a line
|
|
804
|
+
newArrowMarker.bindTooltip (this.options.tooltipTextAdd, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
805
|
+
}
|
|
806
|
+
newArrowMarker.on ('click', this._clickedArrow, this);
|
|
807
|
+
return newArrowMarker;
|
|
808
|
+
},
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Event to fire on mouse move
|
|
812
|
+
* @param {Object} e Event
|
|
813
|
+
* @private
|
|
814
|
+
*/
|
|
815
|
+
_mouseMove: function (e) {
|
|
816
|
+
var mouseCoords = e.latlng;
|
|
817
|
+
this._map.on ('click', this._mouseClick, this); // necassary for _dragCircle. If switched on already within _dragCircle an unwanted click is fired at the end of the drag.
|
|
818
|
+
if(!mouseCoords || !this._currentLine) {
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
var lastCircleCoords = this._currentLine.circleCoords.last();
|
|
822
|
+
this._rubberlinePath.setLatLngs (this._polylineArc (lastCircleCoords, mouseCoords));
|
|
823
|
+
var currentTooltip = this._currentLine.tooltips.last();
|
|
824
|
+
var prevTooltip = this._currentLine.tooltips.slice(-2,-1)[0];
|
|
825
|
+
currentTooltip.setLatLng (mouseCoords);
|
|
826
|
+
var distanceSegment = mouseCoords.distanceTo (lastCircleCoords);
|
|
827
|
+
this._updateTooltip (currentTooltip, prevTooltip, this._currentLine.distance + distanceSegment, distanceSegment, lastCircleCoords, mouseCoords);
|
|
828
|
+
},
|
|
829
|
+
|
|
830
|
+
_startLine: function (clickCoords) {
|
|
831
|
+
var icon = L.divIcon({
|
|
832
|
+
className: 'polyline-measure-tooltip',
|
|
833
|
+
iconAnchor: [-4, -4]
|
|
834
|
+
});
|
|
835
|
+
var last = function() {
|
|
836
|
+
return this.slice(-1)[0];
|
|
837
|
+
};
|
|
838
|
+
this._rubberlinePath = L.polyline ([], {
|
|
839
|
+
// Style of temporary, dashed line while moving the mouse
|
|
840
|
+
color: this.options.tempLine.color,
|
|
841
|
+
weight: this.options.tempLine.weight,
|
|
842
|
+
interactive: false,
|
|
843
|
+
dashArray: '8,8'
|
|
844
|
+
}).addTo(this._layerPaint).bringToBack();
|
|
845
|
+
|
|
846
|
+
var polylineState = this; // use "polylineState" instead of "this" to allow measuring on 2 different maps the same time
|
|
847
|
+
|
|
848
|
+
this._currentLine = {
|
|
849
|
+
id: 0,
|
|
850
|
+
circleCoords: [],
|
|
851
|
+
circleMarkers: [],
|
|
852
|
+
arrowMarkers: [],
|
|
853
|
+
tooltips: [],
|
|
854
|
+
distance: 0,
|
|
855
|
+
|
|
856
|
+
polylinePath: L.polyline([], {
|
|
857
|
+
// Style of fixed, polyline after mouse is clicked
|
|
858
|
+
color: this.options.fixedLine.color,
|
|
859
|
+
weight: this.options.fixedLine.weight,
|
|
860
|
+
interactive: false
|
|
861
|
+
}).addTo(this._layerPaint).bringToBack(),
|
|
862
|
+
|
|
863
|
+
handleMarkers: function (latlng) {
|
|
864
|
+
// update style on previous marker
|
|
865
|
+
var lastCircleMarker = this.circleMarkers.last();
|
|
866
|
+
if (lastCircleMarker) {
|
|
867
|
+
lastCircleMarker.bindTooltip (polylineState.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
868
|
+
lastCircleMarker.off ('click', polylineState._finishPolylinePath, polylineState);
|
|
869
|
+
if (this.circleMarkers.length === 1) {
|
|
870
|
+
lastCircleMarker.setStyle (polylineState.options.startCircle);
|
|
871
|
+
} else {
|
|
872
|
+
lastCircleMarker.setStyle (polylineState.options.intermedCircle);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
var newCircleMarker = new L.CircleMarker (latlng, polylineState.options.currentCircle).addTo(polylineState._layerPaint);
|
|
876
|
+
newCircleMarker.bindTooltip (polylineState.options.tooltipTextFinish + polylineState.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
877
|
+
newCircleMarker.cntLine = polylineState._currentLine.id;
|
|
878
|
+
newCircleMarker.cntCircle = polylineState._cntCircle;
|
|
879
|
+
polylineState._cntCircle++;
|
|
880
|
+
newCircleMarker.on ('mousedown', polylineState._dragCircle, polylineState);
|
|
881
|
+
newCircleMarker.on ('click', polylineState._finishPolylinePath, polylineState);
|
|
882
|
+
this.circleMarkers.push (newCircleMarker);
|
|
883
|
+
},
|
|
884
|
+
|
|
885
|
+
getNewToolTip: function(latlng) {
|
|
886
|
+
return L.marker (latlng, {
|
|
887
|
+
icon: icon,
|
|
888
|
+
interactive: false
|
|
889
|
+
});
|
|
890
|
+
},
|
|
891
|
+
|
|
892
|
+
addPoint: function (mouseCoords) {
|
|
893
|
+
var lastCircleCoords = this.circleCoords.last();
|
|
894
|
+
if (lastCircleCoords && lastCircleCoords.equals (mouseCoords)) { // don't add a new circle if the click was onto the last circle
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
this.circleCoords.push (mouseCoords);
|
|
898
|
+
// update polyline
|
|
899
|
+
if (this.circleCoords.length > 1) {
|
|
900
|
+
var arc = polylineState._polylineArc (lastCircleCoords, mouseCoords);
|
|
901
|
+
var arrowMarker = polylineState._drawArrow (arc);
|
|
902
|
+
if (this.circleCoords.length > 2) {
|
|
903
|
+
arc.shift(); // remove first coordinate of the arc, cause it is identical with last coordinate of previous arc
|
|
904
|
+
}
|
|
905
|
+
this.polylinePath.setLatLngs (this.polylinePath.getLatLngs().concat(arc));
|
|
906
|
+
// following lines needed especially for Mobile Browsers where we just use mouseclicks. No mousemoves, no tempLine.
|
|
907
|
+
arrowMarker.cntLine = polylineState._currentLine.id;
|
|
908
|
+
arrowMarker.cntArrow = polylineState._cntCircle - 1;
|
|
909
|
+
polylineState._currentLine.arrowMarkers.push (arrowMarker);
|
|
910
|
+
var distanceSegment = lastCircleCoords.distanceTo (mouseCoords);
|
|
911
|
+
this.distance += distanceSegment;
|
|
912
|
+
var currentTooltip = polylineState._currentLine.tooltips.last();
|
|
913
|
+
var prevTooltip = polylineState._currentLine.tooltips.slice(-1,-2)[0];
|
|
914
|
+
polylineState._updateTooltip (currentTooltip, prevTooltip, this.distance, distanceSegment, lastCircleCoords, mouseCoords);
|
|
915
|
+
}
|
|
916
|
+
// update last tooltip with final value
|
|
917
|
+
if (currentTooltip) {
|
|
918
|
+
currentTooltip.setLatLng (mouseCoords);
|
|
919
|
+
}
|
|
920
|
+
// add new tooltip to update on mousemove
|
|
921
|
+
var tooltipNew = this.getNewToolTip(mouseCoords);
|
|
922
|
+
tooltipNew.addTo(polylineState._layerPaint);
|
|
923
|
+
this.tooltips.push (tooltipNew);
|
|
924
|
+
this.handleMarkers (mouseCoords);
|
|
925
|
+
},
|
|
926
|
+
|
|
927
|
+
finalize: function() {
|
|
928
|
+
// remove tooltip created by last click
|
|
929
|
+
polylineState._layerPaint.removeLayer (this.tooltips.last());
|
|
930
|
+
this.tooltips.pop();
|
|
931
|
+
// remove temporary rubberline
|
|
932
|
+
polylineState._layerPaint.removeLayer (polylineState._rubberlinePath);
|
|
933
|
+
if (this.circleCoords.length > 1) {
|
|
934
|
+
this.tooltips.last()._icon.classList.add('polyline-measure-tooltip-end'); // add Class e.g. another background-color to the Previous Tooltip (which is the last fixed tooltip, cause the moving tooltip is being deleted later)
|
|
935
|
+
var lastCircleMarker = this.circleMarkers.last()
|
|
936
|
+
lastCircleMarker.setStyle (polylineState.options.endCircle);
|
|
937
|
+
// use Leaflet's own tooltip method to shwo a popuo tooltip if user hovers the last circle of a polyline
|
|
938
|
+
lastCircleMarker.unbindTooltip (); // to close the opened Tooltip after it's been opened after click onto point to finish the line
|
|
939
|
+
polylineState._currentLine.circleMarkers.map (function (circle) {circle.bindTooltip (polylineState.options.tooltipTextMove + polylineState.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'})});
|
|
940
|
+
polylineState._currentLine.circleMarkers[0].bindTooltip (polylineState.options.tooltipTextMove + polylineState.options.tooltipTextDelete + polylineState.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
941
|
+
lastCircleMarker.bindTooltip (polylineState.options.tooltipTextMove + polylineState.options.tooltipTextDelete + polylineState.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
942
|
+
polylineState._currentLine.arrowMarkers.map (function (arrow) {arrow.bindTooltip (polylineState.options.tooltipTextAdd, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'})});
|
|
943
|
+
lastCircleMarker.off ('click', polylineState._finishPolylinePath, polylineState);
|
|
944
|
+
lastCircleMarker.on ('click', polylineState._resumePolylinePath, polylineState);
|
|
945
|
+
polylineState._arrPolylines [this.id] = this;
|
|
946
|
+
} else {
|
|
947
|
+
// if there is only one point, just clean it up
|
|
948
|
+
polylineState._layerPaint.removeLayer (this.circleMarkers.last());
|
|
949
|
+
polylineState._layerPaint.removeLayer (this.tooltips.last());
|
|
950
|
+
}
|
|
951
|
+
polylineState._resetPathVariables();
|
|
952
|
+
}
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
var firstTooltip = L.marker (clickCoords, {
|
|
956
|
+
icon: icon,
|
|
957
|
+
interactive: false
|
|
958
|
+
})
|
|
959
|
+
firstTooltip.addTo(this._layerPaint);
|
|
960
|
+
var text = '';
|
|
961
|
+
if (this.options.showBearings === true) {
|
|
962
|
+
text = this.options.bearingTextIn+':---°<br>'+this.options.bearingTextOut+':---°';
|
|
963
|
+
}
|
|
964
|
+
text = text + '<div class="polyline-measure-tooltip-difference">+' + '0</div>';
|
|
965
|
+
text = text + '<div class="polyline-measure-tooltip-total">' + '0</div>';
|
|
966
|
+
firstTooltip._icon.innerHTML = text;
|
|
967
|
+
this._currentLine.tooltips.push (firstTooltip);
|
|
968
|
+
this._currentLine.circleCoords.last = last;
|
|
969
|
+
this._currentLine.tooltips.last = last;
|
|
970
|
+
this._currentLine.circleMarkers.last = last;
|
|
971
|
+
this._currentLine.id = this._arrPolylines.length;
|
|
972
|
+
},
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Event to fire on mouse click
|
|
976
|
+
* @param {Object} e Event
|
|
977
|
+
* @private
|
|
978
|
+
*/
|
|
979
|
+
_mouseClick: function (e) {
|
|
980
|
+
// skip if there are no coords provided by the event, or this event's screen coordinates match those of finishing CircleMarker for the line we just completed
|
|
981
|
+
if (!e.latlng || (this._finishCircleScreencoords && this._finishCircleScreencoords.equals(e.containerPoint))) {
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (!this._currentLine && !this._mapdragging) {
|
|
986
|
+
this._startLine (e.latlng);
|
|
987
|
+
this._map.fire('polylinemeasure:start', this._currentLine);
|
|
988
|
+
}
|
|
989
|
+
// just create a point if the map isn't dragged during the mouseclick.
|
|
990
|
+
if (!this._mapdragging) {
|
|
991
|
+
this._currentLine.addPoint (e.latlng);
|
|
992
|
+
this._map.fire('polylinemeasure:add', e);
|
|
993
|
+
this._map.fire('polylinemeasure:change', this._currentLine);
|
|
994
|
+
} else {
|
|
995
|
+
this._mapdragging = false; // this manual setting to "false" needed, instead of a "moveend"-Event. Cause the mouseclick of a "moveend"-event immediately would create a point too the same time.
|
|
996
|
+
}
|
|
997
|
+
},
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* Finish the drawing of the path by clicking onto the last circle or pressing ESC-Key
|
|
1001
|
+
* @private
|
|
1002
|
+
*/
|
|
1003
|
+
_finishPolylinePath: function (e) {
|
|
1004
|
+
this._map.fire('polylinemeasure:finish', this._currentLine);
|
|
1005
|
+
this._currentLine.finalize();
|
|
1006
|
+
if (e) {
|
|
1007
|
+
this._finishCircleScreencoords = e.containerPoint;
|
|
1008
|
+
}
|
|
1009
|
+
},
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* Resume the drawing of a polyline by pressing CTRL-Key and clicking onto the last circle
|
|
1013
|
+
* @private
|
|
1014
|
+
*/
|
|
1015
|
+
_resumePolylinePath: function (e) {
|
|
1016
|
+
if (e.originalEvent.ctrlKey === true || e.originalEvent.metaKey === true) { // just resume if user pressed the CTRL-Key (or metaKey on Mac) while clicking onto the last circle
|
|
1017
|
+
this._currentLine = this._arrPolylines [e.target.cntLine];
|
|
1018
|
+
this._rubberlinePath = L.polyline ([], {
|
|
1019
|
+
// Style of temporary, rubberline while moving the mouse
|
|
1020
|
+
color: this.options.tempLine.color,
|
|
1021
|
+
weight: this.options.tempLine.weight,
|
|
1022
|
+
interactive: false,
|
|
1023
|
+
dashArray: '8,8'
|
|
1024
|
+
}).addTo(this._layerPaint).bringToBack();
|
|
1025
|
+
this._currentLine.tooltips.last()._icon.classList.remove ('polyline-measure-tooltip-end'); // remove extra CSS-class of previous, last tooltip
|
|
1026
|
+
var tooltipNew = this._currentLine.getNewToolTip (e.latlng);
|
|
1027
|
+
tooltipNew.addTo (this._layerPaint);
|
|
1028
|
+
this._currentLine.tooltips.push(tooltipNew);
|
|
1029
|
+
this._currentLine.circleMarkers.last().unbindTooltip(); // remove popup-tooltip of previous, last circleMarker
|
|
1030
|
+
this._currentLine.circleMarkers.last().bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1031
|
+
this._currentLine.circleMarkers.last().setStyle (this.options.currentCircle);
|
|
1032
|
+
this._cntCircle = this._currentLine.circleCoords.length;
|
|
1033
|
+
this._map.fire('polylinemeasure:resume', this._currentLine);
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* After completing a path, reset all the values to prepare in creating the next polyline measurement
|
|
1039
|
+
* @private
|
|
1040
|
+
*/
|
|
1041
|
+
_resetPathVariables: function() {
|
|
1042
|
+
this._cntCircle = 0;
|
|
1043
|
+
this._currentLine = null;
|
|
1044
|
+
},
|
|
1045
|
+
|
|
1046
|
+
_clickedArrow: function(e) {
|
|
1047
|
+
if (e.originalEvent.ctrlKey || e.originalEvent.metaKey) { // (metaKey for Mac)
|
|
1048
|
+
var lineNr = e.target.cntLine;
|
|
1049
|
+
var arrowNr = e.target.cntArrow;
|
|
1050
|
+
this._arrPolylines[lineNr].arrowMarkers [arrowNr].removeFrom (this._layerPaint);
|
|
1051
|
+
var newCircleMarker = new L.CircleMarker (e.latlng, this.options.intermedCircle).addTo(this._layerPaint);
|
|
1052
|
+
newCircleMarker.cntLine = lineNr;
|
|
1053
|
+
newCircleMarker.on ('mousedown', this._dragCircle, this);
|
|
1054
|
+
newCircleMarker.bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1055
|
+
this._arrPolylines[lineNr].circleMarkers.splice (arrowNr+1, 0, newCircleMarker);
|
|
1056
|
+
this._arrPolylines[lineNr].circleMarkers.map (function (item, index) {
|
|
1057
|
+
item.cntCircle = index;
|
|
1058
|
+
});
|
|
1059
|
+
this._arrPolylines[lineNr].circleCoords.splice (arrowNr+1, 0, e.latlng);
|
|
1060
|
+
var lineCoords = this._arrPolylines[lineNr].polylinePath.getLatLngs(); // get Coords of each Point of the current Polyline
|
|
1061
|
+
var arc1 = this._polylineArc (this._arrPolylines[lineNr].circleCoords[arrowNr], e.latlng);
|
|
1062
|
+
arc1.pop();
|
|
1063
|
+
var arc2 = this._polylineArc (e.latlng, this._arrPolylines[lineNr].circleCoords[arrowNr+2]);
|
|
1064
|
+
Array.prototype.splice.apply (lineCoords, [(arrowNr)*(this._arcpoints-1), this._arcpoints].concat (arc1, arc2));
|
|
1065
|
+
this._arrPolylines[lineNr].polylinePath.setLatLngs (lineCoords);
|
|
1066
|
+
var arrowMarker = this._drawArrow (arc1);
|
|
1067
|
+
this._arrPolylines[lineNr].arrowMarkers[arrowNr] = arrowMarker;
|
|
1068
|
+
arrowMarker = this._drawArrow (arc2);
|
|
1069
|
+
this._arrPolylines[lineNr].arrowMarkers.splice(arrowNr+1,0,arrowMarker);
|
|
1070
|
+
this._arrPolylines[lineNr].arrowMarkers.map (function (item, index) {
|
|
1071
|
+
item.cntLine = lineNr;
|
|
1072
|
+
item.cntArrow = index;
|
|
1073
|
+
});
|
|
1074
|
+
this._tooltipNew = L.marker (e.latlng, {
|
|
1075
|
+
icon: L.divIcon({
|
|
1076
|
+
className: 'polyline-measure-tooltip',
|
|
1077
|
+
iconAnchor: [-4, -4]
|
|
1078
|
+
}),
|
|
1079
|
+
interactive: false
|
|
1080
|
+
});
|
|
1081
|
+
this._tooltipNew.addTo(this._layerPaint);
|
|
1082
|
+
this._arrPolylines[lineNr].tooltips.splice (arrowNr+1, 0, this._tooltipNew);
|
|
1083
|
+
var totalDistance = 0;
|
|
1084
|
+
this._arrPolylines[lineNr].tooltips.map (function (item, index) {
|
|
1085
|
+
if (index >= 1) {
|
|
1086
|
+
var distance = this._arrPolylines[lineNr].circleCoords[index-1].distanceTo (this._arrPolylines[lineNr].circleCoords[index]);
|
|
1087
|
+
var lastCircleCoords = this._arrPolylines[lineNr].circleCoords[index - 1];
|
|
1088
|
+
var mouseCoords = this._arrPolylines[lineNr].circleCoords[index];
|
|
1089
|
+
totalDistance += distance;
|
|
1090
|
+
var prevTooltip = this._arrPolylines[lineNr].tooltips[index-1]
|
|
1091
|
+
this._updateTooltip (item, prevTooltip, totalDistance, distance, lastCircleCoords, mouseCoords);
|
|
1092
|
+
}
|
|
1093
|
+
}.bind(this));
|
|
1094
|
+
this._map.fire('polylinemeasure:insert', e);
|
|
1095
|
+
this._map.fire('polylinemeasure:change', this._arrPolylines[this._lineNr]);
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
|
|
1099
|
+
_dragCircleMouseup: function () {
|
|
1100
|
+
// bind new popup-tooltip to the last CircleMArker if dragging finished
|
|
1101
|
+
if ((this._circleNr === 0) || (this._circleNr === this._arrPolylines[this._lineNr].circleCoords.length-1)) {
|
|
1102
|
+
this._e1.target.bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete + this.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1103
|
+
} else {
|
|
1104
|
+
this._e1.target.bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1105
|
+
}
|
|
1106
|
+
this._resetPathVariables();
|
|
1107
|
+
this._map.off ('mousemove', this._dragCircleMousemove, this);
|
|
1108
|
+
this._map.dragging.enable();
|
|
1109
|
+
this._map.on ('mousemove', this._mouseMove, this);
|
|
1110
|
+
this._map.off ('mouseup', this._dragCircleMouseup, this);
|
|
1111
|
+
this._map.fire('polylinemeasure:move', this._e1);
|
|
1112
|
+
this._map.fire('polylinemeasure:change', this._arrPolylines[this._lineNr]);
|
|
1113
|
+
},
|
|
1114
|
+
|
|
1115
|
+
_dragCircleMousemove: function (e2) {
|
|
1116
|
+
var mouseNewLat = e2.latlng.lat;
|
|
1117
|
+
var mouseNewLng = e2.latlng.lng;
|
|
1118
|
+
var latDifference = mouseNewLat - this._mouseStartingLat;
|
|
1119
|
+
var lngDifference = mouseNewLng - this._mouseStartingLng;
|
|
1120
|
+
var currentCircleCoords = L.latLng (this._circleStartingLat + latDifference, this._circleStartingLng + lngDifference);
|
|
1121
|
+
var arcpoints = this._arcpoints;
|
|
1122
|
+
var lineNr = this._e1.target.cntLine;
|
|
1123
|
+
this._lineNr = lineNr;
|
|
1124
|
+
var circleNr = this._e1.target.cntCircle;
|
|
1125
|
+
this._circleNr = circleNr;
|
|
1126
|
+
this._e1.target.setLatLng (currentCircleCoords);
|
|
1127
|
+
this._e1.target.unbindTooltip(); // unbind popup-tooltip cause otherwise it would be annoying during dragging, or popup instantly again if it's just closed
|
|
1128
|
+
this._arrPolylines[lineNr].circleCoords[circleNr] = currentCircleCoords;
|
|
1129
|
+
var lineCoords = this._arrPolylines[lineNr].polylinePath.getLatLngs(); // get Coords of each Point of the current Polyline
|
|
1130
|
+
if (circleNr >= 1) { // redraw previous arc just if circle is not starting circle of polyline
|
|
1131
|
+
var newLineSegment1 = this._polylineArc(this._arrPolylines[lineNr].circleCoords[circleNr-1], currentCircleCoords);
|
|
1132
|
+
// the next line's syntax has to be used since Internet Explorer doesn't know new spread operator (...) for inserting the individual elements of an array as 3rd argument of the splice method; Otherwise we could write: lineCoords.splice (circleNr*(arcpoints-1), arcpoints, ...newLineSegment1);
|
|
1133
|
+
Array.prototype.splice.apply (lineCoords, [(circleNr-1)*(arcpoints-1), arcpoints].concat (newLineSegment1));
|
|
1134
|
+
var arrowMarker = this._drawArrow (newLineSegment1);
|
|
1135
|
+
arrowMarker.cntLine = lineNr;
|
|
1136
|
+
arrowMarker.cntArrow = circleNr-1;
|
|
1137
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr-1].removeFrom (this._layerPaint);
|
|
1138
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr-1] = arrowMarker;
|
|
1139
|
+
}
|
|
1140
|
+
if (circleNr < this._arrPolylines[lineNr].circleCoords.length-1) { // redraw following arc just if circle is not end circle of polyline
|
|
1141
|
+
var newLineSegment2 = this._polylineArc (currentCircleCoords, this._arrPolylines[lineNr].circleCoords[circleNr+1]);
|
|
1142
|
+
Array.prototype.splice.apply (lineCoords, [circleNr*(arcpoints-1), arcpoints].concat (newLineSegment2));
|
|
1143
|
+
arrowMarker = this._drawArrow (newLineSegment2);
|
|
1144
|
+
arrowMarker.cntLine = lineNr;
|
|
1145
|
+
arrowMarker.cntArrow = circleNr;
|
|
1146
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1147
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr] = arrowMarker;
|
|
1148
|
+
}
|
|
1149
|
+
this._arrPolylines[lineNr].polylinePath.setLatLngs (lineCoords);
|
|
1150
|
+
if (circleNr >= 0) { // just update tooltip position if moved circle is 2nd, 3rd, 4th etc. circle of a polyline
|
|
1151
|
+
this._arrPolylines[lineNr].tooltips[circleNr].setLatLng (currentCircleCoords);
|
|
1152
|
+
}
|
|
1153
|
+
var totalDistance = 0;
|
|
1154
|
+
// update tooltip texts of each tooltip
|
|
1155
|
+
this._arrPolylines[lineNr].tooltips.map (function (item, index) {
|
|
1156
|
+
if (index >= 1) {
|
|
1157
|
+
var distance = this._arrPolylines[lineNr].circleCoords[index-1].distanceTo (this._arrPolylines[lineNr].circleCoords[index]);
|
|
1158
|
+
var lastCircleCoords = this._arrPolylines[lineNr].circleCoords[index - 1];
|
|
1159
|
+
var mouseCoords = this._arrPolylines[lineNr].circleCoords[index];
|
|
1160
|
+
totalDistance += distance;
|
|
1161
|
+
this._arrPolylines[lineNr].distance = totalDistance;
|
|
1162
|
+
var prevTooltip = this._arrPolylines[lineNr].tooltips[index-1]
|
|
1163
|
+
this._updateTooltip (item, prevTooltip, totalDistance, distance, lastCircleCoords, mouseCoords);
|
|
1164
|
+
}
|
|
1165
|
+
}.bind(this));
|
|
1166
|
+
this._map.on ('mouseup', this._dragCircleMouseup, this);
|
|
1167
|
+
},
|
|
1168
|
+
|
|
1169
|
+
_resumeFirstpointMousemove: function (e) {
|
|
1170
|
+
var lineNr = this._lineNr;
|
|
1171
|
+
this._map.on ('click', this._resumeFirstpointClick, this); // necassary for _dragCircle. If switched on already within _dragCircle an unwanted click is fired at the end of the drag.
|
|
1172
|
+
var mouseCoords = e.latlng;
|
|
1173
|
+
this._rubberlinePath2.setLatLngs (this._polylineArc (mouseCoords, currentCircleCoords));
|
|
1174
|
+
this._tooltipNew.setLatLng (mouseCoords);
|
|
1175
|
+
var totalDistance = 0;
|
|
1176
|
+
var distance = mouseCoords.distanceTo (this._arrPolylines[lineNr].circleCoords[0]);
|
|
1177
|
+
var lastCircleCoords = mouseCoords;
|
|
1178
|
+
var currentCoords = this._arrPolylines[lineNr].circleCoords[0];
|
|
1179
|
+
totalDistance += distance;
|
|
1180
|
+
var prevTooltip = this._tooltipNew;
|
|
1181
|
+
var currentTooltip = this._arrPolylines[lineNr].tooltips[0]
|
|
1182
|
+
this._updateTooltip (currentTooltip, prevTooltip, totalDistance, distance, lastCircleCoords, currentCoords);
|
|
1183
|
+
this._arrPolylines[lineNr].tooltips.map (function (item, index) {
|
|
1184
|
+
if (index >= 1) {
|
|
1185
|
+
var distance = this._arrPolylines[lineNr].circleCoords[index-1].distanceTo (this._arrPolylines[lineNr].circleCoords[index]);
|
|
1186
|
+
var lastCircleCoords = this._arrPolylines[lineNr].circleCoords[index - 1];
|
|
1187
|
+
var mouseCoords = this._arrPolylines[lineNr].circleCoords[index];
|
|
1188
|
+
totalDistance += distance;
|
|
1189
|
+
var prevTooltip = this._arrPolylines[lineNr].tooltips[index-1]
|
|
1190
|
+
this._updateTooltip (item, prevTooltip, totalDistance, distance, lastCircleCoords, mouseCoords);
|
|
1191
|
+
}
|
|
1192
|
+
}.bind (this));
|
|
1193
|
+
},
|
|
1194
|
+
|
|
1195
|
+
_resumeFirstpointClick: function (e) {
|
|
1196
|
+
var lineNr = this._lineNr;
|
|
1197
|
+
this._resumeFirstpointFlag = false;
|
|
1198
|
+
this._map.off ('mousemove', this._resumeFirstpointMousemove, this);
|
|
1199
|
+
this._map.off ('click', this._resumeFirstpointClick, this);
|
|
1200
|
+
this._layerPaint.removeLayer (this._rubberlinePath2);
|
|
1201
|
+
this._arrPolylines[lineNr].circleMarkers [0].setStyle (this.options.intermedCircle);
|
|
1202
|
+
this._arrPolylines[lineNr].circleMarkers [0].unbindTooltip();
|
|
1203
|
+
this._arrPolylines[lineNr].circleMarkers [0].bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1204
|
+
var newCircleMarker = new L.CircleMarker (e.latlng, this.options.startCircle).addTo(this._layerPaint);
|
|
1205
|
+
newCircleMarker.cntLine = lineNr;
|
|
1206
|
+
newCircleMarker.cntCircle = 0;
|
|
1207
|
+
newCircleMarker.on ('mousedown', this._dragCircle, this);
|
|
1208
|
+
newCircleMarker.bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete + this.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1209
|
+
this._arrPolylines[lineNr].circleMarkers.unshift(newCircleMarker);
|
|
1210
|
+
this._arrPolylines[lineNr].circleMarkers.map (function (item, index) {
|
|
1211
|
+
item.cntCircle = index;
|
|
1212
|
+
});
|
|
1213
|
+
this._arrPolylines[lineNr].circleCoords.unshift(e.latlng);
|
|
1214
|
+
var arc = this._polylineArc (e.latlng, currentCircleCoords);
|
|
1215
|
+
var arrowMarker = this._drawArrow (arc);
|
|
1216
|
+
this._arrPolylines[lineNr].arrowMarkers.unshift(arrowMarker);
|
|
1217
|
+
this._arrPolylines[lineNr].arrowMarkers.map (function (item, index) {
|
|
1218
|
+
item.cntLine = lineNr;
|
|
1219
|
+
item.cntArrow = index;
|
|
1220
|
+
});
|
|
1221
|
+
arc.pop(); // remove last coordinate of arc, cause it's already part of the next arc.
|
|
1222
|
+
this._arrPolylines[lineNr].polylinePath.setLatLngs (arc.concat(this._arrPolylines[lineNr].polylinePath.getLatLngs()));
|
|
1223
|
+
this._arrPolylines[lineNr].tooltips.unshift(this._tooltipNew);
|
|
1224
|
+
this._map.on ('mousemove', this._mouseMove, this);
|
|
1225
|
+
},
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
// not just used for dragging Cirles but also for deleting circles and resuming line at its starting point.
|
|
1229
|
+
_dragCircle: function (e1) {
|
|
1230
|
+
var arcpoints = this._arcpoints;
|
|
1231
|
+
if (e1.originalEvent.ctrlKey || e1.originalEvent.metaKey) { // if user wants to resume drawing a line. metaKey for Mac
|
|
1232
|
+
this._map.off ('click', this._mouseClick, this); // to avoid unwanted creation of a new line if CTRL-clicked onto a point
|
|
1233
|
+
// if user wants resume the line at its starting point
|
|
1234
|
+
if (e1.target.cntCircle === 0) {
|
|
1235
|
+
this._resumeFirstpointFlag = true;
|
|
1236
|
+
this._lineNr = e1.target.cntLine;
|
|
1237
|
+
var lineNr = this._lineNr;
|
|
1238
|
+
this._circleNr = e1.target.cntCircle;
|
|
1239
|
+
currentCircleCoords = e1.latlng;
|
|
1240
|
+
this._arrPolylines[lineNr].circleMarkers [0].setStyle (this.options.currentCircle);
|
|
1241
|
+
this._rubberlinePath2 = L.polyline ([], {
|
|
1242
|
+
// Style of temporary, rubberline while moving the mouse
|
|
1243
|
+
color: this.options.tempLine.color,
|
|
1244
|
+
weight: this.options.tempLine.weight,
|
|
1245
|
+
interactive: false,
|
|
1246
|
+
dashArray: '8,8'
|
|
1247
|
+
}).addTo(this._layerPaint).bringToBack();
|
|
1248
|
+
this._tooltipNew = L.marker (currentCircleCoords, {
|
|
1249
|
+
icon: L.divIcon({
|
|
1250
|
+
className: 'polyline-measure-tooltip',
|
|
1251
|
+
iconAnchor: [-4, -4]
|
|
1252
|
+
}),
|
|
1253
|
+
interactive: false
|
|
1254
|
+
});
|
|
1255
|
+
this._tooltipNew.addTo(this._layerPaint);
|
|
1256
|
+
var text='';
|
|
1257
|
+
if (this.options.showBearings === true) {
|
|
1258
|
+
text = text + this.options.bearingTextIn+':---°<br>'+this.options.bearingTextOut+':---°';
|
|
1259
|
+
}
|
|
1260
|
+
text = text + '<div class="polyline-measure-tooltip-difference">+' + '0</div>';
|
|
1261
|
+
text = text + '<div class="polyline-measure-tooltip-total">' + '0</div>';
|
|
1262
|
+
this._tooltipNew._icon.innerHTML = text;
|
|
1263
|
+
this._map.off ('mousemove', this._mouseMove, this);
|
|
1264
|
+
this._map.on ('mousemove', this._resumeFirstpointMousemove, this);
|
|
1265
|
+
}
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
// if user wants to delete a circle
|
|
1270
|
+
if (e1.originalEvent.shiftKey) { // it's not possible to use "ALT-Key" instead, cause this won't work in some Linux distributions (there it's the default hotkey for moving windows)
|
|
1271
|
+
this._lineNr = e1.target.cntLine;
|
|
1272
|
+
var lineNr = this._lineNr;
|
|
1273
|
+
this._circleNr = e1.target.cntCircle;
|
|
1274
|
+
var circleNr = this._circleNr;
|
|
1275
|
+
|
|
1276
|
+
// if there is a rubberlinePath-layer and rubberline-id = clicked line-id of point meaning user is deleting a point of current line being drawn
|
|
1277
|
+
if ((this._layerPaint.hasLayer (this._rubberlinePath)) && (lineNr === this._currentLine.id)) {
|
|
1278
|
+
// when you're drawing and deleting point you need to take it into account by decreasing _cntCircle
|
|
1279
|
+
this._cntCircle--;
|
|
1280
|
+
// if the last Circle in polyline is being removed
|
|
1281
|
+
if(this._currentLine.circleMarkers.length === 1) {
|
|
1282
|
+
this._currentLine.finalize();
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
this._currentLine.circleCoords.splice(circleNr,1);
|
|
1287
|
+
this._currentLine.circleMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1288
|
+
this._currentLine.circleMarkers.splice(circleNr,1);
|
|
1289
|
+
this._currentLine.circleMarkers.map (function (item, index) {
|
|
1290
|
+
item.cntCircle = index;
|
|
1291
|
+
});
|
|
1292
|
+
lineCoords = this._currentLine.polylinePath.getLatLngs();
|
|
1293
|
+
this._currentLine.tooltips [circleNr].removeFrom (this._layerPaint);
|
|
1294
|
+
this._currentLine.tooltips.splice(circleNr,1);
|
|
1295
|
+
|
|
1296
|
+
// if first Circle is being removed
|
|
1297
|
+
if (circleNr === 0) {
|
|
1298
|
+
if(this._currentLine.circleMarkers.length === 1) {
|
|
1299
|
+
this._currentLine.circleMarkers [0].setStyle (this.options.currentCircle);
|
|
1300
|
+
} else {
|
|
1301
|
+
this._currentLine.circleMarkers [0].setStyle (this.options.startCircle);
|
|
1302
|
+
}
|
|
1303
|
+
lineCoords.splice (0, arcpoints-1);
|
|
1304
|
+
this._currentLine.circleMarkers [0].bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete + this.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1305
|
+
this._currentLine.arrowMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1306
|
+
this._currentLine.arrowMarkers.splice(0,1);
|
|
1307
|
+
var text='';
|
|
1308
|
+
if (this.options.showBearings === true) {
|
|
1309
|
+
text = this.options.bearingTextIn+':---°<br>'+this.options.bearingTextOut+':---°';
|
|
1310
|
+
}
|
|
1311
|
+
text = text + '<div class="polyline-measure-tooltip-difference">+' + '0</div>';
|
|
1312
|
+
text = text + '<div class="polyline-measure-tooltip-total">' + '0</div>';
|
|
1313
|
+
this._currentLine.tooltips [0]._icon.innerHTML = text;
|
|
1314
|
+
// if last Circle is being removed
|
|
1315
|
+
} else if (circleNr === this._currentLine.circleCoords.length) {
|
|
1316
|
+
this._currentLine.circleMarkers [circleNr-1].on ('click', this._resumePolylinePath, this);
|
|
1317
|
+
this._currentLine.circleMarkers [circleNr-1].bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete + this.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1318
|
+
this._currentLine.circleMarkers.slice(-1)[0].setStyle (this.options.currentCircle); // get last element of the array
|
|
1319
|
+
lineCoords.splice (-(arcpoints-1), arcpoints-1);
|
|
1320
|
+
this._currentLine.arrowMarkers [circleNr-1].removeFrom (this._layerPaint);
|
|
1321
|
+
this._currentLine.arrowMarkers.splice(-1,1);
|
|
1322
|
+
// if intermediate Circle is being removed
|
|
1323
|
+
} else {
|
|
1324
|
+
newLineSegment = this._polylineArc (this._currentLine.circleCoords[circleNr-1], this._currentLine.circleCoords[circleNr]);
|
|
1325
|
+
Array.prototype.splice.apply (lineCoords, [(circleNr-1)*(arcpoints-1), (2*arcpoints-1)].concat (newLineSegment));
|
|
1326
|
+
this._currentLine.arrowMarkers [circleNr-1].removeFrom (this._layerPaint);
|
|
1327
|
+
this._currentLine.arrowMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1328
|
+
arrowMarker = this._drawArrow (newLineSegment);
|
|
1329
|
+
this._currentLine.arrowMarkers.splice(circleNr-1,2,arrowMarker);
|
|
1330
|
+
}
|
|
1331
|
+
this._currentLine.polylinePath.setLatLngs (lineCoords);
|
|
1332
|
+
this._currentLine.arrowMarkers.map (function (item, index) {
|
|
1333
|
+
item.cntLine = lineNr;
|
|
1334
|
+
item.cntArrow = index;
|
|
1335
|
+
});
|
|
1336
|
+
var totalDistanceUnfinishedLine = 0;
|
|
1337
|
+
this._currentLine.tooltips.map (function (item, index, arr) {
|
|
1338
|
+
if (index >= 1) {
|
|
1339
|
+
var distance, mouseCoords;
|
|
1340
|
+
var prevTooltip = this._currentLine.tooltips[index-1];
|
|
1341
|
+
var lastCircleCoords = this._currentLine.circleCoords[index - 1];
|
|
1342
|
+
if(index === arr.length - 1) {
|
|
1343
|
+
distance = this._currentLine.circleCoords[index-1].distanceTo (e1.latlng);
|
|
1344
|
+
mouseCoords = e1.latlng;
|
|
1345
|
+
// if this is the last Circle (mouse cursor) then don't sum the distance, but update tooltip like it was summed
|
|
1346
|
+
this._updateTooltip (item, prevTooltip, totalDistanceUnfinishedLine + distance, distance, lastCircleCoords, mouseCoords);
|
|
1347
|
+
} else {
|
|
1348
|
+
distance = this._currentLine.circleCoords[index-1].distanceTo (this._currentLine.circleCoords[index]);
|
|
1349
|
+
mouseCoords = this._currentLine.circleCoords[index];
|
|
1350
|
+
// if this is not the last Circle (mouse cursor) then sum the distance
|
|
1351
|
+
totalDistanceUnfinishedLine += distance;
|
|
1352
|
+
this._updateTooltip (item, prevTooltip, totalDistanceUnfinishedLine, distance, lastCircleCoords, mouseCoords);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}.bind (this));
|
|
1356
|
+
|
|
1357
|
+
// update _currentLine distance after point deletion
|
|
1358
|
+
this._currentLine.distance = totalDistanceUnfinishedLine;
|
|
1359
|
+
} else {
|
|
1360
|
+
if (this._arrPolylines[lineNr].circleMarkers.length === 2) { // if there are just 2 remaining points, delete all these points and the remaining line, since there should not stay a lonely point the map
|
|
1361
|
+
this._layerPaint.removeLayer (this._arrPolylines[lineNr].circleMarkers [1]);
|
|
1362
|
+
this._layerPaint.removeLayer (this._arrPolylines[lineNr].tooltips [1]);
|
|
1363
|
+
this._layerPaint.removeLayer (this._arrPolylines[lineNr].circleMarkers [0]);
|
|
1364
|
+
this._layerPaint.removeLayer (this._arrPolylines[lineNr].tooltips [0]);
|
|
1365
|
+
this._layerPaint.removeLayer (this._arrPolylines[lineNr].arrowMarkers [0]);
|
|
1366
|
+
this._layerPaint.removeLayer (this._arrPolylines[lineNr].polylinePath);
|
|
1367
|
+
this._map.fire('polylinemeasure:remove', e1);
|
|
1368
|
+
this._map.fire('polylinemeasure:change', this._arrPolylines[this._lineNr]);
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
this._arrPolylines[lineNr].circleCoords.splice(circleNr,1);
|
|
1373
|
+
this._arrPolylines[lineNr].circleMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1374
|
+
this._arrPolylines[lineNr].circleMarkers.splice(circleNr,1);
|
|
1375
|
+
this._arrPolylines[lineNr].circleMarkers.map (function (item, index) {
|
|
1376
|
+
item.cntCircle = index;
|
|
1377
|
+
});
|
|
1378
|
+
var lineCoords = this._arrPolylines[lineNr].polylinePath.getLatLngs();
|
|
1379
|
+
this._arrPolylines[lineNr].tooltips [circleNr].removeFrom (this._layerPaint);
|
|
1380
|
+
this._arrPolylines[lineNr].tooltips.splice(circleNr,1);
|
|
1381
|
+
|
|
1382
|
+
// if the last Circle in polyline is being removed (in the code above, so length will be equal 0)
|
|
1383
|
+
if(!this._arrPolylines[lineNr].circleMarkers.length) {
|
|
1384
|
+
this._arrPolylines.splice(lineNr, 1);
|
|
1385
|
+
// when you delete the line in the middle of array, other lines indexes change, so you need to update line number of markers and circles
|
|
1386
|
+
this._arrPolylines.forEach(function(line, index) {
|
|
1387
|
+
line.circleMarkers.map(function (item) {
|
|
1388
|
+
item.cntLine = index;
|
|
1389
|
+
});
|
|
1390
|
+
line.arrowMarkers.map(function (item) {
|
|
1391
|
+
item.cntLine = index;
|
|
1392
|
+
});
|
|
1393
|
+
});
|
|
1394
|
+
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
// if first Circle is being removed
|
|
1398
|
+
if (circleNr === 0) {
|
|
1399
|
+
this._arrPolylines[lineNr].circleMarkers [0].setStyle (this.options.startCircle);
|
|
1400
|
+
lineCoords.splice (0, arcpoints-1);
|
|
1401
|
+
this._arrPolylines[lineNr].circleMarkers [0].bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete + this.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1402
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1403
|
+
this._arrPolylines[lineNr].arrowMarkers.splice(0,1);
|
|
1404
|
+
var text='';
|
|
1405
|
+
if (this.options.showBearings === true) {
|
|
1406
|
+
text = this.options.bearingTextIn+':---°<br>'+this.options.bearingTextOut+':---°';
|
|
1407
|
+
}
|
|
1408
|
+
text = text + '<div class="polyline-measure-tooltip-difference">+' + '0</div>';
|
|
1409
|
+
text = text + '<div class="polyline-measure-tooltip-total">' + '0</div>';
|
|
1410
|
+
this._arrPolylines[lineNr].tooltips [0]._icon.innerHTML = text;
|
|
1411
|
+
// if last Circle is being removed
|
|
1412
|
+
} else if (circleNr === this._arrPolylines[lineNr].circleCoords.length) {
|
|
1413
|
+
this._arrPolylines[lineNr].circleMarkers [circleNr-1].on ('click', this._resumePolylinePath, this);
|
|
1414
|
+
this._arrPolylines[lineNr].circleMarkers [circleNr-1].bindTooltip (this.options.tooltipTextMove + this.options.tooltipTextDelete + this.options.tooltipTextResume, {direction:'top', opacity:0.7, className:'polyline-measure-popupTooltip'});
|
|
1415
|
+
this._arrPolylines[lineNr].circleMarkers.slice(-1)[0].setStyle (this.options.endCircle); // get last element of the array
|
|
1416
|
+
this._arrPolylines[lineNr].tooltips.slice(-1)[0]._icon.classList.add('polyline-measure-tooltip-end');
|
|
1417
|
+
lineCoords.splice (-(arcpoints-1), arcpoints-1);
|
|
1418
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr-1].removeFrom (this._layerPaint);
|
|
1419
|
+
this._arrPolylines[lineNr].arrowMarkers.splice(-1,1);
|
|
1420
|
+
// if intermediate Circle is being removed
|
|
1421
|
+
} else {
|
|
1422
|
+
var newLineSegment = this._polylineArc (this._arrPolylines[lineNr].circleCoords[circleNr-1], this._arrPolylines[lineNr].circleCoords[circleNr]);
|
|
1423
|
+
Array.prototype.splice.apply (lineCoords, [(circleNr-1)*(arcpoints-1), (2*arcpoints-1)].concat (newLineSegment));
|
|
1424
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr-1].removeFrom (this._layerPaint);
|
|
1425
|
+
this._arrPolylines[lineNr].arrowMarkers [circleNr].removeFrom (this._layerPaint);
|
|
1426
|
+
var arrowMarker = this._drawArrow (newLineSegment);
|
|
1427
|
+
this._arrPolylines[lineNr].arrowMarkers.splice(circleNr-1,2,arrowMarker);
|
|
1428
|
+
}
|
|
1429
|
+
this._arrPolylines[lineNr].polylinePath.setLatLngs (lineCoords);
|
|
1430
|
+
this._arrPolylines[lineNr].arrowMarkers.map (function (item, index) {
|
|
1431
|
+
item.cntLine = lineNr;
|
|
1432
|
+
item.cntArrow = index;
|
|
1433
|
+
});
|
|
1434
|
+
var totalDistance = 0;
|
|
1435
|
+
this._arrPolylines[lineNr].tooltips.map (function (item, index) {
|
|
1436
|
+
if (index >= 1) {
|
|
1437
|
+
var distance = this._arrPolylines[lineNr].circleCoords[index-1].distanceTo (this._arrPolylines[lineNr].circleCoords[index]);
|
|
1438
|
+
var lastCircleCoords = this._arrPolylines[lineNr].circleCoords[index - 1];
|
|
1439
|
+
var mouseCoords = this._arrPolylines[lineNr].circleCoords[index];
|
|
1440
|
+
totalDistance += distance;
|
|
1441
|
+
this._arrPolylines[lineNr].distance = totalDistance;
|
|
1442
|
+
var prevTooltip = this._arrPolylines[lineNr].tooltips[index-1];
|
|
1443
|
+
this._updateTooltip (item, prevTooltip, totalDistance, distance, lastCircleCoords, mouseCoords);
|
|
1444
|
+
}
|
|
1445
|
+
}.bind (this));
|
|
1446
|
+
// if user is deleting a point of a line not finished yet (= rubbberline still present)
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
this._map.fire('polylinemeasure:remove', e1);
|
|
1450
|
+
this._map.fire('polylinemeasure:change', this._arrPolylines[this._lineNr]);
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
this._e1 = e1;
|
|
1454
|
+
if ((this._measuring) && (this._cntCircle === 0)) { // just execute drag-function if Measuring tool is active but no line is being drawn at the moment.
|
|
1455
|
+
this._map.dragging.disable(); // turn of moving of the map during drag of a circle
|
|
1456
|
+
this._map.off ('mousemove', this._mouseMove, this);
|
|
1457
|
+
this._map.off ('click', this._mouseClick, this);
|
|
1458
|
+
this._mouseStartingLat = e1.latlng.lat;
|
|
1459
|
+
this._mouseStartingLng = e1.latlng.lng;
|
|
1460
|
+
this._circleStartingLat = e1.target._latlng.lat;
|
|
1461
|
+
this._circleStartingLng = e1.target._latlng.lng;
|
|
1462
|
+
this._map.on ('mousemove', this._dragCircleMousemove, this);
|
|
1463
|
+
}
|
|
1464
|
+
},
|
|
1465
|
+
|
|
1466
|
+
/**
|
|
1467
|
+
* Takes in a dataset and programatically draws the polylines and measurements to the map
|
|
1468
|
+
* Dataset must be in the form of an array of LatLng[], which allows for multiple discontinuous
|
|
1469
|
+
* polylines to be seeded
|
|
1470
|
+
* @param {L.LatLng[][]} polylinesArray | Array of array of points
|
|
1471
|
+
*/
|
|
1472
|
+
seed: function(polylinesArray){
|
|
1473
|
+
// Hijack user actions to manually draw polylines
|
|
1474
|
+
polylinesArray.forEach((polyline) => {
|
|
1475
|
+
// toggle draw state on:
|
|
1476
|
+
this._toggleMeasure();
|
|
1477
|
+
// start line with first point of each polyline
|
|
1478
|
+
this._startLine(polyline[0]);
|
|
1479
|
+
// add subsequent points:
|
|
1480
|
+
polyline.forEach((point, ind) => {
|
|
1481
|
+
const latLng = L.latLng(point);
|
|
1482
|
+
this._mouseMove({ latLng });
|
|
1483
|
+
this._currentLine.addPoint(latLng);
|
|
1484
|
+
// on last point,
|
|
1485
|
+
if (ind === polyline.length - 1) {
|
|
1486
|
+
this._finishPolylinePath();
|
|
1487
|
+
this._toggleMeasure();
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
//======================================================================================
|
|
1495
|
+
|
|
1496
|
+
L.Map.mergeOptions({
|
|
1497
|
+
PolylineMeasureControl: false
|
|
1498
|
+
});
|
|
1499
|
+
|
|
1500
|
+
L.Map.addInitHook(function () {
|
|
1501
|
+
if (this.options.polylineMeasureControl) {
|
|
1502
|
+
this.PMControl = new L.Control.PolylineMeasure();
|
|
1503
|
+
this.addControl(this.PMControl);
|
|
1504
|
+
}
|
|
1505
|
+
});
|
|
1506
|
+
|
|
1507
|
+
L.control.polylineMeasure = function (options) {
|
|
1508
|
+
return new L.Control.PolylineMeasure (options);
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1511
|
+
return L.Control.PolylineMeasure;
|
|
1512
|
+
// to allow
|
|
1513
|
+
// import PolylineMeasure from 'leaflet.polylinemeasure';
|
|
1514
|
+
// const measureControl = new PolylineMeasure();
|
|
1515
|
+
// together with
|
|
1516
|
+
// import 'leaflet.polylinemeasure';
|
|
1517
|
+
// const measureControl = new L.Control.PolylineMeasure();
|
|
1518
|
+
|
|
1519
|
+
}));
|