Как программно вывести метки с произвольными иконками на Яндекс.Карту из 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция 1С с картографическими сервисами — это мощный инструмент для визуализации логистики, мониторинга торговых точек или анализа покрытия регионов. Одной из часто встречающихся задач является не просто вывод точки на карту, а её стилизация: установка определенных иконок, цветов или подписей в зависимости от типа объекта. Разберем подробно, как реализовать передачу параметров стиля из 1С в JavaScript API Яндекс.Карт версии 2.1.

Анализ механизма взаимодействия 1С и JavaScript

Обычно взаимодействие происходит через поле HTML-документа. В 1С мы формируем строку кода JavaScript и исполняем её в контексте загруженной страницы. Рассмотрим ситуацию, когда в коде страницы (HTML) уже определена функция addToPointArray, которая принимает координаты и добавляет метку в массив для последующего отображения. Наша задача — расширить эту функцию так, чтобы она принимала еще и стиль иконки (preset).

Проанализируем исходный код функции, который часто используется в подобных задачах:


function addToPointArray(CoordX, CoordY) {
    var point = new ymaps.GeoObject({
        geometry: {type: "Point", coordinates: [CoordX, CoordY]},
    });
    PointArray.push(point);
}

В данном примере создается базовый GeoObject. Однако для работы с метками (точками) в Яндекс.Картах гораздо удобнее использовать специализированный класс ymaps.Placemark. Он имеет более простую структуру для управления свойствами (балунами) и опциями (иконками).

Модернизация JavaScript-функции для поддержки стилей

Чтобы иметь возможность менять иконку, нам нужно передать в функцию дополнительный параметр. В API Яндекс.Карт визуальное оформление (цвет, форма, значок внутри) управляется через параметр preset. Изменим нашу функцию следующим образом:


function addToPointArray(CoordX, CoordY, balloonContent, iconPreset) {
    // Создаем метку (Placemark)
    // Первый аргумент - координаты [широта, долгота]
    // Второй аргумент - свойства (Properties): содержимое балуна, хинта
    // Третий аргумент - опции (Options): стиль иконки, цвет и т.д.
    var point = new ymaps.Placemark([CoordX, CoordY], {
        balloonContentBody: balloonContent // Текст, который увидит пользователь при клике
    }, {
        preset: iconPreset || 'islands#blueIcon' // Используем переданный стиль или синий по умолчанию
    });

    // Добавляем в глобальный массив (если это необходимо для дальнейшей логики)
    PointArray.push(point);
    
    // Сразу добавляем объект на карту, чтобы он отобразился
    myMap.geoObjects.add(point);
}

Важный момент: Обратите внимание, что параметры в ymaps.Placemark разделены на блоки. geometry (координаты) идет первым, затем объект properties, и только третьим — объект options, где и указывается наш preset.

Вызов функции из 1С с передачей параметров

Теперь разберем, как правильно сформировать строку вызова в 1С. Нам необходимо передать широту, долготу, текст для балуна и строковый идентификатор пресета (например, "islands#buildingsIcon"). Рассмотрим пример кода в 1С при переборе данных из таблицы:


Для каждого Стр Из Отчет.ДанныеПоУчастку Цикл
    Широта = Стр.Широта;
    Долгота = Стр.Долгота;
    СодержимоеТочки = "Контрагент: " + Стр.Контрагент;
    СтильИконки = "islands#blueBuildingsIcon"; // Пример пресета со зданием
    
    // Формируем строку вызова функции JS
    // Важно правильно расставить кавычки для строковых параметров
    ТекстJS = "addToPointArray(" + 
              Формат(Широта, "ЧРД=.; ЧГ=0") + "," + 
              Формат(Долгота, "ЧРД=.; ЧГ=0") + ", '" + 
              СодержимоеТочки + "', '" + 
              СтильИконки + "');";
    
    // Выполняем код в поле HTML-документа
    // В современных конфигурациях лучше использовать метод RunJavaScript
    Элементы.Карта.RunJavaScript(ТекстJS);
КонецЦикла;

В коде выше мы используем Формат с параметром ЧРД=., чтобы гарантировать, что разделителем дробной части в координатах будет точка, а не запятая, иначе JavaScript выдаст ошибку синтаксиса.

Популярные пресеты иконок (Islands API)

Яндекс.Карты предоставляют огромный набор готовых иконок. Вот несколько популярных вариантов, которые можно передавать в качестве параметра iconPreset:

Оптимизация: Передача данных через JSON

Если точек много (сотни или тысячи), вызывать RunJavaScript в цикле — плохая практика, так как это вызывает "подвисание" интерфейса. Рассмотрим более профессиональный подход: соберем все данные в массив структур в 1С, преобразуем в JSON и передадим одной командой.

В 1С это будет выглядеть так:


МассивТочек = Новый Массив;
Для каждого Стр Из Отчет.ДанныеПоУчастку Цикл
    ДанныеТочки = Новый Структура("lat, lon, hint, style", Стр.Широта, Стр.Долгота, Строка(Стр.Контрагент), "islands#dotIcon");
    МассивТочек.Добавить(ДанныеТочки);
КонецЦикла;

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивТочек);
СтрокаДанных = ЗаписьJSON.Закрыть();

// Передаем весь массив одной функцией
Элементы.Карта.RunJavaScript("addManyPoints(" + СтрокаДанных + ")");

На стороне JavaScript добавим соответствующую функцию обработки:


function addManyPoints(dataArray) {
    dataArray.forEach(function(item) {
        var placemark = new ymaps.Placemark([item.lat, item.lon], {
            hintContent: item.hint
        }, {
            preset: item.style
        });
        myMap.geoObjects.add(placemark);
    });
}

Решение проблемы производительности (Кластеризация)

Если вы выводите на карту большое количество объектов (например, все аптеки города), они могут перекрывать друг друга, превращая карту в "кашу". Выясним, как этого избежать. Для этого используется кластеризатор.

Вместо прямого добавления myMap.geoObjects.add(point), выполним следующие шаги:

  1. Создадим объект кластеризатора: var clusterer = new ymaps.Clusterer({ preset: 'islands#invertedBlueClusterIcons' });
  2. В цикле будем добавлять метки в массив.
  3. Добавим весь массив в кластеризатор: clusterer.add(PointArray);
  4. Добавим кластеризатор на карту: myMap.geoObjects.add(clusterer);

Это сгруппирует близко стоящие точки в кружки с числом объектов, что значительно улучшит читаемость и скорость работы карты в 1С.

Использование собственных изображений

Если стандартных пресетов недостаточно, мы можем установить любую картинку (например, логотип компании). Для этого в блоке опций (Options) функции Placemark нужно указать специфические параметры:


{
    iconLayout: 'default#image',
    iconImageHref: 'http://mysite.ru/logo.png', // URL картинки
    iconImageSize: [30, 30], // Размер
    iconImageOffset: [-15, -15] // Смещение центра иконки
}

Таким образом, комбинируя возможности 1С по подготовке данных и гибкость Яндекс.Карт по их отображению, можно создавать интерактивные и информативные карты прямо внутри учетной системы.

← На главную