Получить ограничивающую рамку многоугольника
У меня много сложных полигонов с 750+ точками. есть ли быстрый и эффективный способ, чтобы получить ограничивающий прямоугольник? Я бы не хотел, чтобы цикл через каждую точку и расширить ограничивающую коробку..
решение должно быть в в JavaScript или, может быть, есть функция Google Maps API v3, которую я пропустил.
или я должен жестко закодировать координаты ограничивающей рамки и использовать их для уменьшения нагрузки на клиент?
Как создаются полигоны:
//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 );
Мне нужно сделать домашнее задание, потому что живые вычисления исключены наверняка. Мне, вероятно, нужно будет сделать это тяжелым способом, но может быть, некоторые из вас знают какой-то удобный онлайн-инструмент, который вычисляет граничную коробку на основе вставленных координат?
Мне нужна как можно более простая форма, потому что мне нужно проверить, находится ли мой многоугольник в окне просмотра, и это будет наверное, будет кошмар с 800 очками, потому что я не знаю другого способа, кроме как перебирать все точки.
4 ответов
Polygon
не имеет метода getBounds
на Google Maps API v3. Вы можете реализовать его вручную. Но он содержит Форса. Кстати. Я реализовал метод, метод getbounds. Это жестко закодированная версия. Ссылку демо.
обновление
чтобы получить одну рамку для нескольких полигонов, используйте union
метод getBounds
метод.
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())
});
более простая и компактная версия кода:
google.maps.Polygon.prototype.getBounds = function() {
var bounds = new google.maps.LatLngBounds();
this.getPath().forEach(function(element,index){ bounds.extend(element); });
return bounds;
}
координаты X и Y в массиве, затем X и y массив min и max. Хотя нам нужно больше, чем изображение, чтобы знать, что именно вы хотите и как.
Если очки Даны, мы не априори конструкции нет более эффективного способа чем итерация по точкам и расширение ограничивающей рамки. Поскольку вы ничего не знаете заранее, любая точка может быть на углу (или edge point) и поэтому вы должны принять это во внимание. Ни один алгоритм не может сделать это более эффективно.
Если у вас есть контроль над сервером, который предоставляет координаты, вы можете хранить точки заранее в datastructure как К-Д Дерево. Скажем, например, все точки статичны, вы можете хранить их в таком дереве k-d, а затем вы можете определенно ускорить вещи (хотя, насколько я знаю, проблема все еще O (n), но вы не должны принимать во внимание все пункты).
проблема в том, что вы не предоставляете никакой информации о стороне сервера.