Здравствуйте! В данной статье я хочу поделиться опытом интеграции 1С с сервисом Mappable (Yandex)
Клиент — местная логистическая компания, занимающаяся грузоперевозками по стране и в страны ближнего и дальнего зарубежья. Свой учет она ведет в 1С. Эта компания обратилась к нам для написания модуля интеграции с картографическим сервисом. Клиент настаивал на использовании сервисов от Яндекса. Местный представитель Яндекса сообщил нам, что для решения данной задачи можно воспользоваться сервисом Mappable (это те же Яндекс.Карты, но, как я понял, работающие за пределами РФ).
Заказчик хотел иметь в 1С возможность ввода адреса или какой-нибудь местности, чтобы сервис выдавал список найденных адресов. После выбора значения из списка данный адрес должен отображаться на карте. Параллельно создавались бы данные в новом справочнике “Адреса” с сохранением координат и точного адреса выбранного значения.
Для решения данной задачи необходимо было использовать различные продукты Mappable API, о которых я и расскажу в этой статье.
Для вывода списка возможных адресов я использовал продукт geosuggest:
suggest.api.mappable.world
Для этого в общем серверном модуле был создан следующий метод:
// Получить места.
//
// Параметры:
// ТекстПоиска - Строка - Текст поиска.
//
// Возвращаемое значение:
// Произвольный - Получить места.
Функция ПолучитьМеста(ТекстПоиска = "") Экспорт
АдресСервера = "suggest.api.mappable.world";
СоединениеССервером = ПолучитьСоединение(АдресСервера);//HTTPСоединение
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
Ресурс = "v1/suggest";
ТелоЗапроса = СтрШаблон("?apikey=%1&text=%2&lang=ru_RU&print_address=1&attrs=uri",
Константы.MappableAPIKey.Получить(), ТекстПоиска);
HTTPЗапрос = Новый HTTPЗапрос(Ресурс + ТелоЗапроса, Заголовки);
Результат = СоединениеССервером.ВызватьHTTPМетод("GET", HTTPЗапрос);//HTTPОтвет
Ответ = Результат.ПолучитьТелоКакСтроку();
СтруктураОтвета = ПолучитьДанныеИзJSON(Ответ);
Возврат СтруктураОтвета;
КонецФункции
В ответе данная функция возвращает структуру данных. В этой структуре имеется массив структур “results”, в котором содержатся все необходимые данные. Каждый элемент массива представляет собой структуру, содержащую форматированный адрес, а также адрес, разбитый на компоненты: страну, город, улицу и прочие данные. Также в этой структуре имеется очень важный параметр “Uri” — своего рода идентификатор предлагаемого адреса. Он понадобится для получения координат места.
При выборе значения из выпадающего списка выполняется второй запрос в Mappable: geocoder.api.mappable.world
Для этого в нашем модуле была создана функция:
// Получить координаты места.
//
// Параметры:
// uri - Строка - uri.
//
// Возвращаемое значение:
// Произвольный - Получить координаты места.
Функция ПолучитьКоординатыМеста(uri = "") Экспорт
АдресСервера = "geocoder.api.mappable.world";
СоединениеССервером = ПолучитьСоединение(АдресСервера);//HTTPСоединение
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
Ресурс = "v1/";
ТелоЗапроса = СтрШаблон("?apikey=%1&uri=%2&lang=en_US", Константы.MappableAPIKey.Получить(), uri);
HTTPЗапрос = Новый HTTPЗапрос(Ресурс + ТелоЗапроса, Заголовки);
Результат = СоединениеССервером.ВызватьHTTPМетод("GET", HTTPЗапрос);//HTTPОтвет
Ответ = Результат.ПолучитьТелоКакСтроку();
СтруктураОтвета = ПолучитьДанныеИзJSON(Ответ);
Возврат СтруктураОтвета;
КонецФункции
Этот метод возвращает координаты выбранного места. Обработать результат можно следующим образом:
Если РезультатПоиска.Свойство("response") И РезультатПоиска.response.Свойство("GeoObjectCollection")
И РезультатПоиска.response.GeoObjectCollection.featureMember.Количество() > 0 Тогда
Точка = РезультатПоиска.response.GeoObjectCollection.featureMember[0].GeoObject.Point.pos;
СимволРазделителя = СтрНайти(Точка, " ");
Долгота = СокрЛП(Лев(Точка, СимволРазделителя));
Широта = СокрЛП(Сред(Точка, СимволРазделителя));
КонецЕсли;
Получив необходимые данные (адрес и координаты места), их можно выводить на карте.
Стоит отметить, что на момент написания статьи 1С не поддерживала работу с JavaScript API версий v3 от Яндекса. Поэтому использовалась версия 2.1.
Итак, на форму обработки выводим поле HTML-документа и устанавливаем текст, предоставляемый Яндексом. Сам HTML-код выводить не буду, он доступен в документации от Яндекса.
Для вывода точек на карту нужно написать несколько строк кода на JavaScript:
Вначале необходимо инициализировать карту:
ymaps.ready(init);
var myMap = "";
var exchangeData = "";
function init() {
myMap = new ymaps.Map("map", {
center: [широта, долгота],
zoom: 11,
});
}
Как видно из кода выше, в параметр center
передаются координаты центра отображаемой карты, а в параметр zoom
— значение масштаба карты.
Для непосредственного вывода точки на карту необходимо добавить следующий код:
function setPoints(lat, lng, pointContent, changeZoom = false) {
if (changeZoom) {
myMap.setCenter([lat, lng], 19);
}
var myPlacemark = new ymaps.Placemark([lat, lng], {
balloonContent: pointContent,
});
myMap.geoObjects.add(myPlacemark);
}
В качестве параметров этот метод принимает широту и долготу выводимой точки, содержимое точки (текст, отображаемый при нажатии на точку), а также параметр changeZoom
. На форме карта периодически обновляется. Если изменить масштаб карты вручную, то при следующем обновлении карты масштаб вернется в исходное положение, а этот параметр позволяет сохранить масштаб при обновлении.
В рамках задачи, также нужно было добавить возможность создания адреса при нажатии на произвольное место на карте. Необходимо было получить координаты выбранного места и иметь возможность создания адреса в нашем справочнике “Адреса”.
Для этого в нашем тексте HTML добавляем следующий текст:
<button id="interactionButton" style="display: none">Interaction button</button> - это невидимая кнопка при нажатии на которую данные будут передаваться в 1С.
Код JavaScript:
myMap.events.add('click', function (e) {
if (!myMap.balloon.isOpen()) {
var coords = e.get('coords');
exchangeData = JSON.stringify({"lat":coords[0].toPrecision(6),
"lng":coords[1].toPrecision(6)})
myMap.balloon.open(coords, {
contentHeader:'Новый адрес',
contentBody:'
<p>Координаты: ' + [
coords[0].toPrecision(6),
coords[1].toPrecision(6)
].join(', ') + '</p>',
contentFooter:'<button id="saveNewAddress" style = type="button" onclick = "createNewAddress()">Сохранить новый адрес</button>'
});
}
else {
myMap.balloon.close();
}
});
}
function createNewAddress(){
interactionButton.click();
}
В 1С в форме обработки в событии ПриНажатии нашего поля HTML пишем :
&НаКлиенте
Процедура ПолеHTMLПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
ЭлементНажатия = ДанныеСобытия.Element;
Если ЭлементНажатия.id = "interactionButton" Тогда
MyData = Элементы.ПолеHTML.Документ.defaultView.exchangeData;
ОписаниеОповещения = Новый ОписаниеОповещения("ПолучитьОтвет", ЭтотОбъект, MyData);
ПоказатьВопрос(ОписаниеОповещения, "Сздать адрес?", РежимДиалогаВопрос.ДаНет);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПолучитьОтвет(Параметры, ДопПараметр) Экспорт
Если Параметры = КодВозвратаДиалога.Да Тогда
ДанныеМетки = МодульИнтеграцииВызовСервера.ПолучитьДанныеИзJSON(ДопПараметр);
ФормаНовогоАдреса = ПолучитьФорму("Справочник.Адреса.ФормаОбъекта");
ДанныеФормы = ФормаНовогоАдреса.Объект;
Координаты = ПолучитьКоординатыТочки(Новый Структура("Долгота,Широта", ДанныеМетки.lng, ДанныеМетки.lat));
ОбработатьДанныеНаСервере(ДанныеФормы, Координаты);
КопироватьДанныеФормы(ДанныеФормы, ФормаНовогоАдреса.Объект);
ФормаНовогоАдреса.Модифицированность = Истина;
ФормаНовогоАдреса.Открыть();
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьДанныеНаСервере(ДанныеФормы, Координаты)
НовыйАдрес = ДанныеФормыВЗначение(ДанныеФормы, Тип("СправочникОбъект.Адреса"));
НовыйАдрес.Долгота = Координаты.Долгота;
НовыйАдрес.Широта = Координаты.Широта;
ЗначениеВДанныеФормы(НовыйАдрес, ДанныеФормы);
КонецПроцедуры
![image.png](https://habrastorage.org/getpro/habr/upload_files/36f/bd0/02b/36fbd002bae8064575d0a553464237be.png)
![image.png](https://habrastorage.org/getpro/habr/upload_files/028/efc/c67/028efcc67aa93dc3bf1d5db8d09235fe.png)
![image.png](https://habrastorage.org/getpro/habr/upload_files/ded/92a/445/ded92a4453a5f490afb5e8367f3832df.png)
![image.png](https://habrastorage.org/getpro/habr/upload_files/7ce/062/630/7ce0626301e4e365ae6f4dca180d56bc.png)
![](https://habrastorage.org/getpro/habr/upload_files/812/4c7/420/8124c7420ef5bc47707ee84267b9c182.png)
Заключение
Итак, описанная выше интеграция 1С с картографическим сервисом Mappable позволила успешно реализовать требования заказчика. Благодаря использованию API от Mappable, логистическая компания получила возможность автоматизировать процесс ввода адресов и работы с географическими данными непосредственно в 1С.
Основные задачи, такие как поиск и выбор адресов, получение координат, а также отображение точек на карте, были выполнены с помощью продуктов geosuggest
и geocoder
. Также, интеграция обеспечила возможность создания нового адреса в справочнике 1С при клике на карту.
Данный проект продемонстрировал, как с помощью современных API можно расширить функциональность 1С и повысить эффективность процессов в логистической компании. Подобная интеграция также может быть адаптирована и для других бизнесов, нуждающихся в работе с географическими данными.
В завершение хочу отметить, что поддержка актуальных технологий и гибкость в интеграции позволяют 1С оставаться востребованным инструментом для автоматизации бизнеса в самых разных сферах.
Надеюсь, что данная статья поможет читателям в решении подобных задач. Если у вас возникнут вопросы или предложения по улучшению данной методики, буду рад вашим отзывам и комментариям. Удачи в ваших проектах!
stungnthumz
А что там с лицензией Mappable на использование его в таком виде?
Форматирование кода - тихий ужас...