Кластеризация в API Яндекс.Карт 2.х

На страницах своего блога я уже рассказывал об использовании кластеризации совместно с API Яндекс.Карт 1.1 «Кластеризация меток на Яндекс.Картах – два решения».

В этой заметке я хочу рассказать об способе кластеризации используемом в API Яндекс.Карт 2.х.

Эта возможность уже включена в состав API и нам не нужно использовать никаких дополнительных скриптов.

В самом простом случае для использования кластеризации нам необходимо добавить три строчки кода:

clusterer = new ymaps.Clusterer();
clusterer.add(myGeoObjects);
myMap.geoObjects.add(clusterer);

В первой строке мы определяем объект кластеризатора ymaps.Clusterer.

В следующий строке мы передаем массив объектов (меток) кластеризатору.

Последняя строка добавляет кластеризатор на карту.

Вот как будет выглядеть пример кластеризации для API Яндекс.Карт 2.х. вывода на карту Нижнего Новгорода меток с указанием расположения терминалов QIWI (555 – штук).

Посмотреть пример в действии

Код примера:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Кластеризация меток на Яндекс.картах - API v 2.x</title>
<script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>
<script type="text/javascript" src="http://yandex.st/jquery/1.3.2/jquery.min.js"></script>
 
<script type="text/javascript">
 
ymaps.ready(init);
 
function init () {
 
var myMap = new ymaps.Map("map", {center: [56.316667, 44.0],zoom: 11});
 
myMap.controls.add("zoomControl")
.add("typeSelector")
.add("mapTools");
 
myGeoObjects = [];
 
$.getJSON("http://webmap-blog.ru/examples/clusterer/aztek-yaclusterer/vivmarkers.php", function(json){ 
if (json.status == 'OK') {  
for (i = 0; i < json.markers.length; i++) {   
myPlacemark = new ymaps.Placemark([json.markers[i].lon, json.markers[i].lat], {
 
balloonContentHeader: '<div style="color:#ff0303;font-weight:bold">'+json.markers[i].cname+'</div>',
balloonContentBody: '<strong>Адрес:</strong> '+json.markers[i].address,
 });             
myGeoObjects.push(myPlacemark);
}
clusterer = new ymaps.Clusterer();
clusterer.add(myGeoObjects);
myMap.geoObjects.add(clusterer);
}
else
{
alert('Произошла ошибка!');
}
})
 
}
</script>
</head>
 
<body>
 
<div id="map" style="width:800px; height:600px"></div>
 
</body>
</html>

В этом примере для реализации AJAX запроса на сервер используется библиотека jQuery, которую мы подключаем в начале кода.

Скриптом vivmarkers.php формируется ответ в формате JSON.

Из которого мы формируем массив меток myGeoObjects, он же затем передается кластеризатору.

Мы можем задавать свои иконки для обозначения кластеров и различные параматры.

Подробности смотрите здесь

Приведу пример в котором задается своя картинка для кластера и запрещается приближение карты при клике на кластере.

Посмотреть пример в действии

Код примера:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Кластеризация меток на Яндекс.картах - пример-2 - API v 2.x</title>
<script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>
<script type="text/javascript" src="http://yandex.st/jquery/1.3.2/jquery.min.js"></script>
 
<script type="text/javascript">
 
ymaps.ready(init);
 
function init () {
 
var myMap = new ymaps.Map("map", {center: [56.316667, 44.0],zoom: 11});
 
myMap.controls.add("zoomControl")
.add("typeSelector")
.add("mapTools");
 
myGeoObjects = [];
 
$.getJSON("http://webmap-blog.ru/examples/clusterer/aztek-yaclusterer/vivmarkers.php", function(json){ 
if (json.status == 'OK') {  
for (i = 0; i < json.markers.length; i++) {   
myPlacemark = new ymaps.Placemark([json.markers[i].lon, json.markers[i].lat], {
 
balloonContentHeader: '<div style="color:#ff0303;font-weight:bold">'+json.markers[i].cname+'</div>',
balloonContentBody: '<strong>Адрес:</strong> '+json.markers[i].address,
 });             
myGeoObjects.push(myPlacemark);
}
 
var clusterIcons=[{
href:'http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/images/m1.png',
size:[53,52],
offset:[0,0]
}],
clusterNumbers=[100],
clusterer = new ymaps.Clusterer({
margin:[20],
clusterIcons:clusterIcons,
clusterDisableClickZoom: true,
clusterNumbers:clusterNumbers
});
 
clusterer.add(myGeoObjects);
myMap.geoObjects.add(clusterer);
}
else
{
alert('Произошла ошибка!');
}
})
 
}
</script>
</head>
 
<body>
 
<div id="map" style="width:800px; height:600px"></div>
 
</body>
</html>

Здесь код похож на предыдущий, за исключением нескольких строк кода.

Задаем иконку для обозначения кластера:

var clusterIcons=[{
href:’http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/images/m1.png’,
size:[53,52],
offset:[0,0]
}]

Далее мы задаем ограничение на размер кластера, когда показывается наша картинка

clusterNumbers=[100]

При размере кластера до 100 будет использована картинка стандартного маркера, а более ста — определенная нами.

Затем мы определяем объект кластера с параметрами:

margin:[20] — задает значение отступа для центра кластера относительно ячеек кластеризации (может быть числом или массивом чисел — до 4х);

clusterIcons:clusterIcons — задает обозначение для иконки кластера;

clusterDisableClickZoom: true — запрет на приближение карты при клике на кластере;

clusterNumbers:clusterNumbers — показывает число меток в кластере.

Скачать архив с файлами примеров

В документации также приведен пример использования кластеризации

И в качестве полезного дополнения могу посоветовать Вам ознакомиться со статьей «Кластеризация на клиенте или как показать 10000 точек на карте».

  • Гость: О первом примере. Как посмотреть содержимое файла vivmarkers.php? что нужно изменить, если интересен другой город или например, не терминалы QIWI, а адреса недвижимости?
  • Гость: Файл vivmarkers.php содержится в <a href="http://webmap-blog.ru/files/arhivs/claster-ymap-api-v2.zip" title="Архив примеров" target="_blank" rel="nofollow">архиве</a> с файлами примеров. Структура таблицы с данными терминалов: CREATE TABLE `qiwiterminal` ( `id` int(3) NOT NULL auto_increment, `address` varchar(1000) NOT NULL, `coords` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  • Гость: Спасибо за отличный пост, с нулевыми знаниями JS, PHP, MySqrl я за два дня создал рабочую карту. На статической html странице работает отлично, а вот на Joomla 2.5 добиться работоспособности не удается, проблема в том что в Joomla используется MooTools который конфликтует c jQuery. Отсюда вопрос: чем заменить jQuery? P.S. Пробовал использовать jQuery.noConflict(); - конфликт пропадал, меню и баннеры на MooTools работали, но jQuery не работал и объекты не наносились на карту
  • Гость: Скажите пожалуйста, почему не получается добиться кластаризации с использванием geoXml.load Пытаюсь сделать так: var clusterer = new ymaps.Clusterer(); ymaps.geoXml.load("http://koni-travi.ru/map.xml") .then(function (res) { clusterer.add(res.geoObjects); myMap.geoObjects.add(clusterer); }, function (error){ alert('Ошибка: ' + error); }); Объекты не отображаются, хотя если поставить myMap.geoObjects.add(res.geoObjects) то все ок, но как понимаете - без кластеров!
  • Гость: Проблема в том, что в кластер нужно добавлять массив меток, а не объектов. Нужно сделать так: var i=1; // Загрузка YMapsML-файла ymaps.geoXml.load("http://koni-travi.ru/map.xml") .then(function (res) { // функция обрабатывает успешный результат получения YMapsML clusterer = new ymaps.Clusterer({margin:[20]}); res.geoObjects.each(function (obj, objIndex, group) { obj.properties.set('clusterCaption', i++); clusterer.add(obj); }); myMap.geoObjects.add(clusterer); }, function (error) { alert('Ошибка: ' + error); });
  • Гость: ymaps.ready(init); var myMap; function init(){ myMap = new ymaps.Map ("map", { center: [, ], //устанавливаем начальное центрирование карты zoom: // устанавливаем начальный масштаб карты }); myMap.behaviors.enable('scrollZoom'); //включаем зум при помощи колесика myMap.controls.add(new ymaps.control.TypeSelector(['yandex#map', 'yandex#satellite'])); //подключаем селектор типа карты (подключены: схема, спутник) myGeoObjects = []; &lt;? $g=55; $t=30; for ($i=0;$i&lt;10;$i++) { $row1=xodbc_fetch_array($res,$i+1); $row2=xodbc_fetch_array($res2,$i+1); if ($row2[&#039;Located&#039;]==FALSE) $preset=&quot;preset:&#039;twirl#redDotIcon&#039;&quot;; //устанавливаем цвет маркера на карте, сейчас красный else if ($row2[&#039;Located&#039;]==TRUE) $preset=&quot;preset:&#039;twirl#blueDotIcon&#039;&quot;; //а теперь синий //---создаем маркер, указываем положение в географических координатах, заполняем balloon , $preset - цвет маркера----// echo &#039;myPlacemark = new ymaps.Placemark([&#039;.($g=$g+0.01).&#039;, &#039;.($t=$t+0.01).&#039;], { balloonContentHeader: &#039;&#039;.$row2[&#039;Position&#039;].&quot;, &quot;.$row1[&#039;About&#039;].&#039;&#039;, balloonContentBody: &#039;4й этаж: <a href="/objmenu.php?q=44773&amp;s=2&amp;f=4" rel="nofollow">система 44773</a>5й этаж:<a href="/objmenu.php?q=26408&amp;s=2&amp;f=5" rel="nofollow">Система 26408</a><a href="/objmenu.php?q=36179&amp;s=2&amp;f=5" rel="nofollow">Система 36179</a></a>Технический этаж: <a href="/objmenu.php?q=27452&amp;s=2&amp;f=6" rel="nofollow">Система 27452</a></a>', balloonContentFooter: 'Подробнее' });'; echo 'myGeoObjects.push(myPlacemark);'; } echo 'clusterer = new ymaps.Clusterer();clusterer.add(myGeoObjects);'; echo' myMap.geoObjects.add(clusterer);'; ?&gt; }; никак кластеры не могу сделать... просто куча меток если добавлять как обычные точки выходит, а при кластеризации нифига...
  • Гость: ymaps.ready(init); var myMap; function init(){ myMap = new ymaps.Map ("map", { center: [, ], //устанавливаем начальное центрирование карты zoom: // устанавливаем начальный масштаб карты }); myMap.behaviors.enable('scrollZoom'); //включаем зум при помощи колесика myMap.controls.add(new ymaps.control.TypeSelector(['yandex#map', 'yandex#satellite'])); //подключаем селектор типа карты (подключены: схема, спутник) myGeoObjects = []; &lt;? $g=55; $t=30; for ($i=0;$i&lt;10;$i++) { $row1=xodbc_fetch_array($res,$i+1); $row2=xodbc_fetch_array($res2,$i+1); if ($row2[&#039;Located&#039;]==FALSE) $preset=&quot;preset:&#039;twirl#redDotIcon&#039;&quot;; //устанавливаем цвет маркера на карте, сейчас красный else if ($row2[&#039;Located&#039;]==TRUE) $preset=&quot;preset:&#039;twirl#blueDotIcon&#039;&quot;; //а теперь синий //---создаем маркер, указываем положение в географических координатах, заполняем balloon (внутри можно использовать html конструкции), $preset - цвет маркера----// echo &#039;myPlacemark = new ymaps.Placemark([&#039;.($g=$g+0.01).&#039;, &#039;.($t=$t+0.01).&#039;], { balloonContentHeader: &#039;&#039;.$row2[&#039;Position&#039;].&quot;, &quot;.$row1[&#039;About&#039;].&#039;&#039;, balloonContentBody: &#039;4й этаж: <a href="/objmenu.php?q=44773&amp;s=2&amp;f=4" rel="nofollow">система 44773</a>5й этаж:<a href="/objmenu.php?q=26408&amp;s=2&amp;f=5" rel="nofollow">Система 26408</a><a href="/objmenu.php?q=36179&amp;s=2&amp;f=5" rel="nofollow">Система 36179</a></a>Технический этаж: <a href="/objmenu.php?q=27452&amp;s=2&amp;f=6" rel="nofollow">Система 27452</a></a>', balloonContentFooter: 'Подробнее' });'; echo 'myGeoObjects.push(myPlacemark);'; } echo 'clusterer = new ymaps.Clusterer();clusterer.add(myGeoObjects);myMap.geoObjects.add(clusterer);'; ?&gt; }; еще раз код, в предыдущем ошибки=))
  • Гость: Нужно посмотреть правильно ли формируется массив с метками myGeoObjects
  • Гость: да вроде все в порядке... прям хз что сделать еще!
  • Гость: Подскажите пожалуйста еще код для добавления метки на карту, т.е если указывать в поле адрес объекта , а координаты он сам подставлял?
  • Гость: А как сформировать запрос JSON под новую библиотеку квери? не выводятся метки совсем(
  • Гость: Формат JSON универсальный и не зависит от версии библиотеки jQuery, наверно новая версия не работает в вашем браузере. Проверьте работу на каком-нибудь простом примере.
  • Гость: Добрый вечер, не смог разобраться с примером в архиве, т.к. в файле vivmarkers.php подключается config.php, а самого файла нет. Можно пример или лучше оригинал который вы используете в демонстрации. Спасибо
  • Гость: Это обычный <a href="http://webmap-blog.ru/examples/config.txt" title="файл" target="_blank" rel="nofollow">файл</a> для соединения с базой данных
  • Владлен Макароф: Добавляю в данный пример еще одну карту, но выводится только одна.. var contact = new ymaps.Map("1map", { center: [54.89, 38.07], zoom: 13, behaviors: ["default", "scrollZoom"] }); contact.controls .add("mapTools") .add("zoomControl") .add("typeSelector") .add("searchControl"); В чем проблема??? Подскажите...
  • Steve Johnson: Закиньте пожалуйста данные таблицы! а то я никак под себя отладить не могу (
  • Steve Johnson: Ещё вопрос возник, а как сделать содержимое списком? убрать в окне меню слева?
  • Konstantin Sch: Очень интересует как центрировать карту по всем объектам в myGeoObjects?
  • Алексендр: Ребята, помогите, как добавить кластеризацию? //карта var map; var markersArray = []; var mapObjectsType=1; var mapObjectsCity=1; var is_even=false; //инициализация карты function initialize(callback, coords) { if(typeof(coords) == 'undefined') coords = [56.956838, 38.950559]; setTimeout(function() { map = new ymaps.Map("map_canvas", { // Центр карты center: coords, // Коэффициент масштабирования zoom: 4, // Тип карты type: "yandex#map" }); callback(); map.controls // Добавление кнопки изменения масштаба. В параметрах передаем позицию на карте .add('zoomControl', { left: '15', top: '15' }) }); } //добавление маркера на карту function addMarker(obj_id, myLatlng, contentString, title) { var properties = { balloonContent: contentString, hintContent: title, }; var options = { balloonCloseButton: true, iconImageHref: 'http:rgsu.net/images/tm/img/pinb.png', // картинка иконки iconImageSize: [34, 50], // размеры картинки iconImageOffset: [-14, -43] // смещение картинки }; var placemark = new ymaps.Placemark(myLatlng, properties, options); placemark.obj_id = obj_id; map.geoObjects.add(placemark); markersArray.push(placemark); } //удалить все маркеры function deleteOverlays() { if (markersArray) { for (i in markersArray) { markersArray[i].setMap(null); } markersArray.length = 0; } } //загрузка списка городов function loadCities() { loadMapObjects(); } //показать страницу объекта function loadObjectInfoPage(elem) { var id=$(elem).data('id'); $.scrollTo(".a_map_object_get_info_tab[data-id="+id+"]", 1000, {axis:'y'}); return false; } //сфокусировать карту на обьекте (ссылка) function focusObject_link() { var id = $(this).data("id"); var marker = 0; for (i in markersArray) { if(markersArray[i].obj_id == id) marker=markersArray[i]; } if(marker) { var coords = marker.geometry.getCoordinates(); marker.balloon.open(); map.panTo( coords, { flying: true } ) $.scrollTo("#map_canvas", 1000, {axis:'y'}); } } //загрузить список обьектов function loadMapObjects() { $.each(objs, function() { //var myLatlng = new google.maps.LatLng(this.coord_latitude, this.coord_longitude); var time = typeof(this.time)=='undefined' ? "":'<br>'+this.time+''; //маркер на карту var markerText = ''; markerText += '<div style="width: 250px;font-size: 12px;">'; markerText += '<h3 style="background: #3467A0;-webkit-border-radius: 3px 3px 3px 3px;border-radius: 3px 3px 3px 3px;padding:5px;font-size:12px;color: #FFF !important;">'+this.name+'</h3>'; markerText += '<p style="padding-top:10px;"><b>Адрес:</b> '+this.address+'</p>'; markerText += '</div>'; addMarker(this.id, [this.coord_latitude, this.coord_longitude], markerText, this.name); }); if(markersArray.length>0) { var coords = markersArray[0].geometry.getCoordinates(); map.panTo( coords, { flying: true } ) } $('a.a_map_object_get_info_tab').click(focusObject_link); }
  • Дина Богданова: а что это такое? if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') { что означает эта строка?
  • Дина Богданова: аааа!! беда беда, хочу использовать этот красивый пример на сайте - http://webmap-blog.ru/examples/clusterer/ymap_api2_pr_claster-2.html . Но при подстановке API 2.1 он перестает работать!(( спасите, помогите плиз.
  • Дина Богданова: Извините за тупые вопросы, если что, а в этом примере c json-загрузкой данных , происходит одновременная загрузка всей информации об адресах , или только точечно при клике на метку? Т.е. если у меня будет 10000 точек, не будет ли тормозить? )
  • Гость: Добрый день! не могу найти контактов автора данной статьи, как связаться для возможного коммерческого сотрудничества ?