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

Автор: | 20.06.2012

На страницах своего блога я уже рассказывал об использовании кластеризации совместно с 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 точек на карте».

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

  1. Александр

    О первом примере. Как посмотреть содержимое файла vivmarkers.php? что нужно изменить, если интересен другой город или например, не терминалы QIWI, а адреса недвижимости?

    1. admin Автор записи

      Файл vivmarkers.php содержится в архиве с файлами примеров. Структура таблицы с данными терминалов:

      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;

  2. izxy

    Спасибо за отличный пост, с нулевыми знаниями JS, PHP, MySqrl я за два дня создал рабочую карту.
    На статической html странице работает отлично, а вот на Joomla 2.5 добиться работоспособности не удается, проблема в том что в Joomla используется MooTools который конфликтует c jQuery. Отсюда вопрос: чем заменить jQuery?
    P.S. Пробовал использовать jQuery.noConflict(); — конфликт пропадал, меню и баннеры на MooTools работали, но jQuery не работал и объекты не наносились на карту

  3. Yuriy

    Скажите пожалуйста, почему не получается добиться кластаризации с использванием 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) то все ок, но как понимаете — без кластеров!

    1. admin Автор записи

      Проблема в том, что в кластер нужно добавлять массив меток, а не объектов.

      Нужно сделать так:

      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);
      });

  4. Андрей

    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 = [];

    <?
    $g=55;
    $t=30;
    for ($i=0;$i<10;$i++)
    {
    $row1=xodbc_fetch_array($res,$i+1);
    $row2=xodbc_fetch_array($res2,$i+1);
    if ($row2['Located']==FALSE)
    $preset="preset:'twirl#redDotIcon'"; //устанавливаем цвет маркера на карте, сейчас красный
    else if ($row2['Located']==TRUE)
    $preset="preset:'twirl#blueDotIcon'"; //а теперь синий

    //—создаем маркер, указываем положение в географических координатах, заполняем balloon , $preset — цвет маркера—-//
    echo 'myPlacemark = new ymaps.Placemark(['.($g=$g+0.01).', '.($t=$t+0.01).'], {

    balloonContentHeader: ''.$row2['Position'].", ".$row1['About'].'',
    balloonContentBody: '4й этаж: система 447735й этаж:Система 26408Система 36179Технический этаж: Система 27452‘,
    balloonContentFooter: ‘Подробнее’
    });’;

    echo ‘myGeoObjects.push(myPlacemark);’;

    }
    echo ‘clusterer = new ymaps.Clusterer();clusterer.add(myGeoObjects);’;
    echo’ myMap.geoObjects.add(clusterer);’;

    ?>

    };

    никак кластеры не могу сделать… просто куча меток если добавлять как обычные точки выходит, а при кластеризации нифига…

  5. Андрей

    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 = [];

    <?
    $g=55;
    $t=30;
    for ($i=0;$i<10;$i++)
    {
    $row1=xodbc_fetch_array($res,$i+1);
    $row2=xodbc_fetch_array($res2,$i+1);
    if ($row2['Located']==FALSE)
    $preset="preset:'twirl#redDotIcon'"; //устанавливаем цвет маркера на карте, сейчас красный
    else if ($row2['Located']==TRUE)
    $preset="preset:'twirl#blueDotIcon'"; //а теперь синий

    //—создаем маркер, указываем положение в географических координатах, заполняем balloon (внутри можно использовать html конструкции), $preset — цвет маркера—-//
    echo 'myPlacemark = new ymaps.Placemark(['.($g=$g+0.01).', '.($t=$t+0.01).'], {

    balloonContentHeader: ''.$row2['Position'].", ".$row1['About'].'',
    balloonContentBody: '4й этаж: система 447735й этаж:Система 26408Система 36179Технический этаж: Система 27452‘,
    balloonContentFooter: ‘Подробнее’
    });’;
    echo ‘myGeoObjects.push(myPlacemark);’;

    }
    echo ‘clusterer = new ymaps.Clusterer();clusterer.add(myGeoObjects);myMap.geoObjects.add(clusterer);’;

    ?>

    };

    еще раз код, в предыдущем ошибки=))

    1. admin Автор записи

      Нужно посмотреть правильно ли формируется массив с метками myGeoObjects

  6. Андрей

    да вроде все в порядке… прям хз что сделать еще!

  7. Максим

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

  8. Юрий

    А как сформировать запрос JSON под новую библиотеку квери? не выводятся метки совсем(

    1. admin Автор записи

      Формат JSON универсальный и не зависит от версии библиотеки jQuery, наверно новая версия не работает в вашем браузере.
      Проверьте работу на каком-нибудь простом примере.

  9. Max

    Добрый вечер,

    не смог разобраться с примером в архиве, т.к. в файле vivmarkers.php подключается config.php, а самого файла нет. Можно пример или лучше оригинал который вы используете в демонстрации.

    Спасибо

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *