Подтвердить что ты не робот

Как я могу перечислить все остановки, связанные с маршрутом, используя GTFS?

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

Trips.txt поставляется в таком формате:

route_id,service_id,trip_id,trip_headsign,direction_id,block_id,shape_id 1,A20120610WKD,A20120610WKD_000800_1..S03R,SOUTH FERRY,1,,1..S03R 1,A20120610WKD,A20120610WKD_002700_1..S03R,SOUTH FERRY,1,,1..S03R 1,A20120610WKD,A20120610WKD_004700_1..S03R,SOUTH FERRY,1,,1..S03R 1,A20120610WKD,A20120610WKD_006700_1..S03R,SOUTH FERRY,1,,1..S03R 1,A20120610WKD,A20120610WKD_008700_1..S03R,SOUTH FERRY,1,,1..S03R

Я пробовал читать в соответствующей форме с помощью shape_id, а затем искал остановки с соответствующими широтами и долготами, но это, похоже, не работает надежно. Кто-нибудь знает, как это сделать?

4b9b3361

Ответ 1

Как вы заметили, нет прямой связи между маршрутами и остановками в GTFS. Вместо этого остановки связаны с поездками, где каждая поездка представляет собой один "прогон" транспортного средства по определенному маршруту. Это отражает тот факт, что маршрут не обязательно обслуживает каждую из своих остановок в любое время - в выходные дни он может пропустить остановки за пределами средней школы, например.

Таким образом, получение списка каждой остановки, обслуживаемой маршрутом, включает в себя объединение нескольких моделей:

  • routes.txt дает вам идентификатор маршрута для интересующего вас маршрута.
  • trips.txt дает вам набор идентификаторов поездки для этого маршрута.
  • stop_times.txt дает вам набор идентификаторов остановки для остановок, поданных в каждой из этих отключений.
  • stops.txt предоставляет информацию о каждой из этих остановок.

Предполагая, что вы используете базу данных SQL для хранения данных GTFS, вы можете использовать такой запрос (после получения идентификатора маршрута):

SELECT stop_id, stop_name FROM stops WHERE stop_id IN (
  SELECT DISTINCT stop_id FROM stop_times WHERE trip_id IN (
    SELECT trip_id FROM trips WHERE route_id = <route_id>));

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


Обновление:. Я написал вышеупомянутый SQL-запрос так, как я это делал, поскольку я чувствовал, что он просто просто иллюстрирует взаимосвязь между моделями GTFS, но btse является правильным (в его ответе ниже), что запрос вроде это никогда не будет использовано в производстве. Это слишком медленно. Вместо этого вы должны использовать таблицы и индексы, чтобы время запроса было разумным.

Вот эквивалентный запрос, написанный таким образом, который больше подходит для копирования и вставки в реальное приложение:

SELECT DISTINCT stops.stop_id, stops.stop_name
  FROM trips
  INNER JOIN stop_times ON stop_times.trip_id = trips.trip_id
  INNER JOIN stops ON stops.stop_id = stop_times.stop_id
  WHERE route_id = <route_id>;

Как правило, вы также создадите индекс для каждого столбца, используемого в предложении JOIN или WHERE, что в данном случае означает:

CREATE INDEX stop_times_trip_id_index ON stop_times(trip_id);

CREATE INDEX trips_route_id_index ON trips(route_id);

(Обратите внимание, что RDBMSs автоматически индексируют каждую таблицу по ее первичному ключу автоматически, поэтому нет необходимости явно создавать индекс на stops.stop_id.)

Возможны многие дополнительные оптимизации, в зависимости от конкретной используемой СУБД и вашей готовности жертвовать дисковым пространством для повышения производительности. Но эти команды приносят хорошую производительность практически на любую РСУБД без лишнего пожертвования ясностью.

Ответ 2

Я столкнулся с этим сообщением в своих поисковых процессах Google, и я решил, что обновляю его с лучшим ответом, если кто-то еще наткнется на него. Ответ, который дал Саймон, на 100% правилен, однако запрос, который он предоставил, довольно медленный для больших каналов GTFS. Вот запрос, который делает то же самое, но быстрее выполняет значительно.

Просто, чтобы дать вам несколько анекдотических доказательств, для подачи GTFS около 50 МБ запрос Саймона занял от 10 до 25 секунд. Вышеприведенное утверждение последовательно принимает < 0,2 секунды.

SELECT T3.stop_id, T3.stop_name 
FROM trips AS T1
JOIN
stop_times AS T2
ON T1.trip_id=T2.trip_id AND route_id = <routeid>
JOIN stops AS T3
ON T2.stop_id=T3.stop_id
GROUP BY T3.stop_id, T3.stop_name

UPDATE:

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

Ответ 3

Если вы GROUP BY shape_id при выборе из trips, вы можете сделать запрос еще быстрее.

Использование запроса @btse для получения уникальных остановок для двух маршрутов занимает 1.147 с.

Мой эквивалентный запрос занимает 0,4 с.

SELECT unique_stops.route_id, unique_stops.stop_id, stop_name, stop_desc, stop_lat, stop_lon
FROM
  stops,
  (SELECT stop_id, route_id
   FROM
     stop_times,
     (SELECT trip_id, route_id
      FROM trips
      WHERE route_id IN (801, 803)
      GROUP BY shape_id
     ) AS unique_trips
   WHERE stop_times.trip_id = unique_trips.trip_id
   GROUP BY stop_id) AS unique_stops
WHERE stops.stop_id = unique_stops.stop_id

Ответ 4

Если вы используете "onebusaway", есть быстрый способ сделать это, не касаясь GTFS

Предположим, вы хотите узнать автобусные остановки для маршрута автобуса "M1" в Манхэттене, штат Нью-Йорк

http://bustime.mta.info/api/where/stops-for-route/MTA%20NYCT_M1.json?key=yourapikey&includePolylines=false&version=2

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