如何使用GTFS列出与路线相关的所有停靠点?

Cam*_*aul 16 google-api 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读取匹配的形状,然后寻找具有匹配的纬度和经度的停止,但这似乎不能可靠地工作.有人知道怎么做这个吗?

小智 36

正如您所注意到的,GTFS中的路线和停靠点之间没有直接关系.相反,停靠与行程相关联,其中每次行程代表沿着特定路线的车辆的单个"行驶".这反映了这样一个事实:一条路线不一定能在任何时候为其每一个站点提供服务 - 例如,周末它可能会跳过高中以外的站点.

因此,获取路线服务的每个停靠点的列表涉及组合几个模型:

  • routes.txt 为您提供您感兴趣的路线的路线ID.
  • trips.txt 为您提供该路线的一组旅行ID.
  • stop_times.txt 为您提供一组停靠ID,用于在每次旅行中提供的停靠点.
  • stops.txt 为您提供有关每个停靠点的信息.

假设您正在使用SQL数据库来存储GTFS数据,您可以使用这样的查询(一旦获得路径ID):

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>));
Run Code Online (Sandbox Code Playgroud)

但请记住,这将输出对于每个被停止的纪录不断被路由服务.如果您正在为骑手生成日程安排信息,您可能希望将查询限制为仅限今天运行的行程,并且仅在下一个30分钟内停止离开.


更新:我按照我的方式编写了上面的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>;
Run Code Online (Sandbox Code Playgroud)

通常,您还可以为JOINor WHERE子句中使用的每个列创建索引,在这种情况下,这意味着:

CREATE INDEX stop_times_trip_id_index ON stop_times(trip_id);

CREATE INDEX trips_route_id_index ON trips(route_id);
Run Code Online (Sandbox Code Playgroud)

(请注意,RDBMSes通常会自动为每个表索引其主键,因此无需显式创建索引stops.stop_id.)

许多进一步的优化是可能的,具体取决于所使用的特定DBMS以及您为牺牲性能而牺牲磁盘空间的意愿.但是这些命令几乎可以在任何RDBMS上产生良好的性能,而不会不必要地牺牲清晰度.

  • 很棒的 JOIN 查询说明了 GTFS 中表之间的关系。然而,正如 @Julian 指出的那样,它在确定分支方面存在不足。还需要以某种方式确定 stop_sequence 。如果您可以在答案中附加一些有关如何最好地吐出分支并确定顺序的详细信息,那就太好了。谢谢! (2认同)

bts*_*tse 10

我在谷歌的搜索中发现了这篇文章,我想我会用更好的答案更新它,万一其他人偶然发现它.Simon给出的答案是100%正确的,但是,他提供的查询对于大型GTFS提要来说非常慢.这是一个执行相同操作的查询,但执行速度明显更快.

只是为了给你一些轶事证据,对于大约50mb的GTFS提要,Simon的查询需要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
Run Code Online (Sandbox Code Playgroud)

更新:

我意识到我之前没有提到这一点,但当然你会希望有每个表加入的索引.