From 3336bcbbe9243abeeb430084b704c51d56542939 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sun, 12 Apr 2015 18:33:56 +0200 Subject: [PATCH] Fix Polygon.getCenter returning invalid LatLng when all points in same pixel --- spec/suites/layer/vector/PolygonSpec.js | 22 ++++++++++++++++++++++ src/layer/vector/Polygon.js | 17 +++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/spec/suites/layer/vector/PolygonSpec.js b/spec/suites/layer/vector/PolygonSpec.js index 07c0170f..40f69e33 100644 --- a/spec/suites/layer/vector/PolygonSpec.js +++ b/spec/suites/layer/vector/PolygonSpec.js @@ -93,4 +93,26 @@ describe('Polygon', function () { expect(polygon._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 simple polygon around equator', function () { + var latlngs = [ + [[0, 0], [10, 0], [10, 10], [0, 10]] + ]; + var layer = new L.Polygon(latlngs).addTo(map); + expect(layer.getCenter()).to.be.nearLatLng(L.latLng([5, 5]), 1e-1); + }); + + it('should compute center of a small simple polygon', function () { + var latlngs = [ + [[0, 0], [0.010, 0], [0.010, 0.010], [0, 0.010]] + ]; + var layer = new L.Polygon(latlngs).addTo(map); + map.setZoom(0); // Make the polygon disappear in screen. + expect(layer.getCenter()).to.be.nearLatLng(L.latLng([0, 0])); + }); + + }); + }); diff --git a/src/layer/vector/Polygon.js b/src/layer/vector/Polygon.js index f35bc6df..dacf1633 100644 --- a/src/layer/vector/Polygon.js +++ b/src/layer/vector/Polygon.js @@ -9,14 +9,17 @@ L.Polygon = L.Polyline.extend({ }, getCenter: function () { - var i, j, len, p1, p2, f, area, x, y, - points = this._rings[0]; + var i, j, p1, p2, f, area, x, y, center, + points = this._rings[0], + len = points.length; + + if (!len) { return null; } // polygon centroid algorithm; only uses the first ring if there are multiple area = x = y = 0; - for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { + for (i = 0, j = len - 1; i < len; j = i++) { p1 = points[i]; p2 = points[j]; @@ -26,7 +29,13 @@ L.Polygon = L.Polyline.extend({ area += f * 3; } - return this._map.layerPointToLatLng([x / area, y / area]); + if (area === 0) { + // Polygon is so small that all points are on same pixel. + center = points[0]; + } else { + center = [x / area, y / area]; + } + return this._map.layerPointToLatLng(center); }, _convertLatLngs: function (latlngs) {