Как реализовать расчет расстояния и времени между точками маршрута в 1С через API карт с возвратом JSON

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

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

Разбор проблемы: почему стандартные API построения маршрутов не подходят

Обычные веб-сервисы построения маршрутов (например, стандартный Google Directions API или базовый Яндекс.Локатор) отлично работают, когда нам нужно построить путь от точки А до точки Б. Однако, когда точек становится больше (например, 10–15 адресов доставки), последовательный опрос сервиса в цикле по парам точек приводит к лавинообразному росту количества HTTP-запросов. Это моментально исчерпывает бесплатные лимиты, снижает скорость работы системы 1С и повышает риск блокировки со стороны провайдера карт.

Для решения этой проблемы все ведущие геосервисы предоставляют специализированный инструмент — API Матрицы расстояний (Distance Matrix API). Вместо построения отдельных маршрутов мы отправляем один запрос с массивом всех координат, а в ответ получаем готовую JSON-структуру, содержащую попарные расстояния и время в пути между всеми точками.

Вариант 1. Google Distance Matrix API (для глобальных задач)

Если специфика вашего бизнеса позволяет использовать зарубежные сервисы, можно задействовать API матрицы расстояний от Google. Для обхода ограничения в две точки мы используем параметры origins (точки отправления) и destinations (точки прибытия).

Рассмотрим ключевые особенности работы с Google:

  1. Формат запроса: Мы передаем координаты точек через разделитель. Сервис позволяет отправлять до 25 точек отправления и 25 точек назначения в одном HTTP-запросе (всего не более 100 элементов на запрос для стандартного тарифа).
  2. Ограничения: Для использования Google Maps API требуется обязательная привязка зарубежной банковской карты для оплаты сервиса при превышении лимитов.
  3. Качество данных в РФ: Как справедливо отмечают специалисты, за пределами крупных мегаполисов детализация дорожного графа Google в регионах России оставляет желать лучшего, что может приводить к погрешностям в расчетах.

Вариант 2. API Матрицы расстояний от Яндекс (сбалансированное решение)

Многие разработчики отказываются от Яндекса, пугаясь тарифов комплексного продукта «Яндекс Маршрутизация» (VRS), стоимость которого может составлять сотни тысяч рублей в год. Однако для простых учетных задач нет необходимости покупать тяжелое логистическое ПО. Яндекс предоставляет отдельный инструмент — API Матрицы расстояний.

Проанализируем особенности этого решения:

Вариант 3. Полностью бесплатный и безлимитный вариант: собственный сервер OSRM

Если бюджет компании ограничен, или вам необходимо обрабатывать сотни тысяч точек ежедневно без затрат, лучшим выбором станет развертывание собственного сервера OSRM (Open Source Routing Machine) на базе карт OpenStreetMap (OSM).

Выясним преимущества данного подхода:

  1. Полная автономность: Сервер разворачивается внутри локальной сети компании или на недорогом виртуальном сервере (VPS) через Docker-контейнер. Вы больше не зависите от санкций, изменения тарифов Яндекса или Google.
  2. Отсутствие лимитов: Вы можете совершать неограниченное количество запросов любой размерности совершенно бесплатно.
  3. Высокая скорость: Локальный сервер OSRM обрабатывает запросы за миллисекунды, так как все данные графа дорог находятся в оперативной памяти сервера.
  4. Использование Table Service: У OSRM есть готовый метод /table/v1/, который принимает на вход массив координат, а возвращает чистую JSON-строку с матрицами времени (durations) и расстояний (distances).

Вариант 4. API 2ГИС — идеальный выбор для регионов РФ

Если ваш транспорт работает преимущественно в регионах России и за пределами МКАД, незаменимым инструментом станет API Матрицы расстояний от 2ГИС. Данный сервис славится детальной прорисовкой проездов внутри дворов и точной информацией о шлагбаумах и ограничениях.

Рассмотрим сильные стороны 2ГИС:

Реализация интеграции в 1С: пошаговое руководство

Давайте подробно разберем, как написать универсальный код для интеграции 1С с геосервисами на примере бесплатного локального сервера OSRM (для других сервисов логика работы с HTTPСоединение и обработкой JSON будет идентичной, изменятся лишь структура URL и параметры запроса).

Представим, что у нас есть массив точек с координатами (широта и долгота). Нам нужно отправить их на сервер OSRM, получить JSON-ответ, распарсить его средствами 1С и вывести результат.

Посмотрим на пример реализации функции отправки запроса и разбора ответа в 1С:


&НаСервереБезКонтекста
Функция РассчитатьМатрицуРасстоянийOSRM(МассивТочек) Экспорт
    
    // Шаг 1. Формируем строку координат в формате OSRM (долгота,широта через точку с запятой)
    СтрокаКоординат = "";
    Для Каждого Точка Из МассивТочек Цикл
        // Форматируем координаты, заменяя запятую на точку в вещественных числах
        ШиротаСтр = Формат(Точка.Широта, "ЧРД=.; ЧГ=0");
        ДолготаСтр = Формат(Точка.Долгота, "ЧРД=.; ЧГ=0");
        
        Если ЗначениеЗаполнено(СтрокаКоординат) Тогда
            СтрокаКоординат = СтрокаКоординат + ";";
        КонецЕсли;
        
        // В OSRM координаты передаются в формате: Долгота,Широта
        СтрокаКоординат = СтрокаКоординат + ДолготаСтр + "," + ШиротаСтр;
    КонецЦикла;
    
    // Если точек нет, возвращаем пустой результат
    Если Не ЗначениеЗаполнено(СтрокаКоординат) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Шаг 2. Настройка HTTP-соединения со своим сервером OSRM
    // Допустим, ваш сервер развернут локально на порту 5000
    СерверАдрес = "localhost";
    Порт = 5000;
    
    Соединение = Новый HTTPСоединение(СерверАдрес, Порт,,,,, Новый ЗащищенноеСоединениеOpenSSL());
    
    // Формируем путь к методу Table Service с получением и расстояний (distances), и времени (durations)
    АдресРесурса = "/table/v1/driving/" + СтрокаКоординат + "?annotations=duration,distance";
    
    Запрос = Новый HTTPЗапрос(АдресРесурса);
    
    Попытка
        // Отправляем GET-запрос на сервер
        Ответ = Соединение.Получить(Запрос);
    Исключение
        ЗаписьЖурналаРегистрации("ИнтеграцияOSRM", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        ВызватьИсключение "Не удалось установить соединение с сервером маршрутизации.";
    КонецПопытки;
    
    // Шаг 3. Обработка ответа сервера
    Если Ответ.КодСостояния = 200 Тогда
        
        // Читаем полученную JSON-строку
        ТелоJSON = Ответ.ПолучитьТелоКакСтроку();
        
        Чтение = Новый ЧтениеJSON;
        Чтение.УстановитьСтроку(ТелоJSON);
        
        // Десериализуем JSON в структуру 1С
        ДанныеРасчета = ПрочитатьJSON(Чтение);
        Чтение.Закрыть();
        
        // Проверяем успешность статуса в JSON
        Если ДанныеРасчета.Свойство("code") И ДанныеРасчета.code = "Ok" Тогда
            Возврат ДанныеРасчета; // Возвращаем структуру с матрицами distances и durations
        Иначе
            ВызватьИсключение "Сервер OSRM вернул ошибку: " + ДанныеРасчета.code;
        КонецЕсли;
        
    Иначе
        ВызватьИсключение "Ошибка сервера OSRM. Код состояния: " + Ответ.КодСостояния;
    КонецЕсли;
    
КонецФункции

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

  1. durations — массив массивов, где элемент durations[i][j] указывает время в секундах, необходимое для переезда из точки i в точку j.
  2. distances — массив массивов, содержащий расстояния в метрах между соответствующими точками.

Проанализируем пример обработки полученной структуры на стороне 1С для вывода матрицы в лог или таблицу значений:


&НаСервере
Процедура ВывестиМатрицуРасстоянийВЛог(ДанныеРасчета)
    
    Если ДанныеРасчета = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    МатрицаРасстояний = ДанныеРасчета.distances;
    МатрицаВремени = ДанныеРасчета.durations;
    
    КоличествоТочек = МатрицаРасстояний.Количество();
    
    Для СтрокаИндекс = 0 По КоличествоТочек - 1 Цикл
        Для КолонкаИндекс = 0 По КоличествоТочек - 1 Цикл
            
            РасстояниеМетры = МатрицаРасстояний[СтрокаИндекс][КолонкаИндекс];
            ВремяСекунды = МатрицаВремени[СтрокаИндекс][КолонкаИндекс];
            
            // Переводим данные в более читаемый вид
            РасстояниеКм = Окр(РасстояниеМетры / 1000, 2);
            ВремяМинуты = Окр(ВремяСекунды / 60, 1);
            
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = СтрШаблон("Из точки %1 в точку %2: %3 км, %4 мин.", 
                СтрокаИндекс + 1, 
                КолонкаИндекс + 1, 
                РасстояниеКм, 
                ВремяМинуты);
            Сообщение.Сообщить();
            
        КонецЦикла;
    КонецЦикла;
    
КонецПроцедуры

Подведение итогов

Мы проанализировали основные доступные варианты для интеграции 1С с геоинформационными системами в рамках логистических задач. Выбор конкретного инструмента зависит от приоритетов вашего бизнеса:

Использование встроенных в платформу 1С объектов HTTPСоединение и ЧтениеJSON позволяет осуществить любую из этих интеграций силами одного программиста буквально за несколько часов.

← На главную