Search code examples
javascriptgoogle-mapsmathgeolocationgeometry

Find centerpoint of polygon in JavaScript


I have a "place" object from Google Maps which has a set of coordinates that represent a bounding box for a given location, say London. Each set of coordinates has a latitude and longitude.

I have written the below code to find the centerpoint, but I am not sure if it does actually produce the centerpoint. What if the polygon has 5 points instead of 4? Also, can this be done in a more efficient way, with less operations?

function average(array) {
  // Add together and then divide by the length
  return _.reduce(array, function (sum, num) {
    return sum + num;
  }, 0) / array.length;
}

// I have a two-dimensional array that I want to get the average of

var coords = [
  [ -1.2, 5.1 ],
  [ -1.3, 5.2 ],
  [ -1.8, 5.9 ],
  [ -1.9, 5.8 ]
]

// So I get the first column

var lats = coords.map(function (coord) {
  return coord[0];
})

// Then the second

var longs = coords.map(function (coord) {
  return coord[1];
})

// And average each column out

console.log([average(lats), average(longs)])

Example.


Solution

  • This should get the centroid of the area of any polygon

    /*jslint sub: true, maxerr: 50, indent: 4, browser: true */
    /*global console */
    
    (function () {
        "use strict";
    
        function Point(x, y) {
            this.x = x;
            this.y = y;
        }
    
        function Region(points) {
            this.points = points || [];
            this.length = points.length;
        }
    
        Region.prototype.area = function () {
            var area = 0,
                i,
                j,
                point1,
                point2;
    
            for (i = 0, j = this.length - 1; i < this.length; j=i,i++) {
                point1 = this.points[i];
                point2 = this.points[j];
                area += point1.x * point2.y;
                area -= point1.y * point2.x;
            }
            area /= 2;
    
            return area;
        };
    
        Region.prototype.centroid = function () {
            var x = 0,
                y = 0,
                i,
                j,
                f,
                point1,
                point2;
    
            for (i = 0, j = this.length - 1; i < this.length; j=i,i++) {
                point1 = this.points[i];
                point2 = this.points[j];
                f = point1.x * point2.y - point2.x * point1.y;
                x += (point1.x + point2.x) * f;
                y += (point1.y + point2.y) * f;
            }
    
            f = this.area() * 6;
    
            return new Point(x / f, y / f);
        };
    
        var polygon = [
                {"x": -1.2, "y": 5.1},
                {"x": -1.3, "y": 5.2},
                {"x": -1.8, "y": 5.9},
                {"x": -1.9, "y": 5.8}
            ],
            region = new Region(polygon);
    
        console.log(region.centroid());
    }());
    

    On jsfiddle