app/models/chouette/route.rb
class Chouette::Route < Chouette::TridentActiveRecord
include RouteRestrictions
# FIXME http://jira.codehaus.org/browse/JRUBY-6358
self.primary_key = "id"
attr_accessor :wayback_code
attr_accessor :direction_code
def self.nullable_attributes
[:published_name, :comment, :number, :name]
end
belongs_to :line
has_many :journey_patterns, :dependent => :destroy
has_many :vehicle_journeys, :dependent => :destroy do
def timeless
Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id))
end
end
has_many :vehicle_journey_frequencies, :dependent => :destroy do
# Todo : I think there is a better way to do this.
def timeless
Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id))
end
end
belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id
has_many :stop_points, -> { order('position ASC') }, :dependent => :destroy do
def find_by_stop_area(stop_area)
stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id)
where( :stop_area_id => stop_area_ids).first or
raise ActiveRecord::RecordNotFound.new("Can't find a StopArea #{stop_area.inspect} in Route #{proxy_owner.id.inspect}'s StopPoints")
end
def between(departure, arrival)
between_positions = [departure, arrival].collect do |endpoint|
case endpoint
when Chouette::StopArea
find_by_stop_area(endpoint).position
when Chouette::StopPoint
endpoint.position
when Integer
endpoint
else
raise ActiveRecord::RecordNotFound.new("Can't determine position in route #{proxy_owner.id} with #{departure.inspect}")
end
end
where(" position between ? and ? ", between_positions.first, between_positions.last)
end
end
has_many :stop_areas, -> { order('stop_points.position ASC') }, :through => :stop_points do
def between(departure, arrival)
departure, arrival = [departure, arrival].collect do |endpoint|
String === endpoint ? Chouette::StopArea.find_by_objectid(endpoint) : endpoint
end
proxy_owner.stop_points.between(departure, arrival).includes(:stop_area).collect(&:stop_area)
end
end
accepts_nested_attributes_for :stop_points, :allow_destroy => :true
# validates_presence_of :name
validates_presence_of :line
# validates_presence_of :direction_code
# validates_presence_of :wayback_code
before_destroy :dereference_opposite_route
after_commit :journey_patterns_control_route_sections
def geometry_presenter
Chouette::Geometry::RoutePresenter.new self
end
def dereference_opposite_route
self.line.routes.each do |r|
r.update_attributes( :opposite_route => nil) if r.opposite_route == self
end
end
def geometry
points = stop_areas.map(&:to_lat_lng).compact.map do |loc|
[loc.lng, loc.lat]
end
GeoRuby::SimpleFeatures::LineString.from_coordinates( points, 4326)
end
def geometry_jp(journey_pattern)
jp_stop_areas_ids = journey_pattern.stop_points.map(&:stop_area_id)
points = stop_areas.select{|sa| jp_stop_areas_ids.include?(sa.id)}.map(&:to_lat_lng).compact.map do |loc|
[loc.lng, loc.lat]
end
GeoRuby::SimpleFeatures::LineString.from_coordinates( points, 4326)
end
def time_tables
self.vehicle_journeys.joins(:time_tables).map(&:"time_tables").flatten.uniq
end
def sorted_vehicle_journeys(journey_category_model)
send(journey_category_model)
.joins(:journey_pattern, :vehicle_journey_at_stops)
.where("vehicle_journey_at_stops.stop_point_id=journey_patterns.departure_stop_point_id")
.order( "vehicle_journey_at_stops.departure_time")
end
def self.direction_binding
{ "A" => "straight_forward",
"R" => "backward",
"ClockWise" => "clock_wise",
"CounterClockWise" => "counter_clock_wise",
"North" => "north",
"NorthWest" => "north_west",
"West" => "west",
"SouthWest" => "south_west",
"South" => "south",
"SouthEast" => "south_east",
"East" => "east",
"NorthEast" => "north_east"}
end
def direction_code
return nil if self.class.direction_binding[direction].nil?
Chouette::Direction.new( self.class.direction_binding[direction])
end
def direction_code=(direction_code)
self.direction = nil
self.class.direction_binding.each do |k,v|
self.direction = k if v==direction_code
end
end
@@directions = nil
def self.directions
@@directions ||= Chouette::Direction.all
end
def self.wayback_binding
{ "A" => "straight_forward", "R" => "backward"}
end
def wayback_code
return nil if self.class.wayback_binding[wayback].nil?
Chouette::Wayback.new( self.class.wayback_binding[wayback])
end
def wayback_code=(wayback_code)
self.wayback = nil
self.class.wayback_binding.each do |k,v|
self.wayback = k if v==wayback_code
end
end
@@waybacks = nil
def self.waybacks
@@waybacks ||= Chouette::Wayback.all
end
def stop_point_permutation?( stop_point_ids)
stop_points.map(&:id).map(&:to_s).sort == stop_point_ids.map(&:to_s).sort
end
def reorder!( stop_point_ids)
return false unless stop_point_permutation?( stop_point_ids)
stop_area_id_by_stop_point_id = {}
stop_points.each do |sp|
stop_area_id_by_stop_point_id.merge!( sp.id => sp.stop_area_id)
end
reordered_stop_area_ids = []
stop_point_ids.each do |stop_point_id|
reordered_stop_area_ids << stop_area_id_by_stop_point_id[ stop_point_id.to_i]
end
stop_points.each_with_index do |sp, index|
if sp.stop_area_id.to_s != reordered_stop_area_ids[ index].to_s
#result = sp.update_attributes( :stop_area_id => reordered_stop_area_ids[ index])
sp.stop_area_id = reordered_stop_area_ids[ index]
result = sp.save!
end
end
return true
end
def journey_patterns_control_route_sections
self.journey_patterns.each do |jp|
jp.control_route_sections
end
end
protected
def self.vehicle_journeys_timeless(stop_point_id)
all( :conditions => ['vehicle_journeys.id NOT IN (?)', Chouette::VehicleJourneyAtStop.where(stop_point_id: stop_point_id).pluck(:vehicle_journey_id)] )
end
end