我正在处理一些 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 读取匹配的形状,然后寻找具有匹配纬度和经度的停靠点,但这似乎并不可靠。有人知道怎么做这个吗?
最佳答案
正如您所注意到的,GTFS 中的路线和停靠点之间没有直接关系。相反,停靠点与行程相关联,其中每次行程代表车辆沿特定路线的一次“运行”。这反射(reflect)了这样一个事实,即一条路线不一定始终服务于它的每个站点——例如,在周末它可能会跳过高中以外的站点。
因此,获取路线服务的每个站点的列表需要结合几个模型:
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>));
但是请记住,这将为该路线曾经服务的每个站点输出一条记录。如果您正在为骑手生成时间表信息,您可能希望将查询限制为仅在今天运行的行程,并且仅在接下来的 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>;
通常,您还会为
JOIN
中使用的每一列创建一个索引。或 WHERE
子句,在这种情况下意味着:CREATE INDEX stop_times_trip_id_index ON stop_times(trip_id);
CREATE INDEX trips_route_id_index ON trips(route_id);
(请注意,RDBMS 通常会通过主键自动为每个表建立索引,因此无需在
stops.stop_id
上显式创建索引。)许多进一步的优化是可能的,这取决于所使用的特定 DBMS 以及您为性能牺牲磁盘空间的意愿。但是这些命令几乎可以在任何 RDBMS 上产生良好的性能,而不会不必要地牺牲清晰度。
关于google-api - 如何使用 GTFS 列出与路线关联的所有站点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13407468/