При автоматизации логистики, доставки или расчета командировочных расходов в 1С часто возникает задача определения расстояния между двумя адресами или координатами. Геокодирование позволяет получить широту и долготу по текстовому адресу, однако для вычисления расстояния между полученными точками требуются отдельные подходы.
Выясним, какие варианты решения существуют, чем отличается расчет по прямой от расчета по дорожной сети и как правильно реализовать интеграцию в 1С:Предприятии.
Если для бизнес-задачи достаточно знать приблизительное расстояние по прямой (например, для быстрой фильтрации ближайших складов или распределения зон), расчет можно выполнить без постоянных обращений к внешним сервисам.
Для расчета расстояния на сфере применяется формула длины дуги большого круга. Рассмотрим, как реализовать такой расчет на встроенном языке 1С без использования внешних библиотек и устаревших COM-объектов:
&НаСервере
Функция ВычислитьРасстояниеПоПрямой(Знач Широта1, Знач Долгота1, Знач Широта2, Знач Долгота2) Экспорт
// Радиус Земли в метрах
РадиусЗемли = 6372795;
ЧислоПи = 3.14159265358979323846;
// Перевод градусов в радианы
Лат1 = Число(Широта1) * ЧислоПи / 180;
Лат2 = Число(Широта2) * ЧислоПи / 180;
Лонг1 = Число(Долгота1) * ЧислоПи / 180;
Лонг2 = Число(Долгота2) * ЧислоПи / 180;
// Тригонометрические вычисления
КЛат1 = Cos(Лат1);
КЛат2 = Cos(Лат2);
СЛат1 = Sin(Лат1);
СЛат2 = Sin(Лат2);
ДельтаДолготы = Лонг2 - Лонг1;
КДельта = Cos(ДельтаДолготы);
СДельта = Sin(ДельтаДолготы);
// Вычисление центрального угла
У = Sqrt(Pow(КЛат2 * СДельта, 2) + Pow(КЛат1 * СЛат2 - СЛат1 * КЛат2 * КДельта, 2));
Х = СЛат1 * СЛат2 + КЛат1 * КЛат2 * КДельта;
Если Х = 0 И У = 0 Тогда
Возврат 0;
КонецЕсли;
Угол = ACos((КЛат1 * КЛат2 * КДельта + СЛат1 * СЛат2));
// Расстояние в метрах
РасстояниеВМетрах = Угол * РадиусЗемли;
Возврат Окр(РасстояниеВМетрах, 0);
КонецФункции
Важное замечание: на форумах часто встречается решение через MSScriptControl.ScriptControl с кодом на JavaScript. Обратите внимание, что объект MSScriptControl работает исключительно в 32-разрядных версиях платформы Windows. При выполнении на 64-разрядном сервере 1С или в среде Linux такой вызов вызовет аварийное завершение с ошибкой создания COM-объекта. Все математические вычисления рекомендуется выполнять нативно на языке 1С.
Для построения автомобильного маршрута и расчета фактического пробега с учетом развязок и улиц необходимо обращаться к сервисам маршрутизации. Для этого используются специализированные HTTP API, которые принимают координаты точек и возвращают протяженность пути и время движения в формате JSON.
Разберем по шагам типовой алгоритм отправки запроса и парсинга ответа в 1С 8.3:
HTTPСоединение и HTTPЗапрос с необходимыми заголовками.ЧтениеJSON и метода ПрочитатьJSON() для преобразования JSON в структуры и массивы 1С.Посмотрим на пример универсальной процедуры обработки JSON-ответа маршрутизатора в 1С:
&НаСервере
Функция ПолучитьРасстояниеПоМаршруту(ПараметрыПодключения, СтрокаКоординат)
HTTPСоединение = Новый HTTPСоединение(
ПараметрыПодключения.Сервер,
ПараметрыПодключения.Порт,
,,,
ПараметрыПодключения.Таймаут,
Новый ЗащищенноеСоединениеOpenSSL()
);
Запрос = Новый HTTPЗапрос(ПараметрыПодключения.ПутьКРесурсу + СтрокаКоординат);
Ответ = HTTPСоединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Структура ответа зависит от API провайдера
// Например, извлечение расстояния в километрах:
Если Данные.Свойство("routes") И Данные.routes.Количество() > 0 Тогда
РасстояниеМетры = Данные.routes[0].distance;
Возврат Окр(РасстояниеМетры / 1000, 2);
КонецЕсли;
КонецЕсли;
Возврат 0;
КонецФункции
При внедрении сервисов расчета маршрутов обязательно учитывайте следующие особенности:
ПолеHTMLДокумента). Для фонового пакетного расчета маршрутов требуется коммерческий тариф либо открытые решения.Долгота, Широта (Lon, Lat), другие — Широта, Долгота (Lat, Lon). Всегда сверяйтесь со спецификацией конкретного API.