gtfs-realtime 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +33 -4
- data/lib/gtfs/realtime.rb +19 -2
- data/lib/gtfs/realtime/calendar_date.rb +10 -0
- data/lib/gtfs/realtime/database.rb +11 -0
- data/lib/gtfs/realtime/stop.rb +18 -0
- data/lib/gtfs/realtime/stop_time.rb +47 -0
- data/lib/gtfs/realtime/trip.rb +6 -1
- data/lib/gtfs/realtime/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f61ca284c49d493e298935aa54e94f612767a0ff
|
4
|
+
data.tar.gz: 66eefa1d79e49915a85d8a720b879fd20f6b5857
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95f4fa73102e789c946e10eb6b62822c838f3fe7a5fc52506f8a648f1f390070ad8adc0b959b24a3807620f68554fd46090fad0263b08e70ae0fc92d52a03beb
|
7
|
+
data.tar.gz: 0763a7901716864e746c802553a2fa623a579be1e3724b056be7944ca87fa764a8bcbf46c2e97a703ce56ae2074d9f2db18177c5482c08a879e56f4077b728f1
|
data/README.md
CHANGED
@@ -41,10 +41,39 @@ end
|
|
41
41
|
# that you would like to use. gtfs-realtime will generate the relevant tables.
|
42
42
|
|
43
43
|
@nearby = GTFS::Realtime::Stop.nearby(41.834521, -71.396906)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
@nearby.each do |stop|
|
45
|
+
puts stop.name
|
46
|
+
puts "-----"
|
47
|
+
|
48
|
+
# load all stop times for today, including updated live information
|
49
|
+
stop.stop_times_for_today.each do |st|
|
50
|
+
trip_info = st.trip
|
51
|
+
route_info = trip_info.route
|
52
|
+
shapes_info = trip_info.shapes
|
53
|
+
puts "#{st.scheduled_departure_time}: [#{st.trip.route.short_name}] #{st.trip.headsign}"
|
54
|
+
|
55
|
+
if st.live?
|
56
|
+
delay = st.actual_departure_delay / 60
|
57
|
+
delay_string = case
|
58
|
+
when delay < 0
|
59
|
+
"#{delay.abs} minute(s) early"
|
60
|
+
when delay > 0
|
61
|
+
"#{delay} minute(s) late"
|
62
|
+
else
|
63
|
+
"on time"
|
64
|
+
end
|
65
|
+
|
66
|
+
puts "- expected at #{st.departure_time}, #{delay_string}" if st.live?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
puts "\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
# refresh realtime info
|
73
|
+
GTFS::Realtime.refresh_realtime_feed!
|
74
|
+
|
75
|
+
# refresh static info
|
76
|
+
GTFS::Realtime.load_static_feed!(force: true)
|
48
77
|
```
|
49
78
|
|
50
79
|
## Development
|
data/lib/gtfs/realtime.rb
CHANGED
@@ -7,6 +7,7 @@ require "sqlite3"
|
|
7
7
|
require "gtfs/realtime/database"
|
8
8
|
|
9
9
|
require "gtfs/gtfs_gem_patch"
|
10
|
+
require "gtfs/realtime/calendar_date"
|
10
11
|
require "gtfs/realtime/configuration"
|
11
12
|
require "gtfs/realtime/route"
|
12
13
|
require "gtfs/realtime/service_alert"
|
@@ -43,6 +44,17 @@ module GTFS
|
|
43
44
|
return unless static_data
|
44
45
|
|
45
46
|
GTFS::Realtime::Model.db.transaction do
|
47
|
+
GTFS::Realtime::CalendarDate.dataset.delete
|
48
|
+
GTFS::Realtime::CalendarDate.multi_insert(
|
49
|
+
static_data.calendar_dates.collect do |calendar_date|
|
50
|
+
{
|
51
|
+
service_id: calendar_date.service_id.strip,
|
52
|
+
date: Date.strptime(calendar_date.date, "%Y%m%d"),
|
53
|
+
exception_type: calendar_date.exception_type
|
54
|
+
}
|
55
|
+
end
|
56
|
+
)
|
57
|
+
|
46
58
|
GTFS::Realtime::Route.dataset.delete
|
47
59
|
GTFS::Realtime::Route.multi_insert(
|
48
60
|
static_data.routes.collect do |route|
|
@@ -100,7 +112,8 @@ module GTFS
|
|
100
112
|
headsign: trip.headsign.strip,
|
101
113
|
route_id: trip.route_id.strip,
|
102
114
|
service_id: trip.service_id.strip,
|
103
|
-
shape_id: trip.shape_id.strip
|
115
|
+
shape_id: trip.shape_id.strip,
|
116
|
+
direction_id: trip.direction_id
|
104
117
|
}
|
105
118
|
end
|
106
119
|
)
|
@@ -174,7 +187,11 @@ module GTFS
|
|
174
187
|
def get_entities(path)
|
175
188
|
return [] if path.nil?
|
176
189
|
|
177
|
-
|
190
|
+
if File.exists?(path)
|
191
|
+
data = File.open(path, 'r'){|f| f.read}
|
192
|
+
else
|
193
|
+
data = Net::HTTP.get(URI.parse(path))
|
194
|
+
end
|
178
195
|
feed = Transit_realtime::FeedMessage.decode(data)
|
179
196
|
feed.entity # array of entities
|
180
197
|
end
|
@@ -13,6 +13,16 @@ module GTFS
|
|
13
13
|
db = Sequel.connect(new_path || "sqlite://")
|
14
14
|
|
15
15
|
# Set up all database tables
|
16
|
+
db.create_table? :gtfs_realtime_calendar_dates do
|
17
|
+
Integer :id, primary_key: true
|
18
|
+
String :service_id
|
19
|
+
Date :date
|
20
|
+
Integer :exception_type
|
21
|
+
|
22
|
+
index :id
|
23
|
+
index :service_id
|
24
|
+
end
|
25
|
+
|
16
26
|
db.create_table? :gtfs_realtime_routes do
|
17
27
|
String :id, primary_key: true
|
18
28
|
String :short_name
|
@@ -57,6 +67,7 @@ module GTFS
|
|
57
67
|
String :route_id
|
58
68
|
String :service_id
|
59
69
|
String :shape_id
|
70
|
+
Integer :direction_id
|
60
71
|
|
61
72
|
index :id
|
62
73
|
index :route_id
|
data/lib/gtfs/realtime/stop.rb
CHANGED
@@ -18,6 +18,24 @@ module GTFS
|
|
18
18
|
[:stop_time_updates, :stop_id, :trip_update_id],
|
19
19
|
[:trip_updates, :id, :route_id]
|
20
20
|
]
|
21
|
+
|
22
|
+
def stop_times_schedule_for(date)
|
23
|
+
# TODO: .all.first is a weird syntax to do eager loading correctly. Maybe there's a better way?
|
24
|
+
self_with_eager_loads = GTFS::Realtime::Stop.where(id: id).eager(stop_times: {trip: [:calendar_dates, :route, :shapes]}).all.first
|
25
|
+
self_with_eager_loads.stop_times.select{|st| st.trip.active?(Date.today)}.sort_by{|st| st.departure_time}
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop_times_for_today
|
29
|
+
stop_times = stop_times_schedule_for(Date.today)
|
30
|
+
stop_time_updates.each do |stu|
|
31
|
+
# find a matching existing record in the schedule
|
32
|
+
stop_time = stop_times.find{|st| st.trip_id == stu.trip_update.trip_id}
|
33
|
+
|
34
|
+
# update its info
|
35
|
+
stop_time.set(stu)
|
36
|
+
end
|
37
|
+
stop_times
|
38
|
+
end
|
21
39
|
end
|
22
40
|
end
|
23
41
|
end
|
@@ -3,6 +3,53 @@ module GTFS
|
|
3
3
|
class StopTime < GTFS::Realtime::Model
|
4
4
|
many_to_one :trip
|
5
5
|
many_to_one :stop
|
6
|
+
|
7
|
+
attr_accessor :actual_arrival_time, :actual_arrival_delay, :actual_departure_time, :actual_departure_delay
|
8
|
+
|
9
|
+
def live?
|
10
|
+
actual_arrival_time || actual_arrival_delay || actual_departure_time || actual_departure_delay
|
11
|
+
end
|
12
|
+
|
13
|
+
def arrival_time
|
14
|
+
actual_arrival_time || scheduled_arrival_time
|
15
|
+
end
|
16
|
+
|
17
|
+
def departure_time
|
18
|
+
actual_departure_time || scheduled_departure_time
|
19
|
+
end
|
20
|
+
|
21
|
+
def scheduled_arrival_time
|
22
|
+
self.class.parse_time(self[:arrival_time])
|
23
|
+
end
|
24
|
+
|
25
|
+
def scheduled_departure_time
|
26
|
+
self.class.parse_time(self[:departure_time])
|
27
|
+
end
|
28
|
+
|
29
|
+
def set(val)
|
30
|
+
return super(val) unless val.is_a?(GTFS::Realtime::StopTimeUpdate)
|
31
|
+
|
32
|
+
@actual_arrival_time = val.arrival_time
|
33
|
+
@actual_arrival_delay = val.arrival_delay
|
34
|
+
@actual_departure_time = val.departure_time
|
35
|
+
@actual_departure_delay = val.departure_delay
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def self.parse_time(time, date = Date.today)
|
41
|
+
# TODO: handle case where date != Date.today
|
42
|
+
day_adjustment = 0
|
43
|
+
hour = time[0...2].to_i
|
44
|
+
|
45
|
+
# handle timestamps like "24:30"
|
46
|
+
if hour > 24
|
47
|
+
days = hour / 24
|
48
|
+
time[0...2] = (hour % 24).to_s.rjust(2, '0')
|
49
|
+
end
|
50
|
+
|
51
|
+
Time.parse(time) + day_adjustment * 60 * 60 * 24
|
52
|
+
end
|
6
53
|
end
|
7
54
|
end
|
8
55
|
end
|
data/lib/gtfs/realtime/trip.rb
CHANGED
@@ -3,8 +3,13 @@ module GTFS
|
|
3
3
|
class Trip < GTFS::Realtime::Model
|
4
4
|
many_to_one :route
|
5
5
|
many_to_many :stops, join_table: :gtfs_realtime_stop_times
|
6
|
+
one_to_many :calendar_dates, primary_key: :service_id, key: :service_id
|
7
|
+
one_to_many :shapes, primary_key: :shape_id, key: :id
|
6
8
|
|
7
|
-
|
9
|
+
def active?(date)
|
10
|
+
# can't use .where chaining b/c Sequel is weird
|
11
|
+
calendar_dates.find{|cd| cd.exception_type == GTFS::Realtime::CalendarDate::ADDED && cd.date == date}
|
12
|
+
end
|
8
13
|
end
|
9
14
|
end
|
10
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gtfs-realtime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Laughlin
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- gtfs-realtime.gemspec
|
144
144
|
- lib/gtfs/gtfs_gem_patch.rb
|
145
145
|
- lib/gtfs/realtime.rb
|
146
|
+
- lib/gtfs/realtime/calendar_date.rb
|
146
147
|
- lib/gtfs/realtime/configuration.rb
|
147
148
|
- lib/gtfs/realtime/database.rb
|
148
149
|
- lib/gtfs/realtime/nearby.rb
|