При автоматизации логистики, доставки или выездного обслуживания в 1С часто возникает задача определения точных географических координат (широты и долготы) по введенному текстовому адресу. Рассмотрим подробно, как организовать прямое взаимодействие 1С со сторонними картографическими сервисами геокодирования (например, Яндекс Карты) с помощью встроенных механизмов работы по протоколу HTTP.
Процесс прямого геокодирования строится по следующей схеме:
Для реализации этой задачи в платформе 1С:Предприятие 8.3 используются объекты HTTPСоединение, HTTPЗапрос, HTTPОтвет, ЗащищенноеСоединениеOpenSSL и средства разбора данных (ЧтениеJSON или ЧтениеXML).
Разберем современный и производительный вариант реализации. В этом подходе мы запрашиваем ответ в формате JSON и читаем тело ответа напрямую в оперативную память через метод ПолучитьТелоКакСтроку() без создания временных файлов на диске.
Посмотрим на пример функции для отправки запроса и разбора результата:
&НаСервереБезКонтекста
Функция ПолучитьКоординатыПоАдресуJSON(Знач АдресСтрокой, Знач КлючAPI)
Результат = Новый Структура("Широта,Долгота,Найдено", 0, 0, Ложь);
// Подготовка параметров запроса и экранирование адреса
АдресСервера = "geocode-maps.yandex.ru";
АдресЭкранированный = КодироватьСтроку(АдресСтрокой, СпособКодированияСтроки.КодировкаURL);
ПутьЗапроса = "/1.x/?apikey=" + КлючAPI + "&geocode=" + АдресЭкранированный + "&format=json&results=1";
Попытка
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
HTTPСоединение = Новый HTTPСоединение(АдресСервера, 443,,,, 10, ЗащищенноеСоединение);
HTTPЗапрос = Новый HTTPЗапрос(ПутьЗапроса);
HTTPЗапрос.Заголовки.Вставить("User-Agent", "1C:Enterprise Geocoder Client");
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
ДанныеОтвета = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Навигация по структуре ответа API Яндекс
Попытка
СписокОбъектов = ДанныеОтвета.response.GeoObjectCollection.featureMember;
Если СписокОбъектов.Количество() > 0 Тогда
СтрокаКоординат = СписокОбъектов[0].GeoObject.Point.pos;
// Яндекс возвращает координаты в формате "Долгота Широта" через пробел
МассивКоординат = СтрРазделить(СтрокаКоординат, " ");
Если МассивКоординат.Количество() = 2 Тогда
Результат.Долгота = Число(СтрЗаменить(МассивКоординат[0], ".", ","));
Результат.Широта = Число(СтрЗаменить(МассивКоординат[1], ".", ","));
Результат.Найдено = Истина;
КонецЕсли;
КонецЕсли;
Исключение
// Ошибка формата структуры данных
КонецПопытки;
КонецЕсли;
Исключение
ВызватьИсключение "Ошибка при выполнении запроса к геокодеру: " + ОписаниеОшибки();
КонецПопытки;
Возврат Результат;
КонецФункции
Проанализируем альтернативный вариант, когда ответ сервиса запрашивается по умолчанию в формате XML. Координаты в XML-ответе содержатся внутри тега <pos>.
Рассмотрим пример функции, выполняющей запрос и извлечение координат:
&НаСервереБезКонтекста
Функция ПолучитьКоординатыПоАдресуXML(Знач АдресСтрокой, Знач КлючAPI)
Координаты = "";
АдресСервера = "geocode-maps.yandex.ru";
АдресЭкранированный = КодироватьСтроку(АдресСтрокой, СпособКодированияСтроки.КодировкаURL);
ПутьНаСервере = "/1.x/?apikey=" + КлючAPI + "&geocode=" + АдресЭкранированный + "&results=1";
Попытка
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
HTTPСоединение = Новый HTTPСоединение(АдресСервера, 443,,,, 10, ЗащищенноеСоединение);
HTTPЗапрос = Новый HTTPЗапрос(ПутьНаСервере);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
ПозицияНачала = Найти(ТекстОтвета, "<pos>");
ПозицияКонца = Найти(ТекстОтвета, "</pos>");
Если ПозицияНачала > 0 И ПозицияКонца > 0 Тогда
ПозицияНачала = ПозицияНачала + 5;
Координаты = Сред(ТекстОтвета, ПозицияНачала, ПозицияКонца - ПозицияНачала);
КонецЕсли;
КонецЕсли;
Исключение
ВызватьИсключение "Сбой при обращении к сервису геокодирования: " + ОписаниеОшибки();
КонецПопытки;
Возврат Координаты;
КонецФункции
Разберем ключевые особенности, которые необходимо учитывать при промышленной эксплуатации решения:
apikey (или key). Запросы без ключа отклоняются с ошибками HTTP 401 или 403.КодироватьСтроку(Адрес, СпособКодированияСтроки.КодировкаURL) для исключения ошибок HTTP 400 (Bad Request).pos в виде «Долгота Широта» (Longitude Latitude). Большинство мобильных навигаторов, а также API Google Maps принимают координаты в обратном порядке: «Широта, Долгота» (Latitude, Longitude). При сохранении или передаче точек в навигационные системы учитывайте это различие.&НаСервере или регламентными заданиями. Убедитесь, что служба сервера 1С (пользователь usr1cv8) имеет прямой доступ в интернет или настроен системный прокси-сервер через объект ИнтернетПрокси в конструкторе HTTPСоединение.HTTPОтвет.ПолучитьТелоКакСтроку() позволяет быстро получать содержимое ответа без обращений к диску, что существенно повышает скорость пакетной обработки адресов.