From 7ff0fa9c7296f111903980219e53bc21f6441989 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Fri, 3 Jan 2014 00:37:34 +0200 Subject: [PATCH] approximate Circle with ellipse --- spec/suites/layer/vector/CircleSpec.js | 9 +++++---- src/layer/vector/Circle.js | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/spec/suites/layer/vector/CircleSpec.js b/spec/suites/layer/vector/CircleSpec.js index c9ebb6e1..e5d2f5db 100644 --- a/spec/suites/layer/vector/CircleSpec.js +++ b/spec/suites/layer/vector/CircleSpec.js @@ -1,17 +1,18 @@ describe('Circle', function () { describe('#getBounds', function () { - var circle; + var map, circle; beforeEach(function () { - circle = L.circle([50, 30], 200); + map = L.map(document.createElement('div')).setView([0, 0], 4); + circle = L.circle([50, 30], 200).addTo(map); }); it('returns bounds', function () { var bounds = circle.getBounds(); - expect(bounds.getSouthWest().equals([49.998203369, 29.997204939])).to.be.ok(); - expect(bounds.getNorthEast().equals([50.001796631, 30.002795061])).to.be.ok(); + expect(bounds.getSouthWest()).nearLatLng(new L.LatLng(49.95122, 29.88281)); + expect(bounds.getNorthEast()).nearLatLng(new L.LatLng(50.06419, 30.05859)); }); }); }); diff --git a/src/layer/vector/Circle.js b/src/layer/vector/Circle.js index d201657c..1c7d002f 100644 --- a/src/layer/vector/Circle.js +++ b/src/layer/vector/Circle.js @@ -21,7 +21,7 @@ L.Circle = L.CircleMarker.extend({ }, getBounds: function () { - var half = [this._radius, this._radius]; + var half = [this._radius, this._radiusY]; return new L.LatLngBounds( this._map.layerPointToLatLng(this._point.subtract(half)), @@ -31,14 +31,20 @@ L.Circle = L.CircleMarker.extend({ setStyle: L.Path.prototype.setStyle, _project: function () { - var crs = this._map.options.crs, - p1 = crs.project(this._latlng), - latlng2 = crs.unproject(p1.subtract([this._mRadius, 0])); - var pointLeft = this._map.latLngToLayerPoint(latlng2); + var lng = this._latlng.lng, + map = this._map, - this._point = this._map.latLngToLayerPoint(this._latlng); - this._radius = Math.max(this._point.x - pointLeft.x, 1); + latR = 360 * this._mRadius / (2 * L.CRS.Earth.R * Math.PI), + top = map.latLngToLayerPoint([this._latlng.lat + latR, lng]), + bottom = map.latLngToLayerPoint([this._latlng.lat - latR, lng]), + p = this._point = top.add(bottom).divideBy(2), + newLat = map.layerPointToLatLng(p).lat, + lngR = latR / Math.cos(newLat * Math.PI / 180), + left = map.latLngToLayerPoint([newLat, lng - lngR]); + + this._radius = Math.max(p.x - left.x, 1); + this._radiusY = Math.max(p.y - top.y, 1); this._updateBounds(); }