leaflet-with-dashoffset-canvas-fix 1.9.4

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.
Files changed (90) hide show
  1. package/CHANGELOG.md +2191 -0
  2. package/LICENSE +26 -0
  3. package/README.md +3 -0
  4. package/package.json +149 -0
  5. package/src/Leaflet.js +24 -0
  6. package/src/control/Control.Attribution.js +148 -0
  7. package/src/control/Control.Layers.js +443 -0
  8. package/src/control/Control.Scale.js +132 -0
  9. package/src/control/Control.Zoom.js +146 -0
  10. package/src/control/Control.js +174 -0
  11. package/src/control/index.js +17 -0
  12. package/src/core/Browser.js +220 -0
  13. package/src/core/Class.js +135 -0
  14. package/src/core/Events.js +344 -0
  15. package/src/core/Handler.js +57 -0
  16. package/src/core/Util.js +241 -0
  17. package/src/core/index.js +15 -0
  18. package/src/dom/DomEvent.DoubleTap.js +91 -0
  19. package/src/dom/DomEvent.Pointer.js +97 -0
  20. package/src/dom/DomEvent.js +315 -0
  21. package/src/dom/DomUtil.js +349 -0
  22. package/src/dom/Draggable.js +220 -0
  23. package/src/dom/PosAnimation.js +113 -0
  24. package/src/dom/index.js +9 -0
  25. package/src/geo/LatLng.js +137 -0
  26. package/src/geo/LatLngBounds.js +251 -0
  27. package/src/geo/crs/CRS.EPSG3395.js +20 -0
  28. package/src/geo/crs/CRS.EPSG3857.js +27 -0
  29. package/src/geo/crs/CRS.EPSG4326.js +23 -0
  30. package/src/geo/crs/CRS.Earth.js +33 -0
  31. package/src/geo/crs/CRS.Simple.js +36 -0
  32. package/src/geo/crs/CRS.js +139 -0
  33. package/src/geo/crs/index.js +15 -0
  34. package/src/geo/index.js +7 -0
  35. package/src/geo/projection/Projection.LonLat.js +28 -0
  36. package/src/geo/projection/Projection.Mercator.js +49 -0
  37. package/src/geo/projection/Projection.SphericalMercator.js +44 -0
  38. package/src/geo/projection/index.js +26 -0
  39. package/src/geometry/Bounds.js +219 -0
  40. package/src/geometry/LineUtil.js +306 -0
  41. package/src/geometry/Point.js +222 -0
  42. package/src/geometry/PolyUtil.js +129 -0
  43. package/src/geometry/Transformation.js +79 -0
  44. package/src/geometry/index.js +8 -0
  45. package/src/images/layers.svg +1 -0
  46. package/src/images/logo.svg +1 -0
  47. package/src/images/marker.svg +1 -0
  48. package/src/layer/DivOverlay.js +348 -0
  49. package/src/layer/FeatureGroup.js +94 -0
  50. package/src/layer/GeoJSON.js +452 -0
  51. package/src/layer/ImageOverlay.js +270 -0
  52. package/src/layer/Layer.js +275 -0
  53. package/src/layer/LayerGroup.js +159 -0
  54. package/src/layer/Popup.js +506 -0
  55. package/src/layer/SVGOverlay.js +50 -0
  56. package/src/layer/Tooltip.js +444 -0
  57. package/src/layer/VideoOverlay.js +106 -0
  58. package/src/layer/index.js +24 -0
  59. package/src/layer/marker/DivIcon.js +74 -0
  60. package/src/layer/marker/Icon.Default.js +66 -0
  61. package/src/layer/marker/Icon.js +165 -0
  62. package/src/layer/marker/Marker.Drag.js +161 -0
  63. package/src/layer/marker/Marker.js +419 -0
  64. package/src/layer/marker/index.js +8 -0
  65. package/src/layer/tile/GridLayer.js +923 -0
  66. package/src/layer/tile/TileLayer.WMS.js +137 -0
  67. package/src/layer/tile/TileLayer.js +289 -0
  68. package/src/layer/tile/index.js +6 -0
  69. package/src/layer/vector/Canvas.js +493 -0
  70. package/src/layer/vector/Circle.js +113 -0
  71. package/src/layer/vector/CircleMarker.js +109 -0
  72. package/src/layer/vector/Path.js +148 -0
  73. package/src/layer/vector/Polygon.js +159 -0
  74. package/src/layer/vector/Polyline.js +307 -0
  75. package/src/layer/vector/Rectangle.js +57 -0
  76. package/src/layer/vector/Renderer.getRenderer.js +45 -0
  77. package/src/layer/vector/Renderer.js +133 -0
  78. package/src/layer/vector/SVG.Util.js +39 -0
  79. package/src/layer/vector/SVG.VML.js +144 -0
  80. package/src/layer/vector/SVG.js +207 -0
  81. package/src/layer/vector/index.js +14 -0
  82. package/src/map/Map.js +1751 -0
  83. package/src/map/handler/Map.BoxZoom.js +152 -0
  84. package/src/map/handler/Map.DoubleClickZoom.js +55 -0
  85. package/src/map/handler/Map.Drag.js +235 -0
  86. package/src/map/handler/Map.Keyboard.js +183 -0
  87. package/src/map/handler/Map.ScrollWheelZoom.js +91 -0
  88. package/src/map/handler/Map.TapHold.js +102 -0
  89. package/src/map/handler/Map.TouchZoom.js +130 -0
  90. package/src/map/index.js +17 -0
@@ -0,0 +1,493 @@
1
+ import {Renderer} from './Renderer';
2
+ import * as DomUtil from '../../dom/DomUtil';
3
+ import * as DomEvent from '../../dom/DomEvent';
4
+ import Browser from '../../core/Browser';
5
+ import * as Util from '../../core/Util';
6
+ import {Bounds} from '../../geometry/Bounds';
7
+
8
+ /*
9
+ * @class Canvas
10
+ * @inherits Renderer
11
+ * @aka L.Canvas
12
+ *
13
+ * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
14
+ * Inherits `Renderer`.
15
+ *
16
+ * Due to [technical limitations](https://caniuse.com/canvas), Canvas is not
17
+ * available in all web browsers, notably IE8, and overlapping geometries might
18
+ * not display properly in some edge cases.
19
+ *
20
+ * @example
21
+ *
22
+ * Use Canvas by default for all paths in the map:
23
+ *
24
+ * ```js
25
+ * var map = L.map('map', {
26
+ * renderer: L.canvas()
27
+ * });
28
+ * ```
29
+ *
30
+ * Use a Canvas renderer with extra padding for specific vector geometries:
31
+ *
32
+ * ```js
33
+ * var map = L.map('map');
34
+ * var myRenderer = L.canvas({ padding: 0.5 });
35
+ * var line = L.polyline( coordinates, { renderer: myRenderer } );
36
+ * var circle = L.circle( center, { renderer: myRenderer } );
37
+ * ```
38
+ */
39
+
40
+ export var Canvas = Renderer.extend({
41
+
42
+ // @section
43
+ // @aka Canvas options
44
+ options: {
45
+ // @option tolerance: Number = 0
46
+ // How much to extend the click tolerance around a path/object on the map.
47
+ tolerance: 0
48
+ },
49
+
50
+ getEvents: function () {
51
+ var events = Renderer.prototype.getEvents.call(this);
52
+ events.viewprereset = this._onViewPreReset;
53
+ return events;
54
+ },
55
+
56
+ _onViewPreReset: function () {
57
+ // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
58
+ this._postponeUpdatePaths = true;
59
+ },
60
+
61
+ onAdd: function () {
62
+ Renderer.prototype.onAdd.call(this);
63
+
64
+ // Redraw vectors since canvas is cleared upon removal,
65
+ // in case of removing the renderer itself from the map.
66
+ this._draw();
67
+ },
68
+
69
+ _initContainer: function () {
70
+ var container = this._container = document.createElement('canvas');
71
+
72
+ DomEvent.on(container, 'mousemove', this._onMouseMove, this);
73
+ DomEvent.on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this);
74
+ DomEvent.on(container, 'mouseout', this._handleMouseOut, this);
75
+ container['_leaflet_disable_events'] = true;
76
+
77
+ this._ctx = container.getContext('2d');
78
+ },
79
+
80
+ _destroyContainer: function () {
81
+ Util.cancelAnimFrame(this._redrawRequest);
82
+ delete this._ctx;
83
+ DomUtil.remove(this._container);
84
+ DomEvent.off(this._container);
85
+ delete this._container;
86
+ },
87
+
88
+ _updatePaths: function () {
89
+ if (this._postponeUpdatePaths) { return; }
90
+
91
+ var layer;
92
+ this._redrawBounds = null;
93
+ for (var id in this._layers) {
94
+ layer = this._layers[id];
95
+ layer._update();
96
+ }
97
+ this._redraw();
98
+ },
99
+
100
+ _update: function () {
101
+ if (this._map._animatingZoom && this._bounds) { return; }
102
+
103
+ Renderer.prototype._update.call(this);
104
+
105
+ var b = this._bounds,
106
+ container = this._container,
107
+ size = b.getSize(),
108
+ m = Browser.retina ? 2 : 1;
109
+
110
+ DomUtil.setPosition(container, b.min);
111
+
112
+ // set canvas size (also clearing it); use double size on retina
113
+ container.width = m * size.x;
114
+ container.height = m * size.y;
115
+ container.style.width = size.x + 'px';
116
+ container.style.height = size.y + 'px';
117
+
118
+ if (Browser.retina) {
119
+ this._ctx.scale(2, 2);
120
+ }
121
+
122
+ // translate so we use the same path coordinates after canvas element moves
123
+ this._ctx.translate(-b.min.x, -b.min.y);
124
+
125
+ // Tell paths to redraw themselves
126
+ this.fire('update');
127
+ },
128
+
129
+ _reset: function () {
130
+ Renderer.prototype._reset.call(this);
131
+
132
+ if (this._postponeUpdatePaths) {
133
+ this._postponeUpdatePaths = false;
134
+ this._updatePaths();
135
+ }
136
+ },
137
+
138
+ _initPath: function (layer) {
139
+ this._updateDashArray(layer);
140
+ this._layers[Util.stamp(layer)] = layer;
141
+
142
+ var order = layer._order = {
143
+ layer: layer,
144
+ prev: this._drawLast,
145
+ next: null
146
+ };
147
+ if (this._drawLast) { this._drawLast.next = order; }
148
+ this._drawLast = order;
149
+ this._drawFirst = this._drawFirst || this._drawLast;
150
+ },
151
+
152
+ _addPath: function (layer) {
153
+ this._requestRedraw(layer);
154
+ },
155
+
156
+ _removePath: function (layer) {
157
+ var order = layer._order;
158
+ var next = order.next;
159
+ var prev = order.prev;
160
+
161
+ if (next) {
162
+ next.prev = prev;
163
+ } else {
164
+ this._drawLast = prev;
165
+ }
166
+ if (prev) {
167
+ prev.next = next;
168
+ } else {
169
+ this._drawFirst = next;
170
+ }
171
+
172
+ delete layer._order;
173
+
174
+ delete this._layers[Util.stamp(layer)];
175
+
176
+ this._requestRedraw(layer);
177
+ },
178
+
179
+ _updatePath: function (layer) {
180
+ // Redraw the union of the layer's old pixel
181
+ // bounds and the new pixel bounds.
182
+ this._extendRedrawBounds(layer);
183
+ layer._project();
184
+ layer._update();
185
+ // The redraw will extend the redraw bounds
186
+ // with the new pixel bounds.
187
+ this._requestRedraw(layer);
188
+ },
189
+
190
+ _updateStyle: function (layer) {
191
+ this._updateDashArray(layer);
192
+ this._requestRedraw(layer);
193
+ },
194
+
195
+ _updateDashArray: function (layer) {
196
+ if (typeof layer.options.dashArray === 'string') {
197
+ var parts = layer.options.dashArray.split(/[, ]+/),
198
+ dashArray = [],
199
+ dashValue,
200
+ i;
201
+ for (i = 0; i < parts.length; i++) {
202
+ dashValue = Number(parts[i]);
203
+ // Ignore dash array containing invalid lengths
204
+ if (isNaN(dashValue)) { return; }
205
+ dashArray.push(dashValue);
206
+ }
207
+ layer.options._dashArray = dashArray;
208
+ } else {
209
+ layer.options._dashArray = layer.options.dashArray;
210
+ }
211
+ },
212
+
213
+ _requestRedraw: function (layer) {
214
+ if (!this._map) { return; }
215
+
216
+ this._extendRedrawBounds(layer);
217
+ this._redrawRequest = this._redrawRequest || Util.requestAnimFrame(this._redraw, this);
218
+ },
219
+
220
+ _extendRedrawBounds: function (layer) {
221
+ if (layer._pxBounds) {
222
+ var padding = (layer.options.weight || 0) + 1;
223
+ this._redrawBounds = this._redrawBounds || new Bounds();
224
+ this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding]));
225
+ this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding]));
226
+ }
227
+ },
228
+
229
+ _redraw: function () {
230
+ this._redrawRequest = null;
231
+
232
+ if (this._redrawBounds) {
233
+ this._redrawBounds.min._floor();
234
+ this._redrawBounds.max._ceil();
235
+ }
236
+
237
+ this._clear(); // clear layers in redraw bounds
238
+ this._draw(); // draw layers
239
+
240
+ this._redrawBounds = null;
241
+ },
242
+
243
+ _clear: function () {
244
+ var bounds = this._redrawBounds;
245
+ if (bounds) {
246
+ var size = bounds.getSize();
247
+ this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y);
248
+ } else {
249
+ this._ctx.save();
250
+ this._ctx.setTransform(1, 0, 0, 1, 0, 0);
251
+ this._ctx.clearRect(0, 0, this._container.width, this._container.height);
252
+ this._ctx.restore();
253
+ }
254
+ },
255
+
256
+ _draw: function () {
257
+ var layer, bounds = this._redrawBounds;
258
+ this._ctx.save();
259
+ if (bounds) {
260
+ var size = bounds.getSize();
261
+ this._ctx.beginPath();
262
+ this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y);
263
+ this._ctx.clip();
264
+ }
265
+
266
+ this._drawing = true;
267
+
268
+ for (var order = this._drawFirst; order; order = order.next) {
269
+ layer = order.layer;
270
+ if (!bounds || (layer._pxBounds && layer._pxBounds.intersects(bounds))) {
271
+ layer._updatePath();
272
+ }
273
+ }
274
+
275
+ this._drawing = false;
276
+
277
+ this._ctx.restore(); // Restore state before clipping.
278
+ },
279
+
280
+ _updatePoly: function (layer, closed) {
281
+ if (!this._drawing) { return; }
282
+
283
+ var i, j, len2, p,
284
+ parts = layer._parts,
285
+ len = parts.length,
286
+ ctx = this._ctx;
287
+
288
+ if (!len) { return; }
289
+
290
+ ctx.beginPath();
291
+
292
+ for (i = 0; i < len; i++) {
293
+ for (j = 0, len2 = parts[i].length; j < len2; j++) {
294
+ p = parts[i][j];
295
+ ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y);
296
+ }
297
+ if (closed) {
298
+ ctx.closePath();
299
+ }
300
+ }
301
+
302
+ this._fillStroke(ctx, layer);
303
+
304
+ // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature
305
+ },
306
+
307
+ _updateCircle: function (layer) {
308
+
309
+ if (!this._drawing || layer._empty()) { return; }
310
+
311
+ var p = layer._point,
312
+ ctx = this._ctx,
313
+ r = Math.max(Math.round(layer._radius), 1),
314
+ s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
315
+
316
+ if (s !== 1) {
317
+ ctx.save();
318
+ ctx.scale(1, s);
319
+ }
320
+
321
+ ctx.beginPath();
322
+ ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
323
+
324
+ if (s !== 1) {
325
+ ctx.restore();
326
+ }
327
+
328
+ this._fillStroke(ctx, layer);
329
+ },
330
+
331
+ _fillStroke: function (ctx, layer) {
332
+ var options = layer.options;
333
+
334
+ if (options.fill) {
335
+ ctx.globalAlpha = options.fillOpacity;
336
+ ctx.fillStyle = options.fillColor || options.color;
337
+ ctx.fill(options.fillRule || 'evenodd');
338
+ }
339
+
340
+ if (options.stroke && options.weight !== 0) {
341
+ if (ctx.setLineDash) {
342
+ ctx.lineDashOffset = Number(options.dashOffset || 0);
343
+ ctx.setLineDash(options._dashArray || []);
344
+ }
345
+ ctx.globalAlpha = options.opacity;
346
+ ctx.lineWidth = options.weight;
347
+ ctx.strokeStyle = options.color;
348
+ ctx.lineCap = options.lineCap;
349
+ ctx.lineJoin = options.lineJoin;
350
+ ctx.stroke();
351
+ }
352
+ },
353
+
354
+ // Canvas obviously doesn't have mouse events for individual drawn objects,
355
+ // so we emulate that by calculating what's under the mouse on mousemove/click manually
356
+
357
+ _onClick: function (e) {
358
+ var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer;
359
+
360
+ for (var order = this._drawFirst; order; order = order.next) {
361
+ layer = order.layer;
362
+ if (layer.options.interactive && layer._containsPoint(point)) {
363
+ if (!(e.type === 'click' || e.type === 'preclick') || !this._map._draggableMoved(layer)) {
364
+ clickedLayer = layer;
365
+ }
366
+ }
367
+ }
368
+ this._fireEvent(clickedLayer ? [clickedLayer] : false, e);
369
+ },
370
+
371
+ _onMouseMove: function (e) {
372
+ if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; }
373
+
374
+ var point = this._map.mouseEventToLayerPoint(e);
375
+ this._handleMouseHover(e, point);
376
+ },
377
+
378
+
379
+ _handleMouseOut: function (e) {
380
+ var layer = this._hoveredLayer;
381
+ if (layer) {
382
+ // if we're leaving the layer, fire mouseout
383
+ DomUtil.removeClass(this._container, 'leaflet-interactive');
384
+ this._fireEvent([layer], e, 'mouseout');
385
+ this._hoveredLayer = null;
386
+ this._mouseHoverThrottled = false;
387
+ }
388
+ },
389
+
390
+ _handleMouseHover: function (e, point) {
391
+ if (this._mouseHoverThrottled) {
392
+ return;
393
+ }
394
+
395
+ var layer, candidateHoveredLayer;
396
+
397
+ for (var order = this._drawFirst; order; order = order.next) {
398
+ layer = order.layer;
399
+ if (layer.options.interactive && layer._containsPoint(point)) {
400
+ candidateHoveredLayer = layer;
401
+ }
402
+ }
403
+
404
+ if (candidateHoveredLayer !== this._hoveredLayer) {
405
+ this._handleMouseOut(e);
406
+
407
+ if (candidateHoveredLayer) {
408
+ DomUtil.addClass(this._container, 'leaflet-interactive'); // change cursor
409
+ this._fireEvent([candidateHoveredLayer], e, 'mouseover');
410
+ this._hoveredLayer = candidateHoveredLayer;
411
+ }
412
+ }
413
+
414
+ this._fireEvent(this._hoveredLayer ? [this._hoveredLayer] : false, e);
415
+
416
+ this._mouseHoverThrottled = true;
417
+ setTimeout(Util.bind(function () {
418
+ this._mouseHoverThrottled = false;
419
+ }, this), 32);
420
+ },
421
+
422
+ _fireEvent: function (layers, e, type) {
423
+ this._map._fireDOMEvent(e, type || e.type, layers);
424
+ },
425
+
426
+ _bringToFront: function (layer) {
427
+ var order = layer._order;
428
+
429
+ if (!order) { return; }
430
+
431
+ var next = order.next;
432
+ var prev = order.prev;
433
+
434
+ if (next) {
435
+ next.prev = prev;
436
+ } else {
437
+ // Already last
438
+ return;
439
+ }
440
+ if (prev) {
441
+ prev.next = next;
442
+ } else if (next) {
443
+ // Update first entry unless this is the
444
+ // single entry
445
+ this._drawFirst = next;
446
+ }
447
+
448
+ order.prev = this._drawLast;
449
+ this._drawLast.next = order;
450
+
451
+ order.next = null;
452
+ this._drawLast = order;
453
+
454
+ this._requestRedraw(layer);
455
+ },
456
+
457
+ _bringToBack: function (layer) {
458
+ var order = layer._order;
459
+
460
+ if (!order) { return; }
461
+
462
+ var next = order.next;
463
+ var prev = order.prev;
464
+
465
+ if (prev) {
466
+ prev.next = next;
467
+ } else {
468
+ // Already first
469
+ return;
470
+ }
471
+ if (next) {
472
+ next.prev = prev;
473
+ } else if (prev) {
474
+ // Update last entry unless this is the
475
+ // single entry
476
+ this._drawLast = prev;
477
+ }
478
+
479
+ order.prev = null;
480
+
481
+ order.next = this._drawFirst;
482
+ this._drawFirst.prev = order;
483
+ this._drawFirst = order;
484
+
485
+ this._requestRedraw(layer);
486
+ }
487
+ });
488
+
489
+ // @factory L.canvas(options?: Renderer options)
490
+ // Creates a Canvas renderer with the given options.
491
+ export function canvas(options) {
492
+ return Browser.canvas ? new Canvas(options) : null;
493
+ }
@@ -0,0 +1,113 @@
1
+ import {CircleMarker} from './CircleMarker';
2
+ import {Path} from './Path';
3
+ import * as Util from '../../core/Util';
4
+ import {toLatLng} from '../../geo/LatLng';
5
+ import {LatLngBounds} from '../../geo/LatLngBounds';
6
+ import {Earth} from '../../geo/crs/CRS.Earth';
7
+
8
+
9
+ /*
10
+ * @class Circle
11
+ * @aka L.Circle
12
+ * @inherits CircleMarker
13
+ *
14
+ * A class for drawing circle overlays on a map. Extends `CircleMarker`.
15
+ *
16
+ * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion).
17
+ *
18
+ * @example
19
+ *
20
+ * ```js
21
+ * L.circle([50.5, 30.5], {radius: 200}).addTo(map);
22
+ * ```
23
+ */
24
+
25
+ export var Circle = CircleMarker.extend({
26
+
27
+ initialize: function (latlng, options, legacyOptions) {
28
+ if (typeof options === 'number') {
29
+ // Backwards compatibility with 0.7.x factory (latlng, radius, options?)
30
+ options = Util.extend({}, legacyOptions, {radius: options});
31
+ }
32
+ Util.setOptions(this, options);
33
+ this._latlng = toLatLng(latlng);
34
+
35
+ if (isNaN(this.options.radius)) { throw new Error('Circle radius cannot be NaN'); }
36
+
37
+ // @section
38
+ // @aka Circle options
39
+ // @option radius: Number; Radius of the circle, in meters.
40
+ this._mRadius = this.options.radius;
41
+ },
42
+
43
+ // @method setRadius(radius: Number): this
44
+ // Sets the radius of a circle. Units are in meters.
45
+ setRadius: function (radius) {
46
+ this._mRadius = radius;
47
+ return this.redraw();
48
+ },
49
+
50
+ // @method getRadius(): Number
51
+ // Returns the current radius of a circle. Units are in meters.
52
+ getRadius: function () {
53
+ return this._mRadius;
54
+ },
55
+
56
+ // @method getBounds(): LatLngBounds
57
+ // Returns the `LatLngBounds` of the path.
58
+ getBounds: function () {
59
+ var half = [this._radius, this._radiusY || this._radius];
60
+
61
+ return new LatLngBounds(
62
+ this._map.layerPointToLatLng(this._point.subtract(half)),
63
+ this._map.layerPointToLatLng(this._point.add(half)));
64
+ },
65
+
66
+ setStyle: Path.prototype.setStyle,
67
+
68
+ _project: function () {
69
+
70
+ var lng = this._latlng.lng,
71
+ lat = this._latlng.lat,
72
+ map = this._map,
73
+ crs = map.options.crs;
74
+
75
+ if (crs.distance === Earth.distance) {
76
+ var d = Math.PI / 180,
77
+ latR = (this._mRadius / Earth.R) / d,
78
+ top = map.project([lat + latR, lng]),
79
+ bottom = map.project([lat - latR, lng]),
80
+ p = top.add(bottom).divideBy(2),
81
+ lat2 = map.unproject(p).lat,
82
+ lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) /
83
+ (Math.cos(lat * d) * Math.cos(lat2 * d))) / d;
84
+
85
+ if (isNaN(lngR) || lngR === 0) {
86
+ lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425
87
+ }
88
+
89
+ this._point = p.subtract(map.getPixelOrigin());
90
+ this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x;
91
+ this._radiusY = p.y - top.y;
92
+
93
+ } else {
94
+ var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0]));
95
+
96
+ this._point = map.latLngToLayerPoint(this._latlng);
97
+ this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x;
98
+ }
99
+
100
+ this._updateBounds();
101
+ }
102
+ });
103
+
104
+ // @factory L.circle(latlng: LatLng, options?: Circle options)
105
+ // Instantiates a circle object given a geographical point, and an options object
106
+ // which contains the circle radius.
107
+ // @alternative
108
+ // @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options)
109
+ // Obsolete way of instantiating a circle, for compatibility with 0.7.x code.
110
+ // Do not use in new applications or plugins.
111
+ export function circle(latlng, options, legacyOptions) {
112
+ return new Circle(latlng, options, legacyOptions);
113
+ }
@@ -0,0 +1,109 @@
1
+ import {Path} from './Path';
2
+ import * as Util from '../../core/Util';
3
+ import {toLatLng} from '../../geo/LatLng';
4
+ import {Bounds} from '../../geometry/Bounds';
5
+
6
+
7
+ /*
8
+ * @class CircleMarker
9
+ * @aka L.CircleMarker
10
+ * @inherits Path
11
+ *
12
+ * A circle of a fixed size with radius specified in pixels. Extends `Path`.
13
+ */
14
+
15
+ export var CircleMarker = Path.extend({
16
+
17
+ // @section
18
+ // @aka CircleMarker options
19
+ options: {
20
+ fill: true,
21
+
22
+ // @option radius: Number = 10
23
+ // Radius of the circle marker, in pixels
24
+ radius: 10
25
+ },
26
+
27
+ initialize: function (latlng, options) {
28
+ Util.setOptions(this, options);
29
+ this._latlng = toLatLng(latlng);
30
+ this._radius = this.options.radius;
31
+ },
32
+
33
+ // @method setLatLng(latLng: LatLng): this
34
+ // Sets the position of a circle marker to a new location.
35
+ setLatLng: function (latlng) {
36
+ var oldLatLng = this._latlng;
37
+ this._latlng = toLatLng(latlng);
38
+ this.redraw();
39
+
40
+ // @event move: Event
41
+ // Fired when the marker is moved via [`setLatLng`](#circlemarker-setlatlng). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
42
+ return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
43
+ },
44
+
45
+ // @method getLatLng(): LatLng
46
+ // Returns the current geographical position of the circle marker
47
+ getLatLng: function () {
48
+ return this._latlng;
49
+ },
50
+
51
+ // @method setRadius(radius: Number): this
52
+ // Sets the radius of a circle marker. Units are in pixels.
53
+ setRadius: function (radius) {
54
+ this.options.radius = this._radius = radius;
55
+ return this.redraw();
56
+ },
57
+
58
+ // @method getRadius(): Number
59
+ // Returns the current radius of the circle
60
+ getRadius: function () {
61
+ return this._radius;
62
+ },
63
+
64
+ setStyle : function (options) {
65
+ var radius = options && options.radius || this._radius;
66
+ Path.prototype.setStyle.call(this, options);
67
+ this.setRadius(radius);
68
+ return this;
69
+ },
70
+
71
+ _project: function () {
72
+ this._point = this._map.latLngToLayerPoint(this._latlng);
73
+ this._updateBounds();
74
+ },
75
+
76
+ _updateBounds: function () {
77
+ var r = this._radius,
78
+ r2 = this._radiusY || r,
79
+ w = this._clickTolerance(),
80
+ p = [r + w, r2 + w];
81
+ this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p));
82
+ },
83
+
84
+ _update: function () {
85
+ if (this._map) {
86
+ this._updatePath();
87
+ }
88
+ },
89
+
90
+ _updatePath: function () {
91
+ this._renderer._updateCircle(this);
92
+ },
93
+
94
+ _empty: function () {
95
+ return this._radius && !this._renderer._bounds.intersects(this._pxBounds);
96
+ },
97
+
98
+ // Needed by the `Canvas` renderer for interactivity
99
+ _containsPoint: function (p) {
100
+ return p.distanceTo(this._point) <= this._radius + this._clickTolerance();
101
+ }
102
+ });
103
+
104
+
105
+ // @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options)
106
+ // Instantiates a circle marker object given a geographical point, and an optional options object.
107
+ export function circleMarker(latlng, options) {
108
+ return new CircleMarker(latlng, options);
109
+ }