Google Maps и большое количество маркеров

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, пишите в комментариях.

Расскажите друзьям

Оцените статью:
  • 1
  • 2
  • 3
  • 4
  • 5

Комментарии — 27

Neutron
Эх... сижу разбираюсь с api от яндекс-карт и ничегошеньки не понимаю... к сожалению гугловской карты для моего города хорошей нет, а жаль, ваши руководства мне бы очень помогли...
Grin
Neutron, возможно я скоро напишу какую-нибудь вводную статью по Яндекс.Картам
Kotelnikov
А как на счет OpenStreetMap? Через http://openlayers.com/
Neutron
Grin, ,буду очень ждать, а то самому не разобраться никак...
Kotelnikov
Примерно как-то так: http://www.openlayers.org/dev/examples/sundials-spherical-mercator.html
Likoo
А почему отключили зумирование скроллом мышки?
#
Likoo
Grin
Likoo, мне это показалось не очень удобным, особенно на ноутах с тачпадом
Сашко
Grin, можешь написать статью о базе данных (мускуле), точнее как хранить там точки и привязывать к карте? Разобрался тока с xml, там все просто оказалось. А вот чтобы из БД брал данные - это труднее, тем более думаю надо js+php+mysql задействовать
Сашко
Сорри, нашел ответ на свой вопрос: http://code.google.com/support/bin/answer.py?answer=65622&topic=&ctx=sibling
Dr.Death
http://googlegeodevelopers.blogspot.com/2009/04/markerclusterer-solution-to-too-many.html еще одно решение
Grin
Dr.Death, спасибо, судя по дате поста, его не было, когда я делал наш проект
noonv
Привет :) я так же реализовал сервис на основе карт от гугла :) однако недавно решил портировать этот севис на livestreet и столкнулся с неожиданной проблемой - маркеры прекрасно отображаются в FF, а в IE, Opera, Chrome - не отображаются :(
http://livestreet.ru/blog/1695.html
- не сталктвались с такими проблемами?
БОШ
Вопрос немного не в тему. С помощью какого сервиса вы реализовывали смс-биллинг?
Grin
БОШ, A1Agregator
#
Grin
Евгений
>> clusterer.AddMarker(marker, title);
Как я понял в кластер можно добавлять маркеры произвольным образом.
Как у вас реализована группировка по координатом? что бы в кластер попадали только рядом стоящие маркеры и как вычесляется координата где отображать сам кластер
#
Евгений
dr.death
что то он у меня ругается:
GIcon is not defined
[Break on this error] Clusterer.defaultIcon = new GIcon();
deadbead
Заметил неприятную особенность на wifi4free.ru: при клике на кластер расположенный не по центру карты масштаб увеличивается, но карта не центрируется по кликнутому объекту... получается что интересующая область осталась за границей просмотра... Это сделано намерено или нет возможности использовать .setCenter в библиотеке?
#
deadbead
Grin
deadbead, я раньше такого не замечал. И насколько помню, при разработке я как раз делал так, чтобы карта центрировалась по кликнутому объекту.
Евгений
Есть такое дело, легко подправить, В функции PopUp вместо двух последних строчек:
map.panTo(cluster.markers[showMarker].getPoint());
map.setZoom(curZoom);

нужно написать
map.setCenter(cluster.markers[showMarker].getPoint(), curZoom);

#
Евгений
Роман
Я еще не пользовался такой вещью, только Яндекс картами
Сергей
а не сталкивались со сдвигом иконок?
т.е. если использую свои иконки то они сдвигаются на карте, устанавливаю стандартным маркером, а отображаю свои. Калибровал как мог все равно идет сдвиг при масштабировании.
Павел
Что я не правильно делаю?
 
<script type="text/javascript">
 function initialize() {
 if (GBrowserIsCompatible()) {

 var map = new GMap2(document.getElementById("map_canvas")); 
 map.setCenter(new GLatLng(47.83367017560077, 35.16530513763428), 12);
 
  var clusterer = new Clusterer(map);
 
 var point = new GLatLng(47.83335328187376, 35.167365074157715);
 var marker = new GMarker(point);
 clusterer.AddMarker(marker, point);

 var point1 = new GLatLng(47.833324473257164, 35.16697883605957);
 var marker1 = new GMarker(point1);
 clusterer.AddMarker(marker1, point1);
}
}
 </script> 
#
Павел
Павел
Grin, помоги пожалуйста. Если можешь приведи кусок кода работы с кластерами.
Константин
отлично всё разложено. пользуясь этой подборкой статей решил некоторые свои задачи.

сейчас вот ещё другой вопрос возник: как можно программно (например по нажатию на кнопку) вызвать инфоокно для какого-то (заранее известного и уже прорисованного) маркера?

перерыл всю документацию, но либо я туплю, либо...

может кто подскажет?
Паша
Всё круто. но как то сложновато для меня.вопрос такой а можно ли сделать карту непосредственно в гугл мапс, а потом добавить её на сайт. в таком случае как решить проблему большого числа маркеров? спасибо.
#
Паша
Павел
У меня кластерер не работает, и не у меня одного. пройдя по ссылке и посмотрев пример я увидел что у них (авторов библиотеки) тоже маркеры не кластеризуются...
#
Павел
kill_windows
Можно ли реализовать кластеризацию маркеров на сервере. ? Таким образом чтоб не грузить все маркеры сразу а только кластеры, и при увеличение или передвижение карты подгружать те маркеры или кластеры что находятся в области видимости. Просто кластеры это хорошо но когда скрипт обрабатывает сразу например 2000 маркеров, браузер жутко тормозит.
#
kill_windows

Новый комментарий

как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть
как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть

metin2 pvp metin2 pvp serverler pvp serverler