Commit e8bd8ffe authored by Mohcine Chraibi's avatar Mohcine Chraibi

Merge branch '300-tracks-for-trains' into 'develop'

Interface of trains

Closes #300

See merge request !49
parents 02706b98 32795a9e
Pipeline #21759 passed with stages
in 9 minutes and 17 seconds
...@@ -50,6 +50,11 @@ void GeoFileParser::LoadBuilding(Building* building) ...@@ -50,6 +50,11 @@ void GeoFileParser::LoadBuilding(Building* building)
Log->Write("ERROR:\t could not load extra traffic information!"); Log->Write("ERROR:\t could not load extra traffic information!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if(!LoadTrainInfo(building))
{
Log->Write("ERROR:\t could not load train information!");
exit(EXIT_FAILURE);
}
} }
bool GeoFileParser::LoadGeometry(Building* building) bool GeoFileParser::LoadGeometry(Building* building)
...@@ -199,6 +204,7 @@ bool GeoFileParser::LoadGeometry(Building* building) ...@@ -199,6 +204,7 @@ bool GeoFileParser::LoadGeometry(Building* building)
for (TiXmlElement* xPolyVertices = xSubRoom->FirstChildElement("polygon"); xPolyVertices; for (TiXmlElement* xPolyVertices = xSubRoom->FirstChildElement("polygon"); xPolyVertices;
xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) {
std::string wall_type = xmltoa(xPolyVertices->Attribute("type"), "wall");
for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement( for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement(
"vertex"); "vertex");
xVertex && xVertex!=xPolyVertices->LastChild("vertex"); xVertex && xVertex!=xPolyVertices->LastChild("vertex");
...@@ -208,7 +214,7 @@ bool GeoFileParser::LoadGeometry(Building* building) ...@@ -208,7 +214,7 @@ bool GeoFileParser::LoadGeometry(Building* building)
double y1 = xmltof(xVertex->Attribute("py")); double y1 = xmltof(xVertex->Attribute("py"));
double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px"));
double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py"));
subroom->AddWall(Wall(Point(x1, y1), Point(x2, y2))); subroom->AddWall(Wall(Point(x1, y1), Point(x2, y2), wall_type));
//printf("%0.2f %0.2f %0.2f %0.2f\n",x1,y1,x2,y2); //printf("%0.2f %0.2f %0.2f %0.2f\n",x1,y1,x2,y2);
} }
...@@ -327,7 +333,7 @@ bool GeoFileParser::LoadGeometry(Building* building) ...@@ -327,7 +333,7 @@ bool GeoFileParser::LoadGeometry(Building* building)
} }
} }
else{ else{
Log->Write("INFO:\tNot parsing transition from file %s"); Log->Write("INFO:\tNot parsing transition from file");
} }
Log->Write("INFO:\tGot %d transitions", building-> GetAllTransitions().size()); Log->Write("INFO:\tGot %d transitions", building-> GetAllTransitions().size());
...@@ -464,7 +470,7 @@ bool GeoFileParser::parseDoorNode(TiXmlElement * xDoor, int id, Building* buildi ...@@ -464,7 +470,7 @@ bool GeoFileParser::parseDoorNode(TiXmlElement * xDoor, int id, Building* buildi
building->GetTransition(id)->TempClose(); building->GetTransition(id)->TempClose();
break; break;
case DoorState::Error: case DoorState::Error:
Log->Write("WARNING:\t Unknown door state: <%s>. open or close. Default: open", Log->Write("WARNING:\t Unknown door state: <%s>. open, close or temp_close. Default: open",
stateStr.c_str()); stateStr.c_str());
building->GetTransition(id)->Open(); building->GetTransition(id)->Open();
break; break;
...@@ -791,6 +797,220 @@ Goal* GeoFileParser::parseWaitingAreaNode(TiXmlElement * e) ...@@ -791,6 +797,220 @@ Goal* GeoFileParser::parseWaitingAreaNode(TiXmlElement * e)
return wa; return wa;
} }
bool GeoFileParser::LoadTrainInfo(Building* building)
{
Log->Write("--------\nINFO:\tLoading the train info");
TiXmlDocument doc(_configuration->GetProjectFile());
if (!doc.LoadFile()) {
Log->Write("ERROR: \t%s", doc.ErrorDesc());
Log->Write("ERROR: \t could not parse the project file");
return false;
}
TiXmlElement* xRootNode = doc.RootElement();
if (!xRootNode) {
Log->Write("ERROR:\tRoot element does not exist");
return false;
}
if (!xRootNode->FirstChild("train_constraints")) {
Log->Write("WARNING:\tNo train constraints were found. Continue.");
}
bool resTTT = true;
bool resType = true;
if(xRootNode->FirstChild("train_constraints"))
{
resTTT = LoadTrainTimetable(building, xRootNode);
resType = LoadTrainType(building, xRootNode);
}
return (resTTT && resType);
}
bool GeoFileParser::LoadTrainTimetable(Building* building, TiXmlElement * xRootNode)
{
TiXmlNode* xTTTNode = xRootNode->FirstChild("train_constraints")->FirstChild("train_time_table");
std::string TTTFilename;
if(xTTTNode)
{
fs::path p(_configuration->GetProjectRootDir());
TTTFilename = xTTTNode->FirstChild()->ValueStr();
p /= TTTFilename;
TTTFilename = p.string();
Log->Write("INFO:\tTrain Timetable file <%s> will be parsed", TTTFilename.c_str());
}
else return true;
TiXmlDocument docTTT(TTTFilename);
if (!docTTT.LoadFile()) {
Log->Write("ERROR: \t%s", docTTT.ErrorDesc());
Log->Write("ERROR: \t could not parse the train timetable file.");
return false;
}
TiXmlElement* xTTT = docTTT.RootElement();
if (!xTTT) {
Log->Write("ERROR:\tRoot element does not exist in TTT file.");
return false;
}
if (xTTT->ValueStr() != "train_time_table") {
Log->Write("ERROR:\tParsing train timetable file. Root element value is not 'train_time_table'.");
return false;
}
for (TiXmlElement* e = xTTT->FirstChildElement("train"); e;
e = e->NextSiblingElement("train")) {
std::shared_ptr<TrainTimeTable> TTT = parseTrainTimeTableNode(e);
if (TTT) {
building->AddTrainTimeTable(TTT);
}
}
return true;
}
bool GeoFileParser::LoadTrainType(Building* building, TiXmlElement * xRootNode)
{
TiXmlNode* xTTNode = xRootNode->FirstChild("train_constraints")->FirstChild("train_types");
std::string TTFilename;
if(xTTNode)
{
fs::path p(_configuration->GetProjectRootDir());
TTFilename = xTTNode->FirstChild()->ValueStr();
p /= TTFilename;
TTFilename = p.string();
Log->Write("INFO:\tTrain Type file <%s> will be parsed", TTFilename.c_str());
}
else return true;
TiXmlDocument docTT(TTFilename);
if (!docTT.LoadFile()) {
Log->Write("ERROR: \t%s", docTT.ErrorDesc());
Log->Write("ERROR: \t could not parse the train type file.");
return false;
}
TiXmlElement* xTT = docTT.RootElement();
if (!xTT) {
Log->Write("ERROR:\tRoot element does not exist in TT file.");
return false;
}
if (xTT->ValueStr() != "train_type") {
Log->Write("ERROR:\tParsing train type file. Root element value is not 'train_type'.");
return false;
}
for (TiXmlElement* e = xTT->FirstChildElement("train"); e;
e = e->NextSiblingElement("train")) {
std::shared_ptr<TrainType> TT = parseTrainTypeNode(e);
if (TT) {
building->AddTrainType(TT);
}
}
return true;
}
std::shared_ptr<TrainTimeTable> GeoFileParser::parseTrainTimeTableNode(TiXmlElement * e)
{
Log->Write("INFO:\tLoading train time table NODE");
std::string caption = xmltoa(e->Attribute("caption"), "-1");
int id = xmltoi(e->Attribute("id"), -1);
std::string type = xmltoa(e->Attribute("type"), "-1");
int room_id = xmltoi(e->Attribute("room_id"), -1);
int subroom_id = xmltoi(e->Attribute("subroom_id"), -1);
int platform_id = xmltoi(e->Attribute("platform_id"), -1);
float track_start_x = xmltof(e->Attribute("track_start_x"), -1);
float track_start_y = xmltof(e->Attribute("track_start_y"), -1);
float track_end_x = xmltof(e->Attribute("track_end_x"), -1);
float track_end_y = xmltof(e->Attribute("track_end_y"), -1);
float train_start_x = xmltof(e->Attribute("train_start_x"),-1);
float train_start_y = xmltof(e->Attribute("train_start_y"), -1);
float train_end_x = xmltof(e->Attribute("train_end_x"), -1);
float train_end_y = xmltof(e->Attribute("train_end_y"), -1);
float arrival_time = xmltof(e->Attribute("arrival_time"), -1);
float departure_time = xmltof(e->Attribute("departure_time"), -1);
// @todo: check these values for correctness e.g. arrival < departure
Log->Write("INFO:\tTrain time table:");
Log->Write("INFO:\t id: %d", id);
Log->Write("INFO:\t type: %s", type.c_str());
Log->Write("INFO:\t room_id: %d", room_id);
Log->Write("INFO:\t subroom_id: %d", subroom_id);
Log->Write("INFO:\t platform_id: %d", platform_id);
Log->Write("INFO:\t track_start: [%.2f, %.2f]", track_start_x, track_start_y);
Log->Write("INFO:\t track_end: [%.2f, %.2f]", track_end_x, track_end_y);
Log->Write("INFO:\t arrival_time: %.2f", arrival_time);
Log->Write("INFO:\t departure_time: %.2f", departure_time);
Point track_start(track_start_x, track_start_y);
Point track_end(track_end_x, track_end_y);
Point train_start(train_start_x, train_start_y);
Point train_end(train_end_x, train_end_y);
std::shared_ptr<TrainTimeTable> trainTimeTab = std::make_shared<TrainTimeTable>(
TrainTimeTable{
id,
type,
room_id,
subroom_id,
arrival_time,
departure_time,
track_start,
track_end,
train_start,
train_end,
platform_id,
false,
false,
});
return trainTimeTab;
}
std::shared_ptr<TrainType> GeoFileParser::parseTrainTypeNode(TiXmlElement * e)
{
Log->Write("INFO:\tLoading train type");
// int T_id = xmltoi(e->Attribute("id"), -1);
std::string type = xmltoa(e->Attribute("type"), "-1");
int agents_max = xmltoi(e->Attribute("agents_max"), -1);
float length = xmltof(e->Attribute("length"), -1);
// std::shared_ptr<Transition> t = new Transition();
// std::shared_ptr<Transition> doors;
Transition t;
std::vector<Transition> doors;
for (TiXmlElement* xDoor = e->FirstChildElement("door"); xDoor;
xDoor = xDoor->NextSiblingElement("door")) {
int D_id = xmltoi(xDoor->Attribute("id"), -1);
float x1 = xmltof(xDoor->FirstChildElement("vertex")->Attribute("px"), -1);
float y1 = xmltof(xDoor->FirstChildElement("vertex")->Attribute("py"), -1);
float x2 = xmltof(xDoor->LastChild("vertex")->ToElement()->Attribute("px"), -1);
float y2 = xmltof(xDoor->LastChild("vertex")->ToElement()->Attribute("py"), -1);
Point start(x1, y1);
Point end(x2, y2);
float outflow = xmltof(xDoor->Attribute("outflow"), -1);
float dn = xmltoi(xDoor->Attribute("dn"), -1);
t.SetID(D_id);
t.SetCaption(type + std::to_string(D_id));
t.SetPoint1(start);
t.SetPoint2(end);
t.SetOutflowRate(outflow);
t.SetDN(dn);
doors.push_back(t);
}
Log->Write("INFO:\t type: %s", type.c_str());
Log->Write("INFO:\t capacity: %d", agents_max);
Log->Write("INFO:\t number of doors: %d", doors.size());
for(auto d: doors)
{
Log->Write("INFO\t door (%d): %s | %s", d.GetID(), d.GetPoint1().toString().c_str(), d.GetPoint2().toString().c_str());
}
std::shared_ptr<TrainType> Type = std::make_shared<TrainType>(
TrainType{
type,
agents_max,
length,
doors,
});
return Type;
}
GeoFileParser::~GeoFileParser() GeoFileParser::~GeoFileParser()
{ {
......
...@@ -44,6 +44,11 @@ public: ...@@ -44,6 +44,11 @@ public:
Goal* parseGoalNode(TiXmlElement * e); Goal* parseGoalNode(TiXmlElement * e);
Transition* parseTransitionNode(TiXmlElement * xTrans, Building * building); Transition* parseTransitionNode(TiXmlElement * xTrans, Building * building);
Goal* parseWaitingAreaNode(TiXmlElement * e); Goal* parseWaitingAreaNode(TiXmlElement * e);
bool LoadTrainInfo(Building* building);
bool LoadTrainTimetable(Building* building, TiXmlElement * xRootNode);
bool LoadTrainType(Building* building, TiXmlElement * xRootNode);
std::shared_ptr<TrainType> parseTrainTypeNode(TiXmlElement * e);
std::shared_ptr<TrainTimeTable> parseTrainTimeTableNode(TiXmlElement * e);
private: private:
Configuration* _configuration; Configuration* _configuration;
......
...@@ -370,16 +370,69 @@ std::string getEventFileName(const std::string & GetProjectFile) ...@@ -370,16 +370,69 @@ std::string getEventFileName(const std::string & GetProjectFile)
TiXmlNode* xMainNode = doc.RootElement(); TiXmlNode* xMainNode = doc.RootElement();
string eventfile = ""; string eventfile = "";
if (xMainNode->FirstChild("events_file")) { if (xMainNode->FirstChild("events_file")) {
ret = xMainNode->FirstChild("events_file")->FirstChild()->Value(); ret = xMainNode->FirstChild("events_file")->FirstChild()->ValueStr();
Log->Write("INFO: \tevents <" + eventfile + ">"); Log->Write("INFO: \tevents <" + ret + ">");
} else { } else {
Log->Write("INFO: \tNo events found"); Log->Write("INFO: \tNo events found");
return ret; return ret;
} }
return ret; return ret;
} }
// <train_constraints>
// <train_time_table>ttt.xml</train_time_table>
// <train_types>train_types.xml</train_types>
// </train_constraints>
std::string getTrainTimeTableFileName(const std::string & GetProjectFile)
{
std::string ret="";
TiXmlDocument doc(GetProjectFile);
if (!doc.LoadFile()) {
Log->Write("ERROR: \t%s", doc.ErrorDesc());
Log->Write("ERROR: \tGetTrainTimeTable could not parse the project file");
return ret;
}
TiXmlNode* xMainNode = doc.RootElement();
string tttfile = "";
if (xMainNode->FirstChild("train_constraints")) {
TiXmlNode * xFileNode = xMainNode->FirstChild("train_constraints")->FirstChild("train_time_table");
if(xFileNode)
ret = xFileNode->FirstChild()->ValueStr();
Log->Write("INFO: \ttrain_time_table <" + ret + ">");
} else {
Log->Write("INFO: \tNo events no ttt file found");
return ret;
}
return ret;
}
std::string getTrainTypeFileName(const std::string & GetProjectFile)
{
std::string ret="";
TiXmlDocument doc(GetProjectFile);
if (!doc.LoadFile()) {
Log->Write("ERROR: \t%s", doc.ErrorDesc());
Log->Write("ERROR: \tGetTrainType could not parse the project file");
return ret;
}
TiXmlNode* xMainNode = doc.RootElement();
string tttfile = "";
if (xMainNode->FirstChild("train_constraints")) {
auto xFileNode = xMainNode->FirstChild("train_constraints")->FirstChild("train_types");
if(xFileNode)
ret = xFileNode->FirstChild()->ValueStr();
Log->Write("INFO: \ttrain_types <" + ret + ">");
} else {
Log->Write("INFO: \tNo events no train types file found");
return ret;
}
return ret;
}
std::string getGoalFileName(const std::string & GetProjectFile) std::string getGoalFileName(const std::string & GetProjectFile)
{ {
std::string ret=""; std::string ret="";
...@@ -411,6 +464,8 @@ void TrajectoriesFLAT::WriteHeader(long nPeds, double fps, Building* building, i ...@@ -411,6 +464,8 @@ void TrajectoriesFLAT::WriteHeader(long nPeds, double fps, Building* building, i
std::string sourceFileName = getSourceFileName(building->GetProjectFilename()); std::string sourceFileName = getSourceFileName(building->GetProjectFilename());
std::string goalFileName = getGoalFileName(building->GetProjectFilename()); std::string goalFileName = getGoalFileName(building->GetProjectFilename());
std::string eventFileName = getEventFileName(building->GetProjectFilename()); std::string eventFileName = getEventFileName(building->GetProjectFilename());
std::string trainTimeTableFileName = getTrainTimeTableFileName(building->GetProjectFilename());
std::string trainTypeFileName = getTrainTypeFileName(building->GetProjectFilename());
(void) seed; (void) nPeds; (void) seed; (void) nPeds;
char tmp[100] = ""; char tmp[100] = "";
sprintf(tmp, "#description: jpscore (%s)", JPSCORE_VERSION); sprintf(tmp, "#description: jpscore (%s)", JPSCORE_VERSION);
...@@ -436,6 +491,16 @@ void TrajectoriesFLAT::WriteHeader(long nPeds, double fps, Building* building, i ...@@ -436,6 +491,16 @@ void TrajectoriesFLAT::WriteHeader(long nPeds, double fps, Building* building, i
sprintf(tmp,"#events: %s", eventFileName.c_str()); sprintf(tmp,"#events: %s", eventFileName.c_str());
Write(tmp); Write(tmp);
} }
if( trainTimeTableFileName != "")
{
sprintf(tmp,"#trainTimeTable: %s", trainTimeTableFileName.c_str());
Write(tmp);
}
if( trainTypeFileName != "")
{
sprintf(tmp,"#trainType: %s", trainTypeFileName.c_str());
Write(tmp);
}
Write("#ID: the agent ID"); Write("#ID: the agent ID");
Write("#FR: the current frame"); Write("#FR: the current frame");
Write("#X,Y,Z: the agents coordinates (in metres)"); Write("#X,Y,Z: the agents coordinates (in metres)");
......
...@@ -1635,6 +1635,9 @@ bool IniFileParser::ParseStrategyNodeToObject(const TiXmlNode& strategyNode) ...@@ -1635,6 +1635,9 @@ bool IniFileParser::ParseStrategyNodeToObject(const TiXmlNode& strategyNode)
}; };
_config->set_dirStrategy(dynamic_cast<DirectionSubLocalFloorfieldTripsVoronoi*>(_exit_strategy.get())); _config->set_dirStrategy(dynamic_cast<DirectionSubLocalFloorfieldTripsVoronoi*>(_exit_strategy.get()));
break; break;
case 12:
_exit_strategy = std::shared_ptr<DirectionStrategy>(new DirectionTrain());
break;
default: default:
_exit_strategy = std::shared_ptr<DirectionStrategy>(new DirectionMinSeperationShorterLine()); _exit_strategy = std::shared_ptr<DirectionStrategy>(new DirectionMinSeperationShorterLine());
......
This diff is collapsed.
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
#include "events/EventManager.h" #include "events/EventManager.h"
#include "pedestrian/AgentsSourcesManager.h" #include "pedestrian/AgentsSourcesManager.h"
#include "general/Configuration.h" #include "general/Configuration.h"
#include <filesystem>
//Forward declarations //Forward declarations
//class AgentsSourcesManager; //class AgentsSourcesManager;
...@@ -88,6 +91,8 @@ private: ...@@ -88,6 +91,8 @@ private:
int _maxSimTime; int _maxSimTime;
bool _gotSources; // is true if we got some sources. Otherwise, false. bool _gotSources; // is true if we got some sources. Otherwise, false.
bool _trainConstraints; // true if inifile has some train constraints
// bool _printPB; // print progressbar // bool _printPB; // print progressbar
public: public:
/** /**
...@@ -185,6 +190,11 @@ public: ...@@ -185,6 +190,11 @@ public:
*/ */
void UpdateDoorticks() const; void UpdateDoorticks() const;
int GetMaxSimTime() const; int GetMaxSimTime() const;
void incrementCountTraj();
bool correctGeometry(std::shared_ptr<Building> building, std::shared_ptr<TrainTimeTable>);
bool WriteTrajectories(std::string trajName);
bool TrainTraffic();
int _countTraj=0; // count number of TXT trajectories to produce int _countTraj=0; // count number of TXT trajectories to produce
double _maxFileSize; // in MB double _maxFileSize; // in MB
......
This diff is collapsed.
...@@ -45,6 +45,43 @@ ...@@ -45,6 +45,43 @@
#include "Goal.h" #include "Goal.h"
#include "../general/Configuration.h" #include "../general/Configuration.h"
typedef std::pair<Point, Wall> PointWall;
// train schedules: Trains get deleted and added.
struct Platform
{
int id;
int rid;
int sid;
std::map<int, std::vector<Wall> > tracks;
};
struct TrainTimeTable
{
int id;
std::string type;
int rid; // room id
int sid; // subroom id
double tin; // arrival time
double tout; //leaving time
Point pstart; // track start
Point pend; // track end
Point tstart; // train start
Point tend; // train end
int pid; // Platform id
bool arrival;
bool departure;
};
struct TrainType
{
std::string type;
int nmax; // agents_max
float len; //length
std::vector<Transition> doors;
};
class RoutingEngine; class RoutingEngine;
class Pedestrian; class Pedestrian;
...@@ -74,8 +111,9 @@ private: ...@@ -74,8 +111,9 @@ private:
std::map<int, Transition*> _transitions; std::map<int, Transition*> _transitions;
std::map<int, Hline*> _hLines; std::map<int, Hline*> _hLines;
std::map<int, Goal*> _goals; std::map<int, Goal*> _goals;
std::map<int, std::vector<WaitingArea*>> _sr2wa; std::map<std::string, std::shared_ptr<TrainType> > _trainTypes;
std::map<int, std::shared_ptr<TrainTimeTable> > _trainTimeTables;
std::map<int, std::shared_ptr<Platform> > _platforms;
/// pedestrians pathway /// pedestrians pathway
bool _savePathway; bool _savePathway;
std::ofstream _pathWayStream; std::ofstream _pathWayStream;
...@@ -83,10 +121,13 @@ private: ...@@ -83,10 +121,13 @@ private:
public: public:
/// constructor /// constructor
Building(); Building();
std::map<int, std::vector<Wall> > TempAddedWalls; // map to trainTimeTable
std::map<int, std::vector<Wall> > TempRemovedWalls;
std::map<int, std::vector<Transition> > TempAddedDoors;
// Building(const std::string &, const std::string &, RoutingEngine &, PedDistributor &, double); // Building(const std::string &, const std::string &, RoutingEngine &, PedDistributor &, double);
Building(Configuration* config, PedDistributor& pedDistributor); Building(Configuration* config, PedDistributor& pedDistributor);
bool resetGeometry(std::shared_ptr<TrainTimeTable> tab);
/// destructor /// destructor
virtual ~Building(); virtual ~Building();
...@@ -176,7 +217,7 @@ public: ...@@ -176,7 +217,7 @@ public:
*/ */
Transition* GetTransitionByUID(int uid) const; Transition* GetTransitionByUID(int uid) const;
Crossing* GetCrossingByUID(int uid) const; Crossing* GetCrossingByUID(int uid) const;
//TOD0: rename later to GetGoal //TOD0: rename later to GetGoal
Goal* GetFinalGoal(int id) const; Goal* GetFinalGoal(int id) const;
...@@ -208,15 +249,33 @@ public: ...@@ -208,15 +249,33 @@ public:
const std::map<int, Hline*>& GetAllHlines() const; const std::map<int, Hline*>& GetAllHlines() const;
const std::map<int, Goal*>& GetAllGoals() const; const std::map<int, Goal*>& GetAllGoals() const;
// --------------- Trains interface
const std::map<std::string, std::shared_ptr<TrainType> >& GetTrainTypes() const;
const std::map<int, std::shared_ptr<TrainTimeTable> >& GetTrainTimeTables() const;
const std::map<int, std::shared_ptr<Platform> >& GetPlatforms() const;
const std::vector<Wall> GetTrackWalls(Point TrackStart, Point TrackEnd, int & room_id, int & subroom_id) const;
const std::vector<std::pair<PointWall, PointWall > > GetIntersectionPoints(const std::vector<Transition> doors, const std::vector<Wall>) const;
// ------------------------------------
bool AddCrossing(Crossing* line); bool AddCrossing(Crossing* line);
bool RemoveTransition(Transition * line);
bool AddTransition(Transition* line); bool AddTransition(Transition* line);
bool AddHline(Hline* line); bool AddHline(Hline* line);
bool AddGoal(Goal* goal);