Клуб API Карт

Не правильный getCenter()

stokd
8 августа 2010, 11:22

В одной функции создается объект с GeoBounds().

Если по его вершинам построить полигон, то получается:

Но центр для этого объекта, функцией getCenter(), определяется не верно:

С чем это может быть связано?

...

this.setOffset = function(objBorders) {

/* objBorders = { left, right, top, bottom } */

var offset = new YMaps.Point(-Math.floor(getElement().width()/2), -Math.floor(getElement().height()+7) );
var position = map.converter.coordinatesToMapPixels(point).moveBy(offset);

// Вычисляем диагонали объекта.
var objBl = map.converter.localPixelsToCoordinates( new YMaps.Point( position.x-objBorders.left, position.y+getElement().height()+objBorders.bottom ) );
var objTr = map.converter.localPixelsToCoordinates( new YMaps.Point( position.x+getElement().width()+objBorders.right, position.y-objBorders.top ) );
var objBounds = new YMaps.GeoBounds(objBl, objTr);

var newMapBl = map.getBounds().getLeftBottom();
var newMapTr = map.getBounds().getRightTop();

// Проверяем в каких местах относительно видимой части карты, скрыт объект.

// Скрыт справа.
if(map.getBounds().getRight()/objBounds.getRight() < 1)
{
// Назначаем диагональным точкам новый X.
newMapTr.setX(objBounds.getRight());
var difRight = objBounds.getRight() - map.getBounds().getRight();
newMapBl.setX(map.getBounds().getLeft()+difRight);
}

// Скрыт слева. ВОТ ОТ СЮДА ВОЗНИКАЛА ПРОБЛЕМА
if(map.getBounds().getLeft()/objBounds.getLeft() > 1)
{
var cond = 'left'
// Назначаем диагональным точкам новый X.
newMapTr.setX(objBounds.getLeft());
var difLeft = map.getBounds().getLeft() - objBounds.getLeft();
newMapBl.setX(map.getBounds().getRight()-difLeft);
}

// Скрыт сверху.
if(map.getBounds().getTop()/objBounds.getTop() < 1)
{
// Назначаем диагональным точкам новый Y.
newMapTr.setY(objBounds.getTop());
var difTop = objBounds.getTop() - map.getBounds().getTop();
newMapBl.setY(map.getBounds().getBottom()+difTop);
}

// Скрыт снизу.
if(map.getBounds().getBottom()/objBounds.getBottom() > 1)
{
// Назначаем диагональным точкам новый Y.
newMapTr.setY(objBounds.getBottom());
var difBottom = objBounds.getBottom() - map.getBounds().getBottom();
newMapBl.setY(map.getBounds().getTop()+difBottom);
}

// РЕШЕНИЕ: если задействовано проблемное место — менять местами диагонали.
if(cond == 'left') var newMapBounds = new YMaps.GeoBounds(newMapTr, newMapBl);
else var newMapBounds = new YMaps.GeoBounds(newMapBl, newMapTr);

map.panTo(newMapBounds.getCenter(), {flying: true});
}

...
9 комментариев
Подписаться на комментарии к посту
Не могли бы вы дать ссылку на страницу или привести листинг кода, который приводит к неверному определению центра области.
Нашел решение, но сам не понял, как оно работает.
Суть в том, что я сделал функцию передвигающую карту к объекту. Проблема возникала, когда объект был скрыт слева и в этих случаях центр всегда определялся не верно, хотя полигоны и метки по вершинам тут же ставились как надо. 

Для того чтобы решить эту проблему, в проблемном случае, при создании гео-боундса меняю последовательность ввода диагоналей в функцию. С рекомендованных в документации: GeoBounds(southWest, northEast), на GeoBounds(northEast, southWest)
Добавил код в топик.
А можите вкратце описать, что делает этот код? 


Если объект-оверлей частично или полностью скрыт из видимой части карты, то карта передвигается к объекту так, чтобы он стал полностью виден.

Для этого:
находятся боундсы объекта-оверлея, находятся боундсы видимой части карты, затем, если обнаруживается, что объект скрыт из видимой части карты, то боундсам карты присваиваются крайние точки скрытого объекта, затем находится центр боундсов новой части карты и функцией panTo() переносимся туда.

Велосипед?

Я бы пошел по такому алгоритму :

if  (not map.getBounds().contains(bounds..getRightTop()) or  (not map.getBounds().contains(bounds.getLeftBottom())
{ map.panTo(bounds.getCenter()) }

(правда это работает и для частично скрытых объектов, для совсем скрытых еще проще через intersects )

 


Есть функция автоматического позиционирования для балунов, а мне понадобилась такая же для собственных объектов.

Спасибо.
Если у GeoBounds левая граница оказывается больше правой (как в Вашем случае, 56.26 > 56.14) - такой GeoBounds считается по часовой стрелке (т.е. рассматривается как очень широкая область почти на весь земной шар). Центр у него, соответственно - в диаметрально противоположеной точке, на -123 градусе долготы. Вам же нужно только следить, чтобы левая граница была всегда больше правой.
Спасибо.