Привет, клуб!
Сегодня расскажу о том, как работают всем знакомые приложения/сервисы, которые помогают ориентироваться в городском общественном транспорте.
Дисклеймер: пост не претендует на полную и правильную информацию о сабже. Я просто расскажу, как я столкнулся с этими форматами, и немного расскажу про них.
Предыстория
[Действие рассказа происходит в Израиле]
Когда-то давно я сделал бот для телеграма, для того чтобы покрыть свою потребность и изучить пару новых вещей. Бот принимал от пользователя код остановки, и присылал обновляемое время прибытия ближайших автобусов.
Со временем, API который я подсмотрел в каком-то ноунеймовом приложении, окончательно сдох, и я, в поисках источника данных, нашел на официальном сайте нашего МинТранса страницу, на которой сообщалось, что есть официальный государственный источник данных, вот форма для запроса доступа.
Я ее сразу же заполнил, не ожидая особо ничего, и, ВНЕЗАПНО, через несколько часов получил письмо на почту с документацией и доступами к ЭТОМУ.
На этом предыстория заканчивается, перейдем непосредственно к сабжу.
GTFS и SIRI: все уже придумано до нас
Данные, связанные с общественном транспортом, условно можно разделить на две категории: статичные, и динамические. Статичные — это всевозможные списки остановок, транспортных компаний, маршрутов, и.т.д. Динамические — данные о том, что происходит в реальном времени, например, местоположение автобуса, ожидаемое время прибытия на данную остановку, и все в таком духе.
Что приятно, обе эти категории стандартизированы, сейчас расскажу как.
GTFS — формат для хранения статичных данных
General Transit Feed Specification (GTFS) — общедоступный формат описания расписаний движения общественного транспорта и сопутствующей географической информации, позволяющий использовать эти данные на картах, в планировщиках маршрутов и других подобных сервисах. (Вики)
Придуман в начале 2000-х гуглом и транспортной компанией в Портленде.
Я не буду пересказывать подробное описание формата, отмечу только, что по сути своей, это набор из ~10 .csv файлов, с заданными названиями файлов и колонок, и требованиями к данным внутри. Часть из этих файлов обязательна (agency.txt, stops.txt, routes.txt, ...), часть опциональна.
К примеру, файл stops.txt содержит список всех остановок с их координатами, названиями и адресами, а файл toutes.txt — описания всех маршрутов (откуда куда едет, какой транспортной компании принадлежит, и.т.д).
Формат всем понравился, и сегодня его используют во многих городах Европы и США.
Полезные ссылки:
SIRI — интерфейс для динамических данных
The Standard Interface for Real-time Information or SIRI is an XML protocol to allow distributed computers to exchange real-time information about public transport services and vehicles. (Wiki)
Siri — куда более сложная штука. Это уже не формат описания csv, а полноценный протокол для нескольких разных динамических систем, связанных с общественным транспортом. Выпущен и стандартизирован европейским комитетом стандартизации, то есть все серьезно.
Siri состоит из нескольких разных сервисов. Про большинство из них можно почитать на википедии, я же получил доступ только к одному из них — Siri-SM (Stop monitoring), про него и расскажу.
Siri-SM — сервис для мониторинга остановок общественного транспорта на предмет прибывающих в скором времени едениц этого транспорта (автобусы, трамваи, поезда, и.т.д.). Если послать запрос с кодом остановки, можно получить просто ТОННУ информации о каждом транспортном средстве, которое движется в сторону остановки, на вскидку:
- данные о ТС (тип, номер ТС)
- местоположение на момент запроса
- запланированное и ожиданмое время прибытия
- данные о маршруте
- данные об остановках, как уже пройденых, так и предстоящих
Полезные ссылки:
- Описание протокола
- Awesome-list выше содержит полезное и для SIRI
Как со всем этим работать
Если отдавать всю эту кучу данных напрямую, респонсы будут просто гигантских размеров, поэтому внутри используются ссылки на данные из GTFS: например, не вся инфа о маршруте, а ссылка на запись в routes.txt; Аналогично с данными об остановке, компании-перевозчике.
Поэтому, чтобы сделать возможность человеческого использования, нужно сделать систему, которая будет иметь доступ и к Siri-SM api, и к GTFS-данным. Причем, желательно эти данные нормализовать и хранить по-человечески, потому что каждый раз искать запись по id в csv на 10-20к записей грешновато.
Мне для моих потребностей пока что нужно только два файла — stops.txt и routes.txt.
Данные о маршрутах я храню в памяти, потому что их надо вычитывать слишком часто, и хранить их в словаре/мэпе мне кажется удобным, а остановки в монге, для того чтоб можно было удобно искать остановки рядом, по координатам.
Архив с GTFS данными хранится на ftp-сервере, и публикуется каждый день в 12 ночи. Мой сервис его скачивает по ночам, и сохраняет локально, а при запуске загружает в память и в бд (если нужно).
Вот и все, что я хотел рассказать.
По итогу я сделал свой высокоуровневый api, который пока что умеет отдавать инфу о приближающемся транспорте для остановки, а так же находить остановки по коду либо по координатом (в радиусе).
Бот снова работает, все довольны, ура-ура.
@xeningem твой выход