Клуб API Карт

getBounds() от кластеризатора

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

Всем привет.

Я только начал работать с картами, поэтому просьба сильно не пинать за, возможно, глупые вопросы.

 

Итак, суть дела. У меня есть кластеризатор заполненный точками (Placemark), мне нужно получить от него границы, чтобы спозиционировать по ним карту. Можно ли вообще такое сделать?

принимаются любые предложения, по решению данной проблемы :)

 

Заранее спасибо.

11 комментариев

Здравствуйте, вопрос обсуждался ранее.

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

 

Ну да ладно, решать задачу все равно нужно, и я ее решил:

1. Создаем коллекцию (GeoObjectCollectionGeoObjectArray)

2. Заталкиваем все точки в коллекцию

3. Добавляем коллекцию точек на карту ( это камень в огород разработчиков API, для того чтобы вызвать getBounds() у коллекции она обязательно должна быть прикреплена к карте)

4. Получаем границы getBounds() у коллекции

5. Удаляем коллекцию с карты

6. Устанавливаем полученные границы у карты

 

P.S. при работе с несколькими ( > 2) точками на карте данный алгоритм работает прекрасно. Для одной точки лучше всего получить в этой точке минимальный и максимальный зум ( пример есть в описании map.ZoomRange ) ну и отцентровать карту по этой точке и выставить полученный максимальный зум. ( если метод map.zoomRange.get падает с ошибкой ( что-то про toFixed ) то скорее всего вы подаете координаты в виде строк, а нужно в виде чисел ( еще один камень в сторону разработчиков API, ибо метод getCoordinates() возвращает координаты в виде массива строк !!!) )

Этот метод прост с точки зрения количества кода, но не очень хорош в остальном.

При добавлении коллекции на карту объекты добавляются на карту и начинают отрисовываться. Это довольно трудоемкая операция, скорее всего отъест у вас кучу времени.

Про камни учтем и подумаем, как разрешить эти проблемы.

Есть ли менее затратный способ определения границ, инкапсулированный в вашей библиотеке? Именно инкапсулированный, т.к. я не хотел бы чтобы мой код определения границ зависел от вашего представления геокоординат

С getBounds все оказалось сложно.

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

Поэтому пока мы не знаем проекцию карты, мы не можем корректно рассчитать границы. Отсюда и невозможность расчета границ до добавления на карту.

Для кластеризатора сейчас решения 2 - либо ваше затратное, либо приблизительный расчет границ, который выполняется просто поиском минимальных и максимальных координат в массиве меток кластеризаторе.

В будущем мы подумаем, как встроить в кластеризатор правильный расчет границ.

 

И еще - вы не могли бы привести пример, где map.getBounds падает с ошибкой?

Эм, а где я писал что "map.getBounds падает с ошибкой"?

Я писал, что map.zoomRange.get(['10', '10']) - падал у меня с ошибкой (т.к. я подозреваю, что где-то в недрах вашего кода вызывается метод .toFixed() от координаты, переданной в виде строки), нужно было писать map.zoomRange.get([10, 10]), а это не очень удобно, т.к. ваш метод getCoordinates() возвращает пару координат именно в виде строк.

 

Еще у меня возникали проблемы с коллекциями (GeoObjectCollection, GeoObjectArray) я добавлял в них одну точку, прикреплял их к карте и пытался получить getLength(), который почему-то возвращал 0, вместо 1, что сказывалось и на вызове метода коллекции getBounds(), который возвращал null. Поэтому пришлось решать проблему позиционирования карты через map.zoomRange.

 

Еще у меня есть к вам небольшое предложение по улучшению документации - опишите в каких случаях тот или иной метод возвращает то или иное значение. С getBounds() у коллекций я долго не мог понять почему он мне выдает null (точки я в него добавил), и уже в результате различных эксперементов я выяснил, что оказывается чтобы getBounds() начал работать его нужно добавить на карту.

 

P.S. как вариант решения проблем с производительностью добавления коллекций на карту, почему-бы не добавить необязательный параметр объект карты в метод getBounds(), тогда вы бы могли получить проекцию карты без добавления коллекции на карту и вернуть корректные границы

приведите пример где getCoordinates() возвращает координаты в виде строки

Другие методы/классы нормально работают с координатами заданными строками, map.zoomRange.get() падает с ошибкой.

Пример, когда getCoordinates() возвращает строковые координаты:

console.log((new ymaps.Placemark(['55.8', '37.6'])).geometry.getCoordinates())

 

Прошу прощения за формулировку, getCoordinates() может возвращать координаты в виде строки.

Да, я конечно же, опечаталась. Спасибо за репорт, проверим.

А вы не могли бы привести пример, где getLength возвращает неправильный результат? Я подозреваю, что после добавления в коллекцию метка потом добавлялась в другую коллекцию и автоматически из старой удалялась.

Да, вы правы, затем я добавлял ее в кластер. Хм, интересная особенность меток, не знал. Спасибо за информацию)