Часто перед разработчиками сайта встаёт задача отразить на интерактивной карте местоположение каких-либо объектов. Например филиалов компании, магазинов, автозаправочных станций и т.д. Формировать карту в конструкторе яндекс карт каждый раз при появлении нового объекта — неудобно. Для решения этой задачи лучше воспользоваться API Яндекс карт и большими возможностями 1С Битрикс.

И так, разобьём работу на этапы:

  • Установка продукта
  • Подготовка инфоблока
  • Подготовка компонента
  • Внедрение JavaScript формирующего Яндекс карту

Установка продукта

Не стану подробно останавливаться на этом вопросе, думаю ни у кого он не вызывает трудностей. Дам лишь совет, пользоваться кодировкой UTF-8 она в любом случае выгоднее т.к. содержит больше символов нежели кирилица Windows (или windows-1251 стандартная битрикс кодировка). Кодировку можно указать во время установки продукта на 3-м шаге «Регистрация»:

Установить в кодировке UTF-8

Если на следующем шаге будут ошибки , обычно ругается на mbstring.func_overload и mbstring.internal_encoding в файл .htaccess в папке с устанавливаемой CMS укажите следующие директивы и продолжайте установку:


php_value mbstring.func_overload 2
php_value mbstring.internal_encoding UTF-8


На этом всё, переходим к настройке информационного блока.

Подготовка информационного блока

Давайте определимся что мы хотим получить. Допустим у нас есть несколько магазинов которые мы хотим показывать на интерактивной яндекс карте + давать пользователям какую-нибудь доп. информацию о них, например точный адрес магазина, часы работы, контактный телефон и ФИО руководителя. Т.е. по клику на точку на яндекс карте, мы увидим некий блок, так называемый балун с доп. информацией о магазине. Для формирования самой точки на карте, нам потребуется задавать её координаты, для этого в 1С Битрикс существует тип поля привязка к Яндекс карте.

Приступим! Создаём инфоблок «Магазины&qout; со следующими свойствами (Имя свойства — тип — мнемонический код):

  • Адрес магазина — тип строка — ADDRESS
  • Часы работы — тип строка — HOURS
  • Контактный телефон — тип строка — PHONE
  • ФИО руководителя — тип строка — SHOP_MANAGER
  • Координаты — тип привязка к яндекс карте — YANDEX_MAP
Свойства инфоблока

Сохраняем инфоблок и добавляем в него несколько элементов, я добавил 3 магазина с 3-мя адресами в разных районах города Ростов-на-Дону. Важно при добавлении магазинов указать адрес на интерактивной карте Яндекс и сделать двойной щелчёк по заданной точке, чтобы заполнились поля координат точки иначе не получится построить точку на карте.

Координаты точки
Добавив несколько элементов переходим к следующему этапу.

Подготовка компонета

Для реализации задумки я решил использовать компонент bitrix:news.list, с его помощью мы выведем на экран список магазинов, данные для формирования карты и контейнер для самой карты. Для того чтобы JavaScript смог построить интерактиыную карты, ему нужно отдать данные объектов, т.е. данные наших магазинов. Для этого есть 2 способа.

  1. Вывести данные оъектов в специальные атрибуты тегов, т.е. непосредственно в DOM дерево документа
  2. Подготовить структурированный массив в php и затем с помощью функции 1С Битрикс PhpToJSObject преобразовать массив в JavaScript объект и затем работать с этим JS обектом вытаскивая данные для формирования карты.

Лично я предпочитаю первый способ, т.к. считаю его более наглядным и понятным. И так скопируем компонент news.list в текущий шаблон сайта с помощью интерфейса «Эрмитаж» и укажем следующий код шаблона:


<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<div class="shop-list">
<?
 
$index = 1; // Порядковый номер объекта на карте
foreach($arResult["ITEMS"] as $arItem) { ?>
    <?
    $this--->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
    $this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
?>
 
<?
    //Разбиваем координаты яндекс карты на X и Y координату
    $Yandex = explode(",", $arItem["PROPERTIES"]["YANDEX_MAP"]["VALUE"]);
    $Yandex_X = $Yandex[0];
    $Yandex_Y = $Yandex[1];
?>
 
    <!--Засовываем данные для формирования точки на карте в атрибуты контейнера div-->
    <div class="shop-data" data-index="<?=$index?>" data-name="<?=$arItem[" name"]?>"
    data-yandex-x="<?=$Yandex_X;?>"
    data-yandex-y="<?=$Yandex_Y;?>"
    data-address="<?=$arItem["PROPERTIES"]["ADDRESS"]["VALUE"];?>"
    data-hours="<?=$arItem["PROPERTIES"]["HOURS"]["VALUE"];?>"
    data-phone="<?=$arItem["PROPERTIES"]["PHONE"]["VALUE"];?>"
    data-shop-manager="<?=$arItem["PROPERTIES"]["SHOP_MANAGER"]["VALUE"];?>"
 
     >
        <!--Выводим информацию для пользователя-->
        <b><?=$arItem["NAME"]?></b>
        <ul>
            <li><b>Адрес:</b> <?=$arItem["PROPERTIES"]["ADDRESS"]["VALUE"];?></li>
            <li><b>Часы работы:</b> <?=$arItem["PROPERTIES"]["HOURS"]["VALUE"];?></li>
            <li><b>Контактный телефон:</b> <?=$arItem["PROPERTIES"]["PHONE"]["VALUE"];?></li>
            <li><b>ФИО руководителя:</b> <?=$arItem["PROPERTIES"]["SHOP_MANAGER"]["VALUE"];?></li>
        </ul>
    </div>
 
<? ++$index; } unset($index); ?>
 
<!--Контейнер в который прилетит сформированная яндекс карта-->
<div id="map_container"></div>
 
</div>


Давайте так же заранее пропишем css стили для контейнера карты, и точек (маркеров) на самой карте

#map_container {
    width:100%;
    height:600px;
    display:block;
}
 
.marker-circ {
    color: #404040;
    font-size: 14px;
    font-weight: normal;
    height: 80px;
    line-height: 56px;
    width: 58px;
}
 
.claster {
    color: #ffffff;
    font-size: 14px;
    font-weight: bold;
    height: 80px;
    line-height: 56px;
    width: 58px;
}


Компонент готов, можно переходить к подключению JavaScript сформирующего нам яндекс карту.

Внедрение JavaScript Яндекс карты

Первым делом подключаем JQuery (в моём случае это jQuery v1.9.1) и скрипт яндекс карты, чтобы не держать лишьних скриптов на сервере можно воспользоваться удалёнными файлами.


<script src="http://yandex.st/jquery/1.9.1/jquery.min.js"></script>
<script src="http://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>


Затем в отдельном JavaScript файле (назовём его start.js), куда мы будем выносить все наши скрипты (чтобы не писать их прям в DOM дереве документа) пишем код:


$(document).ready(function () {

    //Если на странице есть контейнер для яндекс карты с id map_container, начинаем её формировать
    if ($("#map_container").length > 0) {

        //yandex map
        ymaps.ready(function () {
            var map = new ymaps.Map("map_container", {
                center: [47.223572, 39.725845], //Создаём карту с центром в городе "Ростов-на-Дону"
                zoom: 11,   //Увеличение 11
            });

            //Кластера - группируем близко расположенные друг к другу объекты, чтобы при отдалении карты появлялась другая иконка
            // с количеством объектов в данной точке 

            var ClusterContent = ymaps.templateLayoutFactory.createClass('<div class="claster">$[properties.geoObjects.length] шт.</div>');

            //Параметры иконки кластера, обычно её делают отличной от точки, чтобы пользователь не путал номер объекта
            // и количество объектов

            var clusterIcons = [{
                href: '/bitrix/templates/furniture_pale-blue/images/map-claster.png',
                size: [58, 80],
                offset: [-24, -80],
            }];

            //Создание самого кластера
            myClusterer = new ymaps.Clusterer({
                clusterIcons: clusterIcons,
                clusterNumbers: [1],
                zoomMargin: [30],
                clusterIconContentLayout: ClusterContent
            });

            //HTML шаблон балуна, того самого всплывающего блока, который появляется при щелчке на карту
            var myBalloonLayout = ymaps.templateLayoutFactory.createClass(
                '<address class="address-map">' + '
                < p > < strong > $[properties.name] < /strong>'+                      '
            <br/>
            '+                      ' < /p>

            <ul class="balloon-info">'+ '
                <li><strong>Адрес:&nbsp;</strong>$[properties.address]</li>
                '+ '
                <li><strong>Часы работы:&nbsp;</strong>$[properties.hours]</li>
                '+ '
                <li><strong>Телефон:&nbsp;</strong>$[properties.phone]</li>
                '+ '
                <li><strong>Руоководитель:&nbsp;</strong>$[properties.manager]</li>
                '+ '</ul>
            '+                        ' < /address>'
        )
            ;

            var Placemark = {}; //Пустой объекта, куда будут помещены точки на для карты

            //Перебираем все блоки с картой и считываем данные для формирования точки и балуна по ранее заданному шаблону
            $(".shop-data").each(function () {

                //Координаты точки
                var X = $(this).attr("data-yandex-x");
                var Y = $(this).attr("data-yandex-y");

                Obj = $(this).attr("pointindex");

                //Создаём объект с заданными координатами и доп.свойствами
                Placemark[Obj] = new ymaps.Placemark([X, Y], {
                    name: $(this).attr("data-name"),    //Наименование магазина
                    address: $(this).attr("data-address"),  //Адрес
                    hours: $(this).attr("data-hours"),  //Часы работы
                    phone: $(this).attr("data-phone"),  //Контактный телефон
                    manager: $(this).attr("data-shop-manager"), //Руководитель
                    iconContent: "<div class="marker-circ">"+$(this).attr("data-index") + "</div>",   //Порядковый номер на карте
                }, { //Ниже некоторые параметры точки и балуна
                    balloonContentLayout: myBalloonLayout,
                    balloonOffset: [5, 0],
                    balloonCloseButton: true,
                    balloonMinWidth: 450,
                    balloonMaxWidth: 450,
                    balloonMinHeught: 150,
                    balloonMaxHeught: 200,
                    iconImageHref: '/bitrix/templates/furniture_pale-blue/images/map.png',  //Путь к картинке точки
                    iconImageSize: [58, 80],
                    iconImageOffset: [-24, -80],
                    iconLayout: 'default#imageWithContent',
                    iconactive: '/bitrix/templates/furniture_pale-blue/images/map-a.png' //Путь к картинке точки при наведении курсора мыши

                });

                //Добавляем маркер (точку) через кластер
                myClusterer.add(Placemark[Obj]);

            });

            //Добавление кластеры на карту
            map.geoObjects.add(myClusterer);
            //Запрещаем изменение размеров карты по скролу мыши
            map.behaviors.disable("scrollZoom");
        });
    }
});


Картинки для точек на карте я скачал с сайта www.iconfinder.com — это зарубежный поисковик по иконкам, многие из которых можно скачать абсолютно бесплатно, что я собственно и сделал. А на этом сервисе от яндекса удобно получать координаты точек и центра карты.

Если Вы всё сделали правильно у Вас должна получиться вот такая карта:


Если что-то не получилось, можете ознакомиться с исходниками. Желаю удачи!
Читайте также
Адаптивная вёрстка фотографий с помощью Flexbox

Адаптивная вёрстка фотографий с помощью Flexbox

Как легко вывести галерею изображений разных размеров в виде адаптивных бесшовных блоков не использую JavaScript. 

Упрощенная имитация HTTP-ответов в тестах Laravel

Упрощенная имитация HTTP-ответов в тестах Laravel

В статье рассмотрен пример работы с мок-данными для тестирования работы приложения с HTTP-ответами.

Обновление остатков товара на складе в 1С Битрикс

Обновление остатков товара на складе в 1С Битрикс

Как правильно обновлять остатки товара на сайта под управлением CMS 1С Битрикс.