Как рассчитать время отправления ближайшего общественного транспорта (как на главном экране TransitApp) с помощью GTFS и PostgreSQL?

Я пытаюсь воспроизвести что-то вроде этого, найденного в приложении Transit: по сути, это список ближайших отправлений, и он показывает следующие несколько отправлений в обоих направлениях в пределах определенного радиуса от пользователя или точки ввода.введите описание изображения здесь

У меня есть глобальный набор каналов GTFS (тысячи) в моей базе данных postgres.

Чтобы отсортировать его, я обычно сохраняю все с идентификатором агентства, а затем что-то еще для формирования первичного ключа, например (paris, route_1) в качестве маршрута. Я поместил все остановки в r-дерево, как и все фигуры.

Все расписания весят более 500 ГБ, поэтому мне пришлось сжать их до 100 ГБ следующим образом: Я проверяю смещение времени каждой остановки от начала поездки. Я сохраняю маршруты, которые выглядят как [A:0, B:60, C:500, D: 900], количество секунд с начала. Затем я начинаю идентификатор поездки со времени начала. У меня есть индекс маршрутов в строках остановок, и я сохраняю метаданные для каждого маршрута в отдельной таблице.

Обычно это приводит к коэффициенту сжатия от 4 до 12 в зависимости от агентства. Я также создал набор направлений, которые представляют собой просто уникальные списки идентификаторов остановок, такие как [A, B, C, D] и [D, C, B, A], вместе со средним временем с начала, но это предназначено только для экрана информации о маршруте, а не для этого алгоритма. Метаданные также находятся в отдельной таблице.

Мне также нужно учитывать отмененные остановки в моем алгоритме, используя данные в реальном времени, которые пропускают остановку и переходят к следующей ближайшей остановке. У меня есть система, которая хранит мои данные в реальном времени на кластере серверов RPC, и я сделал некоторые "указатели" на ней.

Вот code, если вам интересно https://github.com/catenarytransit/catenary-backend, я использую diesel в качестве ORM, но я также могу делать необработанные запросы и фильтры.

Чтобы попытаться найти ближайшие отправления, я выполняю поиск по радиусу от точки до 1 км (или 2 км для разреженных областей), а затем выполняю соединение с маршрутами. Проблема в том, что если я попытаюсь запросить chicago или manhatten, r-tree вернет результаты очень быстро (около 900 остановок), но затем фактический поиск itinerary_pattern вернет более 400 000 результатов. Направления немного лучше — 14 000 строк, но мне все равно придется запрашивать все метаданные шаблона маршрута, которые соответствуют направлениям, а затем запрашивать все строки маршрута, соответствующие шаблонам маршрута. Этот запрос сам по себе занимает более 20 секунд на моем сервере postgres, что быстро для других запросов.

Я понимаю, что мне также нужно расшифровать смещения времени, но я уже знаю, как это сделать.

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

Олег
Вопрос задан26 января 2024 г.

1 Ответ

Ваш ответ

Загрузить файл.