Class: CTA::Train

Inherits:
Trip
  • Object
show all
Defined in:
lib/cta_redux/models/train.rb

Overview

Note:

Current columns: [:route_id, :service_id, :trip_id, :direction_id, :block_id, :shape_id, :direction, :wheelchair_accessible, :schd_trip_id]

A Sequel::Model, inherited from Trip This corresponds to trips.txt in the GTFS feed, though the CTA does not fully implement the standard.

Defined Under Namespace

Classes: Live, Prediction

Constant Summary collapse

L_ROUTES =
{
  "red"   => { :name => "Red",
               :directions => { "1" => "Howard-bound", "5" => "95th/Dan Ryan-bound" }
  },
  "blue"  => { :name => "Blue",
               :directions => { "1" => "O'Hare-bound", "5" => "Forest Park-bound" }
  },
  "brn"   => { :name => "Brown",
               :directions => { "1" => "Kimball-bound", "5" => "Loop-bound" }
  },
  "g"     => { :name => "Green",
               :directions => { "1" => "Harlem/Lake-bound", "5" => "Ashland/63rd- or Cottage Grove-bound (toward 63rd St destinations)" }
  },
  "org"   => { :name => "Orange",
               :directions => { "1" => "Loop-bound", "5" => "Midway-bound" }
  },
  "p"     => { :name => "Purple",
               :directions => { "1" => "Linden-bound", "5" => "Howard- or Loop-bound" }
  },
  "pink"  => { :name => "Pink",
               :directions => { "1" => "Loop-bound", "5" => "54th/Cermak-bound" }
  },
  "y"     => { :name => "Yellow",
               :directions => { "1" => "Skokie-bound", "5" => "Howard-bound" }
  },
}
FRIENDLY_L_ROUTES =
Hash[L_ROUTES.values.map { |r| r[:name].downcase.to_sym }.zip(L_ROUTES.keys)]
ANNOYING_GREEN_RUNS =
CTA::DB[:stop_times].with_sql(<<-SQL).select_map(:schd_trip_id)
  SELECT DISTINCT t.schd_trip_id
  FROM stop_times st
    JOIN trips t ON st.trip_id = t.trip_id
  WHERE t.route_id = 'G'
    AND st.stop_headsign = ''
SQL
HEADSIGNS =
{
  "54th/Cermak"   => "54 / Cermak",
  "Ashland/63rd"  => "Ashland / 63",
  "UIC-Halsted"   => "UIC",
  "Harlem/Lake"   => "Harlem",
  "95th/Dan Ryan" => "95th",
}

Constants inherited from Trip

CTA::Trip::BUS_ROUTES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Trip

#calendar, #route, #shapes, #stop_times, #stops

Instance Attribute Details

#liveLive

Note:

a CTA::Train will only contain live data when augmented with an API::Response

Returns the Live data associated with this CTA::Train object, if available.

Returns:


9
10
11
# File 'lib/cta_redux/models/train.rb', line 9

def live
  @live
end

Class Method Details

.find_active_run(run, timestamp, fuzz = false, direction = nil) ⇒ Object

Find a CTA::Trip that should be happening, given a timestamp and a route or run. The CTA does not return GTFS trip_id information in either the BusTracker or TrainTracker API, so it is actually somewhat difficult to associate an API response to a CTA::Trip. However, we know what should be happening at any given time. This method attempts a fuzzy find - internally, we often first try to find the exact Trip that should be happening according to the schedule, and then failing that we assume that the CTA is running late and look for trips that should have ended within the past 90 minutes. This almost always finds something. That said, however, it means we may sometimes find a CTA::Trip that's incorrect. In practical usage however, that doesn't matter too much - most Trips for a run service the same stops. However, to be safe, your program may wish to compare certain other bits of the API responses to ensure we found something valid. For example, almost all Brown line trains service the same stops, so finding the wrong Trip doesn't matter too much. However, a handful of Brown line runs throughout the dat actually change to Orange line trains at Midway - so, you may wish to verify that the destination of the Trip matches the reported destination of the API. Suggestions on how to approach this problem are most welcome (as are patches for better behavior).

Parameters:

  • run (String)

    The run or route to search for

  • timestamp (DateTime, String)

    The timestamp to search against.

  • fuzz (true, false) (defaults to: false)

    Whether or not to do an exact schedule search or a fuzzy search.

  • direction (String) (defaults to: nil)

    The stop headsign. Highly recommended to use because otherwise results may be inaccurate.


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/cta_redux/models/train.rb', line 96

def self.find_active_run(run, timestamp, fuzz = false, direction = nil)
  # The TrainTracker API sets the stop_headsign to 'Cottage Grove' but GTFS has it as blank...
  if run == "516"
    puts run
    puts timestamp.to_s
    puts fuzz.inspect
    puts direction
  end
  if ANNOYING_GREEN_RUNS.any? { |r| r =~ /#{run}/ } && false
    direction_str = <<-EOF
      AND (st.stop_headsign = '#{(HEADSIGNS[direction] || direction).gsub("'", "''")}'
        OR (t.route_id = 'G' AND st.stop_headsign = ''))
    EOF
  elsif direction
    direction_str = "AND st.stop_headsign = '#{(HEADSIGNS[direction] || direction).gsub("'", "''")}'"
  else
    direction_str = ''
  end
  d = timestamp.is_a?(DateTime) ? timestamp : DateTime.parse(timestamp)
  wday = d.strftime("%A").downcase
  end_ts = (fuzz ? (d.to_time + (60 * 60 * 6) - (90 * 60)) : d).strftime("%H:%M:%S")
  Trip.with_sql(<<-SQL)
    SELECT t.*
    FROM trips t
      JOIN stop_times st ON t.trip_id = st.trip_id
      JOIN calendar   c  ON t.service_id = c.service_id
    WHERE t.schd_trip_id = 'R#{run}'
      #{direction_str}
      AND c.start_date <= '#{d.to_s}'
      AND c.end_date   >= '#{d.to_s}'
      AND c.#{wday}
    GROUP BY t.trip_id
    HAVING MAX(st.departure_time) >= '#{end_ts}'
    ORDER BY st.departure_time ASC
  SQL
end

Instance Method Details

#block_idInteger

Returns:

  • (Integer)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#directionString

Returns:

  • (String)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#direction_idInteger

Returns:

  • (Integer)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#follow!CTA::TrainTracker::FollowResponse

Follows a train, using the TrainTracker follow API

Returns:


135
136
137
# File 'lib/cta_redux/models/train.rb', line 135

def follow!
  CTA::TrainTracker.follow!(:run => self.schd_trip_id.gsub("R", ""))
end

#route_idString Also known as: id

Returns:

  • (String)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#schd_trip_idString Also known as: scheduled_trip_id, run

Returns:

  • (String)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#service_idInteger

Returns:

  • (Integer)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#shape_idInteger

Returns:

  • (Integer)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#trip_idInteger

Returns:

  • (Integer)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id

#wheelchair_accessibletrue, false

Returns:

  • (true, false)

73
# File 'lib/cta_redux/models/train.rb', line 73

alias_method :id, :route_id