golang加载和解析GTFS文件插件库go-gtfs的使用
Golang加载和解析GTFS文件插件库go-gtfs的使用
安装
go get github.com/artonge/go-gtfs
示例
加载包含GTFS文件的单个目录
假设目录结构如下:
path/to/gtfs_files
├── agency.txt
├── attributions.txt
├── calendar_dates.txt
├── calendar.txt
├── fare_attributes.txt
├── fare_rules.txt
├── feed_info.txt
├── frequencies.txt
├── levels.txt
├── pathways.txt
├── routes.txt
├── shapes.txt
├── stops.txt
├── stop_times.txt
├── transfers.txt
└── trips.txt
加载代码示例:
package main
import (
"fmt"
"github.com/artonge/go-gtfs"
)
func main() {
// 加载单个GTFS目录
g, err := gtfs.Load("path/to/gtfs_files", nil)
if err != nil {
fmt.Printf("加载GTFS文件失败: %v\n", err)
return
}
// 访问数据
fmt.Printf("共加载了 %d 条路线\n", len(g.Routes))
fmt.Printf("共加载了 %d 个站点\n", len(g.Stops))
// 示例:打印前5条路线信息
for i, route := range g.Routes {
if i >= 5 {
break
}
fmt.Printf("路线ID: %s, 短名称: %s, 长名称: %s\n",
route.ID, route.ShortName, route.LongName)
}
}
加载包含多个GTFS子目录的目录
假设目录结构如下:
path/to/gtfs_directories
├── gtfs1
│ ├── agency.txt
│ ├── attributions.txt
│ ├── ...
└── gtfs2
├── agency.txt
├── attributions.txt
├── ...
加载代码示例:
package main
import (
"fmt"
"github.com/artonge/go-gtfs"
)
func main() {
// 加载包含多个GTFS子目录的目录
gs, err := gtfs.LoadSplitted("path/to/gtfs_directories", nil)
if err != nil {
fmt.Printf("加载GTFS文件失败: %v\n", err)
return
}
// 访问数据
for i, gtfsData := range gs {
fmt.Printf("数据集 %d:\n", i+1)
fmt.Printf(" 共加载了 %d 条路线\n", len(gtfsData.Routes))
fmt.Printf(" 共加载了 %d 个站点\n", len(gtfsData.Stops))
}
}
数据结构
go-gtfs库提供了完整的GTFS数据结构:
type GTFS struct {
Path string // 包含目录的路径
Agency Agency
Agencies []Agency
Attributions []Attribution
Calendars []Calendar
CalendarDates []CalendarDate
FareAttributes []FareAttribute
FareRules []FareRule
FeedInfos []FeedInfo
Frequencies []Frequency
Levels []Level
Routes []Route
Pathways []Pathway
Shapes []Shape
Stops []Stop
StopsTimes []StopTime
Trips []Trip
Transfers []Transfer
}
type Route struct {
ID string `csv:"route_id"`
AgencyID string `csv:"agency_id"`
ShortName string `csv:"route_short_name"`
LongName string `csv:"route_long_name"`
Type int `csv:"route_type"`
Desc string `csv:"route_desc"`
URL string `csv:"route_url"`
Color string `csv:"route_color"`
TextColor string `csv:"route_text_color"`
}
// 其他数据结构类似...
项目状态
该项目目前处于维护模式。它保持与Go生态系统的变化兼容,但不会开发新功能。可能会接受Pull Request。
更多关于golang加载和解析GTFS文件插件库go-gtfs的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang加载和解析GTFS文件插件库go-gtfs的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-gtfs加载和解析GTFS文件
GTFS(General Transit Feed Specification)是公共交通数据的标准格式。在Go语言中,go-gtfs是一个专门用于处理GTFS文件的库。下面我将详细介绍如何使用这个库。
安装go-gtfs
首先需要安装go-gtfs库:
go get github.com/artonge/go-gtfs
基本使用示例
1. 加载GTFS文件
package main
import (
"fmt"
"log"
"github.com/artonge/go-gtfs"
)
func main() {
// 加载GTFS文件
gtfsPath := "path/to/your/gtfs.zip"
feed, err := gtfs.Load(gtfsPath)
if err != nil {
log.Fatalf("加载GTFS失败: %v", err)
}
fmt.Printf("成功加载GTFS文件,包含 %d 条路线\n", len(feed.Routes))
}
2. 解析GTFS内容
// 打印所有路线信息
func printRoutes(feed *gtfs.Feed) {
fmt.Println("=== 路线列表 ===")
for _, route := range feed.Routes {
fmt.Printf("ID: %s, 简称: %s, 全称: %s, 类型: %d\n",
route.ID, route.ShortName, route.LongName, route.Type)
}
}
// 打印指定路线的所有站点
func printStopsForRoute(feed *gtfs.Feed, routeID string) {
fmt.Printf("\n=== 路线 %s 的站点 ===\n", routeID)
// 获取路线对应的行程
var trips []gtfs.Trip
for _, trip := range feed.Trips {
if trip.RouteID == routeID {
trips = append(trips, trip)
}
}
// 获取行程对应的站点
for _, trip := range trips {
fmt.Printf("\n行程 %s:\n", trip.ID)
stopTimes := getStopTimesForTrip(feed, trip.ID)
for _, st := range stopTimes {
stop := getStopByID(feed, st.StopID)
fmt.Printf("- %s (到达: %s, 离开: %s)\n",
stop.Name, st.ArrivalTime, st.DepartureTime)
}
}
}
// 辅助函数:根据行程ID获取站点时间
func getStopTimesForTrip(feed *gtfs.Feed, tripID string) []gtfs.StopTime {
var result []gtfs.StopTime
for _, st := range feed.StopTimes {
if st.TripID == tripID {
result = append(result, st)
}
}
return result
}
// 辅助函数:根据站点ID获取站点信息
func getStopByID(feed *gtfs.Feed, stopID string) gtfs.Stop {
for _, stop := range feed.Stops {
if stop.ID == stopID {
return stop
}
}
return gtfs.Stop{}
}
3. 查询功能示例
// 根据站点名称查找站点
func findStopsByName(feed *gtfs.Feed, name string) []gtfs.Stop {
var result []gtfs.Stop
for _, stop := range feed.Stops {
if strings.Contains(strings.ToLower(stop.Name), strings.ToLower(name)) {
result = append(result, stop)
}
}
return result
}
// 查找两个站点之间的路线
func findRoutesBetweenStops(feed *gtfs.Feed, startStopID, endStopID string) []gtfs.Route {
var routes []gtfs.Route
// 获取包含起始站点的行程
startTrips := getTripsForStop(feed, startStopID)
endTrips := getTripsForStop(feed, endStopID)
// 找出共同的行程
for _, st := range startTrips {
for _, et := range endTrips {
if st.TripID == et.TripID {
// 检查站点顺序
if isStopBeforeInTrip(feed, st, et) {
route := getRouteByID(feed, st.RouteID)
routes = append(routes, route)
}
}
}
}
return routes
}
// 辅助函数:获取包含特定站点的所有行程
func getTripsForStop(feed *gtfs.Feed, stopID string) []gtfs.StopTime {
var result []gtfs.StopTime
for _, st := range feed.StopTimes {
if st.StopID == stopID {
result = append(result, st)
}
}
return result
}
// 辅助函数:检查站点顺序
func isStopBeforeInTrip(feed *gtfs.Feed, first, second gtfs.StopTime) bool {
var firstSeq, secondSeq int
for _, st := range feed.StopTimes {
if st.TripID == first.TripID {
if st.StopID == first.StopID {
firstSeq = st.StopSequence
}
if st.StopID == second.StopID {
secondSeq = st.StopSequence
}
}
}
return firstSeq < secondSeq
}
// 辅助函数:根据ID获取路线
func getRouteByID(feed *gtfs.Feed, routeID string) gtfs.Route {
for _, route := range feed.Routes {
if route.ID == routeID {
return route
}
}
return gtfs.Route{}
}
高级功能
1. 加载特定表
如果只需要加载GTFS中的特定表,可以使用LoadSpecific
函数:
// 只加载路线和站点表
tablesToLoad := []string{"routes", "stops"}
feed, err := gtfs.LoadSpecific(gtfsPath, tablesToLoad)
if err != nil {
log.Fatal(err)
}
2. 导出为CSV
// 将GTFS数据导出为CSV文件
err = gtfs.ExportToCsv(feed, "output_directory")
if err != nil {
log.Fatal(err)
}
性能优化建议
- 对于大型GTFS文件,考虑只加载需要的表
- 可以预先建立索引数据结构来提高查询速度
- 对于频繁查询,可以将数据存储在内存数据库或缓存中
总结
go-gtfs库提供了简单易用的接口来加载和解析GTFS文件。通过上述示例,您可以:
- 加载GTFS ZIP文件
- 访问路线、站点、行程等数据
- 实现基本的查询功能
- 进行数据导出等操作
根据您的具体需求,可以在此基础上构建更复杂的公共交通查询系统。