Мультиточечная маршрутизация — это расчет маршрута, который охватывает несколько адресов за одну поездку. Яндекс Маршрутизация решает эту задачу через API: вы передаете список точек и ограничения, а сервис возвращает порядок объезда, время прибытия по каждой точке и общую длину пути.
Отличие от маршрута между двумя точками в том, что сервис перебирает варианты последовательности и выбирает выгодный по времени или километражу. Порядок посещения можно оставить алгоритму или зафиксировать вручную, когда клиент ждет курьера только в конкретном интервале.
Дальше: подготовка ключа, структура запроса, временные окна, грузоподъемность, разбор ответа, типичные ошибки и пример маршрута сервисного инженера на четыре адреса с расчетом времени. Имена полей и числовые лимиты сверяйте с актуальной версией документации: контракт API обновляется, и детали прошлых версий могут не совпадать с текущими.
Что такое мультиточечная маршрутизация и зачем она нужна
Мультиточечный маршрут — это последовательность из трех и более адресов, которую нужно обойти за одну смену с учетом ресурсов исполнителя. Классическая задача «склад — клиент — склад» решается перебором двух вариантов, а на десяти адресах число возможных последовательностей достигает 3,6 миллиона. Ручной подбор в таком объеме превращается в лотерею: курьер экономит десять минут на одном участке и теряет сорок на следующем.
Типовые сценарии, где нужен расчет нескольких точек:
- курьерская доставка: десятки адресов, у части получателей задан интервал;
- выездное обслуживание: инженер едет к клиентам с разным приоритетом заявок;
- инкассация и заправка банкоматов: фиксированные окна плюс требования безопасности;
- сервис оборудования: доставка запчастей на объект и вывоз неисправных узлов.
Задача усложняется, когда ограничений больше одного. Нужно уложиться в интервалы клиентов, не превысить грузоподъемность машины, успеть вернуться на склад и учесть график работы самого исполнителя. Такая постановка ближе к задаче маршрутизации транспорта (VRP), чем к поиску кратчайшего пути.
Что дает автоматический подбор порядка на практике. Возьмем шесть адресов и перебор вручную: диспетчер тратит 10–15 минут на построение смены, и результат зависит от того, насколько хорошо он знает район. Алгоритм выполняет ту же работу за доли секунды и учитывает пробки, развороты и запреты поворотов. Проверить качество расчета можно только по ответу API: там есть время прибытия, длины участков и предупреждения.
Подготовка к работе с API Яндекс Маршрутизации
Работа начинается с ключа доступа в кабинете разработчика Яндекса. Ключ выдается для конкретного сервиса, поэтому при регистрации нужно выбрать Маршрутизацию, а не, например, Геокодер или Карты. Если компания ведет несколько сред, разумно завести отдельные ключи для разработки, тестового контура и продакшена: так ротация или блокировка одного ключа не остановит остальные системы.
Порядок подготовки:
- Зарегистрируйте приложение или сервисный аккаунт в кабинете разработчика.
- Получите ключ и сразу ограничьте его: привяжите к IP-адресам серверов, задайте список разрешенных методов.
- Изучите раздел документации, посвященный Маршрутизации: там перечислены обязательные параметры, форматы координат и коды ошибок.
- Проверьте связь тестовым запросом с двумя точками из Postman или curl, прежде чем писать код интеграции.
- Заведите учет квот: сколько запросов в сутки доступно на текущем тарифе и что происходит при их исчерпании.
Хранение ключа. Ключ не попадает в git и не зашивается в образ контейнера: держите его в переменных окружения или в секрет-хранилище (Vault, Kubernetes Secrets, менеджер секретов облака). Публичный ключ в мобильном приложении или фронтенде легко извлечь, поэтому для клиентской части используйте промежуточный бэкенд-прокси, который подставляет ключ на своей стороне и ограничивает набор разрешенных операций.
Отдельно проверьте сетевой доступ: если сервер выходит в интернет через корпоративный прокси, а в запросе не учтены переменные окружения для прокси, ошибка соединения появится без внятного пояснения. Диагностика таких сбоев разобрана в материале про поиск причин проблем маршрутизации — подход с проверкой соединения и логов применим и к внешним геосервисам.
Формирование запроса с несколькими точками
Структура запроса повторяется от сценария к сценарию: адрес метода, ключ, режим движения и список точек. Режим определяет, по каким правилам считать время: легковой автомобиль, грузовик, пешеход. Для логистики выбирайте грузовой режим, иначе сервис построит маршрут по улицам, закрытым для грузового транспорта.
Координаты в геосервисах Яндекса принято передавать в порядке «долгота,широта» в десятичных градусах. Перепутанный порядок — самая частая причина того, что маршрут уезжает в другой регион или сервис отвечает ошибкой. Ниже упрощенная схема запроса, она показывает логику, а не буквальный контракт API.
{
"apikey": "<ваш ключ>",
"mode": "truck",
"waypoints": [
"37.520,55.700",
"37.610,55.740",
"37.700,55.720",
"37.520,55.700"
]
}
Первая точка обычно склад или стартовый адрес смены, последняя — место возврата. Если возврат не нужен, последнюю точку не дублируют.
Передача координат и порядка посещения
Порядок обхода задается либо явно, либо остается на усмотрение алгоритма. Явное задание полезно, когда последовательность продиктована бизнес-правилом: сначала забор документов, потом доставка. В документации API порядок описывается индексами точек, например последовательность «0,2,1» означает, что второй адрес из списка посещается последним.
Когда порядок не указан, сервис сам подбирает оптимум. Практическое правило для интеграции: фиксируйте порядок только там, где он действительно обязателен, и оставляйте свободу на остальных участках. Каждое жесткое требование к последовательности сужает пространство поиска, и в худшем случае маршрут может не построиться вовсе.
Использование временных окон
Временное окно — интервал, в который исполнитель обязан прибыть к клиенту, формат записи вида «HH:MM-HH:MM». Для каждой точки окно задается отдельно. К окну добавляйте время обслуживания: сколько минут инженер или курьер проводит на объекте. Без этого параметра сервис посчитает, что на точке он не задерживается, и расписание окажется нереалистичным.
Пример двух точек с разными окнами: клиент A принимает с 09:30 до 11:00, обслуживание 45 минут; клиент B — с 11:00 до 13:00, обслуживание 60 минут. Если расчет помещает прибытие к A в 08:55, сервис либо поставит ожидание до открытия окна, либо переставит порядок. Ожидание не ошибка, но оно съедает рабочее время, поэтому длинные паузы стоит устранять подбором другой последовательности.
Если ни одна последовательность не укладывается в окна, запрос вернет ошибку или предупреждение о невыполнимости. Дальше три пути: расширить окно у клиента, увеличить количество исполнителей на смену или перенести часть точек на другой день. Попытка «поджать» окна в коде без согласования с заказчиком приводит к сорванным SLA.
Учет грузоподъемности транспортного средства
Ограничение по весу задается для машины, а вес груза указывается для каждой точки. Сервис суммирует загрузку по ходу маршрута и отбрасывает варианты, где суммарный вес превышает допустимый. Для сценариев с забором и выгрузкой учитывайте не только доставку: если инженер забирает неисправное оборудование по пути, вес растет, а не убывает, и это меняет выполнимость маршрута.
Пример реакции API на перегруз: машина рассчитана на 40 кг, а суммарный вес груза по четырем адресам дает 45 кг. Маршрут в таких условиях не строится либо возвращается с предупреждением о нарушении ограничения. Решения: разделить заявки на два рейса, взять машину большей грузоподъемности или выгрузить часть груза на складе перед выездом. Проверку веса стоит делать в коде до отправки запроса — это дешевле, чем разбирать ошибку в проде.
Проверка и интерпретация результатов расчета
Ответ API содержит статус обработки, порядок точек, время прибытия по каждой из них, общую длительность, расстояние и массив предупреждений. Для грузового режима добавляются ограничения, которые сервис учел при построении.
{
"status": "OK",
"route": {
"order": [0, 1, 2, 3],
"arrival_times": ["08:55", "10:45", "12:45", "14:40"],
"duration_minutes": 550,
"distance_km": 96.4,
"warnings": []
}
}
Что проверять в первую очередь:
- статус ответа и наличие предупреждений: пустой массив ошибок не гарантирует, что окна соблюдены идеально, но исключает грубые нарушения;
- время прибытия по каждой точке, попадает ли оно в заданный интервал с учетом времени обслуживания;
- суммарный вес на самом длинном участке маршрута, не превышает ли он грузоподъемность;
- число точек в ответе, совпадает ли оно с числом точек в запросе, нет ли молча выброшенных адресов;
- длительность смены: сумма времени в пути, обслуживания и ожиданий должна помещаться в рабочий день исполнителя.
Ошибки стоит логировать отдельно от успешных ответов, сохраняя текст запроса без ключа доступа и полный ответ сервиса. Это упрощает разбор инцидентов: по логам видно, была ли проблема в координатах, в ограничениях или в квоте.
Практический пример: маршрут сервисного инженера
Сценарий: сервисный инженер выезжает со склада, посещает четыре объекта, забирает неисправный узел и возвращается на склад. Смена начинается в 08:20, машина рассчитана на 40 кг груза.
| Точка | Координаты | Временное окно | Обслуживание | Вес груза |
|---|---|---|---|---|
| Склад | 37.520,55.700 | 08:00-19:00 | - | - |
| Клиент A | 37.610,55.740 | 09:30-11:00 | 45 мин | 12 кг |
| Клиент B | 37.700,55.720 | 11:00-13:00 | 60 мин | 8 кг |
| Клиент C | 37.760,55.780 | 13:30-16:00 | 30 мин | 5 кг |
| Клиент D | 37.650,55.800 | 16:00-18:00 | 40 мин | 20 кг |
Шаг 1. Формируем запрос: склад как первая и последняя точка, четыре клиента в списке, для каждого указано окно, время обслуживания и вес. Режим движения — грузовой.
Шаг 2. Отправляем запрос. Выбранный порядок обхода: склад, A, B, C, D, склад.
Шаг 3. Считаем время по полученному ответу:
- выезд 08:20, дорога до A — 35 минут, прибытие 08:55, ожидание до окна 35 минут, обслуживание 45 минут, освобождение 10:15;
- дорога A — B — 30 минут, прибытие 10:45, ожидание 15 минут, обслуживание 60 минут, освобождение 12:00;
- дорога B — C — 45 минут, прибытие 12:45, ожидание 45 минут, обслуживание 30 минут, освобождение 14:00;
- дорога C — D — 40 минут, прибытие 14:40, ожидание 80 минут, обслуживание 40 минут, освобождение 16:40;
- дорога D — склад — 50 минут, возврат 17:30.
Итог: 200 минут в пути, 175 минут обслуживания, 175 минут ожидания, смена длится 9 часов 10 минут.
Шаг 4. Проверяем ограничения. Суммарный вес 12 + 8 + 5 + 20 = 45 кг превышает грузоподъемность 40 кг, значит маршрут в таком виде невыполним. Варианты: отправить заявку клиента D вторым рейсом, взять машину на 60 кг или оставить неисправный узел на объекте и забрать его отдельным выездом.
Шаг 5. Меняем временное окно у клиента D на 14:00-16:00 и пересчитываем. Прибытие 14:40 попадает в интервал, ожидание сокращается с 80 до 0 минут, возврат на склад происходит в 16:10, а вся смена занимает 7 часов 50 минут. Экономия 80 минут получена изменением одного параметра, без правок в коде интеграции.
Если окно у клиента D сдвинуть нельзя, разумнее поменять порядок: поставить D перед C. Тогда алгоритм либо предложит новый вариант, либо вернет предупреждение. Именно для таких случаев автоматический подбор порядка удобнее ручного: перебрать четыре варианта последовательности вручную еще реально, а на двадцати точках — нет.
Типичные ошибки и способы их устранения
Большинство сбоев интеграции связано не с логикой сервиса, а с данными и обработкой ответов.
| Ошибка | Как проявляется | Решение |
|---|---|---|
| Перепутан порядок координат | Маршрут строится в другом регионе или приходит ошибка о некорректной точке | Привести координаты к формату «долгота,широта», проверить десятичные градусы вместо градусов и минут |
| Превышен лимит точек в запросе | Сервис отвечает ошибкой валидации и не строит маршрут | Разбить смену на несколько запросов, уточнить лимит для текущего тарифа |
| Некорректные временные окна | Маршрут невыполним, есть предупреждение о невозможности уложиться | Проверить пересечение окон, время обслуживания, часовой пояс и момент старта смены |
| Превышение грузоподъемности | Нет решения с заданной машиной или приходит предупреждение | Проверять суммарный вес до запроса, дробить рейсы, менять транспорт |
| Недействительный ключ | Ответ с ошибкой авторизации при корректном запросе | Проверить срок действия ключа, привязку к IP, права сервисного аккаунта |
| Отсутствие повторных попыток | Разовый сетевой сбой ломает расчет смены | Добавить ретраи с задержкой, таймауты и идемпотентность вызовов |
Устойчивость интеграции строится на тех же принципах, что и для любого внешнего API: таймауты, ограниченное число повторных попыток, разделение ошибок клиента и ошибок сервиса. Разбор подходов к защите от каскадных сбоев собран в статье про типичные ошибки проектирования маршрутизации — схемы с Circuit Breaker, Retry и Timeout переносятся на вызовы геосервисов без изменений.
Логирование запросов и ответов решает половину проблем отладки. Пишите в лог идентификатор смены, набор точек, ограничения и код ответа, а ключ доступа маскируйте. Тогда при разборе инцидента видно, пришли ли неверные координаты из системы-источника или сервис отказал из-за квоты.
Ограничения и лимиты Яндекс Маршрутизации
У сервиса есть пределы по объему одного запроса и по числу запросов за период. Конкретные значения зависят от тарифа и меняются, поэтому перед запуском в продакшен выпишите для себя три числа из кабинета разработчика и документации: максимум точек в одном запросе, суточная квота запросов, стоимость запроса сверх бесплатного объема.
Что учитывать при планировании нагрузки:
- ограничения на количество точек: если смена содержит больше адресов, чем допускает один запрос, делите ее на части и стыкуйте результаты на своей стороне;
- лимит запросов: при десятках пересчетов в минуту квота расходуется быстро, помогает кэширование неизменных маршрутов и пересчет только при изменении данных;
- временные окна и грузоподъемность увеличивают время расчета: чем больше ограничений, тем дольше сервис ищет решение и тем выше шанс получить ответ о невыполнимости;
- тарифные различия: бесплатный объем подходит для отладки и небольших смен, для регулярной логистики считайте стоимость запросов заранее;
- обработка отказа по квоте: приложение должно не терять заявку, а ставить ее в очередь на повторный расчет.
Практический порядок действий перед вводом в эксплуатацию: проверьте ключ на тестовом контуре, зафиксируйте формат координат в коде преобразования адресов, добавьте валидацию веса и временных окон до отправки запроса, включите логирование ответов без секретов и настройте алерт на всплеск ошибок авторизации или превышение квоты. Такой набор покрывает почти все инциденты, которые возникают на первом месяце работы с мультиточечными маршрутами.