Skip to content

Филиалы организации на яндекс карте

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

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

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

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

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

utf-8-bitrix

 

Если на следующем шаге будут ошибки , обычно ругается на 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 — это зарубежный поисковик по иконкам, многие из которых можно скачать абсолютно бесплатно, что я собственно и сделал. А на этом сервисе от яндекса удобно получать координаты точек и центра карты.

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

Если что-то не получилось, можете ознакомиться с исходниками. Желаю удачи!

Понравилось? Поделись с друзьями:Share on VKShare on FacebookTweet about this on TwitterShare on Google+
ОпубликованоРазработка сайтов на 1С Битрикс

32 комментов

  1. Виталий Виталий

    Интересное решение — очень помогло в одном проекте. Но есть вопрос: А как реализовать 2 разных вида метки, например с мощью управления из инфоблока. Допустим отметил чекбокс в инфоблоке и данный элемент вывелся с другой картинкой меткой? Я естественно не лажу с API Яндекса и js в принципе …

    • maler1988 maler1988

      Ну смотрите, данные для формирования карты у меня передаются в DOM (т.е. в атрибуты тегов). откуда я их потом считываю js скриптом и запускаю карту. В параметрах скрипта в моём примере картинка маркера (точки) определена заранее «iconImageHref: ‘/bitrix/templates/furniture_pale-blue/images/map.png’, //Путь к картинке точки» — но вы можете вместо «/bitrix/templates/furniture_pale-blue/images/map.png» подгружать свою картинку из атрибута тега. Т.е. в инфоблоке ставим радиобокс «картинка 1″, «картинка 2″ в зависимости от галочки в в какой-нибудь атрибут тега (например data-markerimage) выводим путь к картинке. ну а в js соответственно считываем его как в свойство «iconImageHref: $(this).attr(‘data-markerimage’)» или так «iconImageHref: $(this).data(‘markerimage’)». Вуаля =)

  2. valery valery

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

    • maler1988 maler1988

      Я думаю у вас просто ошибка в оформлении, проверьте CSS тех блоков в которые вы размещаете яндекс карту.

  3. Артем Артем

    Отличная статья, большое спасибо! Возможно не много не по теме кластеризации, но относящийся к картам. Подскажите пожалуйста, как можно настроить Поиск по свойствам? Например выводить форму с чекбоксами, которые в свою очередь проверяют 0 или 1, Да или Нет и т.д. и убирают\добаваляют точки на карту, без перезагрузки страницы.

    • maler1988 maler1988

      Ну смотрите, делайте вначале обычную формы с перезагрузкой, если речь идёт о битриксе вот тут можно посмотреть самую простейшую реализацию фильтра (без использования компонента). Получили фильтр с перезагрузкой страницы — отлично, дальше навешиваем jquery ajax, т.е. по кнопке «фильтровать» (или при нажатии на чекбокс) отправляем данные через POST на эту же страницу (смотрите jquery change()). Результат запроса обрабатываете в jquey ajax, там (в ajax ответе, обычно это переменная $(data)) находите контейнер с картой, функцией jquery html() получаете его содержимое и заменяете им содержимое текущего контейнера и перезапускаете карту. Пример реализации можно глянуть тут vertikal-invest.ru файл script.js

  4. Артем Артем

    Понял, буду пробовать, спасибо. Просто я как вижу js, так сразу начинается паника.
    И у меня еще один вопрос. При максимальном увеличении карты, все ок, но как только начинаю отдалять, точки начинают съезжать на встречу друг к другу, видать для того, что бы потом объединиться. Как это можно убрать? Кластеризация пускай остается, но точки при этом не ездили бы на встречу друг к другу, оставались статично на одном месте.
    Спасибо.

    • maler1988 maler1988

      Чтобы js-а не бояться посмотрите этот курс, я после него стал js понимать. Маркеры на карте всёравно будут съезжаться, они должны в кластеры собираться (смотрите решение тут vertikal-invest.ru), это нельзя убрать (если правильно понял о чём вы говорите), это работают скрипты яндекса, api карт.

  5. Артем Артем

    За курс спасибо, обязательно ознакомлюсь. На сайте как раз все отлично с метками, они съезжают из-за уменьшения размера карты(при этом точки остаются прежнего размера) из-за этого как бы и съезжают.
    У меня есть точка, расположение ее находится в Москве, если я максимально отдаляю, точка идет почти на северный полюс.
    Если я от максимально приближенного размера два-четыре раза отдалю, то точка перепрыгивает на соседнюю улицу(постепенно с каждым кликом все выше и выше).

  6. valery valery

    Добрый день. Сделали данную штуку у себя на портале Битрикс, менеджеры заводят объекты, они отображаются на карте, руководитель видит работу менеджера :). Ну буквально месяц назад, перестала отображаться карта, объекты заводятся все хорошо, но на странице форматирования карты пустой контейнер. Вопрос, а в данной карте есть ограничения по количеству объектов на карте? Если нет, что могло случится предположительно, доступа к админке Битрикс ни у кого нет блок новостей не правился..

    • maler1988 maler1988

      Никаких ошибок JS не выдаёт? По идеи ограничений нет, возможно что у самого яндекса что-то поменялось, но вы бы наверняка увидели бы ошибки в консоли (F12 в Chrome), а может яндекс затребовал ключ доступа (возможно есть ограничения на использования API яндекс карт без ключа, token, возможно яндкес посчитал что у вас какое-то коммерческое приложение с кучей объектов на карте). Я бы написал в яндекс.

  7. Александр Александр

    Добрый день. Спасибо за решение. Подскажите пожалуйста, а как сделать, чтобы карта появлялась не (center: [47.223572, 39.725845], //Создаём карту с центром в городе «Ростов-на-Дону»), а по координатам элемента. Поясню: создан ИБ — Россия — Санкт-Петербург, Москва, Ростов-на-Дону и т.д. с магазинами в этих городах и прописанными координатами. Сейчас открывается карта с центром прописанных координат в JS, а мне нужно чтобы она открывалась по координатам при нажатии на Москва, Ростов-на-Дону, Санкт-Петербург и т.д. центровалась по этим регионам. Москва — список магазинов — Карта с центровкой Москвы. И также при нажатии на другие регионы.
    Спасибо.

    • maler1988 maler1988

      Создайте доп.свойста у ИБ куда пропишите координаты нужных городов, а дальше аналогично (data-yandex-x, data-yandex-y) нужно вывести эти координаты в отдельный контейнер (какой-нибудь невидимый span с data-атрибутами) и считав из него значения подстваить их в атрибут center: [коордианты вашего города].

  8. volfernion volfernion

    Здравствуйте
    вывдит не одну а кучу карт, то есть для каждого элемента инфоблока.
    а не одну общую карту для всех

  9. volfernion volfernion

    либо выводит список элементов инфоблока, карту снизу и все.

    • maler1988 maler1988

      Ну вы скорее всего поместили в цикл создание самой карты, проверьте чтобы объект var map = new ymaps.Map(«map_container») у вас создавался один (причём map_container — id единственного элемента, проверте чтобы map_container был один в html), так же выведите в консоль Placemark, точки на карте, что туда попадает. Конкретней сказать не могу, надо код смотреть =)

  10. volfernion volfernion

    Все получилось.
    Спасибо.
    Очень полезный материал.

    подскажите как убрать нумерацию у точек?

    • maler1988 maler1988

      iconContent: "

      "+$(this).attr("data-index")+"

      " — надо $(this).attr("data-index") убрать помоему =)

  11. Александр Александр

    Подскажите, куда лучше вставить start.js? В шаблон страницы или шаблон компонента?

    • maler1988 maler1988

      А это уже как вам будет удобнее. Я например всё в шаблоне сайта храню, чтобы не искать скрипты по компонентам.

  12. Александр Александр

    Странно. Вроде все по инструкции, а карта не работает. И еще данные о скрипте где то в кэш падают. Пока не переименуешь имя файла изменения в коде не работают.
    Словом выводится список элементов, под списком карта, а на карте только цифры вместо меток.
    Помогите кто нибудь пожалуйста…

      • Александр Александр

        Убрал вот этот кусок

        Адрес:
        Часы работы:
        Контактный телефон:
        ФИО руководителя:

        Список пропал. На карте данные есть. Только не работает оформление меток.

      • maler1988 maler1988

        Во первых проверьте правильность путей к картинкам, это параметры в скрпте iconImageHref и iconactive , прямо откройте их в браузере и посмотрите что покажет Что касается кеша, думаю вы подключили скрипты напрямую, а надо через ядро с использованием метода $APPLICATION->AddHeadScript(), тогда с кешем проблем не будет.

  13. Александр Александр

    Что касается пути, то он выглядит так.
    iconImageHref: ‘/images/map.png’, //Путь к картинке точки

    И можно буквально пару слов о подключении скриптов?
    Спасибо вам огромное за решение. Давно искал.

    • maler1988 maler1988

      Я имел ввиду у вас картинка открывается по этому пути (в браузере #ваш_сайт#/images/map.png )? По скриптам всё в доках есть https://dev.1c-bitrix.ru/api_help/main/reference/cmain/addheadscript.php , рекомендую так же к прохождению курс https://academy.1c-bitrix.ru/training/course/5862/ , там все эти вопросы подробно раскрываются.

      • Александр Александр

        Ok. Цифры на карту выводятся. Картинки из браузера доступны.
        Если нажать на цифру — данные видно. Кластеризация отрабатывает — пишет при масштабировании «2 шт.». Значит скрипт отрабатывает.
        Но метки все равно не видно. Куда еще можно капнуть?

      • maler1988 maler1988

        Даже не знаю, надо смотреть конкретно.

  14. Александр Александр

    Вы были правы — нужно было через ядро скрипты подключить.
    Все работает — отличный метод, спасибо!

  15. Гарик Гарик

    Здравствуйте, почему то тут пуста и метки непонятно где

    <div

    class="shop-data"
    data-index="3"
    data-name="есть тут"
    data-yandex-x=""
    data-yandex-y=""
    data-address=""
    data-hours=""
    data-phone=""

    • maler1988 maler1988

      А вы задали элементам инфоблока координаты? Свойство YANDEX_MAP не пустое?

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

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

Защита от ботов *

Оставляя комментарий на сайте, вы даёте согласие на обработку персональных данных и соглашаетесь с политикой конфиденциальности
© it-svalka.ru 2013 - 2016 г.