В JS API Яндекс.
Карт можно создавать на карте различные объекты.
Один из них — полигон, с помощью которого можно улучшить интерактивность пользовательской карты: выделить отдельные области или отобразить расположение неточечного объекта.
Например, это можно использовать, чтобы показать план строительства нового района или зоны доставки пиццы.
У пользователей API Яндекс.
Карт давно возник вопрос о добавлении подписей поверх полигонов.
Люди придумывали умные решения, как добавить подпись к объекту в нужном месте, скрыть его, перекрасить и т. д., но такие решения оказались сложными и негибкими.
Например, к нам обратился исследовательский отдел Яндекса с просьбой написать удобный инструмент для разметки полигонов после того, как они провели несколько исследований на карте мира.
Отображения региональных слов из словаря Даля, т.е.
слов, которые ищут гораздо чаще, чем в среднем по России.
Действительно, задача оказалась нетривиальной.
Представьте себе, для каждого полигона нужно определить подходящий центр для отображения подписи, на каждом масштабе нужно определить, подходит ли подпись, нужно ли ее скрывать при выбранном масштабе, менять стили при каждом масштабе и пересчитать все заново.
То есть, чтобы сделать не особо сложную инфографику, нужно хорошо потрудиться и подготовить массу дополнительных данных.
Создание надписей для полигонов — одна из рутинных задач.
Можно сидеть и рисовать всё в фотошопе, но это оказывается крайне негибко:
- Любые изменения содержимого (значений в метках, цвета) приведут к изменению всех меток; каждый из них нужно будет нарисовать заново.
- Полноценное взаимодействие с картой включает в себя изменение масштабов, из-за чего не всегда удается разместить на карте читаемый текст в виде полигона.
Размера полигона может быть недостаточно для полного отображения подписи в определенных масштабах, поэтому для каждого необходимо рисовать подписи разного размера.
Выводит самые популярные слова в запросах о разных странах
В результате мы решили сделать модуль, который бы решал проблемы пользователей с подписанием полигонов и давал свободу в его настройке.
Выбор алгоритма определения подходящего сигнатурного центра
Одной из основных задач, стоящих перед нами, было определение наиболее подходящего центра отображения подписи, чтобы пользователь мог получить готовый результат без дополнительных настроек.
Существует несколько алгоритмов решения задачи нахождения центра:
Расчет положения по центроиду
Это самое первое, что приходит на ум.В математике и физике центроид (геометрический центр плоской фигуры) — это среднее арифметическое положений всех точек.
Реализуйте поиск центроид Это довольно просто, а сам алгоритм работает быстро.
Казалось бы, это все, но если фигура не является выпуклым многоугольником или имеет дырку, то точка может выйти за пределы фигуры или оказаться в неподходящем для отображения подписи месте.
Вот как выглядит результат определения центроида.
Видно, что точки в Хабаровском и Камчатском краях находились в неблагоприятном для отображения подписи месте.
Полюс недоступности или точка наибольшего вписанного круга.
Проблема поиска такой точки уже возникла у многих, поэтому существуют различные алгоритмы поиска полюса недоступности, но, к сожалению, опубликованные решения требуют сложных реализаций и слишком медленны для применения на практике.
Во-первых, после изучения теории всегда ищешь готовые решения.
Итак, нам посчастливилось найти что-то интересное от разработчиков из Картбокс .
Они рассмотрели несколько решений поиска полюса недоступности, столкнулись с рядом проблем и, вдохновившись одним из алгоритмов, смогли создать свой, исключающий ошибки, ускоряющий поиск и повышающий точность получения высокоточного результата.
качественный результат.
Как работает поиск?
Алгоритм основан на квадродерево .То есть для исследуемого многоугольника строится область (квадрант), в которую полигон полностью помещается.
Затем эта область делится на четыре равные части и так далее рекурсивно с каждым квадрантом.
Исследование продолжается только в клетках, удовлетворяющих условию.
Ячейка считается пригодной, если сумма расстояния от ее центра до края многоугольника и радиуса окружности, описывающей ячейку, больше, чем предыдущие расчеты в квадрантах.
Внутри этого модуля также используется алгоритм поиска центроида как запасной вариант: если найденный полюс недоступности не удовлетворяет требуемой точности.
Подробная информация описано здесь .
Результат алгоритма
Вы можете видеть, насколько отличается точность алгоритмов: «центр» на «проблемных» полигонах стал гораздо лучше подходить для расположения подписи:
- Красные точки — центроид
- Зелень – полюс недоступности
Выбрав алгоритм поиска «центра» многоугольника, мы начали работу над модулем подписи.
Алгоритм работы модуля
Подписание полигона происходит в несколько этапов.На вход модулю передается коллекция, содержащая вершины многоугольников для подписи.
Сначала координаты каждого полигона передаются через модуль поиска полюса недоступности, а на выходе получаются координаты точки, где будет находиться подпись.
Модуль будет применять этот центр ко всем масштабам, если только центр не был переопределен с помощью специальной опции.
Значения центра полигона кэшируются вместе с состоянием емкости сигнатуры, чтобы избежать необходимости вычислять их более одного раза для каждого масштабирования.
Далее перед нами стоит задача понять, вписывается ли подпись в полигон.
Модуль берет шаблон подписи и создает на его основе подпись.
objectManager.add({ .
options: { labelLayout: '<h1>{{properties.name}}</h1>' }, properties: { name: 'nameOfMyPolygon' } });
Далее модуль ожидает загрузки изображений из тегов, если таковые имеются, и с помощью getBoundingClientRect() рассчитаны размеры этой подписи.
К сожалению, не существует методов, которые могли бы сообщить вам размер элемента, который не был вставлен в DOM. Поэтому сначала нужно визуализировать подпись.
А для того, чтобы при получении размера не было «мигания» (показа и скрытия подписи), он рисуется в специальном контейнере, скрытом от глаз пользователей.
Поскольку модуль поддерживает различные параметры, такие как смещение центра или ошибка отображения, они применяются первыми, а затем проверяется, подходит ли подпись.
objectManager.add({
.
options: {
labelLayout: '<h1>{{properties.name}}</h1>',
labelOffset: [80, -50]
},
properties: {
name: 'nameOfMyPolygon'
}
});
Центр подписи представлен в виде географических координат, а размеры элемента подписи — в пикселях, поэтому происходит перевод географических координат центра.
Далее от этого центра откладывается ширина и высота элемента и применяется погрешность расчета, если она была указана.
objectManager.add({
.
options: {
labelLayout: '<h1>{{properties.name}}</h1>',
labelOffset: [80, -50],
labelPermissibleInaccuracyOfVisibility: 10
},
properties: {
name: 'nameOfMyPolygon'
}
});
Полученные координаты преобразуются в географические и проверяется, вписывается ли подпись в полигон.
Все это происходит для каждого зума и для двух типов подписей, которые подробнее описаны в следующей части.
Возможности модуля
Рассмотрев самые неприятные проблемы, с которыми сталкиваются веб-мастера, мы сделали ряд опций, которые помогут вам удобно настроить работу модуля под свои личные нужды.Одной из важных задач было создание удобного способа вставки макета в полигон.
С помощью специальной опции можно указать в виде строки HTML-макет , который поддерживает базовый синтаксис языков шаблонов Twig/Django. Каждый полигон имеет два типа подписи: основную и малую.
Это сделано для того, чтобы отобразить уменьшенную копию основной подписи в случае, если она не подойдёт.
Каждая подпись принадлежит одному полигону, посредством которого контролируются параметры подписи.
Чтобы иметь возможность контролировать параметры подписи в разных масштабах, введены дополнительные опции.
Если пользователя не устраивает стандартное определение центра подписи, то можно задать необходимые координаты, в которых он хочет видеть подпись.
Слева автоматический центр, справа заданы координаты [72, 92]
Также можно задать отступы от положения подписи и ошибки отображения, значение которой означает, насколько подписи разрешено выходить за границы полигона.
Отступ 30 пикселей сверху и слева
ошибка 25 пикселей
Есть также стили; можно изменить размер и цвет текста или установить значение атрибута класса.
Все эти параметры подписи можно настроить для каждого масштаба или установить одно значение для всех масштабов.
Все это необходимо для того, чтобы пользователь мог настроить поведение модуля.
Здесь представлен весь список возможных вариантов.
Не осталось незамеченным события .
Все события, происходящие с подписью (нажатие, наведение.
) перенаправляются в родительский полигон и соответствуют базовым событиям в API, вам просто нужно добавить его перед ними.
"этикетка" .
Для быстрого изменения видимости подписи предусмотрен специальный состояние , который есть у каждого многоугольника.
Получив его через экземпляр модуля, мы можем изменить тип подписи или вообще скрыть ее.
Например, вы хотите, чтобы на полигонах, в которые не помещалась основная подпись, при наведении курсора на ее уменьшенную копию она появлялась.
Также через это состояние вы можете получить текущий тип отображаемой подписи или координаты, где находится подпись.
Дизайн и интерфейс решения
Часто текст является одной из основных частей подписи, поэтому мы уделили ему особое внимание.Чтобы подпись была четко читаема при пересечении границ регионов и на полупрозрачных полигонах, необходимо было отделить ее от фона штрихом.
Мы сделали два стандартных стиля, которые подходят в большинстве случаев:
Изображения выше: простой текст, без контура.
Изображения ниже: Два стандартных стиля модуля.
Многострочные подписи не очень читабельны, когда текст выровнен по левому краю, поэтому выравнивание по центру было установлено по умолчанию.
Поскольку макет подписи можно задать как произвольный html, к подписям несложно добавить изображения — это полезно, например, для создания прогноза погоды на карте или для визуализации данных с помощью диаграмм.
Гибкая компоновка подписей удобна и для инфографики, например, для отображения флагов стран мира или гербов регионов.
Итак, что мы имеем?
- Модуль может принимать любой тип подписи.
- Модуль сам определяет подходящее место для подписи и позволяет пользователю контролировать ее положение с помощью отступов или точных координат.
- Подпись можно настроить по стилю, цвету и размеру текста.
- Пользователь может изменить видимость подписей.
- Пользователь может установить собственные параметры как для всех действующих шкал, так и для отдельных.
Заключение
Мы решили сосредоточиться на базовых вариантах использования, способных удовлетворить базовые потребности в удобном создании подписи, но если у вас есть предложения по работе модуля, мы обязательно их рассмотрим.
Для тех, кому интересно
Чтобы начать использовать модуль, вам необходимо выполнить пару шагов из инструкции в этот репозиторий .
Пример
jsfiddle.net/51qtdx3a/5 Мы всегда рады получить предложения и отзывы.Если у вас возникли вопросы, напишите в нашу техподдержку или оставьте свои пожелания в комментариях.
Мы надеемся, что наши инструменты немного облегчат жизнь веб-мастеру и откроют для вас новые горизонты в визуализации данных на карте.
Теги: #Алгоритмы #api #Яндекс #Развлекательные задачи #API Яндекса #Yandex.maps #Yandex.maps api
-
Стоимость Курса Sap: Выбор Модуля
19 Oct, 24 -
Уокману 30 Лет!
19 Oct, 24 -
Как Избежать Sql-Запросов Внутри Циклов
19 Oct, 24