Skip to content

Commit

Permalink
Merge pull request #1245 from transitland/master
Browse files Browse the repository at this point in the history
Production release 85.1
  • Loading branch information
irees committed Aug 22, 2018
2 parents 99a4170 + b332a05 commit fab6f8e
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 73 deletions.
10 changes: 5 additions & 5 deletions app/controllers/api/v1/routes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ def headways
set_model
dates = (params[:dates] || "").split(",")
between = (params[:origin_departure_between] || "").split(",")
fail Exception.new('Requires at least one date') unless dates.size > 0
(between = [between.first, '1000:00']) if between.size == 1
(between = ['00:00', '1000:00']) if between.size == 0
between = between[0..2]
render :json => @model.headways(dates, between[0], between[1]).map { |k,v| [k.join(':'), v] }.to_h
departure_span = params[:departure_span].presence || '00:00'
h = params[:headway_percentile].presence
headway_percentile = h ? h.to_f : nil
# dates, w, departure_start=nil, departure_end=nil, departure_span=nil, headway_percentile=0.5
render :json => ScheduleStopPair.headways(dates, {route_id: @model.id}, between[0], between[1], departure_span, headway_percentile).map { |k,v| [k.join(':'), v] }.to_h
end

private
Expand Down
9 changes: 4 additions & 5 deletions app/controllers/api/v1/stops_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ def headways
set_model
dates = (params[:dates] || "").split(",")
between = (params[:origin_departure_between] || "").split(",")
fail Exception.new('Requires at least one date') unless dates.size > 0
(between = [between.first, '1000:00']) if between.size == 1
(between = ['00:00', '1000:00']) if between.size == 0
between = between[0..2]
render :json => @model.headways(dates, between[0], between[1])
departure_span = params[:departure_span].presence
h = params[:headway_percentile].presence
headway_percentile = h ? h.to_f : nil
render :json => ScheduleStopPair.headways(dates, {origin_id: @model.id}, between[0], between[1], departure_span, headway_percentile).map { |k,v| [k.join(':'), v] }.to_h
end

private
Expand Down
33 changes: 0 additions & 33 deletions app/models/route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -230,39 +230,6 @@ def self.geometry_from_rsps(route, repr_rsps)
)
end

def median(ary)
return nil if ary.size == 0
mid = ary.length / 2
sorted = ary.sort
ary.length.odd? ? sorted[mid].to_f : 0.5 * (sorted[mid] + sorted[mid - 1])
end

def headways(dates, departure_start=nil, departure_end=nil)
departure_start = GTFS::WideTime.parse(departure_start || '00:00').to_seconds
departure_end = GTFS::WideTime.parse(departure_end || '1000:00').to_seconds
headways = Hash.new { |h,k| h[k] = [] }
dates.each do |date|
stops = Hash.new { |h,k| h[k] = [] }
ScheduleStopPair
.where(route_id: id)
.where_service_on_date(date)
.select([:id, :origin_id, :destination_id, :origin_arrival_time, :frequency_start_time, :frequency_end_time, :frequency_headway_seconds])
.find_each do |ssp|
ssp.expand_frequency.each do |ssp|
t = GTFS::WideTime.parse(ssp.origin_arrival_time).to_seconds
key = [ssp.origin_id, ssp.destination_id]
(stops[key] << t) if departure_start <= t && t <= departure_end
end
end
stops.map do |k,v|
v = v.sort
headways[k] += v[0..-2].zip(v[1..-1] || []).map { |a,b| b - a }.select { |i| i > 0 }
end
end
sids = Stop.select([:id, :onestop_id]).where(id: headways.keys.flatten).map { |s| [s.id, s.onestop_id] }.to_h
headways.map { |k,v| [k.map { |i| sids[i] }, median(v) ]}.select { |k,v| v }.to_h
end

##### FromGTFS ####
def generate_onestop_id
stops = self.serves || self.stops
Expand Down
39 changes: 39 additions & 0 deletions app/models/schedule_stop_pair.rb
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,45 @@ def expand_frequency
ret
end

def self.percentile(values, percentile)
return values[0]
values_sorted = values.sort
k = (percentile*(values_sorted.length-1)+1).floor - 1
f = (percentile*(values_sorted.length-1)+1).modulo(1)
return values_sorted[k] + (f * (values_sorted[k+1] - values_sorted[k]))
end

def self.headways(dates, w, departure_start=nil, departure_end=nil, departure_span=nil, headway_percentile=0.5)
dates = Array.wrap(dates)
fail Exception.new('must supply at least one date') unless dates.size > 0
departure_start = GTFS::WideTime.parse(departure_start || '00:00').to_seconds
departure_end = GTFS::WideTime.parse(departure_end || '1000:00').to_seconds
departure_span = GTFS::WideTime.parse(departure_span).try(:to_seconds) || 0
headways = Hash.new { |h,k| h[k] = [] }
dates.each do |date|
stop_pairs = Hash.new { |h,k| h[k] = [] }
ScheduleStopPair
.where(w)
.where_service_on_date(date)
.select([:id, :origin_id, :destination_id, :origin_arrival_time, :origin_departure_time, :destination_arrival_time, :destination_departure_time, :frequency_start_time, :frequency_end_time, :frequency_headway_seconds])
.find_each do |ssp|
ssp.expand_frequency.each do |ssp|
t = GTFS::WideTime.parse(ssp.origin_arrival_time).to_seconds
key = [ssp.origin_id, ssp.destination_id]
stop_pairs[key] << t
end
end
stop_pairs.each do |k,v|
v = v.sort
next unless (v.last - v.first) > departure_span
v = v.select { |i| departure_start <= i && i <= departure_end }
headways[k] += v[0..-2].zip(v[1..-1] || []).map { |a,b| b - a }.select { |i| i > 0 }
end
end
sids = Stop.select([:id, :onestop_id]).where(id: headways.keys.flatten).map { |s| [s.id, s.onestop_id] }.to_h
headways.map { |k,v| [k.map { |i| sids[i] }, percentile(v, headway_percentile) ]}.select { |k,v| v }.to_h
end

# Tracked by changeset
include CurrentTrackedByChangeset
current_tracked_by_changeset({
Expand Down
29 changes: 0 additions & 29 deletions app/models/stop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,35 +179,6 @@ def served_by_vehicle_types
.distinct
}

# Headways
def median(ary)
return nil if ary.size == 0
mid = ary.length / 2
sorted = ary.sort
ary.length.odd? ? sorted[mid].to_f : 0.5 * (sorted[mid] + sorted[mid - 1])
end

def headways(dates, departure_start=nil, departure_end=nil)
departure_start = GTFS::WideTime.parse(departure_start || '00:00').to_seconds
departure_end = GTFS::WideTime.parse(departure_end || '1000:00').to_seconds
trips_out
.includes(:destination)
.group_by(&:destination)
.map { |dest,ssps|
b = dates.map { |date|
h = ssps
.select { |i| i.service_on_date?(date) }
.map(&:expand_frequency)
.flatten
.map { |i| GTFS::WideTime.parse(i.origin_departure_time).to_seconds }
.select { |i| departure_start <= i && i <= departure_end }
.sort
h[0..-2].zip(h[1..-1] || []).map { |i,j| j - i }
}.flatten
[dest.onestop_id, median(b)]
}.select { |k,v| v }.to_h
end

# GTFS
has_many :gtfs_entities, class_name: GTFSStop, foreign_key: :entity_id

Expand Down
2 changes: 1 addition & 1 deletion config/initializers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module TransitlandDatastore
class Application
VERSION = "84"
VERSION = "85.1"
end
end

0 comments on commit fab6f8e

Please sign in to comment.