gtfs

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2026 License: MIT Imports: 18 Imported by: 0

README

gtfs

This is a Go package for parsing GTFS static and realtime feeds.

The static parser is pretty straightforward and simply maps fields in the GTFS static CSV files to associated Go types.

For realtime parsing this package offers two options. Option 1 is to use the parser and types generated by the protobuf compiler which are available in the proto subpackage. This saves you from having to compile the protobufs yourself.

Option 2 is to use the package's custom parser, which takes the protobuf output from option 1, does a bunch of post-processing, and then outputs the result in standard (non-proto) Go types. This post-processing does useful things like:

  • Converts some data fields to more idiomatic Go types - for example, times are converted from int64 Unix timestamps to time.Time values.

  • Makes the representation of trips and vehicles more explicit. Each trip has a (nullable) pointer to the associated vehicle in the feed, if it exists, and vice-versa.

  • Implements business logic to map data in various GTFS realtime extensions to regular GTFS realtime fields.

Backwards compatibility warning: this package is under active development and backwards incompatible changes are frequently made. We're eventually planning to release a v1.0.0 version, and after that all changes will be backwards compatible and consistent with semantic versioning.

Examples

Parse the GTFS static feed for the New York City Subway:

resp, _ := http.Get("http://web.mta.info/developers/data/nyct/subway/google_transit.zip")
b, _ := io.ReadAll(resp.Body)
staticData, _ := gtfs.ParseStatic(b, gtfs.ParseStaticOptions{})
fmt.Printf("The New York City subway has %d routes and %d stations\n", len(staticData.Routes), len(staticData.Stops))

Parse the GTFS realtime feed for the San Francisco Bay Area BART:

resp, _ := http.Get("http://api.bart.gov/gtfsrt/tripupdate.aspx")
b, _ := io.ReadAll(resp.Body)
realtimeData, _ := gtfs.ParseRealtime(b, &gtfs.ParseRealtimeOptions{})
fmt.Printf("The SF BART currently has %d trains running or scheduled\n", len(realtimeData.Trips))

Supported GTFS Schedule files

Below is a list of the GTFS schedule files and whether they are currently supported. Progress for full support is being tracked in issue #4.

File Name Supported Required by Spec Notes
agency.txt Required
stops.txt Conditionally Required Always required by library
routes.txt Required
trips.txt Required
stop_times.txt Required
calendar.txt Conditionally Required Surfaced as a Service, always required by library
calendar_dates.txt Conditionally Required Surfaced as part of a Service, always required by library
fare_attributes.txt Optional
fare_rules.txt Optional
timeframes.txt Optional
fare_media.txt Optional
fare_products.txt Optional
fare_leg_rules.txt Optional
fare_leg_join_rules.txt Optional
fare_transfer_rules.txt Optional
areas.txt Optional
stop_areas.txt Optional
networks.txt Conditionally Forbidden
route_networks.txt Conditionally Forbidden
location_groups.txt Conditionally Forbidden
shapes.txt Optional
frequencies.txt Optional
transfers.txt 🟨 Optional Partially implemented
pathways.txt Optional
levels.txt Conditionally Required
location_group_stops.txt Optional
locations.geojson Optional
booking_rules.txt Optional
translations.txt Optional
feed_info.txt Conditionally Required
attributions.txt Optional

Performance

The package is designed to be about as fast as possible without resorting to unreadable code. A profiler for the package is in the performance directory.

Static parser

The static parser has been performance optimized somewhat significantly. It takes about 3 seconds to parse the GTFS static data for the NYC buses (45 megabytes compressed, 360 megabytes uncompressed). The rough breakdown is:

  • 30% of the time unzipping the archives (using the archive/zip standard library package).

  • 40% of the time parsing the CSV files into strings (using the encoding/csv standard library package)

  • 30% of the time in this package performing the conversions from strings into types like time.Duration and linking related entities.

Realtime parser

TBD

Documentation

Overview

Package gtfs contains parsers for GTFS static and realtime feeds.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agency

type Agency struct {
	Id       string
	Name     string
	Url      string
	Timezone string
	Language string
	Phone    string
	FareUrl  string
	Email    string
}

Agency corresponds to a single row in the agency.txt file.

type Alert

type Alert struct {
	ID               string
	Cause            AlertCause
	Effect           AlertEffect
	ActivePeriods    []AlertActivePeriod
	InformedEntities []AlertInformedEntity
	Header           []AlertText
	Description      []AlertText
	URL              []AlertText
}

type AlertActivePeriod

type AlertActivePeriod struct {
	StartsAt *time.Time
	EndsAt   *time.Time
}

type AlertInformedEntity

type AlertInformedEntity struct {
	AgencyID *string
	RouteID  *string
	// If RouteType isn't set, this will be RouteType_Unknown.
	RouteType   RouteType
	DirectionID DirectionID
	TripID      *TripID
	StopID      *string
}

type AlertText

type AlertText struct {
	Text     string
	Language string
}

type BikesAllowed

type BikesAllowed int32

BikesAllowed describes whether bikes are allowed on a scheduled trip.

This is a Go representation of the enum described in the `bikes_allowed` field of `stops.txt`.

const (
	BikesAllowed_NotSpecified BikesAllowed = 0
	BikesAllowed_Allowed      BikesAllowed = 1
	BikesAllowed_NotAllowed   BikesAllowed = 2
)

func (BikesAllowed) String

func (b BikesAllowed) String() string

type DirectionID

type DirectionID uint8

DirectionID is a mechanism for distinguishing between trips going in the opposite direction.

const (
	DirectionID_Unspecified DirectionID = 0
	DirectionID_True        DirectionID = 1
	DirectionID_False       DirectionID = 2
)

func (DirectionID) String

func (d DirectionID) String() string

type ExactTimes

type ExactTimes int32

ExactTimes describes the type of service for a trip.

This is a Go representation of the enum described in the `exact_times` field of `frequencies.txt`.

const (
	FrequencyBased ExactTimes = 0
	ScheduleBased  ExactTimes = 1
)

func (ExactTimes) String

func (t ExactTimes) String() string

type Frequency

type Frequency struct {
	StartTime  time.Duration
	EndTime    time.Duration
	Headway    time.Duration
	ExactTimes ExactTimes
}

type ParseRealtimeOptions

type ParseRealtimeOptions struct {
	// The timezone to interpret date field.
	//
	// It can be nil, in which case UTC will used.
	Timezone *time.Location

	// The GTFS Realtime extension to use when parsing.
	//
	// This can be nil, in which case no extension is used.
	Extension extensions.Extension
}

type ParseStaticOptions

type ParseStaticOptions struct {
	// If true, wheelchair boarding information is inherited from parent station
	// when unspecified for a child stop/platform, entrance, or exit.
	InheritWheelchairBoarding bool
}

type PickupDropOffPolicy

type PickupDropOffPolicy int32

PickupDropOffPolicy describes the pickup or drop-off policy for a route or scheduled trip.

This is a Go representation of the enum described in the `continuous_pickup` field of `routes.txt`, and `pickup_type` field of `stop_times.txt`, and similar fields.

const (
	// Pickup or drop off happens by default.
	PickupDropOffPolicy_Yes PickupDropOffPolicy = 0
	// No pickup or drop off is possible.
	PickupDropOffPolicy_No PickupDropOffPolicy = 1
	// Must phone an agency to arrange pickup or drop off.
	PickupDropOffPolicy_PhoneAgency PickupDropOffPolicy = 2
	// Must coordinate with a driver to arrange pickup or drop off.
	PickupDropOffPolicy_CoordinateWithDriver PickupDropOffPolicy = 3
)

func (PickupDropOffPolicy) String

func (t PickupDropOffPolicy) String() string

type Position

type Position struct {
	// Degrees North, in the WGS-84 coordinate system.
	Latitude *float32
	// Degrees East, in the WGS-84 coordinate system.
	Longitude *float32
	// Bearing, in degrees, clockwise from North, i.e., 0 is North and 90 is East.
	// This can be the compass bearing, or the direction towards the next stop
	// or intermediate location.
	// This should not be direction deduced from the sequence of previous
	// positions, which can be computed from previous data.
	Bearing *float32
	// Odometer value, in meters.
	Odometer *float64
	// Momentary speed measured by the vehicle, in meters per second.
	Speed *float32
}

type Realtime

type Realtime struct {
	CreatedAt time.Time

	Trips []Trip

	Vehicles []Vehicle

	Alerts []Alert
}

Realtime contains the parsed content for a single GTFS realtime message.

func ParseRealtime

func ParseRealtime(content []byte, opts *ParseRealtimeOptions) (*Realtime, error)

type Route

type Route struct {
	Id                string
	Agency            *Agency
	Color             string
	TextColor         string
	ShortName         string
	LongName          string
	Description       string
	Type              RouteType
	Url               string
	SortOrder         *int32
	ContinuousPickup  PickupDropOffPolicy
	ContinuousDropOff PickupDropOffPolicy
}

Route corresponds to a single row in the routes.txt file.

type RouteType

type RouteType int32

RouteType describes the type of a route.

This is a Go representation of the enum described in the `route_type` field of `routes.txt`.

const (
	RouteType_Tram       RouteType = 0
	RouteType_Subway     RouteType = 1
	RouteType_Rail       RouteType = 2
	RouteType_Bus        RouteType = 3
	RouteType_Ferry      RouteType = 4
	RouteType_CableTram  RouteType = 5
	RouteType_AerialLift RouteType = 6
	RouteType_Funicular  RouteType = 7
	RouteType_TrolleyBus RouteType = 11
	RouteType_Monorail   RouteType = 12

	RouteType_RailwayService              RouteType = 100
	RouteType_HighSpeedRailService        RouteType = 101
	RouteType_LongDistanceRailService     RouteType = 102
	RouteType_InterRegionalRailService    RouteType = 103
	RouteType_CarTransportRailService     RouteType = 104
	RouteType_SleeperRailService          RouteType = 105
	RouteType_RegionalRailService         RouteType = 106
	RouteType_TouristRailwayService       RouteType = 107
	RouteType_RailShuttle                 RouteType = 108
	RouteType_SuburbanRailway             RouteType = 109
	RouteType_ReplacementRailService      RouteType = 110
	RouteType_SpecialRailService          RouteType = 111
	RouteType_LorryTransportRailService   RouteType = 112
	RouteType_AllRailServices             RouteType = 113
	RouteType_CrossCountryRailService     RouteType = 114
	RouteType_VehicleTransportRailService RouteType = 115
	RouteType_RackAndPinionRailway        RouteType = 116
	RouteType_AdditionalRailService       RouteType = 117

	RouteType_CoachService         RouteType = 200
	RouteType_InternationalCoach   RouteType = 201
	RouteType_NationalCoach        RouteType = 202
	RouteType_ShuttleCoach         RouteType = 203
	RouteType_RegionalCoach        RouteType = 204
	RouteType_SpecialCoach         RouteType = 205
	RouteType_TouristCoach         RouteType = 206
	RouteType_CommuterCoach        RouteType = 207
	RouteType_AllCoachServices     RouteType = 208
	RouteType_SuburbanCoachService RouteType = 209

	RouteType_UrbanRailwayService     RouteType = 400
	RouteType_MetroService            RouteType = 401
	RouteType_UndergroundService      RouteType = 402
	RouteType_UrbanRailway            RouteType = 403
	RouteType_AllUrbanRailwayServices RouteType = 404
	RouteType_UrbanMonorail           RouteType = 405

	RouteType_BusService                    RouteType = 700
	RouteType_RegionalBus                   RouteType = 701
	RouteType_ExpressBus                    RouteType = 702
	RouteType_StoppingBus                   RouteType = 703
	RouteType_LocalBus                      RouteType = 704
	RouteType_NightBus                      RouteType = 705
	RouteType_PostBus                       RouteType = 706
	RouteType_SpecialNeedsBus               RouteType = 707
	RouteType_MobilityBus                   RouteType = 708
	RouteType_MobilityBusRegisteredDisabled RouteType = 709
	RouteType_SightseeingBus                RouteType = 710
	RouteType_ShuttleBus                    RouteType = 711
	RouteType_SchoolBus                     RouteType = 712
	RouteType_SchoolPublicServiceBus        RouteType = 713
	RouteType_RailReplacementBus            RouteType = 714
	RouteType_DemandResponseBus             RouteType = 715
	RouteType_AllBusServices                RouteType = 716
	RouteType_ShareTaxiBus                  RouteType = 717

	RouteType_TrolleybusService RouteType = 800

	RouteType_TramService     RouteType = 900
	RouteType_CityTram        RouteType = 901
	RouteType_LocalTram       RouteType = 902
	RouteType_RegionalTram    RouteType = 903
	RouteType_SightseeingTram RouteType = 904
	RouteType_ShuttleTram     RouteType = 905
	RouteType_AllTramServices RouteType = 906
	RouteType_CrossborderTram RouteType = 907

	RouteType_WaterTransportService       RouteType = 1000
	RouteType_InternationalCarFerry       RouteType = 1001
	RouteType_NationalCarFerry            RouteType = 1002
	RouteType_RegionalCarFerry            RouteType = 1003
	RouteType_LocalCarFerry               RouteType = 1004
	RouteType_InternationalPassengerFerry RouteType = 1005
	RouteType_NationalPassengerFerry      RouteType = 1006
	RouteType_RegionalPassengerFerry      RouteType = 1007
	RouteType_LocalPassengerFerry         RouteType = 1008
	RouteType_PostBoat                    RouteType = 1009
	RouteType_TrainFerry                  RouteType = 1010
	RouteType_RoadLinkFerry               RouteType = 1011
	RouteType_AirportLinkFerry            RouteType = 1012
	RouteType_CarHighSpeedFerry           RouteType = 1013
	RouteType_PassengerHighSpeedFerry     RouteType = 1014
	RouteType_SightseeingBoat             RouteType = 1015
	RouteType_SchoolBoat                  RouteType = 1016
	RouteType_CableDrawnBoat              RouteType = 1017
	RouteType_RiverBus                    RouteType = 1018
	RouteType_ScheduledFerry              RouteType = 1019
	RouteType_ShuttleFerry                RouteType = 1020
	RouteType_AllWaterTransportServices   RouteType = 1021

	RouteType_AirService                  RouteType = 1100
	RouteType_InternationalAirService     RouteType = 1101
	RouteType_DomesticAirService          RouteType = 1102
	RouteType_IntercontinentalAirService  RouteType = 1103
	RouteType_DomesticScheduledAirService RouteType = 1104
	RouteType_ShuttleAirService           RouteType = 1105
	RouteType_IntercontinentalCharterAir  RouteType = 1106
	RouteType_InternationalCharterAir     RouteType = 1107
	RouteType_RoundTripCharterAir         RouteType = 1108
	RouteType_SightseeingAirService       RouteType = 1109
	RouteType_HelicopterAirService        RouteType = 1110
	RouteType_DomesticCharterAirService   RouteType = 1111
	RouteType_AllAirServices              RouteType = 1112

	RouteType_FerryService RouteType = 1200

	RouteType_AerialLiftService    RouteType = 1300
	RouteType_TelecabinService     RouteType = 1301
	RouteType_CableCarService      RouteType = 1302
	RouteType_ElevatorService      RouteType = 1303
	RouteType_ChairLiftService     RouteType = 1304
	RouteType_DragLiftService      RouteType = 1305
	RouteType_SmallTelecabin       RouteType = 1306
	RouteType_AllTelecabinServices RouteType = 1307

	RouteType_FunicularService    RouteType = 1400
	RouteType_Funicular_1         RouteType = 1401
	RouteType_AllFunicularService RouteType = 1402

	RouteType_TaxiService        RouteType = 1500
	RouteType_CommunalTaxi       RouteType = 1501
	RouteType_WaterTaxi          RouteType = 1502
	RouteType_RailTaxi           RouteType = 1503
	RouteType_BikeTaxi           RouteType = 1504
	RouteType_LicensedTaxi       RouteType = 1505
	RouteType_PrivateHireVehicle RouteType = 1506
	RouteType_AllTaxiServices    RouteType = 1507

	RouteType_MiscellaneousService RouteType = 1700
	RouteType_CableCarMisc         RouteType = 1701
	RouteType_HorseDrawnCarriage   RouteType = 1702

	RouteType_Unknown RouteType = 10000
)

func (RouteType) String

func (t RouteType) String() string

type ScheduledStopTime

type ScheduledStopTime struct {
	Trip                  *ScheduledTrip
	Stop                  *Stop
	ArrivalTime           time.Duration
	DepartureTime         time.Duration
	StopSequence          int
	Headsign              string
	PickupType            PickupDropOffPolicy
	DropOffType           PickupDropOffPolicy
	ContinuousPickup      PickupDropOffPolicy
	ContinuousDropOff     PickupDropOffPolicy
	ShapeDistanceTraveled *float64
	ExactTimes            bool
}

type ScheduledTrip

type ScheduledTrip struct {
	Route                *Route
	Service              *Service
	ID                   string
	Headsign             string
	ShortName            string
	DirectionId          DirectionID
	BlockID              string
	WheelchairAccessible WheelchairBoarding
	BikesAllowed         BikesAllowed
	StopTimes            []ScheduledStopTime
	Shape                *Shape
	Frequencies          []Frequency
}

type Service

type Service struct {
	Id           string
	Monday       bool
	Tuesday      bool
	Wednesday    bool
	Thursday     bool
	Friday       bool
	Saturday     bool
	Sunday       bool
	StartDate    time.Time
	EndDate      time.Time
	AddedDates   []time.Time
	RemovedDates []time.Time
}

type Shape

type Shape struct {
	ID     string
	Points []ShapePoint
}

type ShapePoint

type ShapePoint struct {
	Latitude  float64
	Longitude float64
	Distance  *float64
}

type ShapeRow

type ShapeRow struct {
	ShapePtLat        float64
	ShapePtLon        float64
	ShapePtSequence   int32
	ShapeDistTraveled *float64
}

type Static

type Static struct {
	Agencies  []Agency
	Routes    []Route
	Stops     []Stop
	Transfers []Transfer
	Services  []Service
	Trips     []ScheduledTrip
	Shapes    []Shape

	// Warnings raised during GTFS static parsing.
	Warnings []warnings.StaticWarning
}

Static contains the parsed content for a single GTFS static message.

func ParseStatic

func ParseStatic(content []byte, opts ParseStaticOptions) (*Static, error)

ParseStatic parses the content as a GTFS static feed.

type Stop

type Stop struct {
	Id                 string
	Code               string
	Name               string
	Description        string
	ZoneId             string
	Longitude          *float64
	Latitude           *float64
	Url                string
	Type               StopType
	Parent             *Stop
	Timezone           string
	WheelchairBoarding WheelchairBoarding
	PlatformCode       string
}

func (*Stop) Root

func (stop *Stop) Root() *Stop

Root returns the root stop.

type StopTimeEvent

type StopTimeEvent struct {
	Time        *time.Time
	Delay       *time.Duration
	Uncertainty *int32
}

type StopTimeUpdate

type StopTimeUpdate struct {
	StopSequence         *uint32
	StopID               *string
	Arrival              *StopTimeEvent
	Departure            *StopTimeEvent
	NyctTrack            *string
	ScheduleRelationship StopTimeUpdateScheduleRelationship
}

TODO: shouldn't this just be StopTime?

func (*StopTimeUpdate) GetArrival

func (stopTimeUpdate *StopTimeUpdate) GetArrival() StopTimeEvent

func (*StopTimeUpdate) GetDeparture

func (stopTimeUpdate *StopTimeUpdate) GetDeparture() StopTimeEvent

type StopType

type StopType int32

StopType describes the type of a stop.

This is a Go representation of the enum described in the `location_type` field of `stops.txt`.

const (
	StopType_Stop           StopType = 0
	StopType_Station        StopType = 1
	StopType_EntranceOrExit StopType = 2
	StopType_GenericNode    StopType = 3
	StopType_BoardingArea   StopType = 4
	StopType_Platform       StopType = 5
)

func (StopType) String

func (t StopType) String() string

type Transfer

type Transfer struct {
	From            *Stop
	To              *Stop
	Type            TransferType
	MinTransferTime *int32

	FromRoute *Route
	ToRoute   *Route

	FromTrip *ScheduledTrip
	ToTrip   *ScheduledTrip
}

type TransferType

type TransferType int32

StopType describes the type of a transfer.

This is a Go representation of the enum described in the `transfer_type` field of `transfers.txt`.

const (
	TransferType_Recommended  TransferType = 0
	TransferType_Timed        TransferType = 1
	TransferType_RequiresTime TransferType = 2
	TransferType_NotPossible  TransferType = 3
)

func (TransferType) String

func (t TransferType) String() string

type Trip

type Trip struct {
	ID              TripID
	StopTimeUpdates []StopTimeUpdate

	Vehicle *Vehicle

	Delay *time.Duration

	IsEntityInMessage bool
}

func (*Trip) GetVehicle

func (trip *Trip) GetVehicle() Vehicle

func (*Trip) Hash

func (t *Trip) Hash(h hash.Hash)

Hash calculates a hash of a trip using the provided hash function.

The Vehicle and IsEntityInFeed fields are ignored for the purposes of hashing.

type TripID

type TripID struct {
	ID          string
	RouteID     string
	DirectionID DirectionID

	HasStartTime bool
	StartTime    time.Duration

	HasStartDate bool
	StartDate    time.Time

	ScheduleRelationship TripScheduleRelationship
}

func (TripID) Less

func (t1 TripID) Less(t2 TripID) bool

Define ordering on trip ids for test consistency

type Vehicle

type Vehicle struct {
	ID *VehicleID

	Trip *Trip

	Position *Position

	CurrentStopSequence *uint32

	StopID *string

	CurrentStatus *CurrentStatus

	Timestamp *time.Time

	CongestionLevel CongestionLevel

	OccupancyStatus *OccupancyStatus

	OccupancyPercentage *uint32

	IsEntityInMessage bool
}

func (*Vehicle) GetID

func (vehicle *Vehicle) GetID() VehicleID

func (*Vehicle) GetTrip

func (vehicle *Vehicle) GetTrip() Trip

func (*Vehicle) Hash

func (v *Vehicle) Hash(h hash.Hash)

Hash calculates a hash of a vehicle using the provided hash function.

The Trip and IsEntityInFeed fields are ignored for the purposes of hashing.

type VehicleID

type VehicleID struct {
	ID           string
	Label        string
	LicensePlate string
}

type WheelchairBoarding

type WheelchairBoarding int32

WheelchairBoarding describes whether wheelchair boarding is available at a stop.

This is a Go representation of the enum described in the `wheelchair_boarding` field of `stops.txt` and `wheelchair_accessible` field of `trips.txt`.

const (
	WheelchairBoarding_NotSpecified WheelchairBoarding = 0
	WheelchairBoarding_Possible     WheelchairBoarding = 1
	WheelchairBoarding_NotPossible  WheelchairBoarding = 2
)

func (WheelchairBoarding) String

func (w WheelchairBoarding) String() string

Directories

Path Synopsis
Package csv is a wrapper around the stdlib csv library that provides a nice API for the GTFS static parser.
Package csv is a wrapper around the stdlib csv library that provides a nice API for the GTFS static parser.
nycttrips
Package nycttrips contains logic for the New York City Transit GTFS realtime extensions
Package nycttrips contains logic for the New York City Transit GTFS realtime extensions
internal
Package journal contains a tool for building trip journals.
Package journal contains a tool for building trip journals.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL