Навигация | TSP API | Примеры | 2GIS Documentation
TSP API

Примеры

Ниже приведено детальное описание параметров из Справочника API и примеры использования их при отправке запросов к TSP API.

Временны́е окна — это допустимые временные отрезки посещения точки. Доступны два вида временных окон:

  • Жёсткое (по умолчанию): если курьер не попал на точку в указанный временной отрезок, точка исключается из расчёта маршрута.

  • Мягкое: точка остаётся в расчёте маршрута даже при опоздании курьера. Маршрут рассчитывается так, чтобы суммарное время опозданий в точках было минимальным.

    Для мягких временных окон можно задать дополнительное время после закрытия окна: максимальное допустимое время опоздания, после которого точка исключается из маршрута. Если задано допустимое время опоздания для всех точек (soft_time_windows_max_delay), то значение для отдельной точки (max_delay) приоритетнее. Если максимальное время опоздания не указано, то при расчёте маршрута допускается любое время опоздания.

Задать временное окно можно как для отдельной точки (параметр time_windows в массиве waypoints), так и для всех точек маршрута сразу (options). Время задаётся в секундах.

Например, чтобы задать жёсткое временное окно для точки и посетить её с 15 часов 07 минут до 17 часов 54 минут:

{
    "waypoints": [
        {
            "waypoint_id": 0,
            "point": {
                "lat": 54.994814,
                "lon": 82.87837
            },
            "time_windows": [
                {
                    "start": 54420,
                    "end": 64440
                }
            ]
        }
    ]
}

Например, чтобы задать мягкое временное окно для всех точек маршрута с максимальным допустимым временем опоздания в 2 часа:

{
    "agents": [...],
    "waypoints": [...],
    "options": {
        "is_soft_time_windows": true,
        "soft_time_windows_max_delay": 7200
    }
}

Отрезок времени, который курьер проведёт в точке (например, чтобы оформить и забрать груз), задаётся в секундах.

Например, задержаться в точке на 10 минут:

{
    "waypoints": [
        {
            "waypoint_id": 0,
            "point": {
                "lat": 54.994814,
                "lon": 82.87837
            },
            "service_time": 600
        }
    ]
}

Укажите параметр priority, чтобы построить маршрут через точки с наибольшим приоритетом. Точки с низким приоритетом тоже могут попасть в построенный маршрут, если они близко расположены к точкам с высоким приоритетом.

Параметр priority указывается в интервале от 0 (значение по умолчанию, не приоритетная точка) до 100 (максимальный приоритет):

{
    "waypoints": [
        {
            "waypoint_id": 0,
            "point": {
                "lat": 54.994814,
                "lon": 82.87837
            },
            "priority": 100
        }
    ]
}

По умолчанию прокладывается кратчайший по времени автомобильный маршрут с учётом текущих пробок. Чтобы указать тип маршрута явно, добавьте в запрос поле type:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "type": "jam" // автомобильный маршрут по текущим пробкам
    }
}

Вместо текущих пробок можно использовать статистическую информацию по пробкам. Для этого укажите тип маршрута statistics и нужную дату и время в формате RFC 3339 в поле start_time:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "type": "statistics" // автомобильный маршрут на основе статистических данных по пробкам...
    },
    "start_time": "2020-05-15T15:52:01Z" // ...на 15 мая 2020 года, 15:52:01 UTC
}

Если параметр start_time не используется, временем начала движения по маршруту считается время отправки запроса.

Пример расчёта обхода одних и тех же точек с учётом текущих пробок (слева) и с учётом статистической информации по пробкам (справа):

Расчёт с учётом пробок  Расчёт по статистике пробок

Чтобы построить самый короткий маршрут, даже если он не является оптимальным по времени из-за пробок, укажите тип shortest:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "type": "shortest"
    }
}

Чтобы построить маршрут для грузового транспорта:

  1. Укажите параметр transport со значением truck:

    {
        "waypoints": [...],
        "routing_options": {
            "transport": "truck" // грузовой транспорт
        }
    }
    
  2. (Дополнительно) Укажите характеристики груза и транспорта при помощи параметра truck_params. Если какая-либо характеристика не указана, будет использовано значение по умолчанию:

    {
        "waypoints": [...],
        "routing_options": {
            "transport": "truck",
            "truck_params": {
                "max_perm_mass": 10,
                "mass": 9,
                "axle_load": 4,
                "height": 3.2,
                "width": 2.5,
                "length": 7,
                "dangerous_cargo": true,
                "explosive_cargo": true
            }
        }
    }
    
  3. Если маршрут проходит через пропускные зоны, где движение грузового транспорта ограничено, вам необходимо выполнить следующие шаги:

    1. Получите список всех действующих пропусков для грузового транспорта: отправьте GET-запрос на /truck_passes/1.0.0/global:
    curl --location --request GET 'http://routing.api.2gis.com/truck_passes/1.0.0/global?key=API_KEY' \
    --header 'Accept: application/json'
    

    В ответе будут перечислены актуальные пропускные зоны и ID пропусков.

    1. Укажите ID необходимых пропусков при помощи параметра pass_zone_pass_ids при отправке запроса к TSP API:
    {
        "waypoints": [...],
        "routing_options": {
            "transport": "truck",
            "pass_zone_pass_ids": [4, 3, 2],
        }
    }
    

Чтобы построить пешеходный маршрут, укажите параметр transport со значением walking:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "transport": "walking" // пешеходный маршрут
    }
}

Чтобы построить велосипедный маршрут, укажите параметр transport со значением bicycle:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "transport": "bicycle" // велосипедный маршрут
    }
}

Чтобы построить самокатный маршрут, укажите параметр transport со значением scooter:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "transport": "scooter" // самокатный маршрут
    }
}

Чтобы получить в ответе информацию о высоте пешеходного или велосипедного маршрута, добавьте в запрос поле need_altitudes со значением true:

{
    "waypoints": [...],
    "agents": [...],
    "routing_options": {
        "transport": "walking", //или "transport": "bicycle"
        "need_altitudes": true
    }
}

Файл с решением содержит JSON-объект, в котором указана информация о высоте маршрута:

{
    "routes": [
        {
            ...
            "altitudes_info": {
                "elevation_gain": 0,
                "elevation_loss": 0,
                "max_altitude": 0,
                "min_altitude": 0,
                "max_road_angle": 0
                }
        },
        ...
    ]
}

Где:

  • elevation_gain — суммарное увеличение высоты в см;
  • elevation_loss — суммарное снижение высоты в см;
  • max_altitude — максимальная высота над уровнем моря в см;
  • min_altitude — минимальная высота над уровнем в см;
  • max_road_angle — максимальный угол наклона.

JSON-файл с решением содержит данные о продолжительности маршрута:

{
    "routes": [
        {
            "agent_id": 0,
            "points": [0, 1, 2, 4],
            "duration": 7713, // продолжительность маршрута данного курьера (в секундах)
            "distance": 45818, // протяженность маршрута данного курьера (в метрах)
            "waypoints": [
                {
                    "waypoint_id": 1,
                    "duration_waypoint": 4321, // время в пути до точки
                    "distance_to_waypoint": 33125 // протяженность пути до точки
                },
                ...
            ]
        },
        ...
    ],
    "summary_duration": 14244, // общее время в пути всех курьеров (в секундах)
    "summary_distance": 95634 // общая протяженность пути всех курьеров (в метрах)
}

Где:

  • duration и distance: время в пути и длина маршрута каждого курьера.

  • summary_duration и summary_distance: общее время в пути и длина маршрута всех курьеров.

  • duration_waypoint и distance_to_waypoint: время в пути и длина маршрута до конкретной точки.

    По умолчанию при расчёте этих значений используются данные о пробках, актуальные на момент начала движения по маршруту (параметр start_time или время запроса, если параметр не используется). Чтобы уточнить расчёт времени, укажите в запросе параметр travel_time_calculation со значением from_each_point. В этом случае при расчете времени в пути до точки будет учитываться время остановки курьера на предыдущей точке, время старта с предыдущей точки и статистические данные о пробках в этот момент.

    {
        "waypoints": [...],
        "agents": [...],
        "travel_time_calculation": "from_each_point"
    }
    

Стартовая и финишная точка — особый тип точек. Они не участвуют в оптимизации маршрута курьера и выступают в роли склада:

  • Для этих точек учитываются только параметры waypoint_id и time_windows. Параметры delivery_value, pickup_value и service_time не учитываются.
  • Маршрут курьера может оказаться пустым, если алгоритм не определил для курьера иные waypoint_id, помимо стартовой и финишной точек. Маршрут для такого курьера в файле с решением будет отсутствовать.

Стартовую точку (start_waypoint_id) необходимо указывать для каждого курьера. Финишную точку (finish_waypoint_id) указывать необязательно: в этом случае алгоритм подберёт оптимальное место финиша в текущей задаче.

Время, в которое курьер может посещать точки.

Время задаётся в секундах. Например, время работы курьера с 14:00 до 15:00:

{
    "agents": [
        {
            "agent_id": 0,
            "start_waypoint_id": 1,
            "work_time_window": {
                "start": 50400,
                "end": 54000
            }
        }
    ]
}

Если в рамках маршрута необходимо контролировать, сколько груза курьер доставит в точку или заберёт из неё, нужно указать следующие параметры:

  • Вместимость курьера: сколько единиц груза он может перевозить.

    Например, вместимость курьера 100 единиц:

    {
        "agents": [
            {
                "agent_id": 0,
                "start_waypoint_id": 1,
                "capacity": 100
            }
        ]
    }
    
  • Загрузка каждой точки (кроме стартовой и финишной). Для всех точек должен быть установлен одинаковый тип загрузки в зависимости от типа задачи:

    • delivery_value: сколько единиц груза курьер должен доставить в точку со склада.
    • pickup_value: сколько единиц груза курьер должен забрать с точки для доставки на склад.

    Например, забрать с точки 50 единиц груза:

    {
        "waypoints": [
            {
                "waypoint_id": 0,
                "point": {
                    "lat": 54.994814,
                    "lon": 82.87837
                },
                "pickup_value": 50
            }
        ]
    }
    

Если суммарная загрузка pickup_value или delivery_value точек превышает суммарную вместимость курьеров, то запрос считается невалидным.

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

Чтобы избегать дороги определённых типов, используйте параметр filters, например:

{
    "routing_options": {
        "filters": ["toll_roads"] // избегать платных дорог
    }
}

Чтобы избегать определённую область, задайте её координаты с помощью поля exclude, указав следующие параметры:

  • points — координаты исключаемой области (массив точек):

    • x — градусы восточной долготы;
    • y — градусы северной широты.
  • type — форма исключаемой области:

    • point — круг с радиусом, равным extent (points — это центр окружности);
    • polyline — ломаная линия с шириной, равной extent (points — вершины линии);
    • polygon — многоугольник (points — вершины многоугольника).
  • extent — размер исключаемой области в метрах.

  • severity — как строго нужно избегать заданную область:

    • soft — избегать по возможности;
    • hard — избегать всегда.

Максимальное количество исключаемых областей - 25.

Например, добавить строго избегаемую область в виде окружности в пример задачи:

{
    "routing_options": {
        "exclude": [
            {
                "type": "point",
                "severity": "hard",
                "extent": 2000, // 2 км
                "points": [
                    {
                        "y": 55.57853647062775,
                        "x": 37.577274080925086
                    }
                ]
            }
        ]
    }
}

Исключаемая область на карте

Даже если в результате избегания зоны количество точек в маршруте не изменится, может увеличиться длина маршрута или время в пути. Обратите внимание на параметры summary_duration и summary_distance в файле с решением.

Например, длина маршрута и время в пути из примера задачи без избегаемой области:

{
    "summary_duration": 14548, // 4 часа
    "summary_distance": 99124 // 99 км
}

И с заданной выше избегаемой областью:

{
    "summary_duration": 16299, // 4.5 часа
    "summary_distance": 117929 // 118 км
}

Если задачу невозможно решить с соблюдением всех условий, TSP API предложит маршрут с исключением некоторых точек или курьеров. Чтобы увидеть информацию об исключённых компонентах, отправьте запрос на проверку статуса задачи. Ответ будет содержать ссылку на файл с нужной информацией в поле url_excluded.

Файл содержит JSON-объект, в котором указаны исключенные точки (excluded_waypoints) и курьеры (excluded_agents), сгруппированные по причинам. Например:

{
    "excluded_waypoints": {
        "count_waypoints": 9,
        "reasons": [
            {
                "reason": "route_does_not_exist",
                "count": 2,
                "waypoints": [16, 18]
            },
            {
                "reason": "failed_time",
                "count": 1,
                "waypoints": [7]
            },
            {
                "reason": "failed_time_window_for_worktime",
                "count": 3,
                "waypoints": [5, 10, 12]
            },
            {
                "reason": "failed_pickup_value",
                "count": 1,
                "waypoints": [8]
            },
            {
                "reason": "failed_delivery_value",
                "count": 2,
                "waypoints": [2, 13]
            }
        ]
    },
    "excluded_agents": {
        "count_agents": 2,
        "reasons": [
            {
                "reason": "empty_agent",
                "count": 2,
                "agents": [1, 4]
            }
        ]
    }
}

Причины исключения:

  • route_does_not_exist — точки, до которых невозможно построить маршрут;
  • failed_time — точки, которые не успевает посетить курьер;
  • failed_time_window_for_worktime — точки, у которых временное окно не совпадает с расписанием любого из курьеров;
  • failed_pickup_value — точки, у которых объем груза для погрузки больше вместимости любого из курьеров;
  • failed_delivery_value — точки, у которых объем груза для доставки больше вместимости любого из курьеров;
  • empty_agent — курьеры, для которых отсутствуют маршруты (не были определены иные точки, кроме заданной стартовой или финишной).