Find centerpoint of polygon in JavaScript

后端 未结 5 1182
余生分开走
余生分开走 2020-12-15 08:39

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 latit

相关标签:
5条回答
  • 2020-12-15 09:32

    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

    0 讨论(0)
  • 2020-12-15 09:32

    To get the bounds of a Polygon (with your data) in the Google Maps API v3 (not tested):

    var coords = [
      [ -1.2, 5.1 ],
      [ -1.3, 5.2 ],
      [ -1.8, 5.9 ],
      [ -1.9, 5.8 ]
    ];
    
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i<coords.length; i++) {
       bounds.extend(new google.maps.LatLng(coords[i][0], coords[i][1]));
    }
    var center = bounds.getCenter();
    
    var latitude = center.lat();           // latitude=-1.5499999999999998
    var longitude = center.lng();          // longitude=5.5
    var coordinates = center.toUrlValue(); // coordinates=-1.55,5.5
    

    var coords = [
      [-1.2, 5.1],
      [-1.3, 5.2],
      [-1.8, 5.9],
      [-1.9, 5.8]
    ];
    
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < coords.length; i++) {
      bounds.extend(new google.maps.LatLng(coords[i][0], coords[i][1]));
    }
    var center = bounds.getCenter();
    
    var latitude = center.lat();
    console.log("latitude=" + latitude);
    var longitude = center.lng();
    console.log("longitude=" + longitude);
    var coordinates = center.toUrlValue();
    console.log("coordinates=" + coordinates);
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>

    0 讨论(0)
  • 2020-12-15 09:36

    I realize this is not exactly what you are looking for, but in case no one else answers it may be of some help. This is a PHP function which I use to to find the center point of polygons for my map application. It should be fairly easily converted to javascript for your use.

    function getCenter($coord_array){
        $i = 0;
        $center = $coord_array[0];
        unset($coord_array[0]);
        foreach($coord_array as $key => $coord){    
            $plat = $coord[0];
            $plng = $coord[1];
            $clat = $center[0];
            $clng = $center[1];
            $mlat = ($plat + ($clat * $i)) / ($i + 1);
            $mlng = ($plng + ($clng * $i)) / ($i + 1);
            $center = array($mlat, $mlng);
            $i++;
        }
        return array($mlat, $mlng);
    }
    

    Note that the polygon has to be closed, meaning the first point in the array and the last point in the array are the same.

    The function that converts the coordinate string to the necessary array:

    function coordStringToArray($coord_string)
    {
        $coord_array = explode("\n",$coord_string);
        foreach($coord_array as $key => $coord){
            $coord_array[$key] = explode(', ',$coord);
        }
        return $coord_array;
    }
    

    A sample of the raw coordinate string:

    42.390576, -71.074258
    42.385822, -71.077091
    42.382461, -71.079408
    42.382018, -71.081468
    42.380496, -71.080953
    42.380433, -71.076576
    42.373902, -71.073915
    42.373078, -71.069967
    42.369273, -71.064216
    42.368892, -71.062328
    42.369527, -71.056491
    42.370288, -71.050741
    42.371619, -71.047908
    42.376185, -71.046278
    42.383476, -71.045763
    42.386139, -71.050483
    42.386202, -71.057693
    42.387597, -71.066534
    42.390259, -71.072284
    42.391210, -71.073658
    
    0 讨论(0)
  • 2020-12-15 09:39

    This will get the centerpoint of any shape as an array [centerX, centerY]:

    var center = function (arr)
    {
        var minX, maxX, minY, maxY;
        for (var i = 0; i < arr.length; i++)
        {
            minX = (arr[i][0] < minX || minX == null) ? arr[i][0] : minX;
            maxX = (arr[i][0] > maxX || maxX == null) ? arr[i][0] : maxX;
            minY = (arr[i][1] < minY || minY == null) ? arr[i][1] : minY;
            maxY = (arr[i][1] > maxY || maxY == null) ? arr[i][1] : maxY;
        }
        return [(minX + maxX) / 2, (minY + maxY) / 2];
    }
    

    Another way:

    var center = function (arr)
    {
        var x = arr.map (function (a){ return a[0] });
        var y = arr.map (function (a){ return a[1] });
        var minX = Math.min.apply (null, x);
        var maxX = Math.max.apply (null, x);
        var minY = Math.min.apply (null, y);
        var maxY = Math.max.apply (null, y);
        return [(minX + maxX) / 2, (minY + maxY) / 2];
    }
    getCenter (coords);
    

    Alternatively if your browser supports ECMAScript 6, then you can use Arrow functions and Spread syntax as follows:

    var center = function (arr)
    {
        var x = arr.map (xy => xy[0]);
        var y = arr.map (xy => xy[1]);
        var cx = (Math.min (...x) + Math.max (...x)) / 2;
        var cy = (Math.min (...y) + Math.max (...y)) / 2;
        return [cx, cy];
    }
    

    jsfiddle

    0 讨论(0)
  • 2020-12-15 09:42

    Here is my es6 solution to average an array of latitudes and longitudes. Average is not the exact center point but it gets the job done in my case.

    getLatLonCenterFromGeom = (coords) => {
        const arrAvg = arr => arr.reduce((a,b) => a + b, 0) / arr.length;
    
        const centerLat = arrAvg(coords.map(c=>c.latitude));
        const centerLon = arrAvg(coords.map(c=>c.longitude));
    
        if (isNaN(centerLat)|| isNaN(centerLon))
            return null;
        else return {latitude: centerLat, longitude:centerLon};
    }
    
    0 讨论(0)
提交回复
热议问题