Как реализовать бесплатное геокодирование в 1С: получение координат по адресу

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

В современной автоматизации бизнеса часто возникает задача визуализации данных на карте: будь то маршруты курьеров, точки продаж или анализ плотности клиентской базы. Для этого текстовый адрес (например, "Москва, ул. Ленина, д. 1") необходимо преобразовать в географические координаты — широту и долготу. Этот процесс называется геокодированием. Рассмотрим подробнее, как реализовать это в 1С, используя различные бесплатные инструменты и программные методы.

Вариант 1: Использование API Яндекс.Карт

Яндекс предоставляет один из самых точных инструментов для работы с адресами в СНГ. Несмотря на коммерческую направленность, у сервиса есть бесплатный тариф. Разберем программную реализацию запроса к HTTP-сервису Яндекса.

Для работы вам потребуется получить API-ключ в Кабинете разработчика Яндекса. После получения ключа мы можем использовать объект HTTPСоединение для отправки запроса. Проанализируем пример кода, который выполняет запрос и разбирает полученный ответ:


&НаСервереБезКонтекста
Функция ОпределитьКоординатыПоАдресуНаСервере(Адрес)
    
    АдресСервера = "geocode-maps.yandex.ru";
    // Формируем путь, не забывая про API-ключ и формат ответа
    ПутьНаСервере = "/1.x/?geocode=" + Адрес + "&results=1&format=xml&apikey=ВАШ_КЛЮЧ";
    
    Попытка
        ССЛ = Новый ЗащищенноеСоединениеOpenSSL;
        Соединение = Новый HTTPСоединение(АдресСервера,,,,, 5, ССЛ);
        Запрос = Новый HTTPЗапрос(ПутьНаСервере);
        Ответ = Соединение.Получить(Запрос);
        
        Если Ответ.КодСостояния = 200 Тогда
            ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
        Иначе
            Возврат Неопределено;
        КонецЕсли;
    Исключение
        Возврат Неопределено;
    КонецПопытки;

    // Поиск координат в XML-ответе через строковые функции
    ПозицияНачала = Найти(ТекстОтвета, "");
    ПозицияКонца = Найти(ТекстОтвета, "");
    
    Если ПозицияНачала > 0 И ПозицияКонца > 0 Тогда
        ПозицияНачала = ПозицияНачала + 5;
        КоординатыСтрокой = Сред(ТекстОтвета, ПозицияНачала, ПозицияКонца - ПозицияНачала);
        // Яндекс возвращает "Долгота Широта", разделим их
        МассивКоординат = СтрРазделить(КоординатыСтрокой, " ");
        
        Результат = Новый Структура;
        Результат.Вставить("Долгота", Число(МассивКоординат[0]));
        Результат.Вставить("Широта", Число(МассивКоординат[1]));
        Возврат Результат;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Важное примечание: При использовании бесплатного API Яндекса существуют ограничения. Во-первых, это лимит на количество запросов в сутки (обычно до 1000). Во-вторых, по условиям лицензии, вы обязаны отображать результаты поиска на карте Яндекса. Использование координат исключительно для внутренних расчетов без показа карты может привести к блокировке ключа.

Вариант 2: OpenStreetMap и сервис Nominatim

Если вам требуется полностью открытое решение без жестких привязок к коммерческим условиям, стоит рассмотреть OpenStreetMap (OSM). Сервис Nominatim позволяет искать объекты по названию и адресу.

Выясним особенности работы с OSM. Этот сервис очень чувствителен к формату адреса. Для улучшения качества поиска рекомендуется очищать строку от лишних символов и специфических сокращений. Посмотрим на пример реализации запроса к OSM:


Функция ПолучитьКоординатыOSM(АдресСтрокой)
    // Очищаем адрес от лишних запятых для лучшего поиска
    АдресДляПоиска = СтрЗаменить(АдресСтрокой, ",", " ");
    
    Сервер = "nominatim.openstreetmap.org";
    Соединение = Новый HTTPСоединение(Сервер, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
    
    // Кодируем строку для URL
    АдресURL = КодироватьСтроку(АдресДляПоиска, СпособКодированияСтроки.КодировкаURL, "UTF-8");
    Ресурс = "/search?q=" + АдресURL + "&format=json&addressdetails=1&limit=1";
    
    Запрос = Новый HTTPЗапрос(Ресурс);
    // Обязательно добавляем User-Agent, иначе OSM может отклонить запрос
    Запрос.Заголовки.Вставить("User-Agent", "1C_Geocoding_App");
    
    Ответ = Соединение.Получить(Запрос);
    
    Если Ответ.КодСостояния = 200 Тогда
        ТекстJSON = Ответ.ПолучитьТелоКакСтроку();
        // Используем встроенные средства 1С для парсинга JSON
        Чтение = Новый ЧтениеJSON;
        Чтение.УстановитьСтроку(ТекстJSON);
        Данные = ПрочитатьJSON(Чтение);
        Чтение.Закрыть();
        
        Если Данные.Количество() > 0 Тогда
            Возврат Новый Структура("Широта, Долгота", Число(Данные[0].lat), Число(Данные[0].lon));
        КонецЕсли;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Проанализируем преимущества OSM: нет явных ограничений на хранение координат в базе данных. Однако скорость работы публичного сервера может быть ниже, чем у коммерческих аналогов, а точность в некоторых регионах РФ уступает Яндексу.

Вариант 3: Использование DaData (Подсказки)

Сервис DaData предлагает очень удобный API для нормализации адресов. У них есть хитрость: при использовании бесплатного API "Подсказок" (до 10 000 запросов в сутки), в ответе вместе с красивым адресом приходят и его координаты.

Рассмотрим, почему это выгодно:

  1. Исправление опечаток: DaData отлично справляется с "грязными" адресами.
  2. Форматирование: Вы получаете не только координаты, но и адрес, разложенный по ФИАС (код региона, города, улицы).
  3. Бесплатный лимит: 10 000 запросов в день покрывает потребности большинства малых и средних компаний.

Стратегия обработки больших объемов данных (100 000+ адресов)

Если перед вами стоит задача разово или периодически обрабатывать огромные массивы данных (например, 120 000 адресов), обычный цикл в коде не подойдет по нескольким причинам: превышение лимитов API, зависание сеанса 1С и риск блокировки по IP.

Разберем по шагам правильную архитектуру такого решения:

  1. Очередь задач: Создайте регистр сведений ОчередьГеокодирования. Запишите туда все адреса со статусом "Не обработано".
  2. Регламентное задание: Настройте фоновое задание, которое запускается раз в несколько минут.
  3. Порционная обработка: Фоновое задание должно брать небольшую порцию (например, 100-200 записей), отправлять запросы к API, записывать результат в справочник и помечать запись в очереди как "Готово".
  4. Паузы между запросами: Чтобы внешние сервисы не приняли вашу активность за DDoS-атаку, добавьте небольшую задержку (Приостановить(0.5)) между вызовами HTTP-запросов.
  5. Комбинированный подход: Сначала пробуйте получить данные через бесплатный OSM, и только если адрес не найден — обращайтесь к более точным Яндекс или DaData.

Рекомендации по технической реализации

При написании кода в 1С всегда учитывайте следующие моменты:

Во-первых, используйте ЗащищенноеСоединениеOpenSSL, так как почти все современные API работают через HTTPS. Без этого объекта соединение не будет установлено.

Во-вторых, откажитесь от поиска координат через Найти() в тексте XML или JSON. Это крайне хрупкий метод. Используйте ЧтениеJSON для формата JSON или ЧтениеXML (с построением DOM-модели) для XML. Это гарантирует, что ваш код не сломается при добавлении сервисом новых полей в ответ.

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

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

← На главную