Клуб API Карт

getBounds у кластера

Пост в архиве.

Здравствуйте!

Не получается масштабировать карту под все кластеры.

Код такой:

clusterer = new ymaps.Clusterer();

var point = new ymaps.Placemark([49.145338, 55.769048], { iconContent: 'text', balloonContentHeader: "text", balloonContentBody: "text", balloonContentFooter: "<a href='#'>text</a>" },{ preset: 'twirl#redStretchyIcon' } ); 
clusterer.add(point);

myMap.geoObjects.add(clusterer);
myMap.setBounds(clusterer.getBounds());


Метки пявляются, но карта не масштабируется под все метки.
В чем ошибка?
11 комментариев

а где написано что такой метод есть у кластеризатора?

Нигде. Тогда вопрос - как это реализовать?
Алексей Yarrr!
28 января 2016, 03:51

clusterer.getBounds() нет, их надо руками посчитать?

берем все точки, считаем минимум и максимум широты и долготы. например, в лоб:

var getBounds = function (coords) {

  var result = [[999,999],[0,0]], i, l;

  for (i = 0, l = coords.length; l; --l, ++i) {

    result[0][0] = Math.min(result[0][0], coords[i][0]);

    result[0][1] = Math.min(result[0][1], coords[i][1]);

    result[1][0] = Math.max(result[1][0], coords[i][0]);

    result[1][1] = Math.max(result[1][1], coords[i][1]);

  }

  return result;

}

 

проход внутри функции можешь поменять с учетом своего хранилища точек.

Нужно учитывать что этот вариант не будет работать в случае если точки расположены вокруг 0-го меридиана.

Вообщем задача расчета области несколько сложнее.

Алексей Yarrr!
28 января 2016, 03:51

Я так и думал. А если координаты переводить в глобальные пиксельные, и затем назад?

Алексей Yarrr!
28 января 2016, 03:51

Кстати, если у вас динамически будут добавляться, удаляться метки, наверное, можно еще повесить на события этот пересчет. Но если меток очень много - то лучше отдельной логикой это рулить, чтобы не перегружать зря CPU.

У меня есть координаты всех точек, в связи с этим я попробую сделать через setBounds
Но хотелось бы автоматически сделать
Алексей Yarrr!
28 января 2016, 03:51

Автоматически - добавь их еще и в коллекцию, выставь парентом карту и возьми у коллекции getBounds.

Это конечно вариант, но он будет работать довольно долго - метки начнут отрисовываться на карте. Еще - когда вы добавляете метку в коллекцию, она удаляется из кластеризатора - у объекта может быть только 1 родитель.

Вам придется следить за тем, какие метки добавляются и удаляются из кластеризатора, и каждый раз пересчитывать границы видимой области (просто перебрать все метки, и посчитать максимальные-минимальные координаты). Ну а потом делать setBounds.

Алексей Yarrr!
28 января 2016, 03:51

Человек же хотел автоматически ;-)

В руководстве пользователя(2.0). Раньше использовал. Работает!

clusterer.add(geoObjects);

    /**
     * Поскольку кластеры добавляются асинхронно,
     * дождемся их добавления, чтобы выставить карте область, которую они занимают.
     * Используем метод once чтобы сделать это один раз.
     */
    clusterer.events.once('objectsaddtomap', function () {
        myMap.setBounds(clusterer.getBounds(), {
                checkZoomRange: true
            }
        );
    });