Работа с картами в 1С на примере бесплатной библиотеки Leaflet

31.03.21

Интеграция - WEB-интеграция

Разработка функционала отображения и выбора пунктов доставки на карте прямо в 1С с помощью бесплатной библиотеки Leaflet. Тестирование производилось на платформе 8.3.15.1534 на тонком клиенте.

Скачать файлы

Наименование Файл Версия Размер
Работа с картами в 1С на примере бесплатной библиотеки Leaflet:
.epf 10,59Kb
90
.epf 10,59Kb 90 Скачать

Всем привет! 

Недавно передо мной встала задача разработки функционала отображения и выбора пунктов доставки на карте прямо в 1С. В данной статье я постараюсь рассказать и показать пример реализации данной задачи.

В начале потребовалось подобрать нужную библиотеку для работы с картами. Так как популярные сервисы предоставляемые компаниями Google и Яндекс платные, а задача не такого уровня, чтобы тратить на неё дополнительные средства, пришлось поискать бесплатные аналоги. Одним из таких аналогов оказалась библиотека Leaflet.

Из википедии мы узнаем, что Leaflet это: "Библиотека с открытым исходным кодом, написанная на JavaScript, предназначенная для отображения карт на веб-сайтах". Функционал предоставляемой API достаточно широкий, и в интернете есть масса примеров реализации различных задач. Это то, что нам нужно.

Для начала нам нужно создать макет и поместить туда HTML-код вывода карты и основные скрипты, необходимые для работы. (В коде есть комментарии для чего нужна каждая из процедур).

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9"/>
    <link rel="stylesheet" href="/redirect.php?url=aHR0cHM6Ly91bnBrZy5jb20vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuY3Nz" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
   crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
   integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
   crossorigin=""></script>
</head>
<body>
    <div id="map" class="map" style="position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px;"></div>

	//Добавляем невидимую кнопку для взаиможействия карта - 1С
	<button id="interactionButton" style="display: none">Кнопка взаимодействия</button>

    <script type="text/javascript">
    
    	//Установка начальных координат (широта и долгата + 13 это зум)
    	var map = L.map('map').setView([55.755814, 37.617635], 13);
    	var markers = L.layerGroup().addTo(map);
    	
	    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    		attribution: '&copy; <a href="/redirect.php?url=aHR0cHM6Ly93d3cub3BlbnN0cmVldG1hcC5vcmcvY29weXJpZ2h0">OpenStreetMap</a> contributors'
		}).addTo(map);
		
		//Функция установки пунктов доставки на карте, в нее передается массив с данными	 
		function addPlaces(placesArray,latitude,longitude){
					
			var placesArray = JSON.parse(placesArray);	
			
			
			map.setView([latitude, longitude], 8);
			    
			for(var i = 0; i < placesArray.length; i++)
		    {       
		        L.marker([placesArray[i][0], placesArray[i][1]],{alt : '{name: '+placesArray[i][2]+', code: '+placesArray[i][4]+'}'}).addTo(markers).bindPopup("<strong>"+placesArray[i][2]+"</strong><br />"+placesArray[i][3]).on('dblclick', onClick);
	
			}
		    						
		}
		
		//Выбор пункта доставки
		function onClick(e)
		{
			
			interactionButton.click();
			map.setView(e.target.getLatLng(), 18);
		}
		
		//Очищаем карту
		function refreshMap(){
			markers.clearLayers();
			
		}
		
		//Установка курсора на текущем пункте доставки
		function SetViewOffice(latitude,longitude){
						
			map.setView([latitude, longitude], 18);
		}	
			
		
    </script>
</body>
</html>

Затем создаем реквизит с типом "Строка" и размещаем его на форме и указываем вариант отображения "Поле HTML документа". При создании на сервере подключаем нашу карту:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Макет=РеквизитФормывЗначение("Объект").ПолучитьМакет("Карта");
	ПолеКарты=Макет.ПолучитьТекст();
КонецПроцедуры

 

На следующем этапе разбираемся с нужными нам функциями:

1. На карте должны отображаться пункты доставки. Для демонстрации я возьму табличку, сформирую нужный массив и вызову процедуру addPlaces().

&НаСервере
Функция ПолучитьМассивПунктовДоставки()

	Масс=Новый Массив;
	
	Для каждого стр из Таблица цикл
		
		НОфис=Новый Массив;
		НОфис.Добавить(стр.Широта);
		НОфис.Добавить(стр.Долгота);
		НОфис.Добавить(стр.Имя);
		НОфис.Добавить(стр.Адрес);
		НОфис.Добавить(стр.Код);

		Масс.Добавить(НОфис);
	КонецЦикла;
	
	пк_ШиротаРегионаДоставки    = Таблица[0].Широта;
	пк_ДолготаРегионаДоставки	= Таблица[0].Долгота;
	
	Возврат Масс;
	
КонецФункции

&НаКлиенте
Процедура ОтобразитьПунктыДоставки(Команда)
	
	МассивТочек = ПолучитьМассивПунктовДоставки();
	JSONМассивТочек = СериализоватьВJSON(МассивТочек);
	ДокументПервогоБраузера = Элементы.ПолеКарты.Документ;
	попытка
		
		ОкноПервогоБраузера     = ДокументПервогоБраузера.parentWindow; // IE
		
	исключение
		
		ОкноПервогоБраузера=неопределено;
		
	конецпопытки;
	
	Если ОкноПервогоБраузера = Неопределено Тогда
		ОкноПервогоБраузера = ДокументПервогоБраузера.defaultView; // Прочие браузеры
	КонецЕсли;
	
	ОкноПервогоБраузера.refreshMap();

	//во 2 и 3 параметр передаются широта и долгота региона, где находятся пункты доставки (нужно для установки примерного общего зума региона (я беру 1 строку таблицы)
	ОкноПервогоБраузера.addPlaces(JSONМассивТочек,пк_ШиротаРегионаДоставки,пк_ДолготаРегионаДоставки);

КонецПроцедуры

&НаКлиенте
Функция СериализоватьВJSON(СериализуемыйОбъект)
    
    #Если ВебКлиент Тогда    
        СтрокаJSON = СериализоватьВJSONНаСервере(СериализуемыйОбъект);
    #Иначе
        ЗаписьJSON = Новый ЗаписьJSON; 
        ЗаписьJSON.УстановитьСтроку();
        НастройкиСериализации = Новый НастройкиСериализацииJSON();
        НастройкиСериализации.СериализовыватьМассивыКакОбъекты = Ложь;
        ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект, НастройкиСериализации, "ПреобразованиеВJSON", ЭтотОбъект); 
        СтрокаJSON = ЗаписьJSON.Закрыть();
    #КонецЕсли
    
    Возврат СтрокаJSON; 

КонецФункции

&НаСервереБезКонтекста
Функция СериализоватьВJSONНаСервере(СериализуемыйОбъект)
    
    ЗаписьJSON = Новый ЗаписьJSON; 
    ЗаписьJSON.УстановитьСтроку();
    НастройкиСериализации = Новый НастройкиСериализацииJSON();
    НастройкиСериализации.СериализовыватьМассивыКакОбъекты = Ложь;
    ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект); 
    // ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект, НастройкиСериализации, "ПреобразованиеВJSON", ЭтотОбъект); 
    //
    // ЭтотОбъект недоступнен в безконтекстном вызове, поэтому нужно либо поместить эту функцию в общий модуль, 
    // либо изменить директиву компиляции в &НаСервере
    СтрокаJSON = ЗаписьJSON.Закрыть();
        
    Возврат СтрокаJSON; 

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ПреобразованиеВJSON(Свойство, Значение, ДополнительныеПараметры, Отказ) Экспорт
    
    // Данная функция вызывается для всех свойств, тип которых не поддерживает преобразование в формат JSON напрямую.
    // Они нам не нужны, поэтому всегда отказ от их записи.
    Отказ = Истина;    
    
    // Можно сделать преобразование в строку.
    // Значение = Строка(Значение);
    // Возврат Значение;
    
КонецФункции

Получаем результат:

 

 

2. Также должна быть возможность выбора пункта доставки на карте и передача выбранного значения в реквизит 1С:

Для этого нам и потребуется задать обработчик события нажатия на нашу карту и вызвать нажатие кнопки "interactionButton" (эта кнопка создана в коде карты для этих целей).

&НаКлиенте
Процедура ПолеКартыПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
	
	НажатыйЭлемент = ДанныеСобытия.Element;
	
	Если НажатыйЭлемент.id = "interactionButton" Тогда
 
		ЗаполнитьПунктДоставки(ДанныеСобытия.Document.activeElement.alt);

	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПунктДоставки(ДанныеПункта)
	
	НачНомер1=СтрНайти(ДанныеПункта,"name")+6;
	КонНомер1=СтрНайти(ДанныеПункта,"code")-2;
	
	НачНомер2=СтрНайти(ДанныеПункта,"code")+6;
	
	ИмяПунктаДоставки=Сред(ДанныеПункта,НачНомер1,СтрДлина(ДанныеПункта)-НачНомер1-(СтрДлина(ДанныеПункта)-КонНомер1));
	КодПунктаДоставки=Сред(ДанныеПункта,НачНомер2,СтрДлина(ДанныеПункта)-НачНомер2);
		
КонецПроцедуры

 

Теперь при двойном клике на пункт доставки устанавливает зум и в реквизиты "Имя пункта доставки" и "Код пункта доставки" заполняются данные:

 

 

В итоге у нас получилась небольшая программа для взаимодействия с картой в оба направления: 1С-карта и карта-1С. В интернете есть множество интересных вещей, реализованных с данной библиотекой, я постарался показать лишь малую часть.

Благодарю за внимание!

Карта Leaflet Работа с картой универсальная обработка Программирование Яндекс Пункты доставки

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    15750    10    17    

11

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17558    6    15    

13

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16364    42    49    

23

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25746    9    0    

7

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    88589    160    215    

318
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. rabid_otter 134 02.04.21 08:43 Сейчас в теме
прикольно, делал подобное еще в 2020-м году.
больше всего проблем ловишь в неожиданном месте - при попытке нарастить совмещенный с картами типовой функционал в веб-клиенте.
Зеленоград; +1 Ответить
2. Зеленоград 02.04.21 10:34 Сейчас в теме
OSM - это хорошо. А насколько он подробен в сравнении с платными картами?
3. Parsec1C 91 02.04.21 10:41 Сейчас в теме
(2) Вопрос сразу обо всём)
Нужно смотреть под конкретные задачи и проводить анализ.
19. KOTzilla 15 07.07.22 13:08 Сейчас в теме
(2) Работал с OSM, сами карты в плане координат довольно точны. Самое лютое приемущество это бесплатность сервиса OSM.
Из минусов опять же его бесплатность=) бывают провалы в производителности (микрофризы и прочее), другой момент он ведется как я понимаю иностранцами и больше заточен под англоязычную категорию (нюансы в прямом и обратном геотаргетировании, названий улиц и прочее, точнее в их не точности), актуальность изменений на карте (например снесли здание в начале года, а на карте оно до сих пор присутсвует).
Если резюмировать для каких-то общих управленческих целей использовать можно, а вот сервис такси или логистики я бы не рекомендовал на них настраивать=)
4. rabid_otter 134 02.04.21 11:44 Сейчас в теме
(2) нам хватило для черчения границ земельных участков для кадастровой оценки
Parsec1C; +1 Ответить
5. ovasiliev 6 03.04.21 11:50 Сейчас в теме
OSM - карта, редактируемая самими пользователями. Не знаю как сейчас, но лет 5 назад во многом она была подробнее, чем монстры.
6. MissionOnly 05.04.21 10:08 Сейчас в теме
Спасибо, интересное решение.
7. user595194_bendery_sh 07.04.21 21:53 Сейчас в теме
почему то карта отображается отдельными квадратами в перемежку с пустыми
http://prntscr.com/116p4gl
8. Зеленоград 12.04.21 16:11 Сейчас в теме
(7) Все 6 фрагментов находятся неправильно друг относительно друга.
9. user799637 24.06.21 09:39 Сейчас в теме
(7) (8) У меня аналогичная проблема. Как она решается?
10. user1617387 24.06.21 18:48 Сейчас в теме
А какие аналогичные платные сервисы от Гугл Вы имели ввиду при описании вначале статьи?
11. Parsec1C 91 25.06.21 09:12 Сейчас в теме
(10) У яндекса это API яндекс карт. У Google - Google maps api (там вроде бы есть много вариаций в зависимости от задач).
12. Shevelev.artem 09.12.21 14:29 Сейчас в теме
Странно но у меня почему не хочет загружаться карта. Я выполнил первый этап и все. Работает ли это сейчас данная схема?
13. sila123 12 09.12.21 16:50 Сейчас в теме
(12) Тоже карту пустую загружает. Непонятно.
14. fddf 5 13.12.21 13:56 Сейчас в теме
(13)
Необходимо заменить кусок кода HTML в следующих тегах:

<head>
......

[*]
<sc ript src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w­0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></sc ript>

.....
</head>

в исходном варианте использована библиотека версии 1.6, сейчас актуальная похоже 1.7.1.
Прикрепленные файлы:
maps.txt
user636541_jabokryak; Xu4kok; abasovit; Alex17; ig77777; akR00b; Parsec1C; +7 Ответить
20. vittany 18 10.11.22 11:23 Сейчас в теме
(13) У вас получилось загрузить карту? Работаю с типовой обработкой конфигураии ТЛЭ, реализация похожая..и проблема с картой та же
15. akR00b 22 27.01.22 21:43 Сейчас в теме
16. ig77777 27.04.22 13:48 Сейчас в теме
Спасибо за демо возможностей.
Но у меня не срабатывает клик по карте, чтобы получать координаты места щелчка.
Эту функцию возможно как-то починить?
17. Shevelev.artem 28.04.22 08:45 Сейчас в теме
(16) а у вас карта загружается или же пустая
18. ig77777 28.04.22 18:40 Сейчас в теме
(17) Да, карта отображается.
У меня проблема в том, что не все адреса прописаны в их базе, соответственно координаты по таким адресам не находятся.
Хотел сделать, чтобы в таком случае, пользователь мог вручную указать нужную точку.
Вроде, из описания получается, что при клике по карте, должна:
1. Поставится метка на карту.
2. Произойти нажатие невидимой кнопки, которая вычислит и вернет координаты клика.

Вот п. 1 уже не происходит.

А знания в JS у меня более чем поверхностные. :-(
Оставьте свое сообщение