leaflet-rotate 0.2.8 → 0.4.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/.github/workflows/ci.yml +21 -0
- package/README.md +6 -2
- package/build/build.js +69 -0
- package/build/dev.js +24 -0
- package/build/server.js +104 -0
- package/build/test.js +18 -0
- package/cucumber.mjs +5 -0
- package/dist/leaflet-rotate-src.js +1425 -1853
- package/dist/leaflet-rotate-src.js.map +7 -1
- package/dist/leaflet-rotate.js +1 -1
- package/dist/leaflet-rotate.js.map +7 -1
- package/lib/debug.js +98 -69
- package/lib/debug.min.js +1 -1
- package/misc/leaflet-heat-rotate.js +96 -0
- package/misc/loremIpsum.js +1 -1
- package/misc/places.js +1 -1
- package/misc/route.js +1 -1
- package/package.json +10 -17
- package/src/control/Rotate.js +25 -25
- package/src/dom/DomUtil.js +31 -47
- package/src/dom/Draggable.js +1 -1
- package/src/geometry/Point.js +16 -7
- package/src/layer/DivOverlay.js +21 -7
- package/src/layer/Popup.js +15 -13
- package/src/layer/Tooltip.js +5 -5
- package/src/layer/marker/Icon.js +8 -8
- package/src/layer/marker/Marker.js +32 -18
- package/src/layer/tile/GridLayer.js +4 -4
- package/src/layer/vector/Renderer.js +51 -7
- package/src/map/Map.js +121 -57
- package/src/map/handler/CompassBearing.js +10 -8
- package/src/map/handler/ContainerMutation.js +2 -2
- package/src/map/handler/ShiftKeyRotate.js +4 -4
- package/src/map/handler/TouchGestures.js +36 -22
- package/src/map/handler/TouchRotate.js +2 -2
- package/src/map/handler/TouchZoom.js +4 -4
- package/test/features/example.feature +92 -0
- package/test/features/gestures.feature +33 -0
- package/test/features/overlays.feature +58 -0
- package/test/features/rotation.feature +36 -0
- package/test/index.html +59 -22
- package/test/steps/bearing.steps.js +235 -0
- package/test/steps/example.steps.js +424 -0
- package/test/steps/gestures.steps.js +145 -0
- package/test/steps/overlays.steps.js +427 -0
- package/test/support/hooks.js +92 -0
- package/build/rollup.config.js +0 -34
- package/test/setup/http_server.js +0 -104
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
* @typedef L.Map.TouchGestures
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
function touchToContainerPoint(map, touch) {
|
|
11
|
+
const container = map.getContainer(),
|
|
12
|
+
rect = container.getBoundingClientRect();
|
|
13
|
+
|
|
14
|
+
return new L.Point(
|
|
15
|
+
touch.clientX - rect.left - container.clientLeft,
|
|
16
|
+
touch.clientY - rect.top - container.clientTop,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
L.Map.mergeOptions({
|
|
11
21
|
|
|
12
22
|
/**
|
|
@@ -22,27 +32,27 @@ L.Map.mergeOptions({
|
|
|
22
32
|
|
|
23
33
|
L.Map.TouchGestures = L.Handler.extend({
|
|
24
34
|
|
|
25
|
-
initialize
|
|
35
|
+
initialize(map) {
|
|
26
36
|
this._map = map;
|
|
27
37
|
this.rotate = !!this._map.options.touchRotate;
|
|
28
38
|
this.zoom = !!this._map.options.touchZoom;
|
|
29
39
|
},
|
|
30
40
|
|
|
31
|
-
addHooks
|
|
41
|
+
addHooks() {
|
|
32
42
|
L.DomEvent.on(this._map._container, 'touchstart', this._onTouchStart, this);
|
|
33
43
|
},
|
|
34
44
|
|
|
35
|
-
removeHooks
|
|
45
|
+
removeHooks() {
|
|
36
46
|
L.DomEvent.off(this._map._container, 'touchstart', this._onTouchStart, this);
|
|
37
47
|
},
|
|
38
48
|
|
|
39
|
-
_onTouchStart
|
|
40
|
-
|
|
49
|
+
_onTouchStart(e) {
|
|
50
|
+
const map = this._map;
|
|
41
51
|
|
|
42
52
|
if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming || this._rotating) { return; }
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
p2 = map
|
|
54
|
+
const p1 = touchToContainerPoint(map, e.touches[0]),
|
|
55
|
+
p2 = touchToContainerPoint(map, e.touches[1]),
|
|
46
56
|
vector = p1.subtract(p2);
|
|
47
57
|
|
|
48
58
|
this._centerPoint = map.getSize()._divideBy(2);
|
|
@@ -79,19 +89,19 @@ L.Map.TouchGestures = L.Handler.extend({
|
|
|
79
89
|
L.DomEvent.preventDefault(e);
|
|
80
90
|
},
|
|
81
91
|
|
|
82
|
-
_onTouchMove
|
|
92
|
+
_onTouchMove(e) {
|
|
83
93
|
if (!e.touches || e.touches.length !== 2 || !(this._zooming || this._rotating)) { return; }
|
|
84
94
|
|
|
85
|
-
|
|
86
|
-
p1 = map
|
|
87
|
-
p2 = map
|
|
95
|
+
const map = this._map,
|
|
96
|
+
p1 = touchToContainerPoint(map, e.touches[0]),
|
|
97
|
+
p2 = touchToContainerPoint(map, e.touches[1]),
|
|
88
98
|
vector = p1.subtract(p2),
|
|
89
|
-
scale = p1.distanceTo(p2) / this._startDist
|
|
90
|
-
|
|
99
|
+
scale = p1.distanceTo(p2) / this._startDist;
|
|
100
|
+
let delta;
|
|
91
101
|
|
|
92
102
|
if (this._rotating) {
|
|
93
|
-
|
|
94
|
-
|
|
103
|
+
const theta = Math.atan(vector.x / vector.y);
|
|
104
|
+
let bearingDelta = (theta - this._startTheta) * (180 / Math.PI);
|
|
95
105
|
if (vector.y < 0) { bearingDelta += 180; }
|
|
96
106
|
if (bearingDelta) {
|
|
97
107
|
/**
|
|
@@ -123,7 +133,7 @@ L.Map.TouchGestures = L.Handler.extend({
|
|
|
123
133
|
delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
|
|
124
134
|
if (scale === 1 && delta.x === 0 && delta.y === 0) { return; }
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
const alpha = -map.getBearing() * (Math.PI / 180);
|
|
127
137
|
|
|
128
138
|
this._center = map.unproject(map.project(this._pinchStartLatLng).subtract(delta.rotate(alpha)));
|
|
129
139
|
}
|
|
@@ -135,15 +145,21 @@ L.Map.TouchGestures = L.Handler.extend({
|
|
|
135
145
|
this._moved = true;
|
|
136
146
|
}
|
|
137
147
|
|
|
138
|
-
|
|
148
|
+
const moveFn = map._move.bind(map, this._center, this._zoom, { pinch: true, round: false }, undefined);
|
|
149
|
+
moveFn();
|
|
139
150
|
|
|
140
|
-
|
|
141
|
-
|
|
151
|
+
if (this.zoom) {
|
|
152
|
+
if (map.options.zoomAnimation) {
|
|
153
|
+
map._animateZoomNoDelay(this._center, map._limitZoom(this._zoom));
|
|
154
|
+
} else {
|
|
155
|
+
map._resetView(this._center, map._limitZoom(this._zoom));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
142
158
|
|
|
143
159
|
L.DomEvent.preventDefault(e);
|
|
144
160
|
},
|
|
145
161
|
|
|
146
|
-
_onTouchEnd
|
|
162
|
+
_onTouchEnd() {
|
|
147
163
|
if (!this._moved || !(this._zooming || this._rotating)) {
|
|
148
164
|
this._zooming = false;
|
|
149
165
|
return;
|
|
@@ -151,8 +167,6 @@ L.Map.TouchGestures = L.Handler.extend({
|
|
|
151
167
|
|
|
152
168
|
this._zooming = false;
|
|
153
169
|
this._rotating = false;
|
|
154
|
-
L.Util.cancelAnimFrame(this._animRequest);
|
|
155
|
-
|
|
156
170
|
L.DomEvent
|
|
157
171
|
.off(document, 'touchmove', this._onTouchMove, this)
|
|
158
172
|
.off(document, 'touchend touchcancel', this._onTouchEnd, this);
|
|
@@ -17,12 +17,12 @@ L.Map.mergeOptions({
|
|
|
17
17
|
|
|
18
18
|
L.Map.TouchRotate = L.Handler.extend({
|
|
19
19
|
|
|
20
|
-
addHooks
|
|
20
|
+
addHooks() {
|
|
21
21
|
this._map.touchGestures.enable();
|
|
22
22
|
this._map.touchGestures.rotate = true;
|
|
23
23
|
},
|
|
24
24
|
|
|
25
|
-
removeHooks
|
|
25
|
+
removeHooks() {
|
|
26
26
|
this._map.touchGestures.rotate = false;
|
|
27
27
|
},
|
|
28
28
|
|
|
@@ -34,14 +34,14 @@ L.Map.mergeOptions({
|
|
|
34
34
|
|
|
35
35
|
L.Map.TouchZoom = L.Handler.extend({
|
|
36
36
|
|
|
37
|
-
addHooks
|
|
38
|
-
|
|
37
|
+
addHooks() {
|
|
38
|
+
this._map._container.classList.add('leaflet-touch-zoom');
|
|
39
39
|
this._map.touchGestures.enable();
|
|
40
40
|
this._map.touchGestures.zoom = true;
|
|
41
41
|
},
|
|
42
42
|
|
|
43
|
-
removeHooks
|
|
44
|
-
|
|
43
|
+
removeHooks() {
|
|
44
|
+
this._map._container.classList.remove('leaflet-touch-zoom');
|
|
45
45
|
this._map.touchGestures.zoom = false;
|
|
46
46
|
},
|
|
47
47
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Feature: Rotating a Leaflet map
|
|
2
|
+
Background:
|
|
3
|
+
Given the example page is open
|
|
4
|
+
|
|
5
|
+
@issue-55 @issue-58
|
|
6
|
+
Scenario: Leaflet heat redraws stay aligned after map rotation
|
|
7
|
+
When I redraw a heat layer after rotating, panning, and zooming
|
|
8
|
+
Then the heat points remain aligned with their coordinates
|
|
9
|
+
|
|
10
|
+
@issue-11
|
|
11
|
+
Scenario: The default rotate control appears only when the map is rotated
|
|
12
|
+
When I rotate a map with the default rotate control
|
|
13
|
+
Then the default rotate control visibility follows the bearing
|
|
14
|
+
|
|
15
|
+
@issue-13
|
|
16
|
+
Scenario: Dragging the rotate control changes the map bearing
|
|
17
|
+
When I drag the rotate control
|
|
18
|
+
Then the map bearing follows the control drag
|
|
19
|
+
|
|
20
|
+
@issue-44
|
|
21
|
+
Scenario: The compass control requests device-orientation permission
|
|
22
|
+
When I activate compass mode on a permission-based device
|
|
23
|
+
Then device-orientation permission is requested
|
|
24
|
+
|
|
25
|
+
@issue-7
|
|
26
|
+
Scenario: Compass headings handle absolute, iOS, and unavailable readings
|
|
27
|
+
When I apply compass heading readings
|
|
28
|
+
Then valid compass readings update bearing and invalid readings are ignored
|
|
29
|
+
|
|
30
|
+
@issue-33 @issue-41
|
|
31
|
+
Scenario: Shift-wheel rotation can be disabled without disabling wheel zoom
|
|
32
|
+
When I use shift-wheel rotation with the handler disabled
|
|
33
|
+
Then shift-wheel input zooms without changing the map bearing
|
|
34
|
+
|
|
35
|
+
@debugger
|
|
36
|
+
Scenario: Debugger rotation presets and keyboard slider stay synchronized
|
|
37
|
+
When I use the debugger rotation controls
|
|
38
|
+
Then every debugger rotation control matches the map bearing
|
|
39
|
+
|
|
40
|
+
@debugger
|
|
41
|
+
Scenario: Debugger bounds padding updates from the keyboard
|
|
42
|
+
When I change the debugger bounds padding from the keyboard
|
|
43
|
+
Then the displayed bounds use the selected padding
|
|
44
|
+
|
|
45
|
+
@debugger
|
|
46
|
+
Scenario: Debugger geometry follows an offset and resized map
|
|
47
|
+
When I inspect debugger geometry after resizing and moving the map
|
|
48
|
+
Then the debugger reports the current map geometry
|
|
49
|
+
|
|
50
|
+
@example-ui
|
|
51
|
+
Scenario: Example base-layer radios select one layer
|
|
52
|
+
When I switch between the example base layers
|
|
53
|
+
Then exactly the selected base layer is visible
|
|
54
|
+
|
|
55
|
+
@example-ui
|
|
56
|
+
Scenario: Example zoom controls change and restore the zoom
|
|
57
|
+
When I use the example zoom controls
|
|
58
|
+
Then the zoom returns to its starting level
|
|
59
|
+
|
|
60
|
+
@example-ui
|
|
61
|
+
Scenario: Debugger rotates all example markers
|
|
62
|
+
When I rotate the example markers from the debugger
|
|
63
|
+
Then every example marker has a new rotation
|
|
64
|
+
|
|
65
|
+
@example-ui
|
|
66
|
+
Scenario Outline: Example destination buttons fly to the selected place
|
|
67
|
+
When I select "<place>" from the example page
|
|
68
|
+
Then the map settles at "<place>" at zoom 10
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
| place |
|
|
72
|
+
| Kyiv |
|
|
73
|
+
| London |
|
|
74
|
+
| San Francisco |
|
|
75
|
+
| Washington |
|
|
76
|
+
| Trondheim |
|
|
77
|
+
|
|
78
|
+
@example-ui
|
|
79
|
+
Scenario Outline: Example bounds buttons fit the selected layer
|
|
80
|
+
When I fit the "<layer>" bounds from the example page
|
|
81
|
+
Then the map view contains the "<layer>" bounds
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
| layer |
|
|
85
|
+
| circle |
|
|
86
|
+
| polygon |
|
|
87
|
+
| path |
|
|
88
|
+
|
|
89
|
+
@example-ui
|
|
90
|
+
Scenario: Rectangle button resets zoom and fits the rectangle
|
|
91
|
+
When I fit the rectangle from the example page
|
|
92
|
+
Then the rectangle is fitted at zoom 14
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Feature: Rotating a Leaflet map
|
|
2
|
+
Background:
|
|
3
|
+
Given the example page is open
|
|
4
|
+
|
|
5
|
+
@issue-43
|
|
6
|
+
Scenario: Pinch zoom refreshes paths during the gesture
|
|
7
|
+
When I move a two-finger pinch gesture
|
|
8
|
+
Then the zoom transition ends before the gesture ends
|
|
9
|
+
|
|
10
|
+
@issue-43
|
|
11
|
+
Scenario: Vector paths follow a rotated two-finger gesture
|
|
12
|
+
When I rotate and zoom two fingers over a vector path
|
|
13
|
+
Then the vector path remains aligned during the gesture
|
|
14
|
+
|
|
15
|
+
@issue-56
|
|
16
|
+
Scenario: Dragging a max-bounds marker preserves callback coordinates on a rotated map
|
|
17
|
+
When I drag a constrained marker on a rotated map
|
|
18
|
+
Then its drag callbacks match the marker and pointer coordinates
|
|
19
|
+
|
|
20
|
+
@issue-60
|
|
21
|
+
Scenario: Interactive layers stay aligned while dragging and rotating the map
|
|
22
|
+
When I drag a map with interactive layers while rotated
|
|
23
|
+
Then the marker and vector path stay at their geographic coordinates
|
|
24
|
+
|
|
25
|
+
@issue-59 @issue-52
|
|
26
|
+
Scenario: Focusing an in-bounds point does not pan an offset rotated map
|
|
27
|
+
When I focus a point near the left edge of an offset map
|
|
28
|
+
Then the map center remains unchanged
|
|
29
|
+
|
|
30
|
+
@issue-65
|
|
31
|
+
Scenario: Two-finger rotation can be disabled
|
|
32
|
+
When I disable touch rotation and rotate two fingers
|
|
33
|
+
Then the map bearing remains unchanged
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Feature: Rotating a Leaflet map
|
|
2
|
+
Background:
|
|
3
|
+
Given the example page is open
|
|
4
|
+
|
|
5
|
+
@issue-4 @issue-35 @issue-62
|
|
6
|
+
Scenario: Rotated road labels stay upright and aligned with the map
|
|
7
|
+
When I rotate a label marker with the view
|
|
8
|
+
Then the label remains upright while following the map bearing
|
|
9
|
+
|
|
10
|
+
@issue-2 @issue-54
|
|
11
|
+
Scenario: GeoJSON in a custom pane rotates with the map
|
|
12
|
+
When I add GeoJSON to a custom pane inside the rotate pane
|
|
13
|
+
Then the custom-pane GeoJSON stays aligned with its coordinates
|
|
14
|
+
|
|
15
|
+
@issue-32
|
|
16
|
+
Scenario: Canvas overlays rotate with the map
|
|
17
|
+
When I render a Canvas vector layer on a rotated map
|
|
18
|
+
Then the Canvas renderer belongs to the rotating pane
|
|
19
|
+
|
|
20
|
+
@issue-57
|
|
21
|
+
Scenario: SVG paths stay aligned near the latitude limit without zoom animation
|
|
22
|
+
When I zoom an SVG path near the latitude limit
|
|
23
|
+
Then the path stays at its geographic coordinate
|
|
24
|
+
|
|
25
|
+
@issue-15 @issue-51
|
|
26
|
+
Scenario: Popup tip remains anchored when zoom animation is disabled
|
|
27
|
+
When I open a popup on a rotated map without zoom animation
|
|
28
|
+
Then the popup tip stays at the marker coordinate
|
|
29
|
+
|
|
30
|
+
@issue-23
|
|
31
|
+
Scenario: Removing the rotate control detaches its map listener
|
|
32
|
+
When I remove the rotate control and change the map bearing
|
|
33
|
+
Then the map rotates without invoking the removed control
|
|
34
|
+
|
|
35
|
+
@issue-3
|
|
36
|
+
Scenario: Markers remain non-draggable unless requested
|
|
37
|
+
When I create default and draggable markers
|
|
38
|
+
Then only the requested marker is draggable
|
|
39
|
+
|
|
40
|
+
@issue-46
|
|
41
|
+
Scenario: Click coordinates match the rotated map location
|
|
42
|
+
When I click a rotated map at a known container point
|
|
43
|
+
Then the click event reports the matching geographic coordinate
|
|
44
|
+
|
|
45
|
+
@issue-18 @issue-59
|
|
46
|
+
Scenario: Focusing an in-bounds marker does not pan the rotated map
|
|
47
|
+
When I focus a marker near the edge of a rotated map
|
|
48
|
+
Then the map center remains unchanged
|
|
49
|
+
|
|
50
|
+
@issue-51
|
|
51
|
+
Scenario: Opening an edge popup pans only enough to keep it visible
|
|
52
|
+
When I open a popup near the edge of a rotated map
|
|
53
|
+
Then the popup stays inside the map without a large jump
|
|
54
|
+
|
|
55
|
+
@issue-52
|
|
56
|
+
Scenario: Opening a popup in a second rotated map does not move it
|
|
57
|
+
When I open a popup in a second rotated map with map listeners
|
|
58
|
+
Then the second map center remains unchanged and its popup stays anchored
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Feature: Rotating a Leaflet map
|
|
2
|
+
Background:
|
|
3
|
+
Given the example page is open
|
|
4
|
+
|
|
5
|
+
@issue-43
|
|
6
|
+
Scenario: Rotation is enabled
|
|
7
|
+
Then rotation is enabled on the map
|
|
8
|
+
|
|
9
|
+
@issue-19
|
|
10
|
+
Scenario: Bearing survives zoom
|
|
11
|
+
When I set the bearing to 10 and zoom in twice
|
|
12
|
+
Then the bearing remains 10
|
|
13
|
+
|
|
14
|
+
@issue-19
|
|
15
|
+
Scenario: Bearing survives setting the view
|
|
16
|
+
When I set the bearing to 10 and change the view twice
|
|
17
|
+
Then the bearing remains 10
|
|
18
|
+
|
|
19
|
+
@issue-63
|
|
20
|
+
Scenario: Bearing can animate
|
|
21
|
+
When I animate the bearing to 90 degrees
|
|
22
|
+
Then the bearing reaches 90 degrees gradually
|
|
23
|
+
|
|
24
|
+
@issue-25
|
|
25
|
+
Scenario: Fit bounds zoom is stable
|
|
26
|
+
When I fit the same bounds twice
|
|
27
|
+
Then the map zoom is 14 both times
|
|
28
|
+
|
|
29
|
+
@issue-28
|
|
30
|
+
Scenario: Panning inside a marker keeps its bounds stable
|
|
31
|
+
When I pan inside the Trondheim marker
|
|
32
|
+
Then panning inside keeps the expected bounds
|
|
33
|
+
|
|
34
|
+
@issue-34
|
|
35
|
+
Scenario: Draggable marker listeners are not duplicated
|
|
36
|
+
Then the draggable marker has one drag listener and one drag-end listener
|
package/test/index.html
CHANGED
|
@@ -6,18 +6,12 @@
|
|
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
7
7
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
<script src="https://unpkg.com/leaflet@1.9/dist/leaflet-src.js"></script>
|
|
11
|
-
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css">
|
|
12
|
-
|
|
13
|
-
<!-- Leaflet-Rotate -->
|
|
14
|
-
<script src="../dist/leaflet-rotate-src.js"></script>
|
|
9
|
+
<link id="leaflet-css" rel="stylesheet">
|
|
15
10
|
|
|
16
11
|
<!-- include some miscellaneous -->
|
|
17
12
|
<script src="../misc/route.js"></script>
|
|
18
13
|
<script src="../misc/places.js"></script>
|
|
19
14
|
<script src="../misc/loremIpsum.js"></script>
|
|
20
|
-
<script src="../lib/debug.js"></script>
|
|
21
15
|
|
|
22
16
|
<style>
|
|
23
17
|
#map {
|
|
@@ -36,6 +30,12 @@
|
|
|
36
30
|
|
|
37
31
|
<body>
|
|
38
32
|
|
|
33
|
+
<label for="leaflet-version">Leaflet version:</label>
|
|
34
|
+
<select id="leaflet-version">
|
|
35
|
+
<option value="1">1.9.4</option>
|
|
36
|
+
<option value="2">2.0.0-alpha.1</option>
|
|
37
|
+
</select>
|
|
38
|
+
|
|
39
39
|
<div id="map"></div>
|
|
40
40
|
|
|
41
41
|
<hr>
|
|
@@ -61,8 +61,37 @@
|
|
|
61
61
|
</p>
|
|
62
62
|
</div>
|
|
63
63
|
|
|
64
|
-
<script>
|
|
65
|
-
|
|
64
|
+
<script type="module">
|
|
65
|
+
const versionSelect = document.getElementById('leaflet-version');
|
|
66
|
+
const params = new URLSearchParams(location.search);
|
|
67
|
+
versionSelect.value = params.get('leaflet') === '2' ? '2' : '1';
|
|
68
|
+
versionSelect.addEventListener('change', () => {
|
|
69
|
+
location.search = `?leaflet=${versionSelect.value}`;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const loadScript = src => new Promise((resolve, reject) => {
|
|
73
|
+
const script = document.createElement('script');
|
|
74
|
+
script.src = src;
|
|
75
|
+
script.onload = resolve;
|
|
76
|
+
script.onerror = () => reject(new Error(`Could not load ${src}`));
|
|
77
|
+
document.head.appendChild(script);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const version = versionSelect.value;
|
|
81
|
+
document.getElementById('leaflet-css').href = version === '2'
|
|
82
|
+
? 'https://unpkg.com/leaflet@2.0.0-alpha.1/dist/leaflet.css'
|
|
83
|
+
: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
|
|
84
|
+
|
|
85
|
+
if (version === '2') {
|
|
86
|
+
globalThis.L = await import('https://unpkg.com/leaflet@2.0.0-alpha.1/dist/leaflet.js');
|
|
87
|
+
} else {
|
|
88
|
+
await loadScript('https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.js');
|
|
89
|
+
}
|
|
90
|
+
await loadScript('../dist/leaflet-rotate-src.js');
|
|
91
|
+
await loadScript('../lib/debug.js');
|
|
92
|
+
const L = globalThis.L;
|
|
93
|
+
|
|
94
|
+
const esri = new L.TileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
|
|
66
95
|
id: 'mapbox.streets',
|
|
67
96
|
maxZoom: 24,
|
|
68
97
|
maxNativeZoom: 18,
|
|
@@ -70,14 +99,14 @@
|
|
|
70
99
|
// noWrap: true
|
|
71
100
|
});
|
|
72
101
|
|
|
73
|
-
|
|
102
|
+
const osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
74
103
|
maxZoom: 24,
|
|
75
104
|
maxNativeZoom: 19,
|
|
76
105
|
attribution: '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
77
106
|
// noWrap: true
|
|
78
107
|
});
|
|
79
108
|
|
|
80
|
-
|
|
109
|
+
const map = new L.Map('map', {
|
|
81
110
|
center: [55, 10],
|
|
82
111
|
zoom: 2,
|
|
83
112
|
layers: [esri],
|
|
@@ -99,6 +128,9 @@
|
|
|
99
128
|
touchRotate: true,
|
|
100
129
|
// touchZoom: true
|
|
101
130
|
});
|
|
131
|
+
window.map = map;
|
|
132
|
+
window.esri = esri;
|
|
133
|
+
window.osm = osm;
|
|
102
134
|
|
|
103
135
|
// map.setBearing(90);
|
|
104
136
|
// map.touchRotate.enable();
|
|
@@ -111,17 +143,18 @@
|
|
|
111
143
|
// map.rotateControl.setPosition('bottomleft');
|
|
112
144
|
// map.setMaxBounds([[-90,-180], [90,180]]);
|
|
113
145
|
|
|
114
|
-
|
|
115
|
-
'Empty': L.
|
|
146
|
+
const layers = new L.Control.Layers({
|
|
147
|
+
'Empty': new L.TileLayer(''),
|
|
116
148
|
'Streets': osm,
|
|
117
149
|
'Satellite': esri,
|
|
118
150
|
}, null, {
|
|
119
151
|
collapsed: false
|
|
120
152
|
}).addTo(map);
|
|
153
|
+
window.layers = layers;
|
|
121
154
|
|
|
122
|
-
|
|
123
|
-
for (
|
|
124
|
-
markers.push(L.
|
|
155
|
+
const markers = [];
|
|
156
|
+
for (const i in places) {
|
|
157
|
+
markers.push(new L.Marker(places[i], {
|
|
125
158
|
draggable: true
|
|
126
159
|
})
|
|
127
160
|
.bindPopup('<b>' + i + '</b><br>' + loremIpsum)
|
|
@@ -133,30 +166,34 @@
|
|
|
133
166
|
)
|
|
134
167
|
.addTo(map));
|
|
135
168
|
}
|
|
169
|
+
window.markers = markers;
|
|
136
170
|
|
|
137
|
-
|
|
138
|
-
renderer: L.
|
|
171
|
+
const path = new L.Polyline(route, {
|
|
172
|
+
renderer: new L.Canvas()
|
|
139
173
|
}).addTo(map);
|
|
174
|
+
window.path = path;
|
|
140
175
|
|
|
141
|
-
|
|
176
|
+
const circle = new L.Circle([53, 4], 111111)
|
|
142
177
|
.addTo(map);
|
|
178
|
+
window.circle = circle;
|
|
143
179
|
|
|
144
|
-
|
|
180
|
+
const polygon = new L.Polygon([
|
|
145
181
|
[48, -3],
|
|
146
182
|
[50, -4],
|
|
147
183
|
[52, 4]
|
|
148
184
|
]).addTo(map);
|
|
185
|
+
window.polygon = polygon;
|
|
149
186
|
|
|
150
|
-
const rectangle = L.
|
|
187
|
+
const rectangle = new L.Rectangle([
|
|
151
188
|
[60.81123, 25.71632],
|
|
152
189
|
[60.81028, 25.73166],
|
|
153
190
|
[60.7997, 25.72892],
|
|
154
191
|
[60.80061, 25.71362]
|
|
155
192
|
]).addTo(map);
|
|
193
|
+
window.rectangle = rectangle;
|
|
156
194
|
|
|
157
195
|
// Display some debug info
|
|
158
196
|
L.Rotate.debug(map);
|
|
159
|
-
|
|
160
197
|
</script>
|
|
161
198
|
|
|
162
199
|
<a href="https://github.com/Raruto/leaflet-rotate" class="view-on-github" style="position: fixed;bottom: 10px;left: calc(50% - 60px);z-index: 9999;"> <img alt="View on Github" src="https://raruto.github.io/img/view-on-github.png" title="View on Github"
|