Клуб API Карт

Быстородействие карт при множестве уникальных объектов (ymaps.Polygon)

Пост в архиве.

Добрый день!

Для того, чтобы создать участки на карте (Polygon) со своим цветом, балуном и т.д. пришлось использовать перебор, причем на PHP. В итоге все работает, но т.к. участков около 1000, скрипт карты составляет примерно 40 000 строк, всвязи с чем загрузка карты явно замедляется. Вот пример кода (php переменные берутся из инфоблока и внимания на них можно не обращать):

 

<?foreach($arResult["ITEMS"] as $arItem):?>

var obj_<?=$arItem['ID']?> = new ymaps.Polygon([

            [

                <?=$arItem['PROPERTIES']['COORDS']['~VALUE']['TEXT']?>

            ]

        ], {

            balloonContent: "<div class='obj-info-window'>уникальная для каждого объекта инфа</div>"

        }, {

            strokeColor: "ffffff",

            strokeWidth: 1,

            strokeOpacity: 0.5,

            fillOpacity: 0.5,

            fillColor: "<?=$color?>",

openBalloonOnClick: false

        });

<?endforeach;?>

 

map.geoObjects

   <?foreach($arResult["ITEMS"] as $arItem):?>

     .add(obj_<?=$arItem['ID']?>)

   <?endforeach;?>;

 

<?foreach($arResult["ITEMS"] as $arItem):?>

obj_<?=$arItem['ID']?>.events.add('click', function () {

   $('#obj-info').html(obj_<?=$arItem['ID']?>.properties._i.balloonContent);

   obj_<?=$arItem['ID']?>.options.set('fillOpacity','1');

});

obj_<?=$arItem['ID']?>.events.add('mouseenter',function(){

   obj_<?=$arItem['ID']?>.options.set('strokeOpacity','1');

});

obj_<?=$arItem['ID']?>.events.add('mouseleave',function(){

   obj_<?=$arItem['ID']?>.options.set('strokeOpacity','0.5');

});

<?endforeach;?>;

 

Вопрос заключается в том, как убрать перебор php-переменных и повесить обработчик на каждый отдельно взятый объект?

7 комментариев
Алексей Yarrr!
28 января 2016, 03:33

Вам бы отделить логику от данных.

Формировать JS скрипты с помощью PHP в вашем случае совершенно не обязательно. Вы вполне можете возвращать json_encoded данные из PHP, а на клиенте сделать простой инициализатор, разбирающий эти данные на JS.

Для начала: вы создаете PHP скриптом пачку JS переменных (в кол-ве count($arResult["ITEMS"])) — перенесите в массив.var obj_ → var objs[]; И далее вся солянка из  .add(obj_) получится много проще: for (var i in objs) { map.geoObjects.add(objs[i]); }. Далее можно генерацию массива отдать в json_encode, но нужно заранее пре. var objs = json_encode($preparedItems); ну и т.д.

 

.properties._i.balloonContent);

так делать категорически не рекомендуется

обращаться к данным через "педальные" свойства не стоит т.к. их имена не гарантируются и могут измениться с выходом след. версии АПИ.

Используйте документированный интерфейс менеджера данных

 

 

1000 обработчиков событий создавать совершенно не обязательно и даже вредно.

Вы можете "повесить" (делегировать) один обработчик на коллекцию геообъектов, и тогда при клике на любой из элементов коллекции, элемент на котором был клик, можно будет получить из объекта-события через e.get('target')

А Вы могли бы пример привести или ссылочку скинуть?

myCollection.events.add('click', function (e) {

    console.log(e.get('target'));

});

даже интересно - это у Вас работает? 

Скиньте ссылочку пожалуйста.

Там должна быть жесть жестяная с добавлением и вообще с любым действием с картой.

По-хорошему (в смысле, по-правильному), тут надо делать тайловый слой с полигонами и слой с хотспотами.

Да, все работает. К сожалению скинуть ссылку не могу, т.к. сайт находится в разработке (коммерческая тайна и т.п.), через недельку скину...