leaflet-rotate 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1925 +1,2 @@
1
- (function (factory) {
2
- typeof define === 'function' && define.amd ? define(factory) :
3
- factory();
4
- })((function () { 'use strict';
5
-
6
- /**
7
- * @external L.DomUtil
8
- *
9
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/dom/DomUtil.js
10
- */
11
-
12
- const domUtilProto = L.extend({}, L.DomUtil);
13
-
14
- L.extend(L.DomUtil, {
15
-
16
- /**
17
- * Resets the 3D CSS transform of `el` so it is
18
- * translated by `offset` pixels and optionally
19
- * scaled by `scale`. Does not have an effect if
20
- * the browser doesn't support 3D CSS transforms.
21
- *
22
- * @param {HTMLElement} el
23
- * @param {L.Point} offset
24
- * @param {Number} scale
25
- * @param {Number} bearing
26
- * @param {L.Point} pivot
27
- */
28
- setTransform: function(el, offset, scale, bearing, pivot) {
29
- var pos = offset || new L.Point(0, 0);
30
-
31
- if (!bearing) {
32
- offset = pos._round();
33
- return domUtilProto.setTransform.apply(this, arguments);
34
- }
35
-
36
- pos = pos.rotateFrom(bearing, pivot);
37
-
38
- el.style[L.DomUtil.TRANSFORM] =
39
- 'translate3d(' + pos.x + 'px,' + pos.y + 'px' + ',0)' +
40
- (scale ? ' scale(' + scale + ')' : '') +
41
- ' rotate(' + bearing + 'rad)';
42
- },
43
-
44
- /**
45
- * Sets the position of `el` to coordinates specified by
46
- * `position`, using CSS translate or top/left positioning
47
- * depending on the browser (used by Leaflet internally
48
- * to position its layers).
49
- *
50
- * @param {HTMLElement} el
51
- * @param {L.Point} point
52
- * @param {Number} bearing
53
- * @param {L.Point} pivot
54
- * @param {Number} scale
55
- */
56
- setPosition: function(el, point, bearing, pivot, scale) {
57
- if (!bearing) {
58
- return domUtilProto.setPosition.apply(this, arguments);
59
- }
60
-
61
- /*eslint-disable */
62
- el._leaflet_pos = point;
63
- /*eslint-enable */
64
-
65
- if (L.Browser.any3d) {
66
- L.DomUtil.setTransform(el, point, scale, bearing, pivot);
67
- } else {
68
- el.style.left = point.x + 'px';
69
- el.style.top = point.y + 'px';
70
- }
71
- },
72
-
73
- /**
74
- * @constant radians = degrees × π/180°
75
- */
76
- DEG_TO_RAD: Math.PI / 180,
77
-
78
- /**
79
- * @constant degrees = radians × 180°/π
80
- */
81
- RAD_TO_DEG: 180 / Math.PI,
82
-
83
- });
84
-
85
- /**
86
- * @external L.Draggable
87
- *
88
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/dom/Draggable.js
89
- */
90
-
91
- /**
92
- * A class for making DOM elements draggable (including touch support).
93
- * Used internally for map and marker dragging. Only works for elements
94
- * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).
95
- */
96
-
97
- L.Draggable.include({
98
-
99
- /** @TODO */
100
- // updateMapBearing: function(mapBearing) {
101
- // this._mapBearing = mapBearing;
102
- // },
103
-
104
- });
105
-
106
- /**
107
- * @external L.Point
108
- *
109
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/geometry/Point.js
110
- */
111
-
112
- L.extend(L.Point.prototype, {
113
-
114
- /**
115
- * Rotate around (0,0) by applying the 2D rotation matrix:
116
- *
117
- * ⎡ x' ⎤ = ⎡ cos θ -sin θ ⎤ ⎡ x ⎤
118
- * ⎣ y' ⎦ ⎣ sin θ cos θ ⎦ ⎣ y ⎦
119
- *
120
- * @param theta must be given in radians.
121
- */
122
- rotate: function(theta) {
123
- return this.rotateFrom(theta, new L.Point(0,0))
124
- },
125
-
126
- /**
127
- * Rotate around (pivot.x, pivot.y) by:
128
- *
129
- * 1. subtract (pivot.x, pivot.y)
130
- * 2. rotate around (0, 0)
131
- * 3. add (pivot.x, pivot.y) back
132
- *
133
- * same as `this.subtract(pivot).rotate(theta).add(pivot)`
134
- *
135
- * @param {Number} theta
136
- * @param {L.Point} pivot
137
- *
138
- * @returns {L.Point}
139
- */
140
- rotateFrom: function(theta, pivot) {
141
- if (!theta) { return this; }
142
- var sinTheta = Math.sin(theta);
143
- var cosTheta = Math.cos(theta);
144
- var cx = pivot.x,
145
- cy = pivot.y;
146
- var x = this.x - cx,
147
- y = this.y - cy;
148
-
149
- return new L.Point(
150
- x * cosTheta - y * sinTheta + cx,
151
- x * sinTheta + y * cosTheta + cy
152
- );
153
- },
154
-
155
- });
156
-
157
- /**
158
- * @external L.DivOverlay
159
- *
160
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/DivOverlay.js
161
- */
162
-
163
- const divOverlayProto = L.extend({}, L.DivOverlay.prototype);
164
-
165
- L.DivOverlay.include({
166
-
167
- /**
168
- * Update L.Popup and L.Tooltip anchor positions after
169
- * the map is moved by calling `map.setBearing(theta)`
170
- *
171
- * @listens L.Map~rotate
172
- */
173
- getEvents: function() {
174
- return L.extend(divOverlayProto.getEvents.apply(this, arguments), { rotate: this._updatePosition });
175
- },
176
-
177
- /**
178
- * 0. update element anchor point (divOverlayProto v1.9.3)
179
- * 1. rotate around anchor point (subtract anchor -> rotate point -> add anchor)
180
- */
181
- _updatePosition: function() {
182
- if (!this._map) { return; }
183
- divOverlayProto._updatePosition.apply(this, arguments);
184
- if (this._map && this._map._rotate && this._zoomAnimated) {
185
- var anchor = this._getAnchor();
186
- var pos = L.DomUtil.getPosition(this._container).subtract(anchor);
187
- L.DomUtil.setPosition(this._container, this._map.rotatedPointToMapPanePoint(pos).add(anchor));
188
- }
189
-
190
- },
191
-
192
- });
193
-
194
- /**
195
- * @external L.Popup
196
- *
197
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/Popup.js
198
- */
199
-
200
- const popupProto = L.extend({}, L.Popup.prototype);
201
-
202
- L.Popup.include({
203
-
204
- /**
205
- * 0. update element anchor point (popupProto v1.9.3)
206
- * 1. rotate around anchor point (subtract anchor -> rotate point -> add anchor)
207
- */
208
- _animateZoom: function(e) {
209
- popupProto._animateZoom.apply(this, arguments);
210
- if (this._map && this._map._rotate) {
211
- var anchor = this._getAnchor();
212
- var pos = L.DomUtil.getPosition(this._container).subtract(anchor);
213
- L.DomUtil.setPosition(this._container, this._map.rotatedPointToMapPanePoint(pos).add(anchor));
214
- }
215
- },
216
-
217
- /**
218
- * Fix for L.popup({ keepInView = true })
219
- *
220
- * @see https://github.com/fnicollet/Leaflet/pull/21
221
- */
222
- _adjustPan: function() {
223
- if (!this.options.autoPan || (this._map._panAnim && this._map._panAnim._inProgress)) { return; }
224
-
225
- // We can endlessly recurse if keepInView is set and the view resets.
226
- // Let's guard against that by exiting early if we're responding to our own autopan.
227
- if (this._autopanning) {
228
- this._autopanning = false;
229
- return;
230
- }
231
-
232
- var map = this._map,
233
- marginBottom = parseInt(L.DomUtil.getStyle(this._container, 'marginBottom'), 10) || 0,
234
- containerHeight = this._container.offsetHeight + marginBottom,
235
- containerWidth = this._containerWidth,
236
- layerPos = new L.Point(this._containerLeft, -containerHeight - this._containerBottom);
237
-
238
- layerPos._add(L.DomUtil.getPosition(this._container));
239
-
240
- /** @TODO use popupProto._adjustPan */
241
- // var containerPos = map.layerPointToContainerPoint(layerPos);
242
- var containerPos = layerPos._add(this._map._getMapPanePos()),
243
- padding = L.point(this.options.autoPanPadding),
244
- paddingTL = L.point(this.options.autoPanPaddingTopLeft || padding),
245
- paddingBR = L.point(this.options.autoPanPaddingBottomRight || padding),
246
- size = map.getSize(),
247
- dx = 0,
248
- dy = 0;
249
-
250
- if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right
251
- dx = containerPos.x + containerWidth - size.x + paddingBR.x;
252
- }
253
- if (containerPos.x - dx - paddingTL.x < 0) { // left
254
- dx = containerPos.x - paddingTL.x;
255
- }
256
- if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom
257
- dy = containerPos.y + containerHeight - size.y + paddingBR.y;
258
- }
259
- if (containerPos.y - dy - paddingTL.y < 0) { // top
260
- dy = containerPos.y - paddingTL.y;
261
- }
262
-
263
- // @namespace Map
264
- // @section Popup events
265
- // @event autopanstart: Event
266
- // Fired when the map starts autopanning when opening a popup.
267
- if (dx || dy) {
268
- // Track that we're autopanning, as this function will be re-ran on moveend
269
- if (this.options.keepInView) {
270
- this._autopanning = true;
271
- }
272
- map
273
- .fire('autopanstart')
274
- .panBy([dx, dy]);
275
- }
276
- },
277
-
278
- });
279
-
280
- /**
281
- * @external L.Tooltip
282
- *
283
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/Tooltip.js
284
- */
285
-
286
- const tooltipProto = L.extend({}, L.Tooltip.prototype);
287
-
288
- L.Tooltip.include({
289
-
290
- _animateZoom: function(e) {
291
- if (!this._map._rotate) {
292
- return tooltipProto._animateZoom.apply(this, arguments);
293
- }
294
- var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
295
-
296
- pos = this._map.rotatedPointToMapPanePoint(pos);
297
- this._setPosition(pos);
298
- },
299
-
300
- _updatePosition: function() {
301
- if (!this._map._rotate) {
302
- return tooltipProto._updatePosition.apply(this, arguments);
303
- }
304
- var pos = this._map.latLngToLayerPoint(this._latlng);
305
-
306
- pos = this._map.rotatedPointToMapPanePoint(pos);
307
- this._setPosition(pos);
308
- },
309
-
310
- });
311
-
312
- /**
313
- * @external L.Icon
314
- *
315
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/marker/Icon.js
316
- */
317
-
318
- L.extend({}, L.Icon.prototype);
319
-
320
- L.Icon.include({
321
-
322
- _setIconStyles: function(img, name) {
323
- var options = this.options;
324
- var sizeOption = options[name + 'Size'];
325
-
326
- if (typeof sizeOption === 'number') {
327
- sizeOption = [sizeOption, sizeOption];
328
- }
329
-
330
- var size = L.point(sizeOption),
331
- anchor = L.point(name === 'shadow' && options.shadowAnchor || options.iconAnchor ||
332
- size && size.divideBy(2, true));
333
-
334
- img.className = 'leaflet-marker-' + name + ' ' + (options.className || '');
335
-
336
- if (anchor) {
337
- img.style.marginLeft = (-anchor.x) + 'px';
338
- img.style.marginTop = (-anchor.y) + 'px';
339
- /** @TODO use iconProto._setIconStyles */
340
- img.style[L.DomUtil.TRANSFORM + "Origin"] = anchor.x + "px " + anchor.y + "px 0px";
341
- }
342
-
343
- if (size) {
344
- img.style.width = size.x + 'px';
345
- img.style.height = size.y + 'px';
346
- }
347
- },
348
-
349
- });
350
-
351
- /**
352
- * @external L.Marker
353
- * @external L.Handler.MarkerDrag
354
- *
355
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/marker/Marker.js
356
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/marker/Marker.Drag.js
357
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/dom/Draggable.js
358
- */
359
-
360
- const markerProto = L.extend({}, L.Marker.prototype);
361
-
362
- L.Marker.mergeOptions({
363
-
364
- /**
365
- * Rotation of this marker in rad
366
- *
367
- * @type {Number}
368
- */
369
- rotation: 0,
370
-
371
- /**
372
- * Rotate this marker when map rotates
373
- *
374
- * @type {Boolean}
375
- */
376
- rotateWithView: false,
377
-
378
- /**
379
- * Scale of the marker icon
380
- *
381
- * @type {Number}
382
- */
383
- scale: undefined,
384
-
385
- });
386
-
387
- var markerDragProto; // retrived at runtime (see below: L.Marker::_initInteraction())
388
-
389
- var MarkerDrag = {
390
-
391
- // _onDragStart: function() {
392
- // if (!this._marker._map._rotate) {
393
- // return markerDragProto._onDragStart.apply(this, arguments);
394
- // }
395
- // this._draggable.updateMapBearing(this._marker._map._bearing);
396
- // },
397
-
398
- _onDrag: function(e) {
399
- var marker = this._marker,
400
- /** @TODO use markerDragProto._onDrag */
401
- rotated_marker = marker.options.rotation || marker.options.rotateWithView,
402
- shadow = marker._shadow,
403
- iconPos = L.DomUtil.getPosition(marker._icon);
404
-
405
- /** @TODO use markerDragProto._onDrag */
406
- // update shadow position
407
- if (!rotated_marker && shadow) {
408
- L.DomUtil.setPosition(shadow, iconPos);
409
- }
410
-
411
- /** @TODO use markerDragProto._onDrag */
412
- if (marker._map._rotate) {
413
- // Reverse calculation from mapPane coordinates to rotatePane coordinates
414
- iconPos = marker._map.mapPanePointToRotatedPoint(iconPos);
415
- }
416
- var latlng = marker._map.layerPointToLatLng(iconPos);
417
-
418
- marker._latlng = latlng;
419
- e.latlng = latlng;
420
- e.oldLatLng = this._oldLatLng;
421
-
422
- /** @TODO use markerDragProto._onDrag */
423
- if (rotated_marker) marker.setLatLng(latlng); // use `setLatLng` to presisit rotation. low efficiency
424
- else marker.fire('move', e); // `setLatLng` will trig 'move' event. we imitate here.
425
-
426
- // @event drag: Event
427
- // Fired repeatedly while the user drags the marker.
428
- marker
429
- .fire('drag', e);
430
- },
431
-
432
- _onDragEnd: function(e) {
433
- if (this._marker._map._rotate) {
434
- this._marker.update();
435
- }
436
- markerDragProto._onDragEnd.apply(this, arguments);
437
- },
438
-
439
- };
440
-
441
- L.Marker.include({
442
-
443
- /**
444
- * Update L.Marker anchor position after the map
445
- * is moved by calling `map.setBearing(theta)`
446
- *
447
- * @listens L.Map~rotate
448
- */
449
- getEvents: function() {
450
- return L.extend(markerProto.getEvents.apply(this, arguments), { rotate: this.update });
451
- },
452
-
453
- _initInteraction: function() {
454
- var ret = markerProto._initInteraction.apply(this, arguments);
455
- if (this.dragging && this.dragging.enabled() && this._map && this._map._rotate) {
456
- // L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable
457
- markerDragProto = markerDragProto || Object.getPrototypeOf(this.dragging);
458
- Object.assign(this.dragging, {
459
- // _onDragStart: MarkerDrag._onDragStart.bind(this.dragging),
460
- _onDrag: MarkerDrag._onDrag.bind(this.dragging),
461
- _onDragEnd: MarkerDrag._onDragEnd.bind(this.dragging),
462
- });
463
- this.dragging.disable();
464
- this.dragging.enable();
465
- }
466
- return ret;
467
- },
468
-
469
- _setPos: function(pos) {
470
-
471
- /** @TODO use markerProto._setPos */
472
- if (this._map._rotate) {
473
- pos = this._map.rotatedPointToMapPanePoint(pos);
474
- }
475
-
476
- /** @TODO use markerProto._setPos */
477
- var bearing = this.options.rotation || 0;
478
- if (this.options.rotateWithView) {
479
- bearing += this._map._bearing;
480
- }
481
-
482
- /** @TODO use markerProto._setPos */
483
- if (this._icon) {
484
- L.DomUtil.setPosition(this._icon, pos, bearing, pos, this.options.scale);
485
- }
486
-
487
- /** @TODO use markerProto._setPos */
488
- if (this._shadow) {
489
- L.DomUtil.setPosition(this._shadow, pos, bearing, pos, this.options.scale);
490
- }
491
-
492
- this._zIndex = pos.y + this.options.zIndexOffset;
493
-
494
- this._resetZIndex();
495
- },
496
-
497
- // _updateZIndex: function(offset) {
498
- // if (!this._map._rotate) {
499
- // return markerProto._updateZIndex.apply(this, arguments);
500
- // }
501
- // this._icon.style.zIndex = Math.round(this._zIndex + offset);
502
- // },
503
-
504
- setRotation: function(rotation) {
505
- this.options.rotation = rotation;
506
- this.update();
507
- },
508
-
509
- });
510
-
511
- /**
512
- * @external L.GridLayer
513
- *
514
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/tile/GridLayer.js
515
- */
516
-
517
- const gridLayerProto = L.extend({}, L.GridLayer.prototype);
518
-
519
- L.GridLayer.include({
520
-
521
- /**
522
- * Redraw L.TileLayer bounds after the map is
523
- * moved by just calling `map.setBearing(theta)`
524
- *
525
- * @listens L.Map~rotate
526
- */
527
- getEvents: function() {
528
- var events = gridLayerProto.getEvents.apply(this, arguments);
529
- if (this._map._rotate && !this.options.updateWhenIdle) {
530
- if (!this._onRotate) {
531
- this._onRotate = L.Util.throttle(this._onMoveEnd, this.options.updateInterval, this);
532
- }
533
- events.rotate = this._onRotate;
534
- }
535
- return events;
536
- },
537
-
538
- _getTiledPixelBounds: function(center) {
539
- if (!this._map._rotate) {
540
- return gridLayerProto._getTiledPixelBounds.apply(this, arguments);
541
- }
542
-
543
- return this._map._getNewPixelBounds(center, this._tileZoom);
544
- },
545
-
546
- });
547
-
548
- /**
549
- * @external L.Renderer
550
- *
551
- * @see https://github.com/Leaflet/Leaflet/tree/v1.9.3/src/layer/vector/Renderer.js
552
- */
553
-
554
- const rendererProto = L.extend({}, L.Renderer.prototype);
555
-
556
- L.Renderer.include({
557
-
558
- /**
559
- * Redraw L.Canvas and L.SVG renderer bounds after the
560
- * map is moved by just calling `map.setBearing(theta)`
561
- *
562
- * @listens L.Map~rotate
563
- */
564
- getEvents: function() {
565
- return L.extend(rendererProto.getEvents.apply(this, arguments), { rotate: this._update });
566
- },
567
-
568
- /**
569
- * Fix for `map.flyTo()` when `false === map.options.zoomAnimation`
570
- *
571
- * @see https://github.com/Leaflet/Leaflet/pull/8794
572
- */
573
- onAdd: function() {
574
- rendererProto.onAdd.apply(this, arguments);
575
- if (L.version <= "1.9.3") {
576
- // always keep transform-origin as 0 0
577
- this._container.classList.add('leaflet-zoom-animated');
578
- }
579
- },
580
-
581
- /**
582
- * @FIXME layer drifts on `map.setZoom()` (eg. zoom during animation)
583
- *
584
- * the main cause seems to be related to `this._updateTransform(path._center, path._zoom))`
585
- * and `this._topLeft = this._map.layerPointToLatLng(this._bounds.min);`
586
- *
587
- * @example
588
- * map.setZoom(2);
589
- * path._renderer._update();
590
- * path._renderer._updateTransform(path._renderer._center, path._renderer._zoom);
591
- *
592
- * @see https://github.com/Leaflet/Leaflet/pull/8794
593
- * @see https://github.com/Leaflet/Leaflet/pull/8103
594
- * @see https://github.com/Leaflet/Leaflet/issues/7466
595
- *
596
- * @TODO rechek this changes from leaflet@v1.9.3
597
- *
598
- * @see https://github.com/Leaflet/Leaflet/compare/v1.7.0...v1.9.3
599
- */
600
- _updateTransform: function(center, zoom) {
601
- if (!this._map._rotate) {
602
- return rendererProto._updateTransform.apply(this, arguments);
603
- }
604
- /**
605
- * @FIXME see path._renderer._reset();
606
- */
607
- var scale = this._map.getZoomScale(zoom, this._zoom),
608
- offset = this._map._latLngToNewLayerPoint(this._topLeft, zoom, center);
609
-
610
- L.DomUtil.setTransform(this._container, offset, scale);
611
-
612
- },
613
-
614
- // getEvents() {
615
- // const events = {
616
- // viewreset: this._reset,
617
- // zoom: this._onZoom,
618
- // moveend: this._update,
619
- // zoomend: this._onZoomEnd
620
- // };
621
- // if (this._zoomAnimated) {
622
- // events.zoomanim = this._onAnimZoom;
623
- // }
624
- // return events;
625
- // },
626
-
627
- // _onAnimZoom(ev) {
628
- // this._updateTransform(ev.center, ev.zoom);
629
- // },
630
-
631
- // _onZoom() {
632
- // this._updateTransform(this._map.getCenter(), this._map.getZoom());
633
- // },
634
-
635
- // _onZoomEnd() {
636
- // for (const id in this._layers) {
637
- // this._layers[id]._project();
638
- // }
639
- // },
640
-
641
- // _reset() {
642
- // this._update();
643
- // this._updateTransform(this._center, this._zoom);
644
-
645
- // for (const id in this._layers) {
646
- // this._layers[id]._reset();
647
- // }
648
- // },
649
-
650
- // _updatePaths() {
651
- // for (const id in this._layers) {
652
- // this._layers[id]._update();
653
- // }
654
- // },
655
-
656
- _update: function() {
657
- if (!this._map._rotate) {
658
- return rendererProto._update.apply(this, arguments);
659
- }
660
- // Update pixel bounds of renderer container (for positioning/sizing/clipping later)
661
- // Subclasses are responsible of firing the 'update' event.
662
- this._bounds = this._map._getPaddedPixelBounds(this.options.padding);
663
- this._topLeft = this._map.layerPointToLatLng(this._bounds.min);
664
- this._center = this._map.getCenter();
665
- this._zoom = this._map.getZoom();
666
- },
667
-
668
- });
669
-
670
- /**
671
- * @external L.Map
672
- *
673
- * @see https://github.com/Leaflet/Leaflet/blob/v1.9.3/src/map/Map.js
674
- */
675
-
676
- const mapProto = L.extend({}, L.Map.prototype);
677
-
678
- L.Map.mergeOptions({ rotate: false, bearing: 0, });
679
-
680
- L.Map.include({
681
-
682
- /**
683
- * @param {(HTMLElement|String)} id html selector
684
- * @param {Object} [options={}] leaflet map options
685
- */
686
- initialize: function(id, options) {
687
- if (options.rotate) {
688
- this._rotate = true;
689
- this._bearing = 0;
690
- }
691
- mapProto.initialize.apply(this, arguments);
692
- if(this.options.rotate){
693
- this.setBearing(this.options.bearing);
694
- }
695
- },
696
-
697
- /**
698
- * Given a pixel coordinate relative to the map container,
699
- * returns the corresponding pixel coordinate relative to
700
- * the [origin pixel](#map-getpixelorigin).
701
- *
702
- * @param {L.Point} point pixel screen coordinates
703
- * @returns {L.Point} transformed pixel point
704
- */
705
- containerPointToLayerPoint: function(point) {
706
- if (!this._rotate) {
707
- return mapProto.containerPointToLayerPoint.apply(this, arguments);
708
- }
709
- return L.point(point)
710
- .subtract(this._getMapPanePos())
711
- .rotateFrom(-this._bearing, this._getRotatePanePos())
712
- .subtract(this._getRotatePanePos());
713
- },
714
-
715
- /**
716
- * Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
717
- * returns the corresponding pixel coordinate relative to the map container.
718
- *
719
- * @param {L.Point} point pixel screen coordinates
720
- * @returns {L.Point} transformed pixel point
721
- */
722
- layerPointToContainerPoint: function(point) {
723
- if (!this._rotate) {
724
- return mapProto.layerPointToContainerPoint.apply(this, arguments);
725
- }
726
- return L.point(point)
727
- .add(this._getRotatePanePos())
728
- .rotateFrom(this._bearing, this._getRotatePanePos())
729
- .add(this._getMapPanePos());
730
- },
731
-
732
- /**
733
- * Converts a coordinate from the rotated pane reference system
734
- * to the reference system of the not rotated map pane.
735
- *
736
- * (rotatePane) --> (mapPane)
737
- * (rotatePane) --> (norotatePane)
738
- *
739
- * @param {L.Point} point pixel screen coordinates
740
- * @returns {L.Point}
741
- *
742
- * @since leaflet-rotate (v0.1)
743
- */
744
- rotatedPointToMapPanePoint: function(point) {
745
- return L.point(point)
746
- .rotate(this._bearing)
747
- ._add(this._getRotatePanePos());
748
- },
749
-
750
- /**
751
- * Converts a coordinate from the not rotated map pane reference system
752
- * to the reference system of the rotated pane.
753
- *
754
- * (mapPane) --> (rotatePane)
755
- * (norotatePane) --> (rotatePane)
756
- *
757
- * @param {L.Point} point pixel screen coordinates
758
- *
759
- * @since leaflet-rotate (v0.1)
760
- */
761
- mapPanePointToRotatedPoint: function(point) {
762
- return L.point(point)
763
- ._subtract(this._getRotatePanePos())
764
- .rotate(-this._bearing);
765
- },
766
-
767
- // latLngToLayerPoint: function (latlng) {
768
- // var projectedPoint = this.project(L.latLng(latlng))._round();
769
- // return projectedPoint._subtract(this.getPixelOrigin());
770
- // },
771
-
772
- // latLngToContainerPoint: function (latlng) {
773
- // return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng)));
774
- // },
775
-
776
- /**
777
- * Given latlng bounds, returns the bounds in projected pixel
778
- * relative to the map container.
779
- *
780
- * @see https://github.com/ronikar/Leaflet/blob/5c480ef959b947c3beed7065425a5a36c486262b/src/map/Map.js#L1114-L1135
781
- *
782
- * @param {L.LatLngBounds} bounds
783
- * @returns {L.Bounds}
784
- *
785
- * @since leaflet-rotate (v0.2)
786
- */
787
- mapBoundsToContainerBounds: function (bounds) {
788
- if (!this._rotate && mapProto.mapBoundsToContainerBounds) {
789
- return mapProto.mapBoundsToContainerBounds.apply(this, arguments);
790
- }
791
- // same as `this.latLngToContainerPoint(latlng)` but with floating point precision
792
- const origin = this.getPixelOrigin().add(this._getMapPanePos());
793
- const nw = this.project(bounds.getNorthWest())._subtract(origin),
794
- ne = this.project(bounds.getNorthEast())._subtract(origin),
795
- sw = this.project(bounds.getSouthWest())._subtract(origin),
796
- se = this.project(bounds.getSouthEast())._subtract(origin);
797
- return L.bounds([
798
- L.point(Math.min(nw.x, ne.x, se.x, sw.x), Math.min(nw.y, ne.y, se.y, sw.y)), // [ minX, minY ]
799
- L.point(Math.max(nw.x, ne.x, se.x, sw.x), Math.max(nw.y, ne.y, se.y, sw.y)) // [ maxX, maxY ]
800
- ]);
801
- },
802
-
803
- /**
804
- * Returns geographical bounds visible in the current map view
805
- *
806
- * @TODO find out if map bounds calculated by `L.Map::getBounds()`
807
- * function should match the `rotatePane` or `norotatePane` bounds
808
- *
809
- * @see https://github.com/fnicollet/Leaflet/issues/7
810
- *
811
- * @returns {L.LatLngBounds}
812
- */
813
- getBounds: function() {
814
- if (!this._rotate) {
815
- return mapProto.getBounds.apply(this, arguments);
816
- }
817
-
818
- // SEE: https://github.com/fnicollet/Leaflet/pull/22
819
- //
820
- // var bounds = this.getPixelBounds(),
821
- // sw = this.unproject(bounds.getBottomLeft()),
822
- // ne = this.unproject(bounds.getTopRight());
823
- // return new LatLngBounds(sw, ne);
824
- //
825
-
826
- // LatLngBounds' constructor automatically
827
- // extends the bounds to fit the passed points
828
- var size = this.getSize();
829
- return new L.LatLngBounds([
830
- this.containerPointToLatLng([0, 0]), // topleft
831
- this.containerPointToLatLng([size.x, 0]), // topright
832
- this.containerPointToLatLng([size.x, size.y]), // bottomright
833
- this.containerPointToLatLng([0, size.y]), // bottomleft
834
- ]);
835
- },
836
-
837
- /**
838
- * Returns the bounds of the current map view in projected pixel
839
- * coordinates (sometimes useful in layer and overlay implementations).
840
- *
841
- * @TODO find out if map bounds calculated by `L.Map::getPixelBounds()`
842
- * function should match the `rotatePane` or `norotatePane` bounds
843
- *
844
- * @see https://github.com/fnicollet/Leaflet/issues/7
845
- *
846
- * @returns {L.Bounds}
847
- */
848
- // getPixelBounds(center, zoom) {
849
- // // const topLeftPoint = map.containerPointToLayerPoint(this._getTopLeftPoint());
850
- // const topLeftPoint = this._getTopLeftPoint(center, zoom);
851
- // return new L.Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
852
- // },
853
-
854
- /**
855
- * Change map rotation
856
- *
857
- * @param {number} theta map degrees
858
- *
859
- * @since leaflet-rotate (v0.1)
860
- */
861
- setBearing: function(theta) {
862
- if (!L.Browser.any3d || !this._rotate) { return; }
863
-
864
- var bearing = L.Util.wrapNum(theta, [0, 360]) * L.DomUtil.DEG_TO_RAD,
865
- center = this._getPixelCenter(),
866
- oldPos = this._getRotatePanePos().rotateFrom(-this._bearing, center),
867
- newPos = oldPos.rotateFrom(bearing, center);
868
-
869
- // CSS transform
870
- L.DomUtil.setPosition(this._rotatePane, oldPos, bearing, center);
871
-
872
- this._pivot = center;
873
- this._bearing = bearing;
874
- this._rotatePanePos = newPos;
875
-
876
- this.fire('rotate');
877
- },
878
-
879
- /**
880
- * Get current map rotation
881
- *
882
- * @returns {number} theta map degrees
883
- *
884
- * @since leaflet-rotate (v0.1)
885
- */
886
- getBearing: function() {
887
- return this._bearing * L.DomUtil.RAD_TO_DEG;
888
- },
889
-
890
- /**
891
- * Creates a new [map pane](#map-pane) with the given name if it doesn't
892
- * exist already, then returns it. The pane is created as a child of
893
- * `container`, or as a child of the main map pane if not set.
894
- *
895
- * @param {String} name leaflet pane
896
- * @param {HTMLElement} [container] parent element
897
- * @returns {HTMLElement} pane container
898
- */
899
- // createPane: function(name, container) {
900
- // if (!this._rotate || name == 'mapPane') {
901
- // return mapProto.createPane.apply(this, arguments);
902
- // }
903
- // // init "rotatePane"
904
- // if (!this._rotatePane) {
905
- // // this._pivot = this.getSize().divideBy(2);
906
- // this._rotatePane = mapProto.createPane.call(this, 'rotatePane', this._mapPane);
907
- // L.DomUtil.setPosition(this._rotatePane, new L.Point(0, 0), this._bearing, this._pivot);
908
- // }
909
- // return mapProto.createPane.call(this, name, container || this._rotatePane);
910
- // },
911
-
912
- /**
913
- * Panes are DOM elements used to control the ordering of layers on
914
- * the map. You can access panes with [`map.getPane`](#map-getpane)
915
- * or [`map.getPanes`](#map-getpanes) methods. New panes can be created
916
- * with the [`map.createPane`](#map-createpane) method.
917
- *
918
- * Every map has the following default panes that differ only in zIndex:
919
- *
920
- * - mapPane [HTMLElement = 'auto'] - Pane that contains all other map panes
921
- * - tilePane [HTMLElement = 2] - Pane for tile layers
922
- * - overlayPane [HTMLElement = 4] - Pane for overlays like polylines and polygons
923
- * - shadowPane [HTMLElement = 5] - Pane for overlay shadows (e.g. marker shadows)
924
- * - markerPane [HTMLElement = 6] - Pane for marker icons
925
- * - tooltipPane [HTMLElement = 650] - Pane for tooltips.
926
- * - popupPane [HTMLElement = 700] - Pane for popups.
927
- */
928
- _initPanes: function() {
929
- var panes = this._panes = {};
930
- this._paneRenderers = {};
931
-
932
- this._mapPane = this.createPane('mapPane', this._container);
933
- L.DomUtil.setPosition(this._mapPane, new L.Point(0, 0));
934
-
935
- if (this._rotate) {
936
- this._rotatePane = this.createPane('rotatePane', this._mapPane);
937
- this._norotatePane = this.createPane('norotatePane', this._mapPane);
938
- // rotatePane
939
- this.createPane('tilePane', this._rotatePane);
940
- this.createPane('overlayPane', this._rotatePane);
941
- // norotatePane
942
- this.createPane('shadowPane', this._norotatePane);
943
- this.createPane('markerPane', this._norotatePane);
944
- this.createPane('tooltipPane', this._norotatePane);
945
- this.createPane('popupPane', this._norotatePane);
946
- } else {
947
- this.createPane('tilePane');
948
- this.createPane('overlayPane');
949
- this.createPane('shadowPane');
950
- this.createPane('markerPane');
951
- this.createPane('tooltipPane');
952
- this.createPane('popupPane');
953
- }
954
-
955
- if (!this.options.markerZoomAnimation) {
956
- L.DomUtil.addClass(panes.markerPane, 'leaflet-zoom-hide');
957
- L.DomUtil.addClass(panes.shadowPane, 'leaflet-zoom-hide');
958
- }
959
- },
960
-
961
- /**
962
- * Pans the map the minimum amount to make the `latlng` visible. Use
963
- * padding options to fit the display to more restricted bounds.
964
- * If `latlng` is already within the (optionally padded) display bounds,
965
- * the map will not be panned.
966
- *
967
- * @see https://github.com/Raruto/leaflet-rotate/issues/18
968
- *
969
- * @param {L.LatLng} latlng coordinates
970
- * @param {Object} [options={}] padding options
971
- *
972
- * @returns {L.Map} current map instance
973
- */
974
- panInside(latlng, options) {
975
- options = options || {};
976
-
977
- const paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]),
978
- paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]),
979
- /** @TODO use mapProto.panInside */
980
- // pixelPoint = this.project(latlng),
981
- // pixelBounds = this.getPixelBounds(),
982
- // pixelCenter = this.project(this.getCenter()),
983
- rect = this._container.getBoundingClientRect(),
984
- pixelPoint = this.latLngToContainerPoint(latlng),
985
- pixelBounds = L.bounds([ L.point(rect), L.point(rect).add(this.getSize()) ]),
986
- pixelCenter = pixelBounds.getCenter(),
987
- //
988
- paddedBounds = L.bounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]),
989
- paddedSize = paddedBounds.getSize();
990
-
991
- if (!paddedBounds.contains(pixelPoint)) {
992
- this._enforcingBounds = true;
993
- const centerOffset = pixelPoint.subtract(paddedBounds.getCenter());
994
- const offset = paddedBounds.extend(pixelPoint).getSize().subtract(paddedSize);
995
- pixelCenter.x += centerOffset.x < 0 ? -offset.x : offset.x;
996
- pixelCenter.y += centerOffset.y < 0 ? -offset.y : offset.y;
997
- /** @TODO use mapProto.panInside */
998
- // this.panTo(this.unproject(pixelCenter), options);
999
- this.panTo(this.containerPointToLatLng(pixelCenter), options);
1000
- //
1001
- this._enforcingBounds = false;
1002
- }
1003
- return this;
1004
- },
1005
-
1006
- /**
1007
- * Pans the map to the closest view that would lie inside the given bounds
1008
- * (if it's not already), controlling the animation using the options specific,
1009
- * if any.
1010
- *
1011
- * @TODO check if map bounds calculated by `L.Map::panInsideBounds()`
1012
- * function should match the `rotatePane` or `norotatePane` bounds
1013
- *
1014
- * @see https://github.com/fnicollet/Leaflet/issues/7
1015
- *
1016
- * @param {L.LatLngBounds} bounds coordinates
1017
- * @param {Object} [options] pan options
1018
- * @returns {L.Map} current map instance
1019
- */
1020
- // panInsideBounds: function (bounds, options) {
1021
- // this._enforcingBounds = true;
1022
- // var center = this.getCenter(),
1023
- // newCenter = this._limitCenter(center, this._zoom, L.latLngBounds(bounds));
1024
- //
1025
- // if (!center.equals(newCenter)) {
1026
- // this.panTo(newCenter, options);
1027
- // }
1028
- //
1029
- // this._enforcingBounds = false;
1030
- // return this;
1031
- // },
1032
-
1033
- // adjust center for view to get inside bounds
1034
- // _limitCenter(center, zoom, bounds) {
1035
- //
1036
- // if (!bounds) { return center; }
1037
- //
1038
- // const centerPoint = this.project(center, zoom),
1039
- // viewHalf = this.getSize().divideBy(2),
1040
- // viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),
1041
- // offset = this._getBoundsOffset(viewBounds, bounds, zoom);
1042
- //
1043
- // // If offset is less than a pixel, ignore.
1044
- // // This prevents unstable projections from getting into
1045
- // // an infinite loop of tiny offsets.
1046
- // if (Math.abs(offset.x) <= 1 && Math.abs(offset.y) <= 1) {
1047
- // return center;
1048
- // }
1049
- //
1050
- // return this.unproject(centerPoint.add(offset), zoom);
1051
- // },
1052
-
1053
- // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this
1054
- // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto),
1055
- // but takes a bounds parameter like [`fitBounds`](#map-fitbounds).
1056
- // flyToBounds(bounds, options) {
1057
- // const target = this._getBoundsCenterZoom(bounds, options);
1058
- // return this.flyTo(target.center, target.zoom, options);
1059
- // },
1060
-
1061
- // _getBoundsCenterZoom(bounds, options) {
1062
- //
1063
- // options = options || {};
1064
- // bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds);
1065
- //
1066
- // const paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]),
1067
- // paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]);
1068
- //
1069
- // let zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));
1070
- //
1071
- // zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom;
1072
- //
1073
- // if (zoom === Infinity) {
1074
- // return { center: bounds.getCenter(), zoom };
1075
- // }
1076
- //
1077
- // return { center, zoom };
1078
- //
1079
- // },
1080
-
1081
- /**
1082
- * Returns the maximum zoom level on which the given bounds fit to the map
1083
- * view in its entirety. If `inside` (optional) is set to `true`, the method
1084
- * instead returns the minimum zoom level on which the map view fits into
1085
- * the given bounds in its entirety.
1086
- *
1087
- * @param {L.LatLngBounds} bounds
1088
- * @param {Boolean} [inside=false]
1089
- * @param {L.Point} [padding=[0,0]]
1090
- *
1091
- * @returns {Number} zoom level
1092
- */
1093
- getBoundsZoom(bounds, inside, padding) {
1094
- if (!this._rotate || Math.abs(this._bearing).toFixed(1) < 0.1) {
1095
- return mapProto.getBoundsZoom.apply(this, arguments);
1096
- }
1097
-
1098
- bounds = L.latLngBounds(bounds);
1099
- padding = L.point(padding || [0, 0]);
1100
-
1101
- let zoom = this.getZoom() || 0;
1102
- const min = this.getMinZoom(),
1103
- max = this.getMaxZoom(),
1104
- /** @TODO use mapProto.getBoundsZoom */
1105
- // nw = bounds.getNorthWest(),
1106
- // se = bounds.getSouthEast(),
1107
- // size = this.getSize().subtract(padding),
1108
- // boundsSize = L.bounds(this.project(se, zoom), this.project(nw, zoom)).getSize(),
1109
- size = this.getSize().subtract(padding),
1110
- boundsSize = this.mapBoundsToContainerBounds(bounds).getSize(),
1111
- snap = this.options.zoomSnap,
1112
- scalex = size.x / boundsSize.x,
1113
- scaley = size.y / boundsSize.y,
1114
- scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley);
1115
-
1116
- zoom = this.getScaleZoom(scale, zoom);
1117
-
1118
- if (snap) {
1119
- zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level
1120
- zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;
1121
- }
1122
-
1123
- return Math.max(min, Math.min(max, zoom));
1124
- },
1125
-
1126
- /**
1127
- * Layer point of the current center
1128
- *
1129
- * @returns {L.Point} layer center
1130
- */
1131
- // _getCenterLayerPoint: function () {
1132
- // return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
1133
- // },
1134
-
1135
- /**
1136
- * Offset of the specified place to the current center in pixels
1137
- *
1138
- * @param {L.LatLng} latlng map coordinates
1139
- */
1140
- _getCenterOffset: function(latlng) {
1141
- var centerOffset = mapProto._getCenterOffset.apply(this, arguments);
1142
- if (this._rotate) {
1143
- centerOffset = centerOffset.rotate(this._bearing);
1144
- }
1145
- return centerOffset;
1146
- },
1147
-
1148
- /**
1149
- * @since leaflet-rotate (v0.1)
1150
- */
1151
- _getRotatePanePos: function() {
1152
- return this._rotatePanePos || new L.Point(0, 0);
1153
- // return L.DomUtil.getPosition(this._rotatePane) || new L.Point(0, 0);
1154
- },
1155
-
1156
- // _latLngToNewLayerPoint(latlng, zoom, center) {
1157
- // const topLeft = this._getNewPixelOrigin(center, zoom);
1158
- // return this.project(latlng, zoom)._subtract(topLeft);
1159
- //},
1160
-
1161
- _getNewPixelOrigin: function(center, zoom) {
1162
- if (!this._rotate) {
1163
- return mapProto._getNewPixelOrigin.apply(this, arguments);
1164
- }
1165
- var viewHalf = this.getSize()._divideBy(2);
1166
- return this.project(center, zoom)
1167
- .rotate(this._bearing)
1168
- ._subtract(viewHalf)
1169
- ._add(this._getMapPanePos())
1170
- ._add(this._getRotatePanePos())
1171
- .rotate(-this._bearing)
1172
- ._round();
1173
- },
1174
-
1175
- /**
1176
- * @since leaflet-rotate (v0.2)
1177
- *
1178
- * @see src\layer\tile\GridLayer::_getTiledPixelBounds()
1179
- */
1180
- _getNewPixelBounds: function(center, zoom) {
1181
- center = center || this.getCenter();
1182
- zoom = zoom || this.getZoom();
1183
- if (!this._rotate && mapProto._getNewPixelBounds) {
1184
- return mapProto._getNewPixelBounds.apply(this, arguments);
1185
- }
1186
- var mapZoom = this._animatingZoom ? Math.max(this._animateToZoom, this.getZoom()) : this.getZoom(),
1187
- scale = this.getZoomScale(mapZoom, zoom),
1188
- pixelCenter = this.project(center, zoom).floor(),
1189
- size = this.getSize(),
1190
- halfSize = new L.Bounds([
1191
- this.containerPointToLayerPoint([0, 0]).floor(),
1192
- this.containerPointToLayerPoint([size.x, 0]).floor(),
1193
- this.containerPointToLayerPoint([0, size.y]).floor(),
1194
- this.containerPointToLayerPoint([size.x, size.y]).floor()
1195
- ]).getSize().divideBy(scale * 2);
1196
-
1197
- return new L.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
1198
- },
1199
-
1200
- /**
1201
- * @since leaflet-rotate (v0.2)
1202
- *
1203
- * @return {L.Point} map pivot point (center)
1204
- */
1205
- _getPixelCenter: function() {
1206
- if (!this._rotate && mapProto._getPixelCenter) {
1207
- return mapProto._getPixelCenter.apply(this, arguments);
1208
- }
1209
- return this.getSize()._divideBy(2)._subtract(this._getMapPanePos());
1210
- },
1211
-
1212
- /**
1213
- * @since leaflet-rotate (v0.2)
1214
- *
1215
- * @see src\layer\vector\Renderer::_update()
1216
- */
1217
- _getPaddedPixelBounds: function(padding) {
1218
- if (!this._rotate && mapProto._getPaddedPixelBounds) {
1219
- return mapProto._getPaddedPixelBounds.apply(this, arguments);
1220
- }
1221
- var p = padding,
1222
- size = this.getSize(),
1223
- padMin = size.multiplyBy(-p),
1224
- padMax = size.multiplyBy(1 + p);
1225
- //min = this.containerPointToLayerPoint(size.multiplyBy(-p)).round();
1226
-
1227
- return new L.Bounds([
1228
- this.containerPointToLayerPoint([padMin.x, padMin.y]).floor(),
1229
- this.containerPointToLayerPoint([padMin.x, padMax.y]).floor(),
1230
- this.containerPointToLayerPoint([padMax.x, padMin.y]).floor(),
1231
- this.containerPointToLayerPoint([padMax.x, padMax.y]).floor()
1232
- ]);
1233
- },
1234
-
1235
- _handleGeolocationResponse: function(pos) {
1236
- if (!this._container._leaflet_id) { return; }
1237
-
1238
- var lat = pos.coords.latitude,
1239
- lng = pos.coords.longitude,
1240
- /** @TODO use mapProto._handleGeolocationResponse */
1241
- hdg = pos.coords.heading,
1242
- latlng = new L.LatLng(lat, lng),
1243
- bounds = latlng.toBounds(pos.coords.accuracy),
1244
- options = this._locateOptions;
1245
-
1246
- if (options.setView) {
1247
- var zoom = this.getBoundsZoom(bounds);
1248
- this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);
1249
- }
1250
-
1251
- var data = {
1252
- latlng: latlng,
1253
- bounds: bounds,
1254
- timestamp: pos.timestamp,
1255
- /** @TODO use mapProto._handleGeolocationResponse */
1256
- heading: hdg
1257
- };
1258
-
1259
- for (var i in pos.coords) {
1260
- if (typeof pos.coords[i] === 'number') {
1261
- data[i] = pos.coords[i];
1262
- }
1263
- }
1264
-
1265
- // @event locationfound: LocationEvent
1266
- // Fired when geolocation (using the [`locate`](#map-locate) method)
1267
- // went successfully.
1268
- this.fire('locationfound', data);
1269
- },
1270
-
1271
- /**
1272
- * @see https://github.com/ronikar/Leaflet/blob/5c480ef959b947c3beed7065425a5a36c486262b/src/geo/LatLngBounds.js#L253-L264
1273
- *
1274
- * @param {L.Bounds} points
1275
- * @returns {L.Bounds}
1276
- */
1277
- // toCircumscribedBounds(points) {
1278
- // var minX = points.reduce(function (pv, v) { return Math.min(pv, v.x); }, points[0].x),
1279
- // maxX = points.reduce(function (pv, v) { return Math.max(pv, v.x); }, points[0].x),
1280
- // minY = points.reduce(function (pv, v) { return Math.min(pv, v.y); }, points[0].y),
1281
- // maxY = points.reduce(function (pv, v) { return Math.max(pv, v.y); }, points[0].y);
1282
- //
1283
- // return L.bounds(L.point(minX, minY), L.point(maxX, maxY));
1284
- // },
1285
-
1286
- });
1287
-
1288
- /**
1289
- * Rotates the map according to a smartphone's compass.
1290
- *
1291
- * @typedef L.Map.CompassBearing
1292
- */
1293
-
1294
- L.Map.CompassBearing = L.Handler.extend({
1295
-
1296
- initialize: function(map) {
1297
- this._map = map;
1298
- /** @see https://caniuse.com/?search=DeviceOrientation */
1299
- if ('ondeviceorientationabsolute' in window) {
1300
- this.__deviceOrientationEvent = 'deviceorientationabsolute';
1301
- } else if('ondeviceorientation' in window) {
1302
- this.__deviceOrientationEvent = 'deviceorientation';
1303
- }
1304
- this._throttled = L.Util.throttle(this._onDeviceOrientation, 100, this);
1305
- },
1306
-
1307
- addHooks: function() {
1308
- if (this._map._rotate && this.__deviceOrientationEvent) {
1309
- L.DomEvent.on(window, this.__deviceOrientationEvent, this._throttled, this);
1310
- } else {
1311
- // L.Map.CompassBearing handler will be automatically
1312
- // disabled if device orientation is not supported.
1313
- this.disable();
1314
- }
1315
- },
1316
-
1317
- removeHooks: function() {
1318
- if (this._map._rotate && this.__deviceOrientationEvent) {
1319
- L.DomEvent.off(window, this.__deviceOrientationEvent, this._throttled, this);
1320
- }
1321
- },
1322
-
1323
- /**
1324
- * `DeviceOrientationEvent.absolute` - Indicates whether the device is providing absolute
1325
- * orientation values (relatives to Magnetic North) or
1326
- * using some arbitrary frame determined by the device.
1327
- *
1328
- * `DeviceOrientationEvent.alpha` - Returns the rotation of the device around the Z axis;
1329
- * that is, the number of degrees by which the device is
1330
- * being twisted around the center of the screen.
1331
- *
1332
- * `window.orientation` - Returns the screen orientation in degrees (in 90-degree increments)
1333
- * of the viewport relative to the device's natural orientation.
1334
- * Its only possible values are -90, 0, 90, and 180. Positive
1335
- * values are counterclockwise; negative values are clockwise.
1336
- *
1337
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/absolute
1338
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/alpha
1339
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation
1340
- */
1341
- _onDeviceOrientation: function(e) {
1342
- var angle = e.webkitCompassHeading || e.alpha;
1343
- var deviceOrientation = 0;
1344
-
1345
- // Safari iOS
1346
- if (!e.absolute && e.webkitCompassHeading) {
1347
- angle = 360 - angle;
1348
- }
1349
-
1350
- // Older browsers
1351
- if (!e.absolute && 'undefined' !== typeof window.orientation) {
1352
- deviceOrientation = window.orientation;
1353
- }
1354
-
1355
- this._map.setBearing(angle - deviceOrientation);
1356
- },
1357
-
1358
- });
1359
-
1360
- /**
1361
- * Add Compass bearing handler to L.Map (disabled unless `window.DeviceOrientationEvent` is set).
1362
- *
1363
- * @property {L.Map.CompassBearing} compassBearing
1364
- */
1365
- L.Map.addInitHook('addHandler', 'compassBearing', L.Map.CompassBearing);
1366
-
1367
- /**
1368
- * Triggers `invalidateResize` when the map's DOM container mutates.
1369
- *
1370
- * @typedef L.Map.ContainerMutation
1371
- */
1372
-
1373
- /**
1374
- * @TODO check again this file after leaflet v1.9.3 (eg. L.Browser.mutation).
1375
- * Mutation Observer support will likely be added by default in next releases.
1376
- */
1377
-
1378
- L.Map.mergeOptions({
1379
-
1380
- /**
1381
- * Whether the map uses mutation observers to
1382
- * detect changes in its container and trigger
1383
- * `invalidateSize`. Disabled by default due to
1384
- * support not being available in all web browsers.
1385
- *
1386
- * @type {Boolean}
1387
- *
1388
- * @see https://developer.mozilla.org/docs/Web/API/MutationObserver
1389
- */
1390
- trackContainerMutation: false
1391
-
1392
- });
1393
-
1394
- L.Map.ContainerMutation = L.Handler.extend({
1395
-
1396
- addHooks: function() {
1397
- // if (!L.Browser.mutation) { return; }
1398
- if (!this._observer) {
1399
- this._observer = new MutationObserver(L.Util.bind(this._map.invalidateSize, this._map));
1400
- }
1401
- this._observer.observe(this._map.getContainer(), {
1402
- childList: false,
1403
- attributes: true,
1404
- characterData: false,
1405
- subtree: false,
1406
- attributeFilter: ['style']
1407
- });
1408
- },
1409
-
1410
- removeHooks: function() {
1411
- // if (!L.Browser.mutation) { return; }
1412
- this._observer.disconnect();
1413
- },
1414
-
1415
- });
1416
-
1417
- /**
1418
- * Add Container mutation handler to L.Map (disabled unless `trackContainerMutation` is set).
1419
- *
1420
- * @property {L.Map.ContainerMutation} trackContainerMutation
1421
- */
1422
- L.Map.addInitHook('addHandler', 'trackContainerMutation', L.Map.ContainerMutation);
1423
-
1424
- /**
1425
- * TouchGestures is both TouchZoom plus TouchRotate
1426
- *
1427
- * @see https://github.com/fnicollet/Leaflet/commit/a77af51a6b10f308d1b9a16552091d1d0aee8834
1428
- * @see https://github.com/Leaflet/Leaflet/blob/v1.9.3/src/map/handler/Map.TouchZoom.js
1429
- *
1430
- * @typedef L.Map.TouchGestures
1431
- */
1432
-
1433
- L.Map.mergeOptions({
1434
-
1435
- /**
1436
- * Set it to false if you don't want the map to
1437
- * zoom beyond min/max zoom and then bounce back
1438
- * when pinch-zooming.
1439
- *
1440
- * @type {Boolean}
1441
- */
1442
- bounceAtZoomLimits: true,
1443
-
1444
- });
1445
-
1446
- L.Map.TouchGestures = L.Handler.extend({
1447
-
1448
- initialize: function(map) {
1449
- this._map = map;
1450
- this.rotate = !!this._map.options.touchRotate;
1451
- this.zoom = !!this._map.options.touchZoom;
1452
- },
1453
-
1454
- addHooks: function() {
1455
- L.DomEvent.on(this._map._container, 'touchstart', this._onTouchStart, this);
1456
- },
1457
-
1458
- removeHooks: function() {
1459
- L.DomEvent.off(this._map._container, 'touchstart', this._onTouchStart, this);
1460
- },
1461
-
1462
- _onTouchStart: function(e) {
1463
- var map = this._map;
1464
-
1465
- if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming || this._rotating) { return; }
1466
-
1467
- var p1 = map.mouseEventToContainerPoint(e.touches[0]),
1468
- p2 = map.mouseEventToContainerPoint(e.touches[1]),
1469
- vector = p1.subtract(p2);
1470
-
1471
- this._centerPoint = map.getSize()._divideBy(2);
1472
- this._startLatLng = map.containerPointToLatLng(this._centerPoint);
1473
-
1474
- if (this.zoom) {
1475
- if (map.options.touchZoom !== 'center') {
1476
- this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));
1477
- }
1478
- this._startDist = p1.distanceTo(p2);
1479
- this._startZoom = map.getZoom();
1480
- this._zooming = true;
1481
- } else {
1482
- this._zooming = false;
1483
- }
1484
-
1485
- if (this.rotate) {
1486
- this._startTheta = Math.atan(vector.x / vector.y);
1487
- this._startBearing = map.getBearing();
1488
- if (vector.y < 0) { this._startBearing += 180; }
1489
- this._rotating = true;
1490
- } else {
1491
- this._rotating = false;
1492
- }
1493
-
1494
- this._moved = false;
1495
-
1496
- map._stop();
1497
-
1498
- L.DomEvent
1499
- .on(document, 'touchmove', this._onTouchMove, this)
1500
- .on(document, 'touchend touchcancel', this._onTouchEnd, this);
1501
-
1502
- L.DomEvent.preventDefault(e);
1503
- },
1504
-
1505
- _onTouchMove: function(e) {
1506
- if (!e.touches || e.touches.length !== 2 || !(this._zooming || this._rotating)) { return; }
1507
-
1508
- var map = this._map,
1509
- p1 = map.mouseEventToContainerPoint(e.touches[0]),
1510
- p2 = map.mouseEventToContainerPoint(e.touches[1]),
1511
- vector = p1.subtract(p2),
1512
- scale = p1.distanceTo(p2) / this._startDist,
1513
- delta;
1514
-
1515
- if (this._rotating) {
1516
- var theta = Math.atan(vector.x / vector.y);
1517
- var bearingDelta = (theta - this._startTheta) * L.DomUtil.RAD_TO_DEG;
1518
- if (vector.y < 0) { bearingDelta += 180; }
1519
- if (bearingDelta) {
1520
- /**
1521
- * @TODO the pivot should be the last touch point,
1522
- * but zoomAnimation manages to overwrite the rotate
1523
- * pane position. Maybe related to #3529.
1524
- *
1525
- * @see https://github.com/Leaflet/Leaflet/pull/3529
1526
- * @see https://github.com/fnicollet/Leaflet/commit/a77af51a6b10f308d1b9a16552091d1d0aee8834
1527
- */
1528
- map.setBearing(this._startBearing - bearingDelta);
1529
- }
1530
- }
1531
-
1532
- if (this._zooming) {
1533
- this._zoom = map.getScaleZoom(scale, this._startZoom);
1534
-
1535
- if (!map.options.bounceAtZoomLimits && (
1536
- (this._zoom < map.getMinZoom() && scale < 1) ||
1537
- (this._zoom > map.getMaxZoom() && scale > 1))) {
1538
- this._zoom = map._limitZoom(this._zoom);
1539
- }
1540
-
1541
- if (map.options.touchZoom === 'center') {
1542
- this._center = this._startLatLng;
1543
- if (scale === 1) { return; }
1544
- } else {
1545
- // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng
1546
- delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
1547
- if (scale === 1 && delta.x === 0 && delta.y === 0) { return; }
1548
-
1549
- var alpha = -map.getBearing() * L.DomUtil.DEG_TO_RAD;
1550
-
1551
- this._center = map.unproject(map.project(this._pinchStartLatLng).subtract(delta.rotate(alpha)));
1552
- }
1553
-
1554
- }
1555
-
1556
- if (!this._moved) {
1557
- map._moveStart(true, false);
1558
- this._moved = true;
1559
- }
1560
-
1561
- L.Util.cancelAnimFrame(this._animRequest);
1562
-
1563
- var moveFn = map._move.bind(map, this._center, this._zoom, { pinch: true, round: false }, undefined);
1564
- this._animRequest = L.Util.requestAnimFrame(moveFn, this, true);
1565
-
1566
- L.DomEvent.preventDefault(e);
1567
- },
1568
-
1569
- _onTouchEnd: function() {
1570
- if (!this._moved || !(this._zooming || this._rotating)) {
1571
- this._zooming = false;
1572
- return;
1573
- }
1574
-
1575
- this._zooming = false;
1576
- this._rotating = false;
1577
- L.Util.cancelAnimFrame(this._animRequest);
1578
-
1579
- L.DomEvent
1580
- .off(document, 'touchmove', this._onTouchMove, this)
1581
- .off(document, 'touchend touchcancel', this._onTouchEnd, this);
1582
-
1583
- if (this.zoom) {
1584
- // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate.
1585
- if (this._map.options.zoomAnimation) {
1586
- this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap);
1587
- } else {
1588
- this._map._resetView(this._center, this._map._limitZoom(this._zoom));
1589
- }
1590
- }
1591
- },
1592
-
1593
- });
1594
-
1595
- /**
1596
- * Add Touch Gestures handler (enabled unless `touchGestures` is unset).
1597
- *
1598
- * @property {L.Map.TouchGestures} touchGestures
1599
- */
1600
- L.Map.addInitHook('addHandler', 'touchGestures', L.Map.TouchGestures);
1601
-
1602
- /**
1603
- * Rotates the map on two-finger (touch devices).
1604
- *
1605
- * @typedef L.Map.TouchRotate
1606
- */
1607
-
1608
- L.Map.mergeOptions({
1609
-
1610
- /**
1611
- * Whether the map can be rotated with a two-finger rotation gesture
1612
- *
1613
- * @type {Boolean}
1614
- */
1615
- touchRotate: false,
1616
-
1617
- });
1618
-
1619
- L.Map.TouchRotate = L.Handler.extend({
1620
-
1621
- addHooks: function() {
1622
- this._map.touchGestures.enable();
1623
- this._map.touchGestures.rotate = true;
1624
- },
1625
-
1626
- removeHooks: function() {
1627
- this._map.touchGestures.rotate = false;
1628
- },
1629
-
1630
- });
1631
-
1632
- /**
1633
- * Add Touch Rotate handler (disabled unless `touchGestures` is set).
1634
- *
1635
- * @property {L.Map.TouchGestures} touchGestures
1636
- */
1637
- L.Map.addInitHook('addHandler', 'touchRotate', L.Map.TouchRotate);
1638
-
1639
- /**
1640
- * Rotates the map on shift key + mousewheel scrolling (desktop).
1641
- *
1642
- * @typedef L.Map.ShiftKeyRotate
1643
- */
1644
-
1645
- L.Map.mergeOptions({
1646
-
1647
- /**
1648
- * Whether the map can be rotated with shift + wheel scroll
1649
- * @type {Boolean}
1650
- */
1651
- shiftKeyRotate: true,
1652
-
1653
- });
1654
-
1655
- L.Map.ShiftKeyRotate = L.Handler.extend({
1656
-
1657
- addHooks: function() {
1658
- L.DomEvent.on(this._map._container, "wheel", this._handleShiftScroll, this);
1659
- // this._map.shiftKeyRotate.enable();
1660
- this._map.shiftKeyRotate.rotate = true;
1661
- },
1662
-
1663
- removeHooks: function() {
1664
- L.DomEvent.off(this._map._container, "wheel", this._handleShiftScroll, this);
1665
- this._map.shiftKeyRotate.rotate = false;
1666
- },
1667
-
1668
- _handleShiftScroll: function(e) {
1669
- if (e.shiftKey) {
1670
- e.preventDefault();
1671
- this._map.scrollWheelZoom.disable();
1672
- this._map.setBearing((this._map._bearing * L.DomUtil.RAD_TO_DEG) + Math.sign(e.deltaY) * 5);
1673
- } else {
1674
- this._map.scrollWheelZoom.enable();
1675
- }
1676
- },
1677
-
1678
- });
1679
-
1680
- /**
1681
- * Add ShiftKey handler to L.Map (enabled unless `shiftKeyRotate` is unset).
1682
- *
1683
- * @property {L.Map.ShiftKeyRotate} shiftKeyRotate
1684
- */
1685
- L.Map.addInitHook('addHandler', 'shiftKeyRotate', L.Map.ShiftKeyRotate);
1686
-
1687
- // decrease `scrollWheelZoom` handler priority over `shiftKeyRotate` handler
1688
- L.Map.addInitHook(function() {
1689
- if (this.scrollWheelZoom.enabled() && this.shiftKeyRotate.enabled()) {
1690
- this.scrollWheelZoom.disable();
1691
- this.scrollWheelZoom.enable();
1692
- }
1693
- });
1694
-
1695
- /**
1696
- * Adds pinch zoom rotation on mobile browsers
1697
- *
1698
- * @see https://github.com/Leaflet/Leaflet/blob/v1.9.3/src/map/handler/Map.TouchZoom.js
1699
- *
1700
- * @external L.Map.TouchZoom
1701
- */
1702
-
1703
- L.Map.mergeOptions({
1704
-
1705
- /**
1706
- * Whether the map can be zoomed by touch-dragging
1707
- * with two fingers. If passed `'center'`, it will
1708
- * zoom to the center of the view regardless of
1709
- * where the touch events (fingers) were. Enabled
1710
- * for touch-capable web browsers.
1711
- *
1712
- * @type {(Boolean|String)}
1713
- */
1714
- touchZoom: L.Browser.touch,
1715
-
1716
- /**
1717
- * @TODO check if this is a duplicate of `L.Map.TouchGestures::bounceAtZoomLimits`
1718
- *
1719
- * Set it to false if you don't want the map to
1720
- * zoom beyond min/max zoom and then bounce back
1721
- * when pinch-zooming.
1722
- *
1723
- * @type {Boolean}
1724
- */
1725
- bounceAtZoomLimits: false,
1726
-
1727
- });
1728
-
1729
- L.Map.TouchZoom = L.Handler.extend({
1730
-
1731
- addHooks: function() {
1732
- L.DomUtil.addClass(this._map._container, 'leaflet-touch-zoom');
1733
- this._map.touchGestures.enable();
1734
- this._map.touchGestures.zoom = true;
1735
- },
1736
-
1737
- removeHooks: function() {
1738
- L.DomUtil.removeClass(this._map._container, 'leaflet-touch-zoom');
1739
- this._map.touchGestures.zoom = false;
1740
- },
1741
-
1742
- });
1743
-
1744
- /**
1745
- * Add Touch Zoom handler (disabled unless `L.Browser.touch` is set).
1746
- *
1747
- * @property {L.Map.TouchGestures} touchGestures
1748
- */
1749
- L.Map.addInitHook('addHandler', 'touchZoom', L.Map.TouchZoom);
1750
-
1751
- /**
1752
- * A tri-state control for map rotation, states are:
1753
- *
1754
- * - Locked (default)
1755
- * - Unlocked (user can pinch-rotate)
1756
- * - Follow (rotation follows device orientation, if available)
1757
- *
1758
- * @typedef L.Control.Rotate
1759
- */
1760
-
1761
- L.Control.Rotate = L.Control.extend({
1762
-
1763
- options: {
1764
- position: 'topleft',
1765
- closeOnZeroBearing: true
1766
- },
1767
-
1768
- onAdd: function(map) {
1769
- var container = this._container = L.DomUtil.create('div', 'leaflet-control-rotate leaflet-bar');
1770
-
1771
- // this.button = L.Control.Zoom.prototype._createButton.call(this, 'R', 'leaflet-control-rotate', 'leaflet-control-rotate', container, this._toggleLock);
1772
-
1773
- var arrow = this._arrow = L.DomUtil.create('span', 'leaflet-control-rotate-arrow');
1774
-
1775
- arrow.style.backgroundImage = `url("data:image/svg+xml;charset=utf-8,%3Csvg width='29' height='29' viewBox='0 0 29 29' xmlns='http://www.w3.org/2000/svg' fill='%23333'%3E%3Cpath d='M10.5 14l4-8 4 8h-8z'/%3E%3Cpath d='M10.5 16l4 8 4-8h-8z' fill='%23ccc'/%3E%3C/svg%3E")`;
1776
- arrow.style.cursor = 'grab';
1777
- arrow.style.display = 'block';
1778
- arrow.style.width = '100%';
1779
- arrow.style.height = '100%';
1780
- arrow.style.backgroundRepeat = 'no-repeat';
1781
- arrow.style.backgroundPosition = '50%';
1782
-
1783
- // Copy-pasted from L.Control.Zoom
1784
- var link = this._link = L.DomUtil.create('a', 'leaflet-control-rotate-toggle', container);
1785
- link.appendChild(arrow);
1786
- link.href = '#';
1787
- link.title = 'Rotate map';
1788
-
1789
- L.DomEvent
1790
- .on(link, 'dblclick', L.DomEvent.stopPropagation)
1791
- .on(link, 'mousedown', this._handleMouseDown, this)
1792
- .on(link, 'click', L.DomEvent.stop)
1793
- .on(link, 'click', this._cycleState, this)
1794
- .on(link, 'click', this._refocusOnMap, this);
1795
-
1796
- if (!L.Browser.any3d) {
1797
- L.DomUtil.addClass(link, 'leaflet-disabled');
1798
- }
1799
-
1800
- this._restyle();
1801
-
1802
- map.on('rotate', this._restyle, this);
1803
-
1804
- // State flag
1805
- this._follow = false;
1806
- this._canFollow = false;
1807
-
1808
- if (this.options.closeOnZeroBearing && map.getBearing() === 0) {
1809
- container.style.display = 'none';
1810
- }
1811
-
1812
- return container;
1813
- },
1814
-
1815
- onRemove: function(map) {
1816
- map.off('rotate', this._restyle, this);
1817
- },
1818
-
1819
- _handleMouseDown: function(e) {
1820
- L.DomEvent.stop(e);
1821
- this.dragging = true;
1822
- this.dragstartX = e.pageX;
1823
- this.dragstartY = e.pageY;
1824
- L.DomEvent
1825
- .on(document, 'mousemove', this._handleMouseDrag, this)
1826
- .on(document, 'mouseup', this._handleMouseUp, this);
1827
- },
1828
-
1829
- _handleMouseUp: function(e) {
1830
- L.DomEvent.stop(e);
1831
- this.dragging = false;
1832
-
1833
- L.DomEvent
1834
- .off(document, 'mousemove', this._handleMouseDrag, this)
1835
- .off(document, 'mouseup', this._handleMouseUp, this);
1836
- },
1837
-
1838
- _handleMouseDrag: function(e) {
1839
- if (!this.dragging) { return; }
1840
- var deltaX = e.clientX - this.dragstartX;
1841
- this._map.setBearing(deltaX);
1842
- },
1843
-
1844
- _cycleState: function(ev) {
1845
- if (!this._map) {
1846
- return;
1847
- }
1848
-
1849
- var map = this._map;
1850
-
1851
- // Touch mode
1852
- if (!map.touchRotate.enabled() && !map.compassBearing.enabled()) {
1853
- map.touchRotate.enable();
1854
- }
1855
-
1856
- // Compass mode
1857
- else if (!map.compassBearing.enabled()) {
1858
- map.touchRotate.disable();
1859
- map.compassBearing.enable();
1860
- }
1861
-
1862
- // Locked mode
1863
- else {
1864
- map.compassBearing.disable();
1865
- map.setBearing(0);
1866
- if (this.options.closeOnZeroBearing) {
1867
- map.touchRotate.enable();
1868
- }
1869
- }
1870
- this._restyle();
1871
- },
1872
-
1873
- _restyle: function() {
1874
- if (!this._map.options.rotate) {
1875
- L.DomUtil.addClass(this._link, 'leaflet-disabled');
1876
- } else {
1877
- var map = this._map;
1878
- var bearing = map.getBearing();
1879
-
1880
- this._arrow.style.transform = 'rotate(' + bearing + 'deg)';
1881
-
1882
- if (bearing && this.options.closeOnZeroBearing) {
1883
- this._container.style.display = 'block';
1884
- }
1885
-
1886
- // Compass mode
1887
- if (map.compassBearing.enabled()) {
1888
- this._link.style.backgroundColor = 'orange';
1889
- }
1890
-
1891
- // Touch mode
1892
- else if (map.touchRotate.enabled()) {
1893
- this._link.style.backgroundColor = null;
1894
- }
1895
-
1896
- // Locked mode
1897
- else {
1898
- this._link.style.backgroundColor = 'grey';
1899
- if (0 === bearing && this.options.closeOnZeroBearing) {
1900
- this._container.style.display = 'none';
1901
- }
1902
- }
1903
- }
1904
- },
1905
-
1906
- });
1907
-
1908
- L.control.rotate = function(options) {
1909
- return new L.Control.Rotate(options);
1910
- };
1911
-
1912
- L.Map.mergeOptions({
1913
- rotateControl: true,
1914
- });
1915
-
1916
- L.Map.addInitHook(function() {
1917
- if (this.options.rotateControl) {
1918
- var options = typeof this.options.rotateControl === 'object' ? this.options.rotateControl : {};
1919
- this.rotateControl = L.control.rotate(options);
1920
- this.addControl(this.rotateControl);
1921
- }
1922
- });
1923
-
1924
- }));
1
+ !function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict";const t=L.extend({},L.DomUtil);L.extend(L.DomUtil,{setTransform:function(o,e,i,n,a){var s=e||new L.Point(0,0);if(!n)return e=s._round(),t.setTransform.apply(this,arguments);s=s.rotateFrom(n,a),o.style[L.DomUtil.TRANSFORM]="translate3d("+s.x+"px,"+s.y+"px,0)"+(i?" scale("+i+")":"")+" rotate("+n+"rad)"},setPosition:function(o,e,i,n,a){if(!i)return t.setPosition.apply(this,arguments);o._leaflet_pos=e,L.Browser.any3d?L.DomUtil.setTransform(o,e,a,i,n):(o.style.left=e.x+"px",o.style.top=e.y+"px")},DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI}),L.Draggable.include({}),L.extend(L.Point.prototype,{rotate:function(t){return this.rotateFrom(t,new L.Point(0,0))},rotateFrom:function(t,o){if(!t)return this;var e=Math.sin(t),i=Math.cos(t),n=o.x,a=o.y,s=this.x-n,r=this.y-a;return new L.Point(s*i-r*e+n,s*e+r*i+a)}});const o=L.extend({},L.DivOverlay.prototype);L.DivOverlay.include({getEvents:function(){return L.extend(o.getEvents.apply(this,arguments),{rotate:this._updatePosition})},_updatePosition:function(){if(this._map&&(o._updatePosition.apply(this,arguments),this._map&&this._map._rotate&&this._zoomAnimated)){var t=this._getAnchor(),e=L.DomUtil.getPosition(this._container).subtract(t);L.DomUtil.setPosition(this._container,this._map.rotatedPointToMapPanePoint(e).add(t))}}});const e=L.extend({},L.Popup.prototype);L.Popup.include({_animateZoom:function(t){if(e._animateZoom.apply(this,arguments),this._map&&this._map._rotate){var o=this._getAnchor(),i=L.DomUtil.getPosition(this._container).subtract(o);L.DomUtil.setPosition(this._container,this._map.rotatedPointToMapPanePoint(i).add(o))}},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress))if(this._autopanning)this._autopanning=!1;else{var t=this._map,o=parseInt(L.DomUtil.getStyle(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+o,i=this._containerWidth,n=new L.Point(this._containerLeft,-e-this._containerBottom);n._add(L.DomUtil.getPosition(this._container));var a=n._add(this._map._getMapPanePos()),s=L.point(this.options.autoPanPadding),r=L.point(this.options.autoPanPaddingTopLeft||s),h=L.point(this.options.autoPanPaddingBottomRight||s),_=t.getSize(),d=0,l=0;a.x+i+h.x>_.x&&(d=a.x+i-_.x+h.x),a.x-d-r.x<0&&(d=a.x-r.x),a.y+e+h.y>_.y&&(l=a.y+e-_.y+h.y),a.y-l-r.y<0&&(l=a.y-r.y),(d||l)&&(this.options.keepInView&&(this._autopanning=!0),t.fire("autopanstart").panBy([d,l]))}}});const i=L.extend({},L.Tooltip.prototype);L.Tooltip.include({_animateZoom:function(t){if(!this._map._rotate)return i._animateZoom.apply(this,arguments);var o=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);o=this._map.rotatedPointToMapPanePoint(o),this._setPosition(o)},_updatePosition:function(){if(!this._map._rotate)return i._updatePosition.apply(this,arguments);var t=this._map.latLngToLayerPoint(this._latlng);t=this._map.rotatedPointToMapPanePoint(t),this._setPosition(t)}}),L.extend({},L.Icon.prototype),L.Icon.include({_setIconStyles:function(t,o){var e=this.options,i=e[o+"Size"];"number"==typeof i&&(i=[i,i]);var n=L.point(i),a=L.point("shadow"===o&&e.shadowAnchor||e.iconAnchor||n&&n.divideBy(2,!0));t.className="leaflet-marker-"+o+" "+(e.className||""),a&&(t.style.marginLeft=-a.x+"px",t.style.marginTop=-a.y+"px",t.style[L.DomUtil.TRANSFORM+"Origin"]=a.x+"px "+a.y+"px 0px"),n&&(t.style.width=n.x+"px",t.style.height=n.y+"px")}});const n=L.extend({},L.Marker.prototype);var a;L.Marker.mergeOptions({rotation:0,rotateWithView:!1,scale:void 0});var s={_onDrag:function(t){var o=this._marker,e=o.options.rotation||o.options.rotateWithView,i=o._shadow,n=L.DomUtil.getPosition(o._icon);!e&&i&&L.DomUtil.setPosition(i,n),o._map._rotate&&(n=o._map.mapPanePointToRotatedPoint(n));var a=o._map.layerPointToLatLng(n);o._latlng=a,t.latlng=a,t.oldLatLng=this._oldLatLng,e?o.setLatLng(a):o.fire("move",t),o.fire("drag",t)},_onDragEnd:function(t){this._marker._map._rotate&&this._marker.update(),a._onDragEnd.apply(this,arguments)}};L.Marker.include({getEvents:function(){return L.extend(n.getEvents.apply(this,arguments),{rotate:this.update})},_initInteraction:function(){var t=n._initInteraction.apply(this,arguments);return this.dragging&&this.dragging.enabled()&&this._map&&this._map._rotate&&(a=a||Object.getPrototypeOf(this.dragging),Object.assign(this.dragging,{_onDrag:s._onDrag.bind(this.dragging),_onDragEnd:s._onDragEnd.bind(this.dragging)}),this.dragging.disable(),this.dragging.enable()),t},_setPos:function(t){this._map._rotate&&(t=this._map.rotatedPointToMapPanePoint(t));var o=this.options.rotation||0;this.options.rotateWithView&&(o+=this._map._bearing),this._icon&&L.DomUtil.setPosition(this._icon,t,o,t,this.options.scale),this._shadow&&L.DomUtil.setPosition(this._shadow,t,o,t,this.options.scale),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},setRotation:function(t){this.options.rotation=t,this.update()}});const r=L.extend({},L.GridLayer.prototype);L.GridLayer.include({getEvents:function(){var t=r.getEvents.apply(this,arguments);return this._map._rotate&&!this.options.updateWhenIdle&&(this._onRotate||(this._onRotate=L.Util.throttle(this._onMoveEnd,this.options.updateInterval,this)),t.rotate=this._onRotate),t},_getTiledPixelBounds:function(t){return this._map._rotate?this._map._getNewPixelBounds(t,this._tileZoom):r._getTiledPixelBounds.apply(this,arguments)}});const h=L.extend({},L.Renderer.prototype);L.Renderer.include({getEvents:function(){return L.extend(h.getEvents.apply(this,arguments),{rotate:this._update})},onAdd:function(){h.onAdd.apply(this,arguments),L.version<="1.9.3"&&this._container.classList.add("leaflet-zoom-animated")},_updateTransform:function(t,o){if(!this._map._rotate)return h._updateTransform.apply(this,arguments);var e=this._map.getZoomScale(o,this._zoom),i=this._map._latLngToNewLayerPoint(this._topLeft,o,t);L.DomUtil.setTransform(this._container,i,e)},_update:function(){if(!this._map._rotate)return h._update.apply(this,arguments);this._bounds=this._map._getPaddedPixelBounds(this.options.padding),this._topLeft=this._map.layerPointToLatLng(this._bounds.min),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}});const _=L.extend({},L.Map.prototype);L.Map.mergeOptions({rotate:!1,bearing:0}),L.Map.include({initialize:function(t,o){o.rotate&&(this._rotate=!0,this._bearing=0),_.initialize.apply(this,arguments),this.options.rotate&&this.setBearing(this.options.bearing)},containerPointToLayerPoint:function(t){return this._rotate?L.point(t).subtract(this._getMapPanePos()).rotateFrom(-this._bearing,this._getRotatePanePos()).subtract(this._getRotatePanePos()):_.containerPointToLayerPoint.apply(this,arguments)},layerPointToContainerPoint:function(t){return this._rotate?L.point(t).add(this._getRotatePanePos()).rotateFrom(this._bearing,this._getRotatePanePos()).add(this._getMapPanePos()):_.layerPointToContainerPoint.apply(this,arguments)},rotatedPointToMapPanePoint:function(t){return L.point(t).rotate(this._bearing)._add(this._getRotatePanePos())},mapPanePointToRotatedPoint:function(t){return L.point(t)._subtract(this._getRotatePanePos()).rotate(-this._bearing)},mapBoundsToContainerBounds:function(t){if(!this._rotate&&_.mapBoundsToContainerBounds)return _.mapBoundsToContainerBounds.apply(this,arguments);const o=this.getPixelOrigin(),e=this.layerPointToContainerPoint(this.project(t.getNorthWest())._subtract(o)),i=this.layerPointToContainerPoint(this.project(t.getNorthEast())._subtract(o)),n=this.layerPointToContainerPoint(this.project(t.getSouthWest())._subtract(o)),a=this.layerPointToContainerPoint(this.project(t.getSouthEast())._subtract(o));return L.bounds([L.point(Math.min(e.x,i.x,a.x,n.x),Math.min(e.y,i.y,a.y,n.y)),L.point(Math.max(e.x,i.x,a.x,n.x),Math.max(e.y,i.y,a.y,n.y))])},getBounds:function(){if(!this._rotate)return _.getBounds.apply(this,arguments);var t=this.getSize();return new L.LatLngBounds([this.containerPointToLatLng([0,0]),this.containerPointToLatLng([t.x,0]),this.containerPointToLatLng([t.x,t.y]),this.containerPointToLatLng([0,t.y])])},setBearing:function(t){if(L.Browser.any3d&&this._rotate){var o=L.Util.wrapNum(t,[0,360])*L.DomUtil.DEG_TO_RAD,e=this._getPixelCenter(),i=this._getRotatePanePos().rotateFrom(-this._bearing,e),n=i.rotateFrom(o,e);L.DomUtil.setPosition(this._rotatePane,i,o,e),this._pivot=e,this._bearing=o,this._rotatePanePos=n,this.fire("rotate")}},getBearing:function(){return this._bearing*L.DomUtil.RAD_TO_DEG},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),L.DomUtil.setPosition(this._mapPane,new L.Point(0,0)),this._rotate?(this._rotatePane=this.createPane("rotatePane",this._mapPane),this._norotatePane=this.createPane("norotatePane",this._mapPane),this.createPane("tilePane",this._rotatePane),this.createPane("overlayPane",this._rotatePane),this.createPane("shadowPane",this._norotatePane),this.createPane("markerPane",this._norotatePane),this.createPane("tooltipPane",this._norotatePane),this.createPane("popupPane",this._norotatePane)):(this.createPane("tilePane"),this.createPane("overlayPane"),this.createPane("shadowPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane")),this.options.markerZoomAnimation||(L.DomUtil.addClass(t.markerPane,"leaflet-zoom-hide"),L.DomUtil.addClass(t.shadowPane,"leaflet-zoom-hide"))},panInside(t,o){o=o||{};const e=L.point(o.paddingTopLeft||o.padding||[0,0]),i=L.point(o.paddingBottomRight||o.padding||[0,0]),n=this._container.getBoundingClientRect(),a=this.latLngToContainerPoint(t),s=L.bounds([L.point(n),L.point(n).add(this.getSize())]),r=s.getCenter(),h=L.bounds([s.min.add(e),s.max.subtract(i)]),_=h.getSize();if(!h.contains(a)){this._enforcingBounds=!0;const t=a.subtract(h.getCenter()),e=h.extend(a).getSize().subtract(_);r.x+=t.x<0?-e.x:e.x,r.y+=t.y<0?-e.y:e.y,this.panTo(this.containerPointToLatLng(r),o),this._enforcingBounds=!1}return this},getBoundsZoom(t,o,e){if(!this._rotate||Math.abs(this._bearing).toFixed(1)<.1)return _.getBoundsZoom.apply(this,arguments);t=L.latLngBounds(t),e=L.point(e||[0,0]);let i=this.getZoom()||0;const n=this.getMinZoom(),a=this.getMaxZoom(),s=this.getSize().subtract(e),r=this.mapBoundsToContainerBounds(t).getSize(),h=this.options.zoomSnap,d=s.x/r.x,l=s.y/r.y,p=o?Math.max(d,l):Math.min(d,l);return i=this.getScaleZoom(p,i),h&&(i=Math.round(i/(h/100))*(h/100),i=o?Math.ceil(i/h)*h:Math.floor(i/h)*h),Math.max(n,Math.min(a,i))},_getCenterOffset:function(t){var o=_._getCenterOffset.apply(this,arguments);return this._rotate&&(o=o.rotate(this._bearing)),o},_getRotatePanePos:function(){return this._rotatePanePos||new L.Point(0,0)},_getNewPixelOrigin:function(t,o){if(!this._rotate)return _._getNewPixelOrigin.apply(this,arguments);var e=this.getSize()._divideBy(2);return this.project(t,o).rotate(this._bearing)._subtract(e)._add(this._getMapPanePos())._add(this._getRotatePanePos()).rotate(-this._bearing)._round()},_getNewPixelBounds:function(t,o){if(t=t||this.getCenter(),o=o||this.getZoom(),!this._rotate&&_._getNewPixelBounds)return _._getNewPixelBounds.apply(this,arguments);var e=this._animatingZoom?Math.max(this._animateToZoom,this.getZoom()):this.getZoom(),i=this.getZoomScale(e,o),n=this.project(t,o).floor(),a=this.getSize(),s=new L.Bounds([this.containerPointToLayerPoint([0,0]).floor(),this.containerPointToLayerPoint([a.x,0]).floor(),this.containerPointToLayerPoint([0,a.y]).floor(),this.containerPointToLayerPoint([a.x,a.y]).floor()]).getSize().divideBy(2*i);return new L.Bounds(n.subtract(s),n.add(s))},_getPixelCenter:function(){return!this._rotate&&_._getPixelCenter?_._getPixelCenter.apply(this,arguments):this.getSize()._divideBy(2)._subtract(this._getMapPanePos())},_getPaddedPixelBounds:function(t){if(!this._rotate&&_._getPaddedPixelBounds)return _._getPaddedPixelBounds.apply(this,arguments);var o=t,e=this.getSize(),i=e.multiplyBy(-o),n=e.multiplyBy(1+o);return new L.Bounds([this.containerPointToLayerPoint([i.x,i.y]).floor(),this.containerPointToLayerPoint([i.x,n.y]).floor(),this.containerPointToLayerPoint([n.x,i.y]).floor(),this.containerPointToLayerPoint([n.x,n.y]).floor()])},_handleGeolocationResponse:function(t){if(this._container._leaflet_id){var o=t.coords.latitude,e=t.coords.longitude,i=t.coords.heading,n=new L.LatLng(o,e),a=n.toBounds(t.coords.accuracy),s=this._locateOptions;if(s.setView){var r=this.getBoundsZoom(a);this.setView(n,s.maxZoom?Math.min(r,s.maxZoom):r)}var h={latlng:n,bounds:a,timestamp:t.timestamp,heading:i};for(var _ in t.coords)"number"==typeof t.coords[_]&&(h[_]=t.coords[_]);this.fire("locationfound",h)}}}),L.Map.CompassBearing=L.Handler.extend({initialize:function(t){this._map=t,"ondeviceorientationabsolute"in window?this.__deviceOrientationEvent="deviceorientationabsolute":"ondeviceorientation"in window&&(this.__deviceOrientationEvent="deviceorientation"),this._throttled=L.Util.throttle(this._onDeviceOrientation,100,this)},addHooks:function(){this._map._rotate&&this.__deviceOrientationEvent?L.DomEvent.on(window,this.__deviceOrientationEvent,this._throttled,this):this.disable()},removeHooks:function(){this._map._rotate&&this.__deviceOrientationEvent&&L.DomEvent.off(window,this.__deviceOrientationEvent,this._throttled,this)},_onDeviceOrientation:function(t){var o=t.webkitCompassHeading||t.alpha,e=0;!t.absolute&&t.webkitCompassHeading&&(o=360-o),t.absolute||void 0===window.orientation||(e=window.orientation),this._map.setBearing(o-e)}}),L.Map.addInitHook("addHandler","compassBearing",L.Map.CompassBearing),L.Map.mergeOptions({trackContainerMutation:!1}),L.Map.ContainerMutation=L.Handler.extend({addHooks:function(){this._observer||(this._observer=new MutationObserver(L.Util.bind(this._map.invalidateSize,this._map))),this._observer.observe(this._map.getContainer(),{childList:!1,attributes:!0,characterData:!1,subtree:!1,attributeFilter:["style"]})},removeHooks:function(){this._observer.disconnect()}}),L.Map.addInitHook("addHandler","trackContainerMutation",L.Map.ContainerMutation),L.Map.mergeOptions({bounceAtZoomLimits:!0}),L.Map.TouchGestures=L.Handler.extend({initialize:function(t){this._map=t,this.rotate=!!this._map.options.touchRotate,this.zoom=!!this._map.options.touchZoom},addHooks:function(){L.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){L.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var o=this._map;if(t.touches&&2===t.touches.length&&!o._animatingZoom&&!this._zooming&&!this._rotating){var e=o.mouseEventToContainerPoint(t.touches[0]),i=o.mouseEventToContainerPoint(t.touches[1]),n=e.subtract(i);this._centerPoint=o.getSize()._divideBy(2),this._startLatLng=o.containerPointToLatLng(this._centerPoint),this.zoom?("center"!==o.options.touchZoom&&(this._pinchStartLatLng=o.containerPointToLatLng(e.add(i)._divideBy(2))),this._startDist=e.distanceTo(i),this._startZoom=o.getZoom(),this._zooming=!0):this._zooming=!1,this.rotate?(this._startTheta=Math.atan(n.x/n.y),this._startBearing=o.getBearing(),n.y<0&&(this._startBearing+=180),this._rotating=!0):this._rotating=!1,this._moved=!1,o._stop(),L.DomEvent.on(document,"touchmove",this._onTouchMove,this).on(document,"touchend touchcancel",this._onTouchEnd,this),L.DomEvent.preventDefault(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&(this._zooming||this._rotating)){var o,e=this._map,i=e.mouseEventToContainerPoint(t.touches[0]),n=e.mouseEventToContainerPoint(t.touches[1]),a=i.subtract(n),s=i.distanceTo(n)/this._startDist;if(this._rotating){var r=(Math.atan(a.x/a.y)-this._startTheta)*L.DomUtil.RAD_TO_DEG;a.y<0&&(r+=180),r&&e.setBearing(this._startBearing-r)}if(this._zooming)if(this._zoom=e.getScaleZoom(s,this._startZoom),!e.options.bounceAtZoomLimits&&(this._zoom<e.getMinZoom()&&s<1||this._zoom>e.getMaxZoom()&&s>1)&&(this._zoom=e._limitZoom(this._zoom)),"center"===e.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{if(o=i._add(n)._divideBy(2)._subtract(this._centerPoint),1===s&&0===o.x&&0===o.y)return;var h=-e.getBearing()*L.DomUtil.DEG_TO_RAD;this._center=e.unproject(e.project(this._pinchStartLatLng).subtract(o.rotate(h)))}this._moved||(e._moveStart(!0,!1),this._moved=!0),L.Util.cancelAnimFrame(this._animRequest);var _=e._move.bind(e,this._center,this._zoom,{pinch:!0,round:!1},void 0);this._animRequest=L.Util.requestAnimFrame(_,this,!0),L.DomEvent.preventDefault(t)}},_onTouchEnd:function(){this._moved&&(this._zooming||this._rotating)?(this._zooming=!1,this._rotating=!1,L.Util.cancelAnimFrame(this._animRequest),L.DomEvent.off(document,"touchmove",this._onTouchMove,this).off(document,"touchend touchcancel",this._onTouchEnd,this),this.zoom&&(this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom)))):this._zooming=!1}}),L.Map.addInitHook("addHandler","touchGestures",L.Map.TouchGestures),L.Map.mergeOptions({touchRotate:!1}),L.Map.TouchRotate=L.Handler.extend({addHooks:function(){this._map.touchGestures.enable(),this._map.touchGestures.rotate=!0},removeHooks:function(){this._map.touchGestures.rotate=!1}}),L.Map.addInitHook("addHandler","touchRotate",L.Map.TouchRotate),L.Map.mergeOptions({shiftKeyRotate:!0}),L.Map.ShiftKeyRotate=L.Handler.extend({addHooks:function(){L.DomEvent.on(this._map._container,"wheel",this._handleShiftScroll,this),this._map.shiftKeyRotate.rotate=!0},removeHooks:function(){L.DomEvent.off(this._map._container,"wheel",this._handleShiftScroll,this),this._map.shiftKeyRotate.rotate=!1},_handleShiftScroll:function(t){t.shiftKey?(t.preventDefault(),this._map.scrollWheelZoom.disable(),this._map.setBearing(this._map._bearing*L.DomUtil.RAD_TO_DEG+5*Math.sign(t.deltaY))):this._map.scrollWheelZoom.enable()}}),L.Map.addInitHook("addHandler","shiftKeyRotate",L.Map.ShiftKeyRotate),L.Map.addInitHook((function(){this.scrollWheelZoom.enabled()&&this.shiftKeyRotate.enabled()&&(this.scrollWheelZoom.disable(),this.scrollWheelZoom.enable())})),L.Map.mergeOptions({touchZoom:L.Browser.touch,bounceAtZoomLimits:!1}),L.Map.TouchZoom=L.Handler.extend({addHooks:function(){L.DomUtil.addClass(this._map._container,"leaflet-touch-zoom"),this._map.touchGestures.enable(),this._map.touchGestures.zoom=!0},removeHooks:function(){L.DomUtil.removeClass(this._map._container,"leaflet-touch-zoom"),this._map.touchGestures.zoom=!1}}),L.Map.addInitHook("addHandler","touchZoom",L.Map.TouchZoom),L.Control.Rotate=L.Control.extend({options:{position:"topleft",closeOnZeroBearing:!0},onAdd:function(t){var o=this._container=L.DomUtil.create("div","leaflet-control-rotate leaflet-bar"),e=this._arrow=L.DomUtil.create("span","leaflet-control-rotate-arrow");e.style.backgroundImage="url(\"data:image/svg+xml;charset=utf-8,%3Csvg width='29' height='29' viewBox='0 0 29 29' xmlns='http://www.w3.org/2000/svg' fill='%23333'%3E%3Cpath d='M10.5 14l4-8 4 8h-8z'/%3E%3Cpath d='M10.5 16l4 8 4-8h-8z' fill='%23ccc'/%3E%3C/svg%3E\")",e.style.cursor="grab",e.style.display="block",e.style.width="100%",e.style.height="100%",e.style.backgroundRepeat="no-repeat",e.style.backgroundPosition="50%";var i=this._link=L.DomUtil.create("a","leaflet-control-rotate-toggle",o);return i.appendChild(e),i.href="#",i.title="Rotate map",L.DomEvent.on(i,"dblclick",L.DomEvent.stopPropagation).on(i,"mousedown",this._handleMouseDown,this).on(i,"click",L.DomEvent.stop).on(i,"click",this._cycleState,this).on(i,"click",this._refocusOnMap,this),L.Browser.any3d||L.DomUtil.addClass(i,"leaflet-disabled"),this._restyle(),t.on("rotate",this._restyle,this),this._follow=!1,this._canFollow=!1,this.options.closeOnZeroBearing&&0===t.getBearing()&&(o.style.display="none"),o},onRemove:function(t){t.off("rotate",this._restyle,this)},_handleMouseDown:function(t){L.DomEvent.stop(t),this.dragging=!0,this.dragstartX=t.pageX,this.dragstartY=t.pageY,L.DomEvent.on(document,"mousemove",this._handleMouseDrag,this).on(document,"mouseup",this._handleMouseUp,this)},_handleMouseUp:function(t){L.DomEvent.stop(t),this.dragging=!1,L.DomEvent.off(document,"mousemove",this._handleMouseDrag,this).off(document,"mouseup",this._handleMouseUp,this)},_handleMouseDrag:function(t){if(this.dragging){var o=t.clientX-this.dragstartX;this._map.setBearing(o)}},_cycleState:function(t){if(this._map){var o=this._map;o.touchRotate.enabled()||o.compassBearing.enabled()?o.compassBearing.enabled()?(o.compassBearing.disable(),o.setBearing(0),this.options.closeOnZeroBearing&&o.touchRotate.enable()):(o.touchRotate.disable(),o.compassBearing.enable()):o.touchRotate.enable(),this._restyle()}},_restyle:function(){if(this._map.options.rotate){var t=this._map,o=t.getBearing();this._arrow.style.transform="rotate("+o+"deg)",o&&this.options.closeOnZeroBearing&&(this._container.style.display="block"),t.compassBearing.enabled()?this._link.style.backgroundColor="orange":t.touchRotate.enabled()?this._link.style.backgroundColor=null:(this._link.style.backgroundColor="grey",0===o&&this.options.closeOnZeroBearing&&(this._container.style.display="none"))}else L.DomUtil.addClass(this._link,"leaflet-disabled")}}),L.control.rotate=function(t){return new L.Control.Rotate(t)},L.Map.mergeOptions({rotateControl:!0}),L.Map.addInitHook((function(){if(this.options.rotateControl){var t="object"==typeof this.options.rotateControl?this.options.rotateControl:{};this.rotateControl=L.control.rotate(t),this.addControl(this.rotateControl)}}))}));
1925
2
  //# sourceMappingURL=leaflet-rotate.js.map