Клуб API Карт

Как сделать кластеризацию объектов на Яндекс Картах 2.1?

Чапаев Сергей
6 декабря 2014, 10:03

День добрый всем!
Помогите плиз разобраться, полночи голову ломаю, я новичок в этом.

Есть JS-скрипт кластеризатора карт Яши. Все вроде нормально. Кластеризация проходит, но вот при интеграции в скрипт выводит во всех точках один и тот же объект (данные объекта).
Более подробно.
У меня CMS на смарти, решил прикрутить к новостям карты. Все сделал как надо, теперь осталось решить вопрос с выводом аннотаций новостей на карте. Без кластеризации все выводит нормально, но, на одно квартале есть и по 5 новостей, и без кластеризации получается полная чушь, не видно домов и т.п.

Нашел скрипт, вставил в шаблон, прописал переменными координаты, а как вывести это на карту не могу разобраться. Они по сути выводятся все, с разными координатами, только вот на всех точках новость одна и та же.
 

 Введите содержимое врезки

 
Помогите плиз. В API ничего не могу понять. Вот сам скрипт. Заранее благодарю.
<code>
<script src="https://api-maps.yandex.ru/2.1/?lang=ru-RU" type="text/javascript"></script>
<script type="text/javascript">
ymaps.ready(function () {
    var myMap = new ymaps.Map('map', {
            center: [55.751574, 37.573856],
            zoom: 9,
            behaviors: ['default', 'scrollZoom']
        }),
        /**
         * Создадим кластеризатор, вызвав функцию-конструктор.
         * Список всех опций доступен в документации.
         * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Clusterer.xml#constructor-summary
         */
            clusterer = new ymaps.Clusterer({
            /**
             * Через кластеризатор можно указать только стили кластеров,
             * стили для меток нужно назначать каждой метке отдельно.
             * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/option.presetStorage.xml
             */
            preset: 'islands#invertedVioletClusterIcons',
            /**
             * Ставим true, если хотим кластеризовать только точки с одинаковыми координатами.
             */
            groupByCoordinates: false,
            /**
             * Опции кластеров указываем в кластеризаторе с префиксом "cluster".
             * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/ClusterPlacemark.xml
             */
            clusterDisableClickZoom: true,
            clusterHideIconOnBalloonOpen: false,
            geoObjectHideIconOnBalloonOpen: false
        }),
        /**
         * Функция возвращает объект, содержащий данные метки.
         * Поле данных clusterCaption будет отображено в списке геообъектов в балуне кластера.
         * Поле balloonContentBody - источник данных для контента балуна.
         * Оба поля поддерживают HTML-разметку.
         * Список полей данных, которые используют стандартные макеты содержимого иконки метки
         * и балуна геообъектов, можно посмотреть в документации.
         * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/GeoObject.xml
         */
            getPointData = function (index) {
            return {
                balloonContentBody: 'балун <strong>метки ' + index + '</strong>',
                clusterCaption: 'Заголовок <strong>' + index + '</strong>'
            };
        },
        /**
         * Функция возвращает объект, содержащий опции метки.
         * Все опции, которые поддерживают геообъекты, можно посмотреть в документации.
         * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/GeoObject.xml
         */
            getPointOptions = function () {
            return {
                preset: 'islands#violetIcon'
            };
        },
        points = [
            [55.831903,37.411961], [55.763338,37.565466], [55.763338,37.565466], [55.744522,37.616378], [55.780898,37.642889], [55.793559,37.435983], [55.800584,37.675638], [55.716733,37.589988], [55.775724,37.560840], [55.822144,37.433781], [55.874170,37.669838], [55.716770,37.482338], [55.780850,37.750210], [55.810906,37.654142], [55.865386,37.713329], [55.847121,37.525797], [55.778655,37.710743], [55.623415,37.717934], [55.863193,37.737000], [55.866770,37.760113], [55.698261,37.730838], [55.633800,37.564769], [55.639996,37.539400], [55.690230,37.405853], [55.775970,37.512900], [55.775777,37.442180], [55.811814,37.440448], [55.751841,37.404853], [55.627303,37.728976], [55.816515,37.597163], [55.664352,37.689397], [55.679195,37.600961], [55.673873,37.658425], [55.681006,37.605126], [55.876327,37.431744], [55.843363,37.778445], [55.875445,37.549348], [55.662903,37.702087], [55.746099,37.434113], [55.838660,37.712326], [55.774838,37.415725], [55.871539,37.630223], [55.657037,37.571271], [55.691046,37.711026], [55.803972,37.659610], [55.616448,37.452759], [55.781329,37.442781], [55.844708,37.748870], [55.723123,37.406067], [55.858585,37.484980]

/*
Вместо этого набора точек я вставляю переменную smarty -
{/literal}
   {foreach key=key item=obj from=$news}
      {if $obj.show_on_map}
{literal}
[{/literal}{$obj.coordinates}{literal}], - это цикл координат в таком же виде, что и выше
{/literal}
     {/if}
   {/foreach}
{literal}

 */
        ],
        geoObjects = [];

    /**
     * Данные передаются вторым параметром в конструктор метки, опции - третьим.
     * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Placemark.xml#constructor-summary
     */
    for(var i = 0, len = points.length; i < len; i++) {
        geoObjects[i] = new ymaps.Placemark(points[i], getPointData(i), getPointOptions());
    }

    /**
     * Можно менять опции кластеризатора после создания.
     */
    clusterer.options.set({
        gridSize: 80,
        clusterDisableClickZoom: true
    });

    /**
     * В кластеризатор можно добавить javascript-массив меток (не геоколлекцию) или одну метку.
     * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Clusterer.xml#add
     */
    clusterer.add(geoObjects);
    myMap.geoObjects.add(clusterer);

    /**
     * Спозиционируем карту так, чтобы на ней были видны все объекты.
     */

    myMap.setBounds(clusterer.getBounds(), {
        checkZoomRange: true
    });
});
</script>

<div id="map"></div>
</code>

9 комментариев
Подписаться на комментарии к посту

Не надо печатать на странице конструкции одного языка (Javascript) из другого языка (PHP)

Отдавайте данные для карты в виде JSON отдельным обработчиком

Чапаев Сергей
6 декабря 2014, 17:19

Я и говорю, что профан в этом, вот и спрашиваю что и как. Можно чуть подробнее про JSON и как это можно реализовать (соместить код и яву)...

В песочнице есть пример получения данных в виде JSON

После получения их можно кластеризовать, при желании вызвав метод clusterize

Чапаев Сергей
6 декабря 2014, 17:24

ок, благодарю, буду разбираться

Чапаев Сергей
6 декабря 2014, 17:40

Я извиняюсь. Может поможете прикрутить кластеризацию к этому примеру? Блин, для меня это темный лес. Со вчерашнего вечера ковыряюсь и бестолку. Буду очень признателен!

Помогу. Настройте сначала в таком виде вывод своих реальных данных. Для кластеризации там надо поменять 2 строчки

Чапаев Сергей
6 декабря 2014, 18:16

В смысле скрипт вывода выборки данных из БД?

У меня есть что-то подобное, но это под версию API 2.0 на примере терминалов QIWI, а у себя хочу сделать на API 2.1.

Вот html

 

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml">


Кластеризация меток на Яндекс.картах - API v 2.x











 

А вот PHP

 

include("../../config.php");

header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {

$json = '{markers:['."\n";

$query1= "SELECT * FROM news";
$result1 = mysql_query($query1);

if(mysql_num_rows($result1)>0)
{
while ($par1 = mysql_fetch_array($result1)){

$cname =  'Теминал QIWI';

$exp_str = explode(",", $par1['coords']);

$lat = $exp_str[0];

$lng = $exp_str[1];

$json.= "\n".'{'.'"id": "'.$par1['id'].'",';

$json.= '"cname": "'.$cname.'",';

$json.= '"address": "'.$par1['address'].'",';
   
$json.= '"lat": "'.$lat.'",';

$json.=  '"lon": "'.$lng.'"';

$json.= '},';

}

$json = substr($json, 0,-1);

echo  $json;

echo '], ', "\n",  '"status": "OK"', "\n", '}';

}
else
{
echo '{"status": "false"}';
}

}

 

Вас это интересует?

Там в примере есть вкладка data.json по ней можно посмотреть как должен выглядеть конечный JSON. И формировать его на сервере надо не конкатенацией строк, а через json_encode

Чапаев Сергей
6 декабря 2014, 18:50

Если вы про результат выдачи в виде

        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    39.89157,
                    59.22049
                ]
            },
            "properties": {
                "balloonContent": "Только курьерская доставка",
                "hintContent": "Только курьерская доставка"
            },
            "options": {
                "preset": "islands#greenDotIcon"
            }
        }

то да, такой.

Блин, не совсем удобно на расстоянии решать вопрос, особенно, когда плохо в этом разбираешься