Я пытаюсь воспроизвести что-то вроде этого, найденного в приложении 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, что быстро для других запросов.
Я понимаю, что мне также нужно расшифровать смещения времени, но я уже знаю, как это сделать.
Мне, возможно, придется также изменить структуру моей базы данных, чтобы справиться с этой проблемой.