Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the center of Leaflet polygon?

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 to determin or be given the center of the polygon.

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

  1. find a way to use the coordinates of a polygon to determine the center of the polygon where the popup will open.

  2. call one point of the polygon, then offset the position of the popup.

  3. Use an id for each polygon, so each popup knows the box area (polygon) it can be opened in.

Can someone help me please?

like image 499
Nxlevel Avatar asked Apr 01 '14 20:04

Nxlevel


People also ask

How do you find the center of a polygon in a leaflet?

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.

How do you know if a point is inside a polygon leaflet?

Use the Ray Casting algorithm for checking if a point (marker) lies inside of a polygon: function isMarkerInsidePolygon(marker, poly) { var polyPoints = poly. getLatLngs(); var x = marker.


2 Answers

Since some time Leaflet has built-in getCenter() method:

polygon.getBounds().getCenter(); 
like image 52
yarl Avatar answered Oct 12 '22 02:10

yarl


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];         } 
like image 43
Steve Clanton Avatar answered Oct 12 '22 03:10

Steve Clanton