简体   繁体   中英

Get bounding box of polygon

I have many complicated polygons some with 750+ points. Is there an fast and efficient way to get bounding box? I would hate to loop throught every point and expand the bounding box..

Solution should be in or maybe there's a Google Maps API v3 function that I've missed.


Or should I hardcode the coordinates of bounding box and use these to decrease the load on client?

在此输入图像描述

How polygons are made:

//Coordinates
var coordinates = [ 
    new google.maps.LatLng(11,22),
    new google.maps.LatLng(11,22),
    new google.maps.LatLng(11,22),

    //etc up to 200, 500 or even 800 points
]

//Options
var options = {
    path: coordinates,
    strokeColor: "#222",
    strokeOpacity: 1,
    strokeWeight: 2,
    fillColor: "#000",
    fillOpacity: 0,
    zIndex: 0
}

//Create polygon
var polygon = new google.maps.Polygon( options );

//Show it on map
polygon.setMap( map );

I need to do my homework because live calculations are excluded for sure. I will probably need to do it the hard way but maybe some of you know some handy online tool which calculates bordering box based on inserted coords?

I need as simple as possible shape because I need to check if my polygon is in viewport and it would probably be a nightmare with 800 points because I don't know any other way besides looping through all the points.

Polygon has not a method getBounds on Google Maps API v3. You can implement it manually. But it contains fors. By the way. I have implemented getBounds method. It is a hard coded version. Link for the demo .

UPDATE

To get single border box for several polygons use union method of getBounds method.

var coordinates = [ 
   new google.maps.LatLng(10,15),
   new google.maps.LatLng(12,16),
   new google.maps.LatLng(11,18),
   new google.maps.LatLng(11,19),
   new google.maps.LatLng(13,21),
   new google.maps.LatLng(12,22),
   new google.maps.LatLng(13,24),
   new google.maps.LatLng(11,25),
   new google.maps.LatLng(8,23),
   new google.maps.LatLng(7,23),
   new google.maps.LatLng(8,21),
   new google.maps.LatLng(6,17),
   new google.maps.LatLng(9,16)
]

var coordinates_1 = [ 
   new google.maps.LatLng(15,28),
   new google.maps.LatLng(16,30),
   new google.maps.LatLng(17,30),
   new google.maps.LatLng(16,31),
   new google.maps.LatLng(16,32),
   new google.maps.LatLng(14,29),
]

var options = {
   path: coordinates,
   strokeColor: "#222",
   strokeOpacity: 1,
   strokeWeight: 2,
   fillColor: "#000",
   fillOpacity: 0,
   zIndex: 0,
   map: map
}

var options_1 = {
   path: coordinates_1,
   strokeColor: "#222",
   strokeOpacity: 1,
   strokeWeight: 2,
   fillColor: "#000",
   fillOpacity: 0,
   zIndex: 0
}

var polygon = new google.maps.Polygon(options);
var polygon_1 = new google.maps.Polygon(options_1);

if(!google.maps.Polygon.prototype.getBounds)
google.maps.Polygon.prototype.getBounds = function() {
    var bounds = new google.maps.LatLngBounds();
    var paths = this.getPaths();    
    for (var i = 0; i < paths.getLength(); i++) {
        var path = paths.getAt(i);
        for (var j = 0; j < path.getLength(); j++) {
            bounds.extend(path.getAt(j));
        }
    }
    return bounds;
}

var rectangle = new google.maps.Rectangle({
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: '#FF0000',
    fillOpacity: 0.35,
    map: map,
    bounds: polygon.getBounds()
  });

var rectangle_1 = new google.maps.Rectangle({
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: '#FF0000',
    fillOpacity: 0.35,
    map: map,
    bounds: polygon_1.getBounds()
  });

var rectangle_single = new google.maps.Rectangle({
    strokeColor: '#FFC000',
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: '#FFF000',
    fillOpacity: 0.35,
    map: map,
    bounds: polygon.getBounds().union(polygon_1.getBounds())
  });

A simpler and more compact version of the code is:

    google.maps.Polygon.prototype.getBounds = function() {
        var bounds = new google.maps.LatLngBounds();
        this.getPath().forEach(function(element,index){ bounds.extend(element); });
        return bounds;
    }

X and Y coordinates in an array then x and y array min and max. Though we need more then a picture to know what you exactly want and how.

If the points are given we no a priori structure, there is no more efficient way than iterating over the points and expanding the bounding box. Since you do not know anything in advance, any point can be a corner point (or edge point ) and therefore you have to take it into consideration. No algorithm can do it more efficiently.

If however you have control about the server that provides the coordinates, you can store the points in advance in a datastructure like a kd tree . Say for instance all the points are static, you can store them in such kd tree, and then you can defintely speed up things (although, as far as I know the problem is still O(n) , but you do not have to take all points into account).

The problem is however that you do not provide any information about the server side.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM