最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get bounding box of polygon - Stack Overflow

programmeradmin2浏览0评论

I have many plicated 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 javascript 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.

I have many plicated 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 javascript 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.

Share Improve this question edited Jun 13, 2017 at 6:46 beaver 17.6k2 gold badges43 silver badges68 bronze badges asked Jan 17, 2016 at 2:28 SoloSolo 6,9678 gold badges38 silver badges75 bronze badges 3
  • Please include some code to show how you display that polygon. Is it an image? SVG? Tiny elements? – Oriol Commented Jan 17, 2016 at 2:38
  • Unless the points are stored in an efficient datastructure (like a kde-tree), there is no more efficient solution than iterating over the points. – willeM_ Van Onsem Commented Jan 17, 2016 at 2:42
  • @Oriol Updated my question with code. – Solo Commented Jan 17, 2016 at 3:14
Add a ment  | 

4 Answers 4

Reset to default 3

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 pact 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 k-d tree. Say for instance all the points are static, you can store them in such k-d 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.

发布评论

评论列表(0)

  1. 暂无评论