22 декабря 2015
20 мая 2009
27
Google Maps и большое количество маркеров
Всем привет!
Сегодня мы продолжим разговор о маркерах, начатый в прошлой статье, и каснемся вопроса вывода большого числа маркеров на карту google maps.
Как вы понимаете, с ростом числа маркеров растет и нагрузка на браузер (особенно на IE), что приводит к «тормозам» и прочим неудобствам для рядовых пользователей. На нашей карте точек Wi-Fi это проблема была особенно актуальна для карты Москвы, где на момент запуска проекта было около 700 точек. Сначала я пробовал выводить точки не все скопом, а по несколько штук с определенным временным интервалом — получалось красиво, но проблему тормозов не решало. Тогда я начал искать наиболее простые и удобные решения для кластеризации точек (англ. clusterer), которые позволяют группировать рядом стоящие точки на определенных уровнях увеличения карты и по мере приближения открывать их.
Среди прочего на сайте карточного апи есть и маркер менеджер, но мне его настройка и работа показалась очень сложной (может быть, это и не так) и я продолжил поиски, найдя в итоге Кластерер. Вот его работу мы и рассмотрим в этой статье.
Объявление и добавление маркеров
Итак, как всегда нам нужно подключить файлик кластерера — думаю, тут все знают что и как. Далее, нам нужно объявить объект кластерера и уже в него добавлять маркеры:
clusterer = new Clusterer(map); // объект кластерера
...
clusterer.AddMarker(marker, title); // добавляем маркер в кластере
Обратите внимание, что добавление маркеров происходит не на карту, а в кластерер. Собственно, вот так просто можно избавиться от тормозов карты с большим количеством маркеров. На этом можно было бы и закончить, но мне было мало и я захотел немного покапаться с кодом и поменять отображение сгруппированных маркеров.
Настройка работы
Для начала, у стандартного кластерера была какая-то странная реакция на клик по иконке сгруппированных точек — вместо того, чтобы дать приближение на этот участок карты, он выводил инфоокно со списком содержащихся маркеров. Согласитесь, это не всегда удобно. Поэтому я немного переписал этот объект, так что при клике на иконку кластерера совершалось приближение этой области карты.
// эта функция до этого отвечала за открытие окна при клике на иконку кластерера
Clusterer.PopUp = function ( cluster ) {
var clusterer = cluster.clusterer;
var showMarker = Math.round(cluster.markers.length / 2);
var curZoom = map.getZoom() + 1;
map.panTo(cluster.markers[showMarker].getPoint());
map.setZoom(curZoom);
};
Мой вариант вы так же можете использовать.
Потом мне захотелось поменять иконку. Это можно сделать либо как написано на странице скрипта:
clusterer.SetIcon(icon)
либо поменять строчки в самом файле (создается как обычная иконка маркера):
Clusterer.defaultIcon = new GIcon();
Clusterer.defaultIcon.image = 'http://wifi4free.ru/files/images/hotarea.png';
Clusterer.defaultIcon.iconSize = new GSize( 40, 40 );
Clusterer.defaultIcon.iconAnchor = new GPoint( 20, 20 );
Clusterer.defaultIcon.infoWindowAnchor = new GPoint( 20, 20 )
Потом я еще повозился с цифрами для минимального количества маркеров в кластере и остальными настройками (они для каждого свои):
clusterer.SetMaxVisibleMarkers(n) // максимальное количество видимых маркеров
clusterer.SetMinMarkersPerCluster(n) // сколько минимум маркеров в кластерере
clusterer.SetMaxLinesPerInfoBox(n) // количество строчек в инфоокне кластерера (мне было не нужно)
В итоге я оптимизировал и ускорил работу карты, которую вы можете видеть на страницах нашей карты точек Wi-Fi.
В общем, в следующей статье я расскажу про инфоокна, которые позволят вам делать подсказки на ваш вкус. Если же у вас есть какие-то вопросы или пожелания по поводу статей о Google Maps API, пишите в комментариях.
http://livestreet.ru/blog/1695.html
- не сталктвались с такими проблемами?
Как я понял в кластер можно добавлять маркеры произвольным образом.
Как у вас реализована группировка по координатом? что бы в кластер попадали только рядом стоящие маркеры и как вычесляется координата где отображать сам кластер
GIcon is not defined
[Break on this error] Clusterer.defaultIcon = new GIcon();
map.panTo(cluster.markers[showMarker].getPoint());
map.setZoom(curZoom);
нужно написать
map.setCenter(cluster.markers[showMarker].getPoint(), curZoom);
т.е. если использую свои иконки то они сдвигаются на карте, устанавливаю стандартным маркером, а отображаю свои. Калибровал как мог все равно идет сдвиг при масштабировании.
сейчас вот ещё другой вопрос возник: как можно программно (например по нажатию на кнопку) вызвать инфоокно для какого-то (заранее известного и уже прорисованного) маркера?
перерыл всю документацию, но либо я туплю, либо...
может кто подскажет?