1С Битрикс Блог

Интерактивная карта объектов с помощью Яндекс.Карт и инфоблоков
1С Битрикс Блог
28.12.2016

Интерактивная карта объектов с помощью Яндекс.Карт и инфоблоков

В 1С Битрикс уже есть компонент bitrix:map.yandex.view, который выводит Яндекс.Карту и метки на ней. Но, на мой взгляд, он немного неудобен, т.к. все метки хранятся на странице вызова компонента. И, если, планируется большое количество меток, будет неудобно ими управлять.

В этом посте я расскажу как вывести элементы информационного блока на Яндекс.Карту. Я буду использовать стандартный компонент 1С Битрикс bitrix:news.list, который выводит список новостей. Давайте создадим  новый тип информационного блока под названием "Объекты на карте":

Добавление нового типа инфоблока

Далее, добавим новый инфоблок, назовем его "Список объектов":

Добавление нового инфоблока

И добавим свойство с типом "Привязка к Яндекс.Карте" и названием "Координаты на карте":

Добавление нового свойства инфоблока

Если Вы не хотите создавать новый тип и инфоблок, Вы можете использовать уже существующие.

Давайте добавим несколько элементов информационного блока, для того, чтобы вывести их на карте на Яндекс.Карте:

Добавление нового элемента инфоблока

Далее, создайте страницу и разместите на ней компонент bitrix:news.list с шаблоном map. Теперь необходимо кастомизировать шаблон компонента bitrix:news.list. Для этого копируем стандартный шаблон .default из папки /bitrix/components/bitrix/news.list/templates в папку map компонента bitrix:news.list с компонентами вашего шаблона.

Подключим Яндекс.Карты:

$this->addExternalJS('https://api-maps.yandex.ru/2.1/?lang=ru_RU');

Для того, чтобы вывести метку на карте, нужно знать ее координаты. Координаты метки на карте можно получить из свойства элемента инфоблока COORDS. Для этого добавьте в параметр PROPERTY_CODE в вызове компонента bitrix:news.list элемент массива COORDS:

"PROPERTY_CODE" => array("COORDS", ""),

Теперь у нас есть все необходимое для вывода меток на Яндекс.Карту. Удалите код стандартного шаблона. Должно получиться так:

<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var array $arParams */
/** @var array $arResult */
/** @global CMain $APPLICATION */
/** @global CUser $USER */
/** @global CDatabase $DB */
/** @var CBitrixComponentTemplate $this */
/** @var string $templateName */
/** @var string $templateFile */
/** @var string $templateFolder */
/** @var string $componentPath */
/** @var CBitrixComponent $component */
$this->setFrameMode(true);
$this->addExternalJS('https://api-maps.yandex.ru/2.1/?lang=ru_RU');
?>

Инициализируйте массив $jsParams, в котором будете хранить метки:

$jsParams = [];

Координаты у свойства с типом "Привязка к Яндекс.Карте" выводятся в виде строки, через запятую, широта и долгота. Поэтому, для того, чтобы получить на выходе объект, разбейте эту строку на массив. Получаем координаты меток, разбиваем строку и добавляем их в массив $jsParams со значением ключа coordPoint:

	$arCoords = explode(',', $arItem['DISPLAY_PROPERTIES']['COORDS']['VALUE']);

	$jsParams[] = [
		'coordPoint'     => $arCoords
	];

Теперь выведем Яндекс.Карту, для этого добавьте тег div с идентификатором map, нужной Вам ширины и высоты:

<div id="map" style="width: 600px; height: 400px"></div>

Создайте экземпляр класса карты, в конструкторе которого укажите id map, ее центр и коэффициент масштабирования. У меня будет Москва и масштаб 10:

		myMap = new ymaps.Map("map", {
			center: [55.76, 37.64],
			zoom: 10
		});

Создавать карту следует после того, как веб-страница загрузится целиком. Это даст уверенность в том, что контейнер для карты создан и к нему можно обращаться по id. Чтобы инициализировать карту после загрузки страницы, можно воспользоваться функцией ready().

Функция ready вызовется тогда, когда API будет загружен и DOM сформирован:

	ymaps.ready(init);
	var myMap;

	function init() {
		myMap = new ymaps.Map("map", {
			center: [55.76, 37.64],
			zoom: 10
		});
	}

Давайте теперь добавим метки на карту. Для этого сначала объявим переменную placemarks, в которой будем хранить объект со всеми метками. Используйте метод PhpToJSObject класса CUtil, который преобразует PHP массив  в объект JS:

placemarks = <?=CUtil::PhpToJSObject($jsParams);?>;

Теперь переберем все элементы объекта placemarks, создадим и метки на карту:

		for (var i in placemarks) {
			if (placemarks.hasOwnProperty(i)) {
				var placemark = new ymaps.Placemark(placemarks[i].coordPoint);
				myMap.geoObjects.add(placemark);
			}
		}

Все метки будут добавлены и выведены на карту. Полный код шаблона map компонента bitrix:news.list:

<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var array $arParams */
/** @var array $arResult */
/** @global CMain $APPLICATION */
/** @global CUser $USER */
/** @global CDatabase $DB */
/** @var CBitrixComponentTemplate $this */
/** @var string $templateName */
/** @var string $templateFile */
/** @var string $templateFolder */
/** @var string $componentPath */
/** @var CBitrixComponent $component */
$this->setFrameMode(true);
$this->addExternalJS('https://api-maps.yandex.ru/2.1/?lang=ru_RU');
?>

<?
$jsParams = [];
foreach ($arResult["ITEMS"] as $arItem)
{

	$arCoords = explode(',', $arItem['DISPLAY_PROPERTIES']['COORDS']['VALUE']);

	$jsParams[] = [
		'coordPoint'     => $arCoords
	];
};
?>

<div id="map" style="width: 600px; height: 400px"></div>

<script type="text/javascript">
	ymaps.ready(init);
	var myMap,
		placemarks = <?=CUtil::PhpToJSObject($jsParams);?>;

	function init() {
		myMap = new ymaps.Map("map", {
			center: [55.76, 37.64],
			zoom: 10
		});

		for (var i in placemarks) {
			if (placemarks.hasOwnProperty(i)) {
				var placemark = new ymaps.Placemark(placemarks[i].coordPoint);
				myMap.geoObjects.add(placemark);
			}
		}
	}
</script>

Коммментарии

Возврат к списку