leaflet-rotate 0.1.4 → 0.2.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/README.md +2 -2
- package/build/rollup.config.js +4 -4
- package/dist/leaflet-rotate-src.js +625 -310
- package/dist/leaflet-rotate-src.js.map +1 -1
- package/dist/leaflet-rotate.js +1660 -1
- package/dist/leaflet-rotate.js.map +1 -1
- package/lib/debug.js +219 -25
- package/lib/debug.min.js +1 -9
- package/package.json +10 -7
- package/src/control/Rotate.js +10 -7
- package/src/dom/DomUtil.js +4 -1
- package/src/dom/Draggable.js +8 -5
- package/src/geometry/Point.js +22 -18
- package/src/index.js +5 -3
- package/src/layer/DivOverlay.js +13 -21
- package/src/layer/Popup.js +30 -10
- package/src/layer/Tooltip.js +10 -7
- package/src/layer/marker/Icon.js +5 -2
- package/src/layer/marker/Marker.js +42 -37
- package/src/layer/tile/GridLayer.js +5 -14
- package/src/layer/vector/Canvas.js +18 -15
- package/src/layer/vector/Renderer.js +21 -30
- package/src/layer/vector/SVG.js +10 -7
- package/src/map/Map.js +363 -93
- package/src/map/handler/CompassBearing.js +7 -11
- package/src/map/handler/ContainerMutation.js +12 -8
- package/src/map/handler/ShiftKeyRotate.js +5 -2
- package/src/map/handler/TouchGestures.js +16 -11
- package/src/map/handler/TouchRotate.js +4 -2
- package/src/map/handler/TouchZoom.js +16 -4
- package/test/index.html +29 -6
- package/build/rollup.config.min.js +0 -2
- package/src/map/handler/ShiftKeyRotate.min.js +0 -1
package/src/map/Map.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* L.Map
|
|
2
|
+
* @external L.Map
|
|
3
|
+
*
|
|
4
|
+
* @see https://github.com/Leaflet/Leaflet/blob/v1.9.3/src/map/Map.js
|
|
3
5
|
*/
|
|
6
|
+
|
|
4
7
|
const mapProto = L.extend({}, L.Map.prototype);
|
|
5
8
|
|
|
6
9
|
L.Map.mergeOptions({ rotate: false, bearing: 0, });
|
|
7
10
|
|
|
8
11
|
L.Map.include({
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @param {(HTMLElement|String)} id html selector
|
|
15
|
+
* @param {Object} [options={}] leaflet map options
|
|
16
|
+
*/
|
|
17
|
+
initialize: function(id, options) {
|
|
11
18
|
if (options.rotate) {
|
|
12
19
|
this._rotate = true;
|
|
13
20
|
this._bearing = 0;
|
|
@@ -18,20 +25,15 @@ L.Map.include({
|
|
|
18
25
|
}
|
|
19
26
|
},
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// }
|
|
31
|
-
// return mapProto.createPane.call(this, name, container || this._rotatePane);
|
|
32
|
-
// },
|
|
33
|
-
|
|
34
|
-
containerPointToLayerPoint: function(point) { // (Point)
|
|
28
|
+
/**
|
|
29
|
+
* Given a pixel coordinate relative to the map container,
|
|
30
|
+
* returns the corresponding pixel coordinate relative to
|
|
31
|
+
* the [origin pixel](#map-getpixelorigin).
|
|
32
|
+
*
|
|
33
|
+
* @param {L.Point} point pixel screen coordinates
|
|
34
|
+
* @returns {L.Point} transformed pixel point
|
|
35
|
+
*/
|
|
36
|
+
containerPointToLayerPoint: function(point) {
|
|
35
37
|
if (!this._rotate) {
|
|
36
38
|
return mapProto.containerPointToLayerPoint.call(this, point);
|
|
37
39
|
}
|
|
@@ -41,20 +43,13 @@ L.Map.include({
|
|
|
41
43
|
.subtract(this._getRotatePanePos());
|
|
42
44
|
},
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
bottomright = this.layerPointToLatLng(this.containerPointToLayerPoint([size.x, size.y])),
|
|
52
|
-
bottomleft = this.layerPointToLatLng(this.containerPointToLayerPoint([0, size.y]));
|
|
53
|
-
|
|
54
|
-
// Use LatLngBounds' build-in constructor that automatically extends the bounds to fit the passed points
|
|
55
|
-
return new L.LatLngBounds([topleft, topright, bottomright, bottomleft]);
|
|
56
|
-
},
|
|
57
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
|
|
48
|
+
* returns the corresponding pixel coordinate relative to the map container.
|
|
49
|
+
*
|
|
50
|
+
* @param {L.Point} point pixel screen coordinates
|
|
51
|
+
* @returns {L.Point} transformed pixel point
|
|
52
|
+
*/
|
|
58
53
|
layerPointToContainerPoint: function(point) { // (Point)
|
|
59
54
|
if (!this._rotate) {
|
|
60
55
|
return mapProto.layerPointToContainerPoint.call(this, point);
|
|
@@ -65,89 +60,182 @@ L.Map.include({
|
|
|
65
60
|
.add(this._getMapPanePos());
|
|
66
61
|
},
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Converts a coordinate from the rotated pane reference system
|
|
65
|
+
* to the reference system of the not rotated map pane.
|
|
66
|
+
*
|
|
67
|
+
* (rotatePane) --> (mapPane)
|
|
68
|
+
* (rotatePane) --> (norotatePane)
|
|
69
|
+
*
|
|
70
|
+
* @param {L.Point} point pixel screen coordinates
|
|
71
|
+
* @returns {L.Point}
|
|
72
|
+
*/
|
|
73
|
+
rotatedPointToMapPanePoint: function(point) {
|
|
74
|
+
return L.point(point)
|
|
75
|
+
.rotate(this._bearing)
|
|
76
|
+
._add(this._getRotatePanePos());
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Converts a coordinate from the not rotated map pane reference system
|
|
81
|
+
* to the reference system of the rotated pane.
|
|
82
|
+
*
|
|
83
|
+
* (mapPane) --> (rotatePane)
|
|
84
|
+
* (norotatePane) --> (rotatePane)
|
|
85
|
+
*
|
|
86
|
+
* @param {L.Point} point pixel screen coordinates
|
|
87
|
+
*/
|
|
88
|
+
mapPanePointToRotatedPoint: function(point) {
|
|
89
|
+
return L.point(point)
|
|
90
|
+
._subtract(this._getRotatePanePos())
|
|
91
|
+
.rotate(-this._bearing);
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Returns geographical bounds visible in the current map view
|
|
96
|
+
*
|
|
97
|
+
* @TODO find out if map bounds calculated by `L.Map::getBounds()`
|
|
98
|
+
* function should match the `rotatePane` or `norotatePane` bounds
|
|
99
|
+
*
|
|
100
|
+
* @see https://github.com/fnicollet/Leaflet/issues/7
|
|
101
|
+
*
|
|
102
|
+
* @returns {L.LatLngBounds}
|
|
103
|
+
*/
|
|
104
|
+
getBounds: function() {
|
|
105
|
+
if (!this._rotate) {
|
|
106
|
+
return mapProto.getBounds.call(this);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// SEE: https://github.com/fnicollet/Leaflet/pull/22
|
|
110
|
+
//
|
|
111
|
+
// var bounds = this.getPixelBounds(),
|
|
112
|
+
// sw = this.unproject(bounds.getBottomLeft()),
|
|
113
|
+
// ne = this.unproject(bounds.getTopRight());
|
|
114
|
+
// return new LatLngBounds(sw, ne);
|
|
115
|
+
//
|
|
116
|
+
|
|
117
|
+
// LatLngBounds' constructor automatically
|
|
118
|
+
// extends the bounds to fit the passed points
|
|
119
|
+
var size = this.getSize();
|
|
120
|
+
return new L.LatLngBounds([
|
|
121
|
+
this.containerPointToLatLng([0, 0]), // topleft
|
|
122
|
+
this.containerPointToLatLng([size.x, 0]), // topright
|
|
123
|
+
this.containerPointToLatLng([size.x, size.y]), // bottomright
|
|
124
|
+
this.containerPointToLatLng([0, size.y]), // bottomleft
|
|
125
|
+
]);
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Returns the bounds of the current map view in projected pixel
|
|
130
|
+
* coordinates (sometimes useful in layer and overlay implementations).
|
|
131
|
+
*
|
|
132
|
+
* @TODO find out if map bounds calculated by `L.Map::getPixelBounds()`
|
|
133
|
+
* function should match the `rotatePane` or `norotatePane` bounds
|
|
134
|
+
*
|
|
135
|
+
* @see https://github.com/fnicollet/Leaflet/issues/7
|
|
136
|
+
*
|
|
137
|
+
* @returns {L.Bounds}
|
|
138
|
+
*/
|
|
139
|
+
// getPixelBounds(center, zoom) {
|
|
140
|
+
// // const topLeftPoint = map.containerPointToLayerPoint(this._getTopLeftPoint());
|
|
141
|
+
// const topLeftPoint = this._getTopLeftPoint(center, zoom);
|
|
142
|
+
// return new L.Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
|
|
143
|
+
// },
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Change map rotation
|
|
147
|
+
*
|
|
148
|
+
* @param {number} theta map degrees
|
|
149
|
+
*/
|
|
70
150
|
setBearing: function(theta) {
|
|
71
151
|
if (!L.Browser.any3d || !this._rotate) { return; }
|
|
72
152
|
|
|
73
|
-
var
|
|
74
|
-
|
|
75
|
-
|
|
153
|
+
var bearing = L.Util.wrapNum(theta, [0, 360]) * L.DomUtil.DEG_TO_RAD,
|
|
154
|
+
center = this._getPixelCenter(),
|
|
155
|
+
oldPos = this._getRotatePanePos().rotateFrom(-this._bearing, center),
|
|
156
|
+
newPos = oldPos.rotateFrom(bearing, center);
|
|
76
157
|
|
|
77
|
-
|
|
158
|
+
// CSS transform
|
|
159
|
+
L.DomUtil.setPosition(this._rotatePane, oldPos, bearing, center);
|
|
78
160
|
|
|
79
|
-
this.
|
|
80
|
-
this.
|
|
81
|
-
|
|
82
|
-
L.DomUtil.setPosition(this._rotatePane, rotatePanePos, this._bearing, this._pivot);
|
|
161
|
+
this._pivot = center;
|
|
162
|
+
this._bearing = bearing;
|
|
163
|
+
this._rotatePanePos = newPos;
|
|
83
164
|
|
|
84
165
|
this.fire('rotate');
|
|
85
166
|
},
|
|
86
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Get current map rotation
|
|
170
|
+
*
|
|
171
|
+
* @returns {number} theta map degrees
|
|
172
|
+
*/
|
|
87
173
|
getBearing: function() {
|
|
88
174
|
return this._bearing * L.DomUtil.RAD_TO_DEG;
|
|
89
175
|
},
|
|
90
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Creates a new [map pane](#map-pane) with the given name if it doesn't
|
|
179
|
+
* exist already, then returns it. The pane is created as a child of
|
|
180
|
+
* `container`, or as a child of the main map pane if not set.
|
|
181
|
+
*
|
|
182
|
+
* @param {String} name leaflet pane
|
|
183
|
+
* @param {HTMLElement} [container] parent element
|
|
184
|
+
* @returns {HTMLElement} pane container
|
|
185
|
+
*/
|
|
186
|
+
// createPane: function(name, container) {
|
|
187
|
+
// if (!this._rotate || name == 'mapPane') {
|
|
188
|
+
// return mapProto.createPane.call(this, name, container);
|
|
189
|
+
// }
|
|
190
|
+
// // init "rotatePane"
|
|
191
|
+
// if (!this._rotatePane) {
|
|
192
|
+
// // this._pivot = this.getSize().divideBy(2);
|
|
193
|
+
// this._rotatePane = mapProto.createPane.call(this, 'rotatePane', this._mapPane);
|
|
194
|
+
// L.DomUtil.setPosition(this._rotatePane, new L.Point(0, 0), this._bearing, this._pivot);
|
|
195
|
+
// }
|
|
196
|
+
// return mapProto.createPane.call(this, name, container || this._rotatePane);
|
|
197
|
+
// },
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Panes are DOM elements used to control the ordering of layers on
|
|
201
|
+
* the map. You can access panes with [`map.getPane`](#map-getpane)
|
|
202
|
+
* or [`map.getPanes`](#map-getpanes) methods. New panes can be created
|
|
203
|
+
* with the [`map.createPane`](#map-createpane) method.
|
|
204
|
+
*
|
|
205
|
+
* Every map has the following default panes that differ only in zIndex:
|
|
206
|
+
*
|
|
207
|
+
* - mapPane [HTMLElement = 'auto'] - Pane that contains all other map panes
|
|
208
|
+
* - tilePane [HTMLElement = 2] - Pane for tile layers
|
|
209
|
+
* - overlayPane [HTMLElement = 4] - Pane for overlays like polylines and polygons
|
|
210
|
+
* - shadowPane [HTMLElement = 5] - Pane for overlay shadows (e.g. marker shadows)
|
|
211
|
+
* - markerPane [HTMLElement = 6] - Pane for marker icons
|
|
212
|
+
* - tooltipPane [HTMLElement = 650] - Pane for tooltips.
|
|
213
|
+
* - popupPane [HTMLElement = 700] - Pane for popups.
|
|
214
|
+
*/
|
|
91
215
|
_initPanes: function() {
|
|
92
216
|
var panes = this._panes = {};
|
|
93
217
|
this._paneRenderers = {};
|
|
94
218
|
|
|
95
|
-
// @section
|
|
96
|
-
//
|
|
97
|
-
// Panes are DOM elements used to control the ordering of layers on the map. You
|
|
98
|
-
// can access panes with [`map.getPane`](#map-getpane) or
|
|
99
|
-
// [`map.getPanes`](#map-getpanes) methods. New panes can be created with the
|
|
100
|
-
// [`map.createPane`](#map-createpane) method.
|
|
101
|
-
//
|
|
102
|
-
// Every map has the following default panes that differ only in zIndex.
|
|
103
|
-
//
|
|
104
|
-
// @pane mapPane: HTMLElement = 'auto'
|
|
105
|
-
// Pane that contains all other map panes
|
|
106
|
-
|
|
107
219
|
this._mapPane = this.createPane('mapPane', this._container);
|
|
108
220
|
L.DomUtil.setPosition(this._mapPane, new L.Point(0, 0));
|
|
109
221
|
|
|
110
222
|
if (this._rotate) {
|
|
111
223
|
this._rotatePane = this.createPane('rotatePane', this._mapPane);
|
|
112
224
|
this._norotatePane = this.createPane('norotatePane', this._mapPane);
|
|
113
|
-
|
|
114
|
-
// @pane tilePane: HTMLElement = 2
|
|
115
|
-
// Pane for tile layers
|
|
225
|
+
// rotatePane
|
|
116
226
|
this.createPane('tilePane', this._rotatePane);
|
|
117
|
-
// @pane overlayPane: HTMLElement = 4
|
|
118
|
-
// Pane for overlays like polylines and polygons
|
|
119
227
|
this.createPane('overlayPane', this._rotatePane);
|
|
120
|
-
|
|
121
|
-
// @pane shadowPane: HTMLElement = 5
|
|
122
|
-
// Pane for overlay shadows (e.g. marker shadows)
|
|
228
|
+
// norotatePane
|
|
123
229
|
this.createPane('shadowPane', this._norotatePane);
|
|
124
|
-
// @pane markerPane: HTMLElement = 6
|
|
125
|
-
// Pane for marker icons
|
|
126
230
|
this.createPane('markerPane', this._norotatePane);
|
|
127
|
-
// @pane tooltipPane: HTMLElement = 650
|
|
128
|
-
// Pane for tooltips.
|
|
129
231
|
this.createPane('tooltipPane', this._norotatePane);
|
|
130
|
-
// @pane popupPane: HTMLElement = 700
|
|
131
|
-
// Pane for popups.
|
|
132
232
|
this.createPane('popupPane', this._norotatePane);
|
|
133
233
|
} else {
|
|
134
|
-
// @pane tilePane: HTMLElement = 2
|
|
135
|
-
// Pane for tile layers
|
|
136
234
|
this.createPane('tilePane');
|
|
137
|
-
// @pane overlayPane: HTMLElement = 4
|
|
138
|
-
// Pane for overlays like polylines and polygons
|
|
139
235
|
this.createPane('overlayPane');
|
|
140
|
-
// @pane shadowPane: HTMLElement = 5
|
|
141
|
-
// Pane for overlay shadows (e.g. marker shadows)
|
|
142
236
|
this.createPane('shadowPane');
|
|
143
|
-
// @pane markerPane: HTMLElement = 6
|
|
144
|
-
// Pane for marker icons
|
|
145
237
|
this.createPane('markerPane');
|
|
146
|
-
// @pane tooltipPane: HTMLElement = 650
|
|
147
|
-
// Pane for tooltips.
|
|
148
238
|
this.createPane('tooltipPane');
|
|
149
|
-
// @pane popupPane: HTMLElement = 700
|
|
150
|
-
// Pane for popups.
|
|
151
239
|
this.createPane('popupPane');
|
|
152
240
|
}
|
|
153
241
|
|
|
@@ -157,21 +245,92 @@ L.Map.include({
|
|
|
157
245
|
}
|
|
158
246
|
},
|
|
159
247
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
248
|
+
/**
|
|
249
|
+
* Pans the map the minimum amount to make the `latlng` visible. Use
|
|
250
|
+
* padding options to fit the display to more restricted bounds.
|
|
251
|
+
* If `latlng` is already within the (optionally padded) display bounds,
|
|
252
|
+
* the map will not be panned.
|
|
253
|
+
*
|
|
254
|
+
* @see https://github.com/Raruto/leaflet-rotate/issues/18
|
|
255
|
+
*
|
|
256
|
+
* @param {L.LatLng} latlng coordinates
|
|
257
|
+
* @param {Object} [options={}] padding options
|
|
258
|
+
*
|
|
259
|
+
* @returns {L.Map} current map instance
|
|
260
|
+
*/
|
|
261
|
+
panInside(latlng, options) {
|
|
262
|
+
options = options || {};
|
|
263
|
+
|
|
264
|
+
const paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]),
|
|
265
|
+
paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]),
|
|
266
|
+
/** @TODO use mapProto.panInside */
|
|
267
|
+
// pixelPoint = this.project(latlng),
|
|
268
|
+
// pixelBounds = this.getPixelBounds(),
|
|
269
|
+
// pixelCenter = this.project(this.getCenter()),
|
|
270
|
+
rect = this._container.getBoundingClientRect(),
|
|
271
|
+
pixelPoint = this.latLngToContainerPoint(latlng),
|
|
272
|
+
pixelBounds = L.bounds([ L.point(rect), L.point(rect).add(this.getSize()) ]),
|
|
273
|
+
pixelCenter = pixelBounds.getCenter(),
|
|
274
|
+
//
|
|
275
|
+
paddedBounds = L.bounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]),
|
|
276
|
+
paddedSize = paddedBounds.getSize();
|
|
277
|
+
|
|
278
|
+
if (!paddedBounds.contains(pixelPoint)) {
|
|
279
|
+
this._enforcingBounds = true;
|
|
280
|
+
const centerOffset = pixelPoint.subtract(paddedBounds.getCenter());
|
|
281
|
+
const offset = paddedBounds.extend(pixelPoint).getSize().subtract(paddedSize);
|
|
282
|
+
pixelCenter.x += centerOffset.x < 0 ? -offset.x : offset.x;
|
|
283
|
+
pixelCenter.y += centerOffset.y < 0 ? -offset.y : offset.y;
|
|
284
|
+
/** @TODO use mapProto.panInside */
|
|
285
|
+
// this.panTo(this.unproject(pixelCenter), options);
|
|
286
|
+
this.panTo(this.containerPointToLatLng(pixelCenter), options);
|
|
287
|
+
//
|
|
288
|
+
this._enforcingBounds = false;
|
|
289
|
+
}
|
|
290
|
+
return this;
|
|
165
291
|
},
|
|
166
292
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Pans the map to the closest view that would lie inside the given bounds
|
|
295
|
+
* (if it's not already), controlling the animation using the options specific,
|
|
296
|
+
* if any.
|
|
297
|
+
*
|
|
298
|
+
* @TODO check if map bounds calculated by `L.Map::panInsideBounds()`
|
|
299
|
+
* function should match the `rotatePane` or `norotatePane` bounds
|
|
300
|
+
*
|
|
301
|
+
* @see https://github.com/fnicollet/Leaflet/issues/7
|
|
302
|
+
*
|
|
303
|
+
* @param {L.LatLngBounds} bounds coordinates
|
|
304
|
+
* @param {Object} [options] pan options
|
|
305
|
+
* @returns {L.Map} current map instance
|
|
306
|
+
*/
|
|
307
|
+
// panInsideBounds: function (bounds, options) {
|
|
308
|
+
// this._enforcingBounds = true;
|
|
309
|
+
// var center = this.getCenter(),
|
|
310
|
+
// newCenter = this._limitCenter(center, this._zoom, L.latLngBounds(bounds));
|
|
311
|
+
|
|
312
|
+
// if (!center.equals(newCenter)) {
|
|
313
|
+
// this.panTo(newCenter, options);
|
|
314
|
+
// }
|
|
173
315
|
|
|
174
|
-
//
|
|
316
|
+
// this._enforcingBounds = false;
|
|
317
|
+
// return this;
|
|
318
|
+
// },
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Layer point of the current center
|
|
322
|
+
*
|
|
323
|
+
* @returns {L.Point} layer center
|
|
324
|
+
*/
|
|
325
|
+
// _getCenterLayerPoint: function () {
|
|
326
|
+
// return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
|
|
327
|
+
// },
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Offset of the specified place to the current center in pixels
|
|
331
|
+
*
|
|
332
|
+
* @param {L.LatLng} latlng map coordinates
|
|
333
|
+
*/
|
|
175
334
|
_getCenterOffset: function(latlng) {
|
|
176
335
|
var centerOffset = mapProto._getCenterOffset.call(this, latlng);
|
|
177
336
|
if (this._rotate) {
|
|
@@ -182,12 +341,13 @@ L.Map.include({
|
|
|
182
341
|
|
|
183
342
|
_getRotatePanePos: function() {
|
|
184
343
|
return this._rotatePanePos || new L.Point(0, 0);
|
|
344
|
+
// return L.DomUtil.getPosition(this._rotatePane) || new L.Point(0, 0);
|
|
185
345
|
},
|
|
186
346
|
|
|
187
347
|
_getNewPixelOrigin: function(center, zoom) {
|
|
188
348
|
var viewHalf = this.getSize()._divideBy(2);
|
|
189
349
|
if (!this._rotate) {
|
|
190
|
-
mapProto._getNewPixelOrigin.call(this, center, zoom);
|
|
350
|
+
return mapProto._getNewPixelOrigin.call(this, center, zoom);
|
|
191
351
|
}
|
|
192
352
|
return this.project(center, zoom)
|
|
193
353
|
.rotate(this._bearing)
|
|
@@ -198,10 +358,72 @@ L.Map.include({
|
|
|
198
358
|
._round();
|
|
199
359
|
},
|
|
200
360
|
|
|
361
|
+
/**
|
|
362
|
+
* @since leaflet-rotate (v0.2)
|
|
363
|
+
*
|
|
364
|
+
* @see src\layer\tile\GridLayer::_getTiledPixelBounds()
|
|
365
|
+
*/
|
|
366
|
+
_getNewPixelBounds: function(center, zoom) {
|
|
367
|
+
center = center || this.getCenter();
|
|
368
|
+
zoom = zoom || this.getZoom();
|
|
369
|
+
if (!this._rotate && mapProto._getNewPixelBounds) {
|
|
370
|
+
return mapProto._getNewPixelBounds.apply(this, arguments);
|
|
371
|
+
}
|
|
372
|
+
var mapZoom = this._animatingZoom ? Math.max(this._animateToZoom, this.getZoom()) : this.getZoom(),
|
|
373
|
+
scale = this.getZoomScale(mapZoom, zoom),
|
|
374
|
+
pixelCenter = this.project(center, zoom).floor(),
|
|
375
|
+
size = this.getSize(),
|
|
376
|
+
halfSize = new L.Bounds([
|
|
377
|
+
this.containerPointToLayerPoint([0, 0]).floor(),
|
|
378
|
+
this.containerPointToLayerPoint([size.x, 0]).floor(),
|
|
379
|
+
this.containerPointToLayerPoint([0, size.y]).floor(),
|
|
380
|
+
this.containerPointToLayerPoint([size.x, size.y]).floor()
|
|
381
|
+
]).getSize().divideBy(scale * 2);
|
|
382
|
+
|
|
383
|
+
return new L.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
|
|
384
|
+
},
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* @since leaflet-rotate (v0.2)
|
|
388
|
+
*
|
|
389
|
+
* @return {L.Point} map pivot point (center)
|
|
390
|
+
*/
|
|
391
|
+
_getPixelCenter: function() {
|
|
392
|
+
if (!this._rotate && mapProto._getPixelCenter) {
|
|
393
|
+
return mapProto._getPixelCenter.apply(this, arguments);
|
|
394
|
+
}
|
|
395
|
+
return this.getSize()._divideBy(2)._subtract(this._getMapPanePos());
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* @since leaflet-rotate (v0.2)
|
|
400
|
+
*
|
|
401
|
+
* @see src\layer\vector\Renderer::_update()
|
|
402
|
+
*/
|
|
403
|
+
_getPaddedPixelBounds: function(padding) {
|
|
404
|
+
if (!this._rotate && mapProto._getPaddedPixelBounds) {
|
|
405
|
+
return mapProto._getPaddedPixelBounds.apply(this, arguments);
|
|
406
|
+
}
|
|
407
|
+
var p = padding,
|
|
408
|
+
size = this.getSize(),
|
|
409
|
+
padMin = size.multiplyBy(-p),
|
|
410
|
+
padMax = size.multiplyBy(1 + p);
|
|
411
|
+
//min = this.containerPointToLayerPoint(size.multiplyBy(-p)).round();
|
|
412
|
+
|
|
413
|
+
return new L.Bounds([
|
|
414
|
+
this.containerPointToLayerPoint([padMin.x, padMin.y]).floor(),
|
|
415
|
+
this.containerPointToLayerPoint([padMin.x, padMax.y]).floor(),
|
|
416
|
+
this.containerPointToLayerPoint([padMax.x, padMin.y]).floor(),
|
|
417
|
+
this.containerPointToLayerPoint([padMax.x, padMax.y]).floor()
|
|
418
|
+
]);
|
|
419
|
+
},
|
|
420
|
+
|
|
201
421
|
_handleGeolocationResponse: function(pos) {
|
|
422
|
+
if (!this._container._leaflet_id) { return; }
|
|
423
|
+
|
|
202
424
|
var lat = pos.coords.latitude,
|
|
203
425
|
lng = pos.coords.longitude,
|
|
204
|
-
|
|
426
|
+
/** @TODO use mapProto._handleGeolocationResponse */
|
|
205
427
|
hdg = pos.coords.heading,
|
|
206
428
|
latlng = new L.LatLng(lat, lng),
|
|
207
429
|
bounds = latlng.toBounds(pos.coords.accuracy),
|
|
@@ -216,7 +438,7 @@ L.Map.include({
|
|
|
216
438
|
latlng: latlng,
|
|
217
439
|
bounds: bounds,
|
|
218
440
|
timestamp: pos.timestamp,
|
|
219
|
-
|
|
441
|
+
/** @TODO use mapProto._handleGeolocationResponse */
|
|
220
442
|
heading: hdg
|
|
221
443
|
};
|
|
222
444
|
|
|
@@ -232,4 +454,52 @@ L.Map.include({
|
|
|
232
454
|
this.fire('locationfound', data);
|
|
233
455
|
},
|
|
234
456
|
|
|
457
|
+
/**
|
|
458
|
+
* Given latlng bounds, returns the bounds in projected pixel
|
|
459
|
+
* relative to the map container.
|
|
460
|
+
*
|
|
461
|
+
* @see https://github.com/ronikar/Leaflet/blob/5c480ef959b947c3beed7065425a5a36c486262b/src/map/Map.js#L1114-L1135
|
|
462
|
+
*
|
|
463
|
+
* @param {L.LatLngBounds} bounds
|
|
464
|
+
* @returns {L.Bounds}
|
|
465
|
+
*/
|
|
466
|
+
// boundsToContainerBounds: function (bounds) {
|
|
467
|
+
// if (this._rotate) {
|
|
468
|
+
// var northWest = this.latLngToContainerPoint(bounds.getNorthWest());
|
|
469
|
+
// var northEast = this.latLngToContainerPoint(bounds.getNorthEast());
|
|
470
|
+
// var southWest = this.latLngToContainerPoint(bounds.getSouthWest());
|
|
471
|
+
// var southEast = this.latLngToContainerPoint(bounds.getSouthEast());
|
|
472
|
+
//
|
|
473
|
+
// var minX = Math.min(northWest.x, northEast.x, southEast.x, southWest.x);
|
|
474
|
+
// var maxX = Math.max(northWest.x, northEast.x, southEast.x, southWest.x);
|
|
475
|
+
// var minY = Math.min(northWest.y, northEast.y, southEast.y, southWest.y);
|
|
476
|
+
// var maxY = Math.max(northWest.y, northEast.y, southEast.y, southWest.y);
|
|
477
|
+
//
|
|
478
|
+
// return L.bounds(
|
|
479
|
+
// L.point(minX, minY).multiplyBy(-1),
|
|
480
|
+
// L.point(maxX, maxY).multiplyBy(-1).add(this.getSize())
|
|
481
|
+
// );
|
|
482
|
+
// } else {
|
|
483
|
+
// return L.Bounds(
|
|
484
|
+
// this.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
|
|
485
|
+
// this.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1).add(this.getSize())
|
|
486
|
+
// );
|
|
487
|
+
// }
|
|
488
|
+
// },
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* @see https://github.com/ronikar/Leaflet/blob/5c480ef959b947c3beed7065425a5a36c486262b/src/geo/LatLngBounds.js#L253-L264
|
|
492
|
+
*
|
|
493
|
+
* @param {L.Bounds} points
|
|
494
|
+
* @returns {L.Bounds}
|
|
495
|
+
*/
|
|
496
|
+
// toCircumscribedBounds(points) {
|
|
497
|
+
// var minX = points.reduce(function (pv, v) { return Math.min(pv, v.x); }, points[0].x),
|
|
498
|
+
// maxX = points.reduce(function (pv, v) { return Math.max(pv, v.x); }, points[0].x),
|
|
499
|
+
// minY = points.reduce(function (pv, v) { return Math.min(pv, v.y); }, points[0].y),
|
|
500
|
+
// maxY = points.reduce(function (pv, v) { return Math.max(pv, v.y); }, points[0].y);
|
|
501
|
+
//
|
|
502
|
+
// return L.bounds(L.point(minX, minY), L.point(maxX, maxY));
|
|
503
|
+
// },
|
|
504
|
+
|
|
235
505
|
});
|
|
@@ -1,34 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
1
|
+
/**
|
|
2
|
+
* Rotates the map according to a smartphone's compass.
|
|
3
|
+
*
|
|
4
|
+
* @typedef L.Map.CompassBearing
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
L.Map.CompassBearing = L.Handler.extend({
|
|
6
8
|
|
|
7
9
|
initialize: function(map) {
|
|
8
|
-
if (!window.DeviceOrientationEvent) {
|
|
9
|
-
this._capable = false;
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
this._capable = true;
|
|
13
10
|
this._map = map;
|
|
14
|
-
|
|
15
11
|
this._throttled = L.Util.throttle(this._onDeviceOrientation, 1000, this);
|
|
16
12
|
},
|
|
17
13
|
|
|
18
14
|
addHooks: function() {
|
|
19
|
-
if (this.
|
|
15
|
+
if (this._map._rotate && window.DeviceOrientationEvent) {
|
|
20
16
|
L.DomEvent.on(window, 'deviceorientation', this._throttled, this);
|
|
21
17
|
}
|
|
22
18
|
},
|
|
23
19
|
|
|
24
20
|
removeHooks: function() {
|
|
25
|
-
if (this.
|
|
21
|
+
if (this._map._rotate && window.DeviceOrientationEvent) {
|
|
26
22
|
L.DomEvent.off(window, 'deviceorientation', this._throttled, this);
|
|
27
23
|
}
|
|
28
24
|
},
|
|
29
25
|
|
|
30
26
|
_onDeviceOrientation: function(event) {
|
|
31
|
-
if (event.alpha !== null) {
|
|
27
|
+
if (event.alpha !== null && window.orientation !== undefined) {
|
|
32
28
|
this._map.setBearing(event.alpha - window.orientation);
|
|
33
29
|
}
|
|
34
30
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
1
|
+
/**
|
|
2
|
+
* Triggers `invalidateResize` when the map's DOM container mutates.
|
|
3
|
+
*
|
|
4
|
+
* @typedef L.Map.ContainerMutation
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
// @namespace Map
|
|
@@ -17,9 +19,10 @@ L.Map.mergeOptions({
|
|
|
17
19
|
L.Map.ContainerMutation = L.Handler.extend({
|
|
18
20
|
|
|
19
21
|
addHooks: function() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
/** @TODO check again this property. Will likely be added in future releases (leaflet > v1.9.3) */
|
|
23
|
+
// if (!L.Browser.mutation) {
|
|
24
|
+
// return;
|
|
25
|
+
// }
|
|
23
26
|
|
|
24
27
|
if (!this._observer) {
|
|
25
28
|
this._observer = new MutationObserver(L.Util.bind(this._onMutation, this));
|
|
@@ -35,9 +38,10 @@ L.Map.ContainerMutation = L.Handler.extend({
|
|
|
35
38
|
},
|
|
36
39
|
|
|
37
40
|
removeHooks: function() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
/** @TODO check again this property. Will likely be added in future releases (leaflet > v1.9.3) */
|
|
42
|
+
// if (!L.Browser.mutation) {
|
|
43
|
+
// return;
|
|
44
|
+
// }
|
|
41
45
|
this._observer.disconnect();
|
|
42
46
|
},
|
|
43
47
|
|