trainmapdb

package module
v0.0.0-...-25cc1de Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2024 License: MIT Imports: 20 Imported by: 2

README

trainmapdb module

Note: still in development, expect breaking changes

Go Module to:

  • Import GTFS feeds and parse them into a database
  • Use that database to calculate train sights at a given geographical point in a given timespan

Inspiration

  • Inspiration for this module was taken from the Python implementation pygtfs, which was too slow for me so I decided to rewrite it in Golang so it could be faster
    • Note: I'm not parsing all of the GTFS feed, infos such as shapes.txt are left out, check model.go to see what's stored in the DB

Known issues / TODO

  • Route IDs not parsing correctly on some feeds (looking at you ÖBB)
  • Refine sights criteria and parse paths from existing paths
  • Update the route_type criteria to allow for other rail types (monorail and stuffies)
  • Write tests

Examples

See also

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetDateInterval

func GetDateInterval(dayCount uint, startDateTime time.Time) (Date, Date)

returns (day before start date 00:00, start date + dayCount 00:00). Start date is the date of startDateTime if nonzero, today otherwise

Types

type Agency

type Agency struct {
	FeedId         string `csv:"-" gorm:"primaryKey;uniqueIndex:pk_agency" json:"feed_id"`
	AgencyId       string `gorm:"primaryKey;uniqueIndex:pk_agency" csv:"agency_id" json:"agency_id"`
	AgencyName     string `csv:"agency_name" json:"name"`
	AgencyUrl      string `csv:"agency_url"`
	AgencyTimezone string `csv:"agency_timezone"`
	AgencyLang     string `csv:"agency_lang"`
}

func (Agency) TableName

func (Agency) TableName() string

type Bearing

type Bearing float64

represents a bearing in radians

type Calendar

type Calendar struct {
	FeedId        string         `gorm:"primaryKey;uniqueIndex:pk_calendar" json:"feed_id"`
	ServiceId     string         `gorm:"primaryKey;uniqueIndex:pk_calendar" csv:"service_id" json:"service_id"`
	Monday        bool           `csv:"monday" json:"monday"`
	Tuesday       bool           `csv:"tuesday" json:"tuesday"`
	Wednesday     bool           `csv:"wednesday" json:"wednesday"`
	Thursday      bool           `csv:"thursday" json:"thursday"`
	Friday        bool           `csv:"friday" json:"friday"`
	Saturday      bool           `csv:"saturday" json:"saturday"`
	Sunday        bool           `csv:"sunday" json:"sunday"`
	CsvStartDate  string         `gorm:"-:all" csv:"start_date" json:"-"` //YYYYmmdd
	CsvEndDate    string         `gorm:"-:all" csv:"end_date" json:"-"`   //YYYYmmdd
	StartDate     time.Time      `json:"start_date"`
	EndDate       time.Time      `json:"end_date"`
	CalendarDates []CalendarDate `gorm:"foreignKey:FeedId,ServiceId;references:FeedId,ServiceId"`
}

func (Calendar) GetWeekdayStatus

func (c Calendar) GetWeekdayStatus(weekday time.Weekday) bool

func (Calendar) TableName

func (Calendar) TableName() string

type CalendarDate

type CalendarDate struct {
	FeedId        string        `csv:"-" gorm:"primaryKey;uniqueIndex:pk_calendardate" json:"feed_id"`
	ServiceId     string        `gorm:"primaryKey;uniqueIndex:pk_calendardate" csv:"service_id" json:"service_id"`
	Date          time.Time     `csv:"-" gorm:"primaryKey;uniqueIndex:pk_calendardate" json:"date"`
	CsvDate       string        `csv:"date" gorm:"-:all" json:"-"`           //YYYYmmdd
	ExceptionType ExceptionType `csv:"exception_type" json:"exception_type"` //1=added, 2=removed
}

type Date

type Date time.Time

func NewDate

func NewDate(day time.Time) Date

type ExceptionType

type ExceptionType uint
const (
	ExceptionTypeServiceAdded   ExceptionType = 1
	ExceptionTypeServiceRemoved ExceptionType = 2
)

type Feed

type Feed struct {
	DisplayName   string `csv:"-" json:"display_name"` //added by us
	FeedId        string `csv:"-" gorm:"primaryKey;uniqueIndex:pk_feed" json:"feed_id"`
	PublisherName string `csv:"feed_publisher_name" json:"publisher_name"`
	PublisherUrl  string `csv:"feed_publisher_url" json:"publisher_url"`
	FeedLang      string `csv:"feed_lang" json:"feed_lang"`
	DefaultLang   string `csv:"default_lang" json:"default_lang"`
	Version       string `csv:"feed_version" json:"version"`
	ContactEmail  string `csv:"feed_contact_email" json:"contact_email"`
	ContactUrl    string `csv:"feed_contact_url" json:"contact_url"`
}

type FeededService

type FeededService struct {
	FeedId    string
	ServiceId string
}

A FeededService represents a combined feed ID and service ID.

type Fetcher

type Fetcher struct {
	Config FetcherConfig
	// contains filtered or unexported fields
}

A Fetcher is a wrapper around a DB connection.

func NewFetcher

func NewFetcher(dial gorm.Dialector, useMutex bool, config *FetcherConfig) (*Fetcher, error)

func (Fetcher) GetAllAgencies

func (f Fetcher) GetAllAgencies() ([]Agency, error)

func (Fetcher) GetAllStops

func (f Fetcher) GetAllStops() ([]Stop, error)

GetAllStops returns all the stops in the DB.

func (Fetcher) GetAllTrips

func (f Fetcher) GetAllTrips() ([]Trip, error)

GetAllTrips fetches all the trips in the DB by batches and returns them.

func (Fetcher) GetFeed

func (f Fetcher) GetFeed(feedId string) (Feed, error)

func (Fetcher) GetFeededServiceIdTrips

func (f Fetcher) GetFeededServiceIdTrips(feededService FeededService) ([]Trip, error)

GetFeededServiceIdTrips returns all trips that run on the given service

func (Fetcher) GetFeeds

func (f Fetcher) GetFeeds() ([]Feed, error)

GetFeeds returns all the feed info known in the DB.

func (Fetcher) GetRealTrainSights

func (f Fetcher) GetRealTrainSights(obsPoint Point, startDate Date, endDate Date) ([]RealTrainSight, error)

Fetches train sights at an observation point between starting at startDate's services and endDate (including endDate's GTFS services)

func (Fetcher) GetRoute

func (f Fetcher) GetRoute(feedId string, routeId string) (Route, error)

func (Fetcher) GetServicesBetweenDates

func (f Fetcher) GetServicesBetweenDates(startDate time.Time, endDate time.Time) ([]ServiceDay, error)

GetServicesBetweenDates retuns all services that are active between the given dates.

func (Fetcher) GetServicesOnDate

func (f Fetcher) GetServicesOnDate(date time.Time) ([]ServiceDay, error)

GetServicesOnDate returns all services that are active on a given date.

func (*Fetcher) GetSightsFromTrip

func (f *Fetcher) GetSightsFromTrip(trip Trip, date Date, lateTime time.Duration) ([]RealMovingTrainSight, Trip, error)

GetSightsFromTrip gets the sights that are visible while riding the given trip on a given date NOTE: does not check if the trip is actually running on that day

func (*Fetcher) GetSightsFromTripKey

func (f *Fetcher) GetSightsFromTripKey(feedId string, tripId string, date Date, lateTime time.Duration) ([]RealMovingTrainSight, Trip, error)

GetSightsFromTripKey gets the sights that are visible while riding the given trip on a given date NOTE: does not check if the trip is actually running on that day

func (Fetcher) GetStop

func (f Fetcher) GetStop(feedId string, stopId string) (Stop, error)

func (Fetcher) GetStopTimesAtStop

func (f Fetcher) GetStopTimesAtStop(feedId string, stopId string) ([]StopTime, error)

GetStopTimesAtStop returns all the StopTimes related to the given Stop.

func (Fetcher) GetTrip

func (f Fetcher) GetTrip(feedId string, tripId string) (Trip, error)

func (Fetcher) GetTripsContaining

func (f Fetcher) GetTripsContaining(pt Point) ([]Trip, error)

GetTripsContaining returns all trips whose bounding box contains the given point

func (Fetcher) GetTripsInsidePointInterval

func (f Fetcher) GetTripsInsidePointInterval(pt1 Point, pt2 Point) ([]Trip, error)

GetTripsInsidePointInterval returns all trips whose bounding box intersects with the bounding box formed by the 2 given points.

func (Fetcher) GetTripsWithIntersection

func (f Fetcher) GetTripsWithIntersection(minLat float64, maxLat float64, minLon float64, maxLon float64) ([]Trip, error)

GetTripsWithIntersection returns all trips whose bounding box intersects with the given bounding box.

func (Fetcher) LoadDatabase

func (f Fetcher) LoadDatabase(config LoaderConfig) error

LoadDatabase builds a database from the given LoaderConfig into the given file.

type FetcherConfig

type FetcherConfig struct {
	TimeZone                        string //https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
	OutOfBoundsGraceAbsolute        float64
	OutOfBoundsGracePercentage      float64
	BearingMinThreshold             Bearing //anything below this will be not be considered as much
	BearingMaxThreshold             Bearing //anything above this will be more favorably considered
	DatabaseOutOfBoundsGraceDegrees float64
	CloseHeavyRailStationThreshold  float64 //kilometers
	CloseTramStationThreshold       float64 //kilometers
}

A FetcherConfig represents the parameters used for a fetcher.

func NewDefaultConfig

func NewDefaultConfig() FetcherConfig

type InterpolationPoint

type InterpolationPoint struct {
	Position Point
	Time     time.Time
}

an InterpolationPoint is a point+time combination.

type LoaderConfig

type LoaderConfig struct {
	DatabasePath string              `json:"db_path"`
	Contents     []LoaderConfigEntry `json:"contents"`
}

a LoaderConfig represents a config used to load GTFS feeds into a DB.

type LoaderConfigEntry

type LoaderConfigEntry struct {
	Active             bool   `json:"active"`
	FeedURL            string `json:"feed_url"`
	FetchIntervalHours *uint  `json:"fetch_interval_hours"` //0 = always fetch, null = always rely on local file
	DatabaseFileName   string `json:"db_filename"`
	DisplayName        string `json:"display_name"`
}

a LoaderConfigEntry contains info about a specific GTFS feed and how it should be loaded.

type LocationType

type LocationType int
const (
	LocationTypePlatform LocationType = iota
	LocationTypeStation
	LocationTypeEntranceExit
	LocationTypeGeneric
	LocationTypeBoardingArea
)

type MovingTrainSight

type MovingTrainSight struct {
	ServiceId         string             `json:"service_id"`
	TripId            string             `json:"trip_id"`
	FeedId            string             `json:"feed_id"`
	Feed              *Feed              `json:"feed"`
	FirstSt           StopTime           `json:"first_st"`
	LastSt            StopTime           `json:"last_st"`
	Trip              Trip               `json:"trip"`
	RouteName         string             `json:"route_name"`
	PassingInterPoint InterpolationPoint `json:"passing_interpolation_point"`
	Distance          float64            `json:"distance_km"` //distance in kilometers
}

a MovingTrainSight represents a train sight while aboard a given train, but does NOT contain date/time information.

type Point

type Point struct {
	Lat float64 `json:"lat"`
	Lon float64 `json:"lon"`
}

func (Point) GetBearingFrom

func (pt Point) GetBearingFrom(obsPt Point) Bearing

type RealMovingTrainSight

type RealMovingTrainSight struct {
	MovingTrainSight MovingTrainSight `json:"sight"`
	Timestamp        time.Time        `json:"timestamp"`
	Date             time.Time        `json:"date"`
}

a RealMovingTrainSight contains a MovingTrainSight as well as date/time information.

type RealTrainSight

type RealTrainSight struct {
	TrainSight TrainSight `json:"sight"`
	Timestamp  time.Time  `json:"timestamp"`
	Date       time.Time  `json:"date"`
}

type Route

type Route struct {
	Feed           Feed      `csv:"-" gorm:"foreignKey:FeedId" json:"feed"`
	FeedId         string    `csv:"-" gorm:"primaryKey;uniqueIndex:pk_route" json:"feed_id"`
	RouteId        string    `gorm:"primaryKey;uniqueIndex:pk_route" csv:"route_id" json:"route_id"`
	RouteShortName string    `csv:"route_short_name" json:"short_name"`
	RouteLongName  string    `csv:"route_long_name" json:"long_name"`
	RouteDesc      string    `csv:"route_desc" json:"description"`
	RouteType      RouteType `csv:"route_type" json:"type"` //Basically: 0=tram,1=subway,2=heavy rail, 3=Bus, other=not rail (see docs for more info)
	RouteColor     string    `csv:"route_color" json:"color"`
	RouteTextColor string    `csv:"route_text_color" json:"text_color"`
	Trips          []Trip    `csv:"-" gorm:"foreignKey:RefRouteId,FeedId;references:RouteId,FeedId" json:"trips"`
}

type RouteType

type RouteType int
const (
	RouteTypeTram RouteType = iota
	RouteTypeSubway
	RouteTypeHeavyRail
	RouteTypeBus
)

type ServiceDay

type ServiceDay struct {
	Date      time.Time `gorm:"primaryKey;uniqueIndex:pk_servicedays"`
	FeedId    string    `gorm:"primaryKey;uniqueIndex:pk_servicedays"`
	ServiceId string    `gorm:"primaryKey;uniqueIndex:pk_servicedays"`
}

func (ServiceDay) GetFeededService

func (s ServiceDay) GetFeededService() FeededService

type ServiceType

type ServiceType uint
const (
	ServiceTypeScheduled ServiceType = iota
	ServiceTypeNotPossible
	ServiceTypeMustPhone
	ServiceTypeMustCoordinateWithDriver
)

type Stop

type Stop struct {
	// Feed            Feed          `csv:"-" gorm:"foreignKey:FeedId;references:FeedId" json:"feed"`
	Feed               Feed          `csv:"-" gorm:"foreignKey:FeedId" json:"feed"`
	FeedId             string        `csv:"-" gorm:"primaryKey;uniqueIndex:pk_stop" json:"feed_id"`
	StopId             string        `csv:"stop_id" gorm:"primaryKey;uniqueIndex:pk_stop" json:"stop_id"`
	StopCode           string        `csv:"stop_code" json:"stop_code"`
	StopName           string        `csv:"stop_name" json:"stop_name"`
	TtsStopName        string        `csv:"tts_stop_name" json:"tts_stop_name"`
	StopDesc           string        `csv:"stop_desc" json:"stop_desc"`
	StopUrl            string        `csv:"stop_url" json:"stop_url"`
	StopLat            float64       `csv:"-" json:"lat"`
	StopLon            float64       `csv:"-" json:"lon"`
	StopLatString      string        `csv:"stop_lat" json:"-"`
	StopLonString      string        `csv:"stop_lon" json:"-"`
	LocationType       *LocationType `csv:"location_type" json:"location_type"` // 0=Stop/platform, 1=Station, 2=Entrance/exit, 3=Generic, 4=Boarding area
	CsvParentStationId string        `gorm:"-:all" csv:"parent_station" json:"-"`
	ParentStationId    *string       `csv:"-" json:"-"`
	//station hierarchy removed because FK constraint isn't required by the spec, TODO check for breaking changes
	ParentStation *Stop      `csv:"-" gorm:"foreignKey:ParentStationId,FeedId;references:StopId,FeedId" json:"parent_station"`
	ChildStations []Stop     `csv:"-" gorm:"foreignKey:ParentStationId,FeedId;references:StopId,FeedId" json:"child_stations"`
	StopTimes     []StopTime `csv:"-" gorm:"foreignKey:FeedId,StopId;references:FeedId,StopId" json:"stop_times"`
}

func (Stop) GetPoint

func (stop Stop) GetPoint() Point

type StopTime

type StopTime struct {
	FeedId           string      `csv:"-" gorm:"primaryKey;uniqueIndex:pk_stoptime" json:"feed_id"`
	TripId           string      `gorm:"primaryKey;uniqueIndex:pk_stoptime" csv:"trip_id" json:"trip_id"`
	CsvArrivalTime   string      `gorm:"-:all" csv:"arrival_time" json:"-"`   //hh:mm:ss
	CsvDepartureTime string      `gorm:"-:all" csv:"departure_time" json:"-"` //hh:mm:ss
	ArrivalTime      time.Time   `csv:"-" json:"arrival_time"`
	DepartureTime    time.Time   `csv:"-" json:"departure_time"`
	StopId           string      `csv:"stop_id" json:"stop_id"`
	Stop             *Stop       `csv:"-" gorm:"foreignKey:FeedId,StopId" json:"stop"`
	Trip             *Trip       `csv:"-" gorm:"foreignKey:FeedId,TripId" json:"trip"`
	StopSequence     uint        `gorm:"primaryKey;uniqueIndex:pk_stoptime" csv:"stop_sequence" json:"stop_sequence"`
	StopHeadsign     string      `csv:"stop_headsign" json:"stop_headsign"`
	PickupType       ServiceType `csv:"pickup_type" json:"pickup_type"`
	DropOffType      ServiceType `csv:"pickup_type" json:"dorp_off_type"`
}

type TrainSight

type TrainSight struct {
	ServiceId string   `json:"service_id"`
	TripId    string   `json:"trip_id"`
	FeedId    string   `json:"feed_id"`
	Feed      *Feed    `json:"feed"`
	StBefore  StopTime `json:"st_before"`
	StAfter   StopTime `json:"st_after"`
	FirstSt   StopTime `json:"first_st"`
	LastSt    StopTime `json:"last_st"`
	Trip      Trip     `json:"trip"`
	RouteName string   `json:"route_name"`
	// contains filtered or unexported fields
}

copying the types from previous implementation

type Trip

type Trip struct {
	FeedId       string   `csv:"-" gorm:"primaryKey;uniqueIndex:pk_trip" json:"feed_id"`
	TripId       string   `gorm:"primaryKey;uniqueIndex:pk_trip" csv:"trip_id" json:"trip_id"`
	Feed         *Feed    `csv:"-" gorm:"foreignKey:FeedId" json:"feed"`
	RefRouteId   string   `csv:"route_id" json:"-"`
	Route        *Route   `csv:"-" gorm:"foreignKey:RefRouteId,FeedId;references:RouteId,FeedId" json:"route"`
	RefServiceId string   `csv:"service_id" json:"service_id"`
	Calendar     Calendar `csv:"-" json:"calendar" gorm:"foreignKey:FeedId,RefServiceId;references:FeedId,ServiceId"`
	// Calendar Calendar `csv:"-" json:"calendar" gorm:"foreignKey:FeedId,ServiceId"`
	//REMOVING THAT ONE CAUSE NOT PART OF STRICT ORM, TODO check if this breaks anything
	CalendarDates []CalendarDate `csv:"-" json:"calendar_dates" gorm:"foreignKey:FeedId,ServiceId;references:FeedId,RefServiceId"`
	// trying out the many to many aspect (it's fucked up afaik)
	// CalendarDates []CalendarDate `csv:"-" json:"calendar_dates" gorm:"many2many:calendar;foreignKey:FeedId,ServiceId;references:FeedId,ServiceId"`
	Headsign      string     `csv:"trip_headsign" json:"headsign"`
	TripShortName string     `csv:"trip_short_name" json:"short_name"`
	StopTimes     []StopTime `gorm:"foreignKey:FeedId,TripId;references:FeedId,TripId" json:"stop_times" csv:"-"`
	//NOTE: no LongName is speicified in the spec
	//Additional feeds (not part of the gtfs spec but used by our implementation)
	MinLat float64 `gorm:"index:geo_index" json:"-" csv:"-"`
	MaxLat float64 `gorm:"index:geo_index" json:"-" csv:"-"`
	MinLon float64 `gorm:"index:geo_index" json:"-" csv:"-"`
	MaxLon float64 `gorm:"index:geo_index" json:"-" csv:"-"`
}

Jump to

Keyboard shortcuts

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