Merge pull request #3372 from Leaflet/polygon-getcenter

Fix Polygon.getCenter returning invalid LatLng when all points in same pixel
This commit is contained in:
Vladimir Agafonkin 2015-04-12 20:37:11 +03:00
commit 7b1ddd8c73
2 changed files with 35 additions and 4 deletions

View File

@ -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]));
});
});
});

View File

@ -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) {