+int Route::get_turnout(unsigned id) const
+{
+ map<unsigned, int>::const_iterator i = turnouts.find(id);
+ if(i!=turnouts.end())
+ return i->second;
+ return -1;
+}
+
+void Route::add_track(Track &trk)
+{
+ if(tracks.count(&trk))
+ return;
+
+ if(!tracks.empty())
+ {
+ unsigned valid = check_validity(trk);
+ if(!(valid&1))
+ throw Exception("Not linked to existing tracks");
+ else if(!(valid&2))
+ throw Exception("Branching routes not allowed");
+ else if(!(valid&4))
+ throw Exception("Route must be smooth");
+ }
+
+ tracks.insert(&trk);
+ update_turnouts();
+}
+
+void Route::add_tracks(const set<Track *> &trks)
+{
+ set<Track *> pending;
+ for(set<Track *>::const_iterator i=trks.begin(); i!=trks.end(); ++i)
+ if(!tracks.count(*i))
+ pending.insert(*i);
+
+ while(!pending.empty())
+ {
+ bool found = false;
+ for(set<Track *>::const_iterator i=pending.begin(); i!=pending.end(); ++i)
+ if(tracks.empty() || check_validity(**i)==7)
+ {
+ tracks.insert(*i);
+ pending.erase(*i);
+ found = true;
+ break;
+ }
+
+ if(!found)
+ throw Exception("Could not add all tracks to route");
+ }
+
+ update_turnouts();
+}
+
+void Route::add_track_chain(Track &start, unsigned ep, const TurnoutMap &trnts)
+{
+ Track *track = &start;
+ while(1)
+ {
+ if(track->get_type().is_dead_end())
+ break;
+
+ if(tracks.count(track))
+ break;
+
+ int path = 0;
+ if(track->get_turnout_id())
+ {
+ TurnoutMap::const_iterator i = trnts.find(track->get_turnout_id());
+ if(i==trnts.end())
+ break;
+
+ path = i->second;
+ }
+
+ add_track(*track);
+
+ unsigned out_ep = track->traverse(ep, path);
+ Track *next = track->get_links()[out_ep];
+ if(!next)
+ break;
+
+ ep = next->get_endpoint_by_link(*track);
+ track = next;
+ }
+}
+
+bool Route::has_track(Track &t) const
+{
+ return tracks.count(&t);
+}
+
+void Route::save(list<DataFile::Statement> &st) const
+{
+ st.push_back((DataFile::Statement("name"), name));
+ for(map<unsigned, int>::const_iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
+ st.push_back((DataFile::Statement("turnout"), i->first, i->second));
+}
+
+unsigned Route::check_validity(Track &trk) const