Nxlevel - 1 year ago 207

HTML Question

I have a bunch of leaflet polygons on a map I created. Each polygon represents something different. A specific set of information is displayed in a popup depending on the page the user is on. I need to find a way to make the "popup" bubble open in the center of the polygon it represents.

Each polygon is drawn using the following code:

`var L20 = [`

[74.0995, -99.92615],

[74.14008, -99.4043],

[74.07691, -99.33838],

[74.03617, -99.86023]

];

var L19 = [

[74.02559, -99.84924],

[74.06636, -99.32739],

[74.0029, -99.26147],

[73.96197, -99.77783]

];

var L18 = [

[73.95142, -99.76684],

[73.99235, -99.25048],

[73.92889, -99.18456],

[73.8878, -99.69543]

];

var set1 = L.polygon([L20, L19, L18], {

color: "#fff",

weight: 1,

stroke: true,

opacity: 0.05,

fillColor: "#346B1F",

}).addTo(map);

The popup is drawn using the following code:

`var popup = L.popup({})`

.setLatLng([73.64017, -100.32715])

.setContent(content).openOn(map);

var popup = L.popup();

So I need to find a way for

`.setLatLang`

I came up with 3 solutions that may work, not sure how to go about it.

- find a way to use the coordinates of a polygon to determine the center of the polygon where the popup will open.
- call one point of the polygon, then offset the position of the popup.
- Use an id for each polygon, so each popup knows the box area (polygon) it can be opened in.

Can someone help me please?

Answer Source

There are a few ways to approximate the centroid of a polygon.

The easiest (but least accurate method) is to get the center of the bounding box that contains the polygon, as yarl suggested, using `polygon.getBounds().getCenter();`

I originally answered the question with the formula for finding the centroid of the points, which can be found by averaging the coordinates of its vertices.

```
var getCentroid = function (arr) {
return arr.reduce(function (x,y) {
return [x[0] + y[0]/arr.length, x[1] + y[1]/arr.length]
}, [0,0])
}
centerL20 = getCentroid(L20);
```

While the centroid of the points is a close enough approximation to trick me, a commenter pointed out that it is not the centroid *of the polygon*.

An implementation based on the formula for a centroid of a non-self-intersecting closed polygon gives the correct result:

```
var getCentroid2 = function (arr) {
var twoTimesSignedArea = 0;
var cxTimes6SignedArea = 0;
var cyTimes6SignedArea = 0;
var length = arr.length
var x = function (i) { return arr[i % length][0] };
var y = function (i) { return arr[i % length][1] };
for ( var i = 0; i < arr.length; i++) {
var twoSA = x(i)*y(i+1) - x(i+1)*y(i);
twoTimesSignedArea += twoSA;
cxTimes6SignedArea += (x(i) + x(i+1)) * twoSA;
cyTimes6SignedArea += (y(i) + y(i+1)) * twoSA;
}
var sixSignedArea = 3 * twoTimesSignedArea;
return [ cxTimes6SignedArea / sixSignedArea, cyTimes6SignedArea / sixSignedArea];
}
```