Как в 1С 8.3 получить географические координаты по адресу через API геокодера?

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

При автоматизации логистики, доставки или выездного обслуживания в 1С часто возникает задача определения точных географических координат (широты и долготы) по введенному текстовому адресу. Рассмотрим подробно, как организовать прямое взаимодействие 1С со сторонними картографическими сервисами геокодирования (например, Яндекс Карты) с помощью встроенных механизмов работы по протоколу HTTP.

Принцип работы геокодирования в 1С

Процесс прямого геокодирования строится по следующей схеме:

  1. Формирование HTTP-запроса с указанием адреса целевой точки и служебных параметров.
  2. Отправка GET-запроса к серверу API геокодера по защищенному протоколу HTTPS.
  3. Получение ответа сервера в формате JSON или XML.
  4. Парсинг полученного документа и извлечение координат (широты и долготы).

Для реализации этой задачи в платформе 1С:Предприятие 8.3 используются объекты HTTPСоединение, HTTPЗапрос, HTTPОтвет, ЗащищенноеСоединениеOpenSSL и средства разбора данных (ЧтениеJSON или ЧтениеXML).

Решение 1. Получение координат в формате JSON (рекомендуемый способ)

Разберем современный и производительный вариант реализации. В этом подходе мы запрашиваем ответ в формате 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], ".", ","));
                        Результат.Найдено = Истина;
                    КонецЕсли;
                КонецЕсли;
            Исключение
                // Ошибка формата структуры данных
            КонецПопытки;
        КонецЕсли;
        
    Исключение
        ВызватьИсключение "Ошибка при выполнении запроса к геокодеру: " + ОписаниеОшибки();
    КонецПопытки;
    
    Возврат Результат;
    
КонецФункции

Решение 2. Получение координат в формате XML

Проанализируем альтернативный вариант, когда ответ сервиса запрашивается по умолчанию в формате 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;
                Координаты = Сред(ТекстОтвета, ПозицияНачала, ПозицияКонца - ПозицияНачала);
            КонецЕсли;
        КонецЕсли;
    Исключение
        ВызватьИсключение "Сбой при обращении к сервису геокодирования: " + ОписаниеОшибки();
    КонецПопытки;
    
    Возврат Координаты;
    
КонецФункции

Важные технические нюансы при интеграции

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

  1. Обязательное использование API-ключа: Современные версии API картографических сервисов (Яндекс, Google) требуют обязательной авторизации через параметр apikey (или key). Запросы без ключа отклоняются с ошибками HTTP 401 или 403.
  2. Кодирование строки адреса: Адресная строка содержит кириллические символы, знаки препинания и пробелы. Обязательно используйте функцию КодироватьСтроку(Адрес, СпособКодированияСтроки.КодировкаURL) для исключения ошибок HTTP 400 (Bad Request).
  3. Порядок координат (Долгота и Широта): Сервис Яндекс возвращает координаты в строке pos в виде «Долгота Широта» (Longitude Latitude). Большинство мобильных навигаторов, а также API Google Maps принимают координаты в обратном порядке: «Широта, Долгота» (Latitude, Longitude). При сохранении или передаче точек в навигационные системы учитывайте это различие.
  4. Выполнение на стороне сервера 1С: Запросы выполняются в контексте &НаСервере или регламентными заданиями. Убедитесь, что служба сервера 1С (пользователь usr1cv8) имеет прямой доступ в интернет или настроен системный прокси-сервер через объект ИнтернетПрокси в конструкторе HTTPСоединение.
  5. Отказ от временных файлов: Метод HTTPОтвет.ПолучитьТелоКакСтроку() позволяет быстро получать содержимое ответа без обращений к диску, что существенно повышает скорость пакетной обработки адресов.
← На главную