Вывод интерактивной карты в форму 1С: способы и настройка
Содержание
Карту в 1С выводят в элемент формы типа «Поле HTML документа»: в реквизит-строку кладут HTML с инициализацией Яндекс.Карт, а само поле показывает результат. Это основной путь для 8.3 с интерфейсом «Такси» — он не требует установки компонент на каждый клиент и одинаково работает в тонком и веб-клиенте.
Три варианта, из которых выбирают: поле HTML (быстро, почти без ограничений по JS), готовая внешняя компонента (нативный рендер, но нужна установка и подпись) и чистая API-интеграция, когда карта нужна не на форме, а для фоновых задач — например, перевести адрес из справочника в координаты. Ниже — когда какой брать, как настроить каждый и что делать с типовыми сбоями.
Какой способ показать карту выбрать
Отталкивайтесь от того, где карта нужна и кто ей пользуется.
| Способ | Когда подходит | Минусы |
|---|---|---|
| Поле HTML документа | Карта на управляемой форме: точки клиентов, маршруты, выбор адреса мышью | JS грузится из интернета, нужен доступ к api-maps.yandex.ru |
| Внешняя компонента | Нужен нативный рендер, работа без постоянного интернета, тесная связка с данными 1С | Установка и доверие компоненте, сопровождение при обновлении платформы |
| HTTP-запрос к API (геокодер) | Координаты и адреса нужны на сервере: заполнить реквизит, построить отчёт, без визуальной карты | Карту «вживую» не показывает, только данные |
Короткий ориентир по таблице: карта на форме — поле HTML; координаты без картинки — геокодер на сервере; автономность и глубокая связка с объектами 1С — внешняя компонента.
В 9 случаях из 10 для задач «показать адреса на карте» или «выбрать точку» хватает поля HTML. К компонентам переходят, когда HTML-поля уже не хватает.
Вывод карты через поле HTML документа
Это рабочая лошадка. Поле показывает произвольный HTML, а значит и любую JS-карту — Яндекс, 2ГИС или Google.
Что настроить в Конфигураторе:
- Откройте форму, куда встраиваете карту (например, форму списка контрагентов или обработку).
- Добавьте реквизит формы типа
Строка, неограниченной длины. Назовите, скажем,ДанныеКарты. - Добавьте элемент формы «Поле». В свойстве «Вид» выберите
Поле HTML документа. - Свяжите элемент с реквизитом: в свойстве «ПутьКДанным» укажите
ДанныеКарты.
Теперь в реквизит нужно положить HTML. Сделайте это в обработчике ПриСозданииНаСервере или ПриОткрытии:
&НаСервере
Процедура ПриСозданииНаСервереСформироватьКарту()
Шаблон =
"<!DOCTYPE html>
|<html><head>
|<script src='https://api-maps.yandex.ru/2.1/?apikey=ВАШ_КЛЮЧ&lang=ru_RU'></script>
|<style>html,body,#map{width:100%;height:100%;margin:0}</style>
|</head><body><div id='map'></div>
|<script>
|ymaps.ready(function(){
| var map = new ymaps.Map('map', {center:[55.751,37.618], zoom:10});
| map.geoObjects.add(new ymaps.Placemark([55.751,37.618], {balloonContent:'Офис'}));
|});
|</script></body></html>";
ДанныеКарты = Шаблон;
КонецПроцедуры
Координаты в Яндекс.Картах идут «широта, долгота» — именно в таком порядке в массиве JS. Перепутаете — метка уедет в другое полушарие.
Если точек много, не вставляйте их руками в шаблон. Соберите на сервере JSON из справочника и подставьте одной строкой в <script>:
Выборка = Запрос.Выполнить().Выбрать();
МассивТочек = Новый Массив;
Пока Выборка.Следующий() Цикл
МассивТочек.Добавить(Новый Структура("Широта,Долгота,Текст",
Выборка.Широта, Выборка.Долгота, Выборка.Наименование));
КонецЦикла;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивТочек);
СтрокаТочек = ЗаписьJSON.Закрыть();
Дальше СтрокаТочек подставляется в шаблон, а JS в цикле добавляет метки через map.geoObjects.add.
Как прочитать клик по карте обратно в 1С
Частая задача — пользователь ткнул в карту, а 1С должна узнать координаты точки. После загрузки документа у поля срабатывает событие «Документ сформирован». В его обработчике на клиенте доступен DOM через Элементы.ПолеКарты.Документ:
&НаКлиенте
Процедура ПолеКартыДокументСформирован(Элемент)
Документ = Элементы.ПолеКарты.Документ;
// через Документ.defaultView доступен window и ваши JS-функции
КонецПроцедуры
Обратный канал «из JS в 1С» делают просто: JS при клике пишет координаты в скрытый элемент DOM (например, в value поля input), а 1С по кнопке или таймеру читает это значение из Документ. Схема неказистая, но надёжная и работает в тонком и веб-клиенте одинаково.
Готовые внешние компоненты и решения
Внешняя компонента рисует карту средствами ОС, а не через встроенный браузер. Её берут, когда поля HTML мало: нужен офлайн-режим, тяжёлые слои или скорость на тысячах объектов.
Что учесть перед внедрением:
- 🔌 Компоненту нужно подключить методом
ПодключитьВнешнююКомпонентуи, как правило, положить в макет конфигурации или в общий макет. - 🖥️ Для веб-клиента компонента должна быть собрана под браузер (технология Native API), иначе заработает только в тонком клиенте под Windows.
- 🔄 При смене версии платформы компоненту иногда приходится пересобирать или обновлять — это сопровождение, которого нет у поля HTML.
Готовые решения проще не писать самому, а взять с Инфостарта: там есть обёртки над Яндекс.Картами, 2ГИС и OpenStreetMap, часть бесплатна, часть платная (ориентировочно от нескольких сотен до пары тысяч рублей за разработку). Перед покупкой проверьте, под какую платформу и какой клиент собрана компонента.
Внешняя компонента — сторонний исполняемый код в вашей базе. Ставьте только из источника, которому доверяете, и проверяйте, что она подписана. Неизвестную компоненту в рабочую базу не тащите.
Подключение API Яндекс.Карт: ключ и инициализация
Без API-ключа JS-карта либо не загрузится, либо будет ругаться в консоли браузера. Ключ получают в кабинете разработчика Яндекса (раздел для JavaScript API и Геокодера).
Порядок:
- Заведите аккаунт в кабинете разработчика Яндекса.
- Создайте ключ для нужного продукта. JS API и HTTP Геокодер — это РАЗНЫЕ ключи, один вместо другого не подойдёт.
- Для веб-варианта пропишите список доменов, с которых разрешены запросы.
- Подставьте ключ в параметр
apikeyу тега<script>(для JS) или в строку запроса (для геокодера).
О стоимости коротко. У Яндекса есть бесплатный лимит на число загрузок карты и геокодирований в сутки; при превышении включается платный тариф по договору. Google Maps требует привязки карты оплаты (billing) и даёт ежемесячный бесплатный объём, сверх него — поминутная тарификация. У 2ГИС есть бесплатный MapGL для ограниченного использования. Точные цифры и условия смотрите на странице тарифов выбранного сервиса — они меняются, выдумывать их не стоит.
Для внутренней базы, которой пользуются несколько менеджеров, бесплатного лимита почти всегда хватает. Платные тарифы начинают считать при публичных сервисах с тысячами обращений.
Яндекс, 2ГИС или Google — что встраивать
Техника встраивания для всех трёх одинакова: тот же тег <script> с ключом и инициализация карты в поле HTML. Отличается только API и условия:
- Яндекс.Карты. Лучшее покрытие адресов по России, подробный геокодер по российским улицам и домам. Документация на русском. Для задач с отечественными контрагентами — вариант по умолчанию.
- 2ГИС (MapGL). Сильная детализация по городам: этажность, организации внутри зданий, входы. Удобно для доставки и выездных служб. Покрытие сильнее в крупных городах.
- Google Maps. Глобальное покрытие, если среди контрагентов есть зарубежные адреса. Требует привязки карты оплаты даже для бесплатного объёма — для чисто российской базы избыточен.
Менять провайдера на уже готовой форме несложно: HTML-поле и логика заполнения реквизитов остаются, переписывается только содержимое <script> и строка запроса к геокодеру.
Геокодирование адресов: из строки в координаты
Геокодер превращает адрес («Москва, Тверская, 7») в пару координат. Это нужно, чтобы поставить метку на карту или просто записать широту и долготу в реквизиты справочника — без визуальной карты вообще.
Запрос идёт с сервера 1С по HTTP. Пример функции для Яндекс HTTP Геокодера:
&НаСервере
Функция ПолучитьКоординаты(Адрес)
Ключ = "ВАШ_КЛЮЧ_ГЕОКОДЕРА";
Соединение = Новый HTTPСоединение("geocode-maps.yandex.ru", 443,
, , , , Новый ЗащищенноеСоединениеOpenSSL);
АдресURL = КодироватьСтроку(Адрес, СпособКодированияСтроки.КодировкаURL);
Ресурс = "/1.x/?apikey=" + Ключ + "&format=json&geocode=" + АдресURL;
Ответ = Соединение.Получить(Новый HTTPЗапрос(Ресурс));
Если Ответ.КодСостояния <> 200 Тогда
Возврат Неопределено;
КонецЕсли;
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Коллекция = Данные["response"]["GeoObjectCollection"]["featureMember"];
Если Коллекция.Количество() = 0 Тогда
Возврат Неопределено; // адрес не распознан
КонецЕсли;
Поз = Коллекция[0]["GeoObject"]["Point"]["pos"]; // "долгота широта"
Части = СтрРазделить(Поз, " ");
Возврат Новый Структура("Широта,Долгота", Число(Части[1]), Число(Части[0]));
КонецФункции
Два момента, на которых спотыкаются:
- В ответе геокодера строка
posсодержит сначала долготу, потом широту — наоборот относительно порядка в JS-карте. Поэтому в структуре вышеЧасти[1]это широта, аЧасти[0]долгота. - Адрес обязательно кодируется через
КодироватьСтроку(..., СпособКодированияСтроки.КодировкаURL), иначе пробелы и кириллица сломают запрос.
Чтобы не дёргать геокодер каждый раз, сохраняйте полученные координаты в реквизиты справочника контрагентов или адресов. Повторный расчёт делайте только когда адрес изменился — так вы не упираетесь в суточный лимит.
Производительность и практические хитрости
Карта с сотнями меток легко начинает тормозить. Несколько приёмов, которые реально помогают:
- 📍 Кластеризация меток. Вместо тысячи
Placemarkиспользуйтеymaps.Clusterer— близкие точки схлопываются в один значок с числом. Форма перестаёт зависать. - 💾 Кэшируйте координаты. Геокодьте адрес один раз и храните результат. Повторное геокодирование одного и того же адреса — пустая трата лимита.
- ⏳ Грузите карту по требованию. Если поле на вкладке, которую открывают редко, формируйте HTML не при открытии формы, а при активации страницы — форма откроется быстрее.
- 🌐 Проверьте доступ в интернет с сервера и с клиента. Для JS-карты интернет нужен на машине пользователя (браузер тянет api-maps), для геокодера — на сервере 1С.
Если карта нужна в отчёте или на печать, снимайте со статической Static API картинкой по координатам — это быстрее и не зависит от JS в поле.
Когда адресов в справочнике тысячи, не геокодьте их разом в одном вызове. Разбейте на порции по несколько сотен и обрабатывайте регламентным заданием ночью: так вы не упираетесь в суточный лимит и не держите пользователя в ожидании. Результат — широту и долготу — пишите в реквизиты сразу, чтобы при повторном запуске пропускать уже обработанные адреса.
Перед первым запуском пройдитесь по короткому списку — он снимает большинство «карта не рисуется»:
Типичные ошибки при выводе карты
Большинство сбоев — это либо ключ, либо доступ в сеть, либо порядок координат.
<script> стоит ключ JS API (не геокодера) и что в кабинете разрешён ваш домен.[широта, долгота], в ответе геокодера pos — «долгота широта». Поменяйте местами.&format=json и читайте тело в UTF-8.