diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 3630a0ebea41defbd5ffcacd33235340099ae3cf..bbe41520fe29a61cac45fe516769f63643ef5e3e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -424,8 +424,7 @@ FacilityGeometry* MainWindow::parseGeometry(QDomNode geoNode){ { if (fileName.endsWith(".xml",Qt::CaseInsensitive)) { - //cout<<"good bye"<<endl; exit(0); - //SaxParser::parseGeometryPG3(fileName,geometry); + SaxParser::parseGeometryJPS(fileName,geometry); } else if (fileName.endsWith(".trav",Qt::CaseInsensitive)) { @@ -563,22 +562,44 @@ bool MainWindow::addPedestrianGroup(int groupID,QString fileName) SystemSettings::setWorkingDirectory(wd); //the geometry actor - //FacilityGeometry* geometry=NULL; FacilityGeometry* geometry = visualisationThread->getGeometry(); + //try to get a geometry filename + QString geometry_file=SaxParser::extractGeometryFilename(fileName); + + //cout<<"geometry NaMe: "<<geometry_file.toStdString()<<endl; + // if xml is detected, just load and show the geometry then exit - if(fileName.endsWith(".xml",Qt::CaseInsensitive)){ + if(geometry_file.endsWith(".xml",Qt::CaseInsensitive)){ //try to parse the correct way // fall back to this if it fails - //SaxParser::parseGeometryJPS(fileInfo.baseName(),geometry); + SystemSettings::CreateLogfile(); + + if(! SaxParser::parseGeometryJPS(geometry_file,geometry)) + { + int res = QMessageBox::warning(this, "Errors in Geometry. Continue Parsing?", + "JuPedSim has detected an error in the supplied geometry.\n" + "The simulation will likely failed using that geometry.\n" + "Also make sure to validate your file.\n" + "More information are provided in the log file:\n" + +SystemSettings::getLogfile()+ + "\n\nShould I try to parse and display what I can ?" + , QMessageBox::Yes + | QMessageBox::No, QMessageBox::No); + if (res == QMessageBox::No) { + return false; + } + SaxParser::parseGeometryXMLV04(wd+"/"+geometry_file,geometry); + } + else + { //everything was fine. Delete the log file + SystemSettings::DeleteLogfile(); + } - SaxParser::parseGeometryXMLV04(fileName,geometry); + //SaxParser::parseGeometryXMLV04(fileName,geometry); //slotLoadParseShowGeometry(fileName); //return false; - //cout<<"here:"<<endl; - //cout<<"group:"<<groupID<<endl; - //exit(0); } QFile file(fileName); diff --git a/src/SaxParser.cpp b/src/SaxParser.cpp index adc694c8d1b1359c84e992ff5c8a258bc1dd1288..4c946b7aead7f140deb8c64477f75a1e1faeb067 100644 --- a/src/SaxParser.cpp +++ b/src/SaxParser.cpp @@ -111,7 +111,7 @@ bool SaxParser::startElement(const QString & /* namespaceURI */, { if(fileName.endsWith(".xml",Qt::CaseInsensitive)) { - SaxParser::parseGeometryJPS(fileName,geometry); + //SaxParser::parseGeometryJPS(fileName,geometry); } else if (fileName.endsWith(".trav",Qt::CaseInsensitive)) { @@ -658,32 +658,33 @@ void SaxParser::clearPoints(){ /// provided for convenience and will be removed in the next version -void SaxParser::parseGeometryJPS(QString fileName, FacilityGeometry *geometry){ +bool SaxParser::parseGeometryJPS(QString fileName, FacilityGeometry *geometry) +{ double captionsColor=0;//red - - if(!fileName.endsWith(".xml",Qt::CaseInsensitive)) return ; - + if(!fileName.endsWith(".xml",Qt::CaseInsensitive)) return false; QString wd; SystemSettings::getWorkingDirectory(wd); fileName=wd+"/"+fileName; - Building* building = new Building(); + Building* building = new Building(); string geometrypath = fileName.toStdString(); - // read the geometry - building->LoadBuildingFromFile(geometrypath); - building->InitGeometry(); // create the polygons + // read the geometry + if(!building->LoadBuildingFromFile(geometrypath)) + return false; + if(!building->InitGeometry()) + return false; // create the polygons - int currentID=0; - // Setup the points + int currentID=0; + // Setup the points VTK_CREATE(vtkPoints,points); - // Add the polygon to a list of polygons + // Add the polygon to a list of polygons VTK_CREATE(vtkCellArray,polygons); for (int i = 0; i < building->GetNumberOfRooms(); i++) { - Room* r = building->GetRoom(i); + Room* r = building->GetRoom(i); //string caption = r->GetCaption(); for (int k = 0; k < r->GetNumberOfSubRooms(); k++) @@ -751,12 +752,12 @@ void SaxParser::parseGeometryJPS(QString fileName, FacilityGeometry *geometry){ geometry->addObjectLabel(pos,pos,obst->GetCaption(),captionsColor); } } - } + } // Create a PolyData to represent the floor VTK_CREATE(vtkPolyData, polygonPolyData); polygonPolyData->SetPoints(points); - polygonPolyData->SetPolys(polygons); + polygonPolyData->SetPolys(polygons); geometry->addFloor(polygonPolyData); @@ -793,9 +794,10 @@ void SaxParser::parseGeometryJPS(QString fileName, FacilityGeometry *geometry){ } //TODO:dirty hack for parsing the Hlines + // free memory + delete building; - // free memory - delete building; + return true; } @@ -988,7 +990,58 @@ void SaxParser::parseGeometryTRAV(QString content, FacilityGeometry *geometry,QD } // you should normally have only one geometry node, but one never knows... geoNode = geoNode.nextSiblingElement("geometry"); - } + } +} + +QString SaxParser::extractGeometryFilename(QString &filename) +{ + QString extracted_geo_name=""; + //first try to look at a string <file location="filename.xml"/> + QFile file(filename); + QString line; + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QTextStream in(&file); + while (!in.atEnd()) { + //look for a line with + line = in.readLine(); + if(line.contains("location" ,Qt::CaseInsensitive)) + if(line.contains("<file" ,Qt::CaseInsensitive)) + {//try to extract what ever is inside the quotes + + QString begin="\""; + QString end="\""; + int startIndex = line.indexOf(begin)+begin.length(); + if(startIndex <= 0)continue; //false alarm + int endIndex = line.indexOf(end,startIndex); + if(endIndex <= 0)continue; // false alarm + extracted_geo_name= line.mid(startIndex,endIndex - startIndex); + return extracted_geo_name; + //cout<<"geoName:"<<extracted_geo_name.toStdString()<<endl; + //break;// we are done + } + if(line.contains("<geometry" ,Qt::CaseInsensitive)) + if(!line.contains("version" ,Qt::CaseInsensitive)) + {//old format + return ""; + } + } + } + + //maybe this is already the geometry file itself ? + //do a rapid test + FacilityGeometry* geo = new FacilityGeometry(); + QFileInfo fileInfoGeometry(filename); + extracted_geo_name=fileInfoGeometry.fileName(); + + //just check if it starts with geometry + //if(parseGeometryJPS(extracted_geo_name,geo)==true) + //{ + return extracted_geo_name; + //} + delete geo; + + return ""; } @@ -1001,11 +1054,12 @@ void SaxParser::parseGeometryXMLV04(QString filename, FacilityGeometry *geo) int size =file.size()/(1024*1024); //avoid dom parsing a very large dataset - if(size>100){ + if(size>500){ //cout<<"The file is too large: "<<filename.toStdString()<<endl; return; } + //cout<<"filename: "<<filename.toStdString()<<endl; //TODO: check if you can parse this with the building classes. // This should be a fall back option diff --git a/src/SaxParser.h b/src/SaxParser.h index 382bec30453a79fe004d1954f348b9aca516c7a4..faaa1f94c11775fb6d27f448ebbf84a587273c12 100644 --- a/src/SaxParser.h +++ b/src/SaxParser.h @@ -65,7 +65,7 @@ public: const QString& value); /// provided for convenience and will be removed in the next version - static void parseGeometryJPS(QString content, FacilityGeometry *geo); + static bool parseGeometryJPS(QString content, FacilityGeometry *geo); /// provided for convenience and will be removed in the next version static void parseGeometryXMLV04(QString content, FacilityGeometry *geo); @@ -73,6 +73,9 @@ public: /// provided for convenience and will be removed in the next version static void parseGeometryTRAV(QString content, FacilityGeometry *geo,QDomNode geoNode=QDomNode()); + /// take a large file and find the geometry file location. + static QString extractGeometryFilename(QString& filename); + private: //clear the mo void clearPoints(); @@ -87,7 +90,6 @@ private: QStringList initialPedestriansHeights; std::vector<JPoint *> currentPointsList; std::vector<FrameElement *> currentFrame; - //std::vector<TrajectoryPoint *> currentFrame; bool parsingWalls; bool parsingCrossings; diff --git a/src/SystemSettings.cpp b/src/SystemSettings.cpp index 8e69f3f90707e5534712622c989af00d59b3f3e9..8cbd50756b66875e835f123121a2df6ce5058099 100644 --- a/src/SystemSettings.cpp +++ b/src/SystemSettings.cpp @@ -36,6 +36,9 @@ #include "SystemSettings.h" #include "Debug.h" +#include "qdebug.h" +#include "QDateTime" +#include "IO/OutputHandler.h" #include "./forms/Settings.h" bool SystemSettings::showLegend=false; @@ -66,7 +69,10 @@ bool SystemSettings::recordPNGsequence=false; QString SystemSettings::outputDir = QDir::homePath() +"/Desktop/TraVisTo_Files/"; QString SystemSettings::workingDir = QDir::currentPath(); QString SystemSettings::filesPrefix=""; +QString SystemSettings::logfile="log.txt"; +//the log file is writting by a different module +extern OutputHandler* Log; SystemSettings::SystemSettings() {} @@ -218,15 +224,12 @@ void SystemSettings::getPedestrianColor(int groupID, int color[3]){ void SystemSettings::setOutputDirectory(QString dir){ outputDir=dir; } + void SystemSettings::getOutputDirectory(QString& dir){ dir=QString(outputDir); } -//void SystemSettings::setPedestrianCaptionSize( int size){ -// captionSize =size; -//} - int SystemSettings::getPedestrianCaptionSize(){ return captionSize; } @@ -243,7 +246,35 @@ void SystemSettings::setFilenamePrefix(QString prefix){ } QString SystemSettings::getFilenamePrefix() { - return filesPrefix; + return filesPrefix; +} + +void SystemSettings::CreateLogfile() +{ + //create directory if not exits + if(!QDir(outputDir).exists()){ + QDir dir; + if(!dir.mkpath (outputDir )){ + qDebug()<<"could not create directory: "<< outputDir; + outputDir=""; // current + } + } + + logfile = outputDir+"log_"+QDateTime::currentDateTime().toString("yyMMdd_hh_mm_").append(SystemSettings::getFilenamePrefix()).append(".txt"); +} + + QString &SystemSettings::getLogfile() +{ + return logfile; +} + +void SystemSettings::DeleteLogfile() +{ + //first close the opened file + delete Log; + if(! QFile::remove(logfile)){ + qDebug()<<"he log file could not delete the file"<<endl; + } } void SystemSettings::setPedestrianColorProfileFromFile(bool readFromFile) { diff --git a/src/SystemSettings.h b/src/SystemSettings.h index df2e8e384c5ef4ce1e795f17686a4824f7e3ebb4..54327419cd3f36e9dc44990223e1da80ef1e48e2 100644 --- a/src/SystemSettings.h +++ b/src/SystemSettings.h @@ -153,6 +153,10 @@ public: /// This is just the name of the input file. static QString getFilenamePrefix(); + static void CreateLogfile(); + static QString &getLogfile(); + static void DeleteLogfile(); + private: static bool recordPNGsequence; @@ -174,6 +178,7 @@ private: static int trailingGeometry; static QString outputDir; static QString workingDir; + static QString logfile; static int captionSize; static QColor captionColor; static int captionOrientaton; diff --git a/src/geometry/Building.cpp b/src/geometry/Building.cpp index b8e7a8476021379edd16e5adceb01fed7ec1b604..6039ed264ff9effaf46fab620259863004c19da5 100644 --- a/src/geometry/Building.cpp +++ b/src/geometry/Building.cpp @@ -28,6 +28,10 @@ #include "Building.h" #include "../tinyxml/tinyxml.h" +//qt stuff +#include <QString> +#include "../SystemSettings.h" + #ifdef _SIMULATOR #include "../pedestrian/Pedestrian.h" #include "../mpi/LCGrid.h" @@ -43,7 +47,8 @@ #define omp_get_max_threads() 1 #endif -OutputHandler* Log = new STDIOHandler();; +//OutputHandler* Log = new STDIOHandler(); +OutputHandler* Log = NULL; using namespace std; @@ -58,6 +63,7 @@ Building::Building() { _routingEngine = NULL; _linkedCellGrid = NULL; _savePathway = false; + Log = new FileHandler(SystemSettings::getLogfile().toStdString().c_str()); } @@ -238,7 +244,7 @@ void Building::AddSurroundingRoom() { } -void Building::InitGeometry() { +bool Building::InitGeometry() { Log->Write("INFO: \tInit Geometry"); for (int i = 0; i < GetNumberOfRooms(); i++) { Room* room = GetRoom(i); @@ -262,7 +268,8 @@ void Building::InitGeometry() { } // initialize the poly - s->ConvertLineToPoly(goals); + if(!s->ConvertLineToPoly(goals)) + return false; s->CalculateArea(); goals.clear(); @@ -270,11 +277,13 @@ void Building::InitGeometry() { const vector<Obstacle*>& obstacles = s->GetAllObstacles(); for (unsigned int obs = 0; obs < obstacles.size(); ++obs) { if (obstacles[obs]->GetClosed() == 1) - obstacles[obs]->ConvertLineToPoly(); + if(!obstacles[obs]->ConvertLineToPoly()) + return false; } } } Log->Write("INFO: \tInit Geometry successful!!!\n"); + return true; } @@ -297,7 +306,7 @@ const string& Building::GetProjectRootDir() const{ } -void Building::LoadBuildingFromFile(const std::string &filename) { +bool Building::LoadBuildingFromFile(const std::string &filename) { //get the geometry filename from the project file if none was supplied string geoFilename=filename; @@ -306,7 +315,7 @@ void Building::LoadBuildingFromFile(const std::string &filename) { if (!doc.LoadFile()){ Log->Write("ERROR: \t%s", doc.ErrorDesc()); Log->Write("ERROR: \t could not parse the project file"); - exit(EXIT_FAILURE); + return false; } Log->Write("INFO: \tParsing the geometry file"); @@ -323,30 +332,30 @@ void Building::LoadBuildingFromFile(const std::string &filename) { if (!docGeo.LoadFile()){ Log->Write("ERROR: \t%s", docGeo.ErrorDesc()); Log->Write("ERROR: \t could not parse the geometry file [%s]",geoFilename.c_str()); - exit(EXIT_FAILURE); + return false; } TiXmlElement* xRootNode = docGeo.RootElement(); if( ! xRootNode ) { Log->Write("ERROR:\tRoot element does not exist"); - exit(EXIT_FAILURE); + return false; } if( xRootNode->ValueStr () != "geometry" ) { Log->Write("ERROR:\tRoot element value is not 'geometry'."); - exit(EXIT_FAILURE); + return false; } if(string(xRootNode->Attribute("unit"))!="m") { Log->Write("ERROR:\tOnly the unit m (metres) is supported. \n\tYou supplied [%s]",xRootNode->Attribute("unit")); - exit(EXIT_FAILURE); + return false; } double version = xmltof(xRootNode->Attribute("version"), -1); if (version < 0.4) { Log->Write("ERROR: \tOnly version > 0.4 supported. Your version is %f",version); Log->Write("ERROR: \tparsing geometry file failed!"); - exit(EXIT_FAILURE); + return false; } _caption = xmltoa(xRootNode->Attribute("caption"), "virtual building"); @@ -359,7 +368,7 @@ void Building::LoadBuildingFromFile(const std::string &filename) { TiXmlNode* xRoomsNode = xRootNode->FirstChild("rooms"); if (!xRoomsNode){ Log->Write("ERROR: \tThe geometry should have at least one room and one subroom"); - exit(EXIT_FAILURE); + return false; } for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom; diff --git a/src/geometry/Building.h b/src/geometry/Building.h index ba40c002407cf850e8e6bc4ad3ededc1080b6e58..514f48618603c97180a06bf27cbeec03a5e9e93d 100644 --- a/src/geometry/Building.h +++ b/src/geometry/Building.h @@ -148,7 +148,7 @@ public: LCGrid* GetGrid() const; // Sonstiges - void InitGeometry(); + bool InitGeometry(); void InitGrid(double cellSize); //void InitRoomsAndSubroomsMap(); void InitPhiAllPeds(double pDt); // initialize the direction of the ellipses @@ -174,7 +174,7 @@ public: const std::string& GetProjectFilename() const; void SetProjectFilename(const std::string &filename) ; void SetProjectRootDir(const std::string &filename); - void LoadBuildingFromFile(const std::string &filename=""); + bool LoadBuildingFromFile(const std::string &filename=""); void LoadTrafficInfo(); void LoadRoutingInfo(const std::string &filename); void WriteToErrorLog() const; diff --git a/src/geometry/Obstacle.cpp b/src/geometry/Obstacle.cpp index 89eecf0c0861ce881c9f177843d9599edc26d12f..f36458d18613631538dc4917f6b98a2e66920f47 100644 --- a/src/geometry/Obstacle.cpp +++ b/src/geometry/Obstacle.cpp @@ -193,13 +193,13 @@ bool Obstacle::Contains(const Point& ped) const { return false; } -void Obstacle::ConvertLineToPoly() { +bool Obstacle::ConvertLineToPoly() { if(_isClosed==0.0){ char tmp[CLENGTH]; sprintf(tmp, "INFO: \tObstacle [%d] is not closed. Not converting to polyline.\n", _id); Log->Write(tmp); - return; + return true; } vector<Line*> copy; vector<Point> tmpPoly; @@ -235,9 +235,10 @@ void Obstacle::ConvertLineToPoly() { char tmp[CLENGTH]; sprintf(tmp, "ERROR: \tObstacle::ConvertLineToPoly(): ID %d !!!\n", _id); Log->Write(tmp); - exit(0); + return false; } _poly = tmpPoly; + return true; } const Point Obstacle::GetCentroid() const{ diff --git a/src/geometry/Obstacle.h b/src/geometry/Obstacle.h index 79d3ed2c74946927865b0de849ef4804168ab4e5..6456bd22cc43a29458ff85bf0ba086ed6c60b032 100644 --- a/src/geometry/Obstacle.h +++ b/src/geometry/Obstacle.h @@ -111,7 +111,7 @@ public: /** * Create the obstacles polygonal structure from the walls */ - void ConvertLineToPoly(); + bool ConvertLineToPoly(); /** * @return the obstacle as a polygon diff --git a/src/geometry/SubRoom.cpp b/src/geometry/SubRoom.cpp index e0868cdc73453984f1fa41b048cb73dac0d41442..cab0d05a920c9375cfd11398d458c3f6412f3817 100644 --- a/src/geometry/SubRoom.cpp +++ b/src/geometry/SubRoom.cpp @@ -594,7 +594,7 @@ void NormalSubRoom::WriteToErrorLog() const { } } -void NormalSubRoom::ConvertLineToPoly(vector<Line*> goals) { +bool NormalSubRoom::ConvertLineToPoly(vector<Line*> goals) { vector<Line*> copy; vector<Point> tmpPoly; Point point; @@ -635,9 +635,10 @@ void NormalSubRoom::ConvertLineToPoly(vector<Line*> goals) { Log->Write(tmp); sprintf(tmp, "ERROR: \tDistance between the points: %lf !!!\n", (tmpPoly[0] - point).Norm()); Log->Write(tmp); - exit(EXIT_FAILURE); + return false; } _poly = tmpPoly; + return true; } @@ -830,7 +831,7 @@ const Point* Stair::CheckCorner(const Point** otherPoint, const Point** aktPoint return rueck; } -void Stair::ConvertLineToPoly(vector<Line*> goals) { +bool Stair::ConvertLineToPoly(vector<Line*> goals) { //return NormalSubRoom::ConvertLineToPoly(goals); @@ -887,7 +888,7 @@ void Stair::ConvertLineToPoly(vector<Line*> goals) { sprintf(tmp, "ERROR: \tStair::ConvertLineToPoly(): SubRoom %d Room %d Anfangspunkt ungleich Endpunkt!!!\n" "\t(%f, %f) != (%f, %f)\n", GetSubRoomID(), GetRoomID(), x1, y1, x2, y2); Log->Write(tmp); - exit(EXIT_FAILURE); + return false; } if (orgPoly.size() != 4) { @@ -895,7 +896,7 @@ void Stair::ConvertLineToPoly(vector<Line*> goals) { sprintf(tmp, "ERROR: \tStair::ConvertLineToPoly(): Stair %d Room %d ist kein Viereck!!!\n" "Anzahl Ecken: %d\n", GetSubRoomID(), GetRoomID(), orgPoly.size()); Log->Write(tmp); - exit(EXIT_FAILURE); + return false; } vector<Point> neuPoly = (orgPoly); // ganz kleine Treppen (nur eine Stufe) nicht @@ -920,6 +921,7 @@ void Stair::ConvertLineToPoly(vector<Line*> goals) { } } _poly = neuPoly; + return true; } bool Stair::IsInSubRoom(const Point& ped) const { diff --git a/src/geometry/SubRoom.h b/src/geometry/SubRoom.h index 5fc028546cc38131f328cbf5a53539700dba6b78..a73b90209630f80646caca43d7fd5a644b4923cb 100644 --- a/src/geometry/SubRoom.h +++ b/src/geometry/SubRoom.h @@ -307,7 +307,7 @@ public: virtual std::string WritePolyLine() const=0; /// convert all walls and transitions(doors) into a polygon representing the subroom - virtual void ConvertLineToPoly(std::vector<Line*> goals) = 0; + virtual bool ConvertLineToPoly(std::vector<Line*> goals) = 0; ///check whether the pedestrians is still in the subroom virtual bool IsInSubRoom(const Point& ped) const = 0; @@ -352,8 +352,8 @@ public: std::string WriteSubRoom() const; std::string WritePolyLine() const; - void WriteToErrorLog() const; - void ConvertLineToPoly(std::vector<Line*> goals); + virtual void WriteToErrorLog() const; + virtual bool ConvertLineToPoly(std::vector<Line*> goals); bool IsInSubRoom(const Point& ped) const; }; @@ -388,7 +388,7 @@ public: std::string WriteSubRoom() const; std::string WritePolyLine() const; virtual void WriteToErrorLog() const; - virtual void ConvertLineToPoly(std::vector<Line*> goals); + virtual bool ConvertLineToPoly(std::vector<Line*> goals); bool IsInSubRoom(const Point& ped) const; };