diff --git a/spec/suites/layer/vector/PolylineSpec.js b/spec/suites/layer/vector/PolylineSpec.js index 176543e6..49349897 100644 --- a/spec/suites/layer/vector/PolylineSpec.js +++ b/spec/suites/layer/vector/PolylineSpec.js @@ -52,4 +52,40 @@ describe('Polyline', function () { expect(polyline._latlngs).to.eql([L.latLng([1, 2]), L.latLng([7, 8]), L.latLng([5, 6])]); }); }); + + describe('#getCenter', function () { + + it('should compute center of a big flat line on equator', function () { + var polyline = new L.Polyline([[0, 0], [0, 90]]).addTo(map); + expect(polyline.getCenter()).to.eql(L.latLng([0, 45])); + }); + + it('should compute center of a big flat line close to the pole', function () { + var polyline = new L.Polyline([[80, 0], [80, 90]]).addTo(map); + expect(polyline.getCenter()).to.be.nearLatLng(L.latLng([80, 45]), 1e-2); + }); + + it('should compute center of a big diagonal line', function () { + var polyline = new L.Polyline([[0, 0], [80, 80]]).addTo(map); + expect(polyline.getCenter()).to.be.nearLatLng(L.latLng([57, 40]), 1); + }); + + it('should compute center of a diagonal line close to the pole', function () { + var polyline = new L.Polyline([[70, 70], [84, 84]]).addTo(map); + expect(polyline.getCenter()).to.be.nearLatLng(L.latLng([79, 77]), 1); + }); + + it('should compute center of a big multiline', function () { + var polyline = new L.Polyline([[10, -80], [0, 0], [0, 10], [10, 90]]).addTo(map); + expect(polyline.getCenter()).to.be.nearLatLng(L.latLng([0, 5]), 1); + }); + + it('should compute center of a small flat line', function () { + var polyline = new L.Polyline([[0, 0], [0, 0.090]]).addTo(map); + map.setZoom(0); // Make the line disappear in screen; + expect(polyline.getCenter()).to.be.nearLatLng(L.latLng([0, 0]), 1e-2); + }); + + }); + }); diff --git a/src/layer/vector/Polyline.js b/src/layer/vector/Polyline.js index 9f2209fc..e548447d 100644 --- a/src/layer/vector/Polyline.js +++ b/src/layer/vector/Polyline.js @@ -74,12 +74,19 @@ L.Polyline = L.Path.extend({ points = this._rings[0], len = points.length; + if (!len) { return null; } + // polyline centroid algorithm; only uses the first ring if there are multiple for (i = 0, halfDist = 0; i < len - 1; i++) { halfDist += points[i].distanceTo(points[i + 1]) / 2; } + // The line is so small in the current view that all points are on the same pixel. + if (halfDist === 0) { + return this._map.layerPointToLatLng(points[0]); + } + for (i = 0, dist = 0; i < len - 1; i++) { p1 = points[i]; p2 = points[i + 1];