./0000755000175000017500000000000013402370651010630 5ustar wookeywookey./main.cpp0000644000175000017500000000253312760157616012275 0ustar wookeywookey//Qt includes #include #include #include #include //Our includes #include #include int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QStringList args = a.arguments(); if(args.isEmpty() || args.size() != 3) { qDebug() << "How to run: \n./plotsauce [Input File (survex .3d)] [Output XML file] "; return 1; } QList stations; QList lines; QString inputFilename = args[1]; //.first(); QString outputFilename = args[2]; QFileInfo fileinfo(inputFilename); if(fileinfo.exists()) { if(fileinfo.suffix().compare("3d", Qt::CaseInsensitive) == 0) { //We found a survex file psSurvex3DParser survexParser; survexParser.parse(inputFilename); stations = survexParser.stations(); lines = survexParser.lines(); } else { qDebug() << "Plot sauces doesn't know how to handle " << fileinfo.suffix() << "files"; return 1; } } else { qDebug() << inputFilename << "doesn't exist!"; return 1; } //Write data to the file psXMLWriter writer; writer.setLines(lines); writer.setStations(stations); writer.write(outputFilename); return 0; } ./plotsauce.qbs0000644000175000017500000000120012760157616013341 0ustar wookeywookeyimport qbs 1.0 CppApplication { name: "plotsauce" type: "application" consoleApplication: true Depends { name: "Qt"; submodules: ["core", "xml", "gui"] } Depends { name: "cavern-3dReader" } Depends { name: "z" } cpp.cxxLanguageVersion: (Qt.core.versionMajor >= 5 && Qt.core.versionMinor >= 7 ? "c++11" : "c++98"); cpp.includePaths: ["src"] Group { fileTagsFilter: ["application"] qbs.install: true qbs.installDir: project.installDir } files: [ "main.cpp", "src/*.cpp", "src/*.h" //"src/survex/*.c", //"src/survex/*.h" ] } ./src/0000755000175000017500000000000012760157616011431 5ustar wookeywookey./src/psStationLookup.cpp0000644000175000017500000000264112760157616015316 0ustar wookeywookey//Our includes #include "psStationLookup.h" #include "psStation.h" //Qt includes #include psStationLookup::psStationLookup() { } /** This will find the station by it's position */ psStation* psStationLookup::findStation(QVector3D position) { QList stations = XLookup.values(position.x()); foreach(psStation* currentStation, stations) { if(currentStation->position() == position) { return currentStation; } } return NULL; } /** This will find the station by it's name */ psStation* psStationLookup::findStation(QString fullStationName) { return NameLookup.value(fullStationName, NULL); } /** \brief Gets all stations from the lookup */ QList psStationLookup::allStations() { if(XLookup.size() != NameLookup.size()) { qDebug() << "The xLookup doesn't equal the nameLookup" << XLookup.size() << NameLookup.size(); } return NameLookup.values(); } /** \brief Adds a station to the lookup This will not add the station twice into the lookup */ void psStationLookup::addStation(psStation* station) { psStation* positionLookup = findStation(station->position()); psStation* nameLookup = findStation(station->name()); if(positionLookup == NULL) { XLookup.insertMulti(station->position().x(), station); } if(nameLookup == NULL) { NameLookup.insert(station->name(), station); } } ./src/psSurvex3DParser.h0000644000175000017500000000113512760157616015005 0ustar wookeywookey#ifndef PSSURVEX3DPARSER_H #define PSSURVEX3DPARSER_H //Our includes class psStation; class psLine; //Qt includes #include #include #include class psSurvex3DParser { public: psSurvex3DParser(); void parse(QString filename); QList lines() const; QList stations() const; private: QList Lines; QList Stations; }; inline QList psSurvex3DParser::lines() const { return Lines; } inline QList psSurvex3DParser::stations() const { return Stations; } #endif // PSSURVEX3DPARSER_H ./src/psLine.h0000644000175000017500000000105112760157616013031 0ustar wookeywookey#ifndef PSLINE_H #define PSLINE_H //Our includes #include class psLine { public: psLine(); psLine(psStation* s1, psStation* s2); bool isValid(); psStation* station1(); psStation* station2(); private: psStation* Station1; psStation* Station2; }; /** Gets the first station that makes up the line */ inline psStation* psLine::station1() { return Station1; } /** Gets the second station that makes up the line */ inline psStation* psLine::station2() { return Station2; } #endif // PSLINE_H ./src/psXMLWriter.cpp0000644000175000017500000000773712760157616014353 0ustar wookeywookey#include "psXMLWriter.h" //Qt includes #include #include #include #include //Our includes #include #include //zlib includes #include psXMLWriter::psXMLWriter() { } /** \brief Writes the lines and station data to */ void psXMLWriter::write(QString outputFile) { Document.clear(); QDomElement root = Document.createElement("PlotSauceDocument"); Document.appendChild(root); QDomElement stationsNode = createXMLForStations(); QDomElement linesNode = createXMLForLines(); root.appendChild(stationsNode); root.appendChild(linesNode); QByteArray fullDocumentAsXML = Document.toByteArray(); gzFile zippedFile = gzopen(outputFile.toLocal8Bit(), "w"); //Write with level 9 huffman gzwrite(zippedFile, fullDocumentAsXML.constData(), fullDocumentAsXML.length()); gzclose(zippedFile); // QFile file(outputFile); // bool succes = file.open(QFile::WriteOnly); // if(succes) { // file.write(fullDocumentAsXML); // } else { // qDebug() << "Couldn't write xml to " << fullDocumentAsXML; // } } /** Creates the xml nodes for a station */ QDomElement psXMLWriter::createXMLForStations() { QDomElement rootStationNode = Document.createElement("Stations"); foreach(psStation* station, Stations) { QDomElement stationNode = createXMLForStation(station); rootStationNode.appendChild(stationNode); } return rootStationNode; } /** Creates the xml node for a single station */ QDomElement psXMLWriter::createXMLForStation(psStation* station) { QDomElement stationNode = Document.createElement("Station"); QDomElement uniqueIdNode = Document.createElement("Id"); QDomText idTextElement = Document.createTextNode(QString("%1").arg(station->id())); uniqueIdNode.appendChild(idTextElement); QDomElement nameNode = Document.createElement("Name"); QDomText nameTextElement = Document.createTextNode(station->name()); nameNode.appendChild(nameTextElement); QDomElement positionNode = Document.createElement("Position"); QVector3D position = station->position(); QDomElement xNode = Document.createElement("X"); QDomText xNodeValue = Document.createTextNode(QString("%1").arg(position.x())); xNode.appendChild(xNodeValue); QDomElement yNode = Document.createElement("Y"); QDomText yNodeValue = Document.createTextNode(QString("%1").arg(position.y())); yNode.appendChild(yNodeValue); QDomElement zNode = Document.createElement("Z"); QDomText zNodeValue = Document.createTextNode(QString("%1").arg(position.z())); zNode.appendChild(zNodeValue); positionNode.appendChild(xNode); positionNode.appendChild(yNode); positionNode.appendChild(zNode); stationNode.appendChild(uniqueIdNode); stationNode.appendChild(nameNode); stationNode.appendChild(positionNode); return stationNode; } /** Creates the xml node for all the lines */ QDomElement psXMLWriter::createXMLForLines() { QDomElement rootLineNode = Document.createElement("Lines"); foreach(psLine* line, Lines) { QDomElement lineNode = createXMLForLine(line); rootLineNode.appendChild(lineNode); } return rootLineNode; } /** Creates the xml node for a line */ QDomElement psXMLWriter::createXMLForLine(psLine* line) { QDomElement lineNode = Document.createElement("Line"); psStation* station1 = line->station1(); QDomElement station1Node = Document.createElement("Station1ID"); QDomText station1TextNode = Document.createTextNode(QString("%1").arg(station1->id())); station1Node.appendChild(station1TextNode); psStation* station2 = line->station2(); QDomElement station2Node = Document.createElement("Station2ID"); QDomText station2TextNode = Document.createTextNode(QString("%2").arg(station2->id())); station2Node.appendChild(station2TextNode); lineNode.appendChild(station1Node); lineNode.appendChild(station2Node); return lineNode; } ./src/psXMLWriter.h0000644000175000017500000000161512760157616014005 0ustar wookeywookey#ifndef PSXMLWRITER_H #define PSXMLWRITER_H //Qt includes #include #include //Our includes class psLine; class psStation; class psXMLWriter { public: psXMLWriter(); void setLines(QList lines); void setStations(QList stations); void write(QString outputFile); private: QList Lines; QList Stations; QDomDocument Document; QDomElement createXMLForStations(); QDomElement createXMLForStation(psStation* station); QDomElement createXMLForLines(); QDomElement createXMLForLine(psLine* line); }; /** \brief Set's the lines for the writer */ inline void psXMLWriter::setLines(QList lines) { Lines = lines; } /** \brief Set's the stations for the writer */ inline void psXMLWriter::setStations(QList stations) { Stations = stations; } #endif // PSXMLWRITER_H ./src/psStation.h0000644000175000017500000000137712760157616013576 0ustar wookeywookey#ifndef PSSTATION_H #define PSSTATION_H //Qt includes #include #include class psStation { public: psStation(); int id(); void setName(QString name); QString name() const; void setPosition(QVector3D position); QVector3D position() const; private: int Id; QString Name; QVector3D Position; static int LastId; static int GenerateNewId(); }; inline int psStation::id() { return Id; } inline void psStation::setName(QString name) { Name = name; } inline QString psStation::name() const { return Name; } inline void psStation::setPosition(QVector3D position) { Position = position; } inline QVector3D psStation::position() const { return Position; } #endif // PSSTATION_H ./src/psLine.cpp0000644000175000017500000000055412760157616013373 0ustar wookeywookey#include "psLine.h" psLine::psLine() : Station1(NULL), Station2(NULL) { } psLine::psLine(psStation* s1, psStation* s2) { Station1 = s1; Station2 = s2; } /** Checks to see if the psLine is valid */ bool psLine::isValid() { if(Station1 != Station2 && Station1 != NULL && Station2 != NULL) { return true; } return false; } ./src/psStation.cpp0000644000175000017500000000025612760157616014124 0ustar wookeywookey#include "psStation.h" int psStation::LastId = 0; psStation::psStation() { Id = GenerateNewId(); } int psStation::GenerateNewId() { LastId++; return LastId; } ./src/psStationLookup.h0000644000175000017500000000105012760157616014754 0ustar wookeywookey#ifndef PSSTATIONLOOKUP_H #define PSSTATIONLOOKUP_H //Our includes class psStation; //Qt includes #include #include #include class psStationLookup { public: psStationLookup(); psStation* findStation(QVector3D station); psStation* findStation(QString fullStationName); void addStation(psStation* station); QList allStations(); private: QMultiMap XLookup; //Lookup for just the x axis QMap NameLookup; }; #endif // PSSTATIONLOOKUP_H ./src/psSurvex3DParser.cpp0000644000175000017500000002525612760157616015352 0ustar wookeywookey//Our includes #include "psSurvex3DParser.h" #include "psStationLookup.h" #include "psStation.h" #include "psLine.h" //Survex includes #include //Qt includes #include #include //Std includes #include psSurvex3DParser::psSurvex3DParser() { } void psSurvex3DParser::parse(QString filename) { //Open the survey from the file img* survey = img_open_survey((const char*)filename.toLocal8Bit(), NULL); if(survey == NULL) { //Error couldn't open file qWarning() << "PlotSauce couldn't open " << filename; return; } float xmin = std::numeric_limits::max(); float xmax = -std::numeric_limits::max(); float ymin = std::numeric_limits::max(); float ymax = -std::numeric_limits::max(); float zmin = std::numeric_limits::max(); float zmax = -std::numeric_limits::max(); float depthmax = -std::numeric_limits::max(); int datemax = 0; int result; img_point prev_pt = {0,0,0}; bool current_polyline_is_surface = false; bool pending_move = false; // When a traverse is split between surface and underground, we split it // into contiguous traverses of each, but we need to track these so we can // assign the error statistics to all of them. So we keep counts of how // many surface_traverses and traverses we've generated for the current // traverse. size_t n_traverses = 0; size_t n_surface_traverses = 0; psStationLookup stationLookup; psStation* previousStation = NULL; psStation* currentStation = NULL; //Parse that bitch, copied straight out of maintrm.cc for aven do { img_point pt; result = img_read_item(survey, &pt); switch (result) { case img_MOVE: { //Get the current line QVector3D position(pt.x, pt.y, pt.z); currentStation = stationLookup.findStation(position); if(currentStation == NULL) { currentStation = new psStation(); currentStation->setPosition(position); stationLookup.addStation(currentStation); } QString stationName = QString::fromLocal8Bit(survey->label); n_traverses = n_surface_traverses = 0; pending_move = true; prev_pt = pt; previousStation = currentStation; break; } case img_LINE: { QVector3D position(pt.x, pt.y, pt.z); currentStation = stationLookup.findStation(position); if(currentStation == NULL) { currentStation = new psStation(); currentStation->setPosition(position); stationLookup.addStation(currentStation); } // Update survey extents. if (pt.x < xmin) xmin = pt.x; if (pt.x > xmax) xmax = pt.x; if (pt.y < ymin) ymin = pt.y; if (pt.y > ymax) ymax = pt.y; if (pt.z < zmin) zmin = pt.z; if (pt.z > zmax) zmax = pt.z; int date = survey->days1; if (date != -1) { date += (survey->days2 - date) / 2; //if (date < m_DateMin) m_DateMin = date; if (date > datemax) datemax = date; } else { //complete_dateinfo = false; } bool is_surface = (survey->flags & img_FLAG_SURFACE); if (!is_surface) { //if (pt.z < m_DepthMin) m_DepthMin = pt.z; if (pt.z > depthmax) depthmax = pt.z; } if (pending_move || current_polyline_is_surface != is_surface) { // if (!current_polyline_is_surface && current_traverse) { // //FixLRUD(*current_traverse); // } current_polyline_is_surface = is_surface; // Start new traverse (surface or underground). if (is_surface) { //m_HasSurfaceLegs = true; //surface_traverses.push_back(traverse()); //current_surface_traverse = &surface_traverses.back(); // ++n_surface_traverses; } else { // m_HasUndergroundLegs = true; // traverses.push_back(traverse()); // current_traverse = &traverses.back(); // ++n_traverses; // The previous point was at a surface->ug transition. // if (prev_pt.z < m_DepthMin) m_DepthMin = prev_pt.z; if (prev_pt.z > depthmax) depthmax = prev_pt.z; } if (pending_move) { // Update survey extents. We only need to do this if // there's a pending move, since for a surface <-> // underground transition, we'll already have handled // this point. if (prev_pt.x < xmin) xmin = prev_pt.x; if (prev_pt.x > xmax) xmax = prev_pt.x; if (prev_pt.y < ymin) ymin = prev_pt.y; if (prev_pt.y > ymax) ymax = prev_pt.y; if (prev_pt.z < zmin) zmin = prev_pt.z; if (prev_pt.z > zmax) zmax = prev_pt.z; } if (is_surface) { // current_surface_traverse->push_back(PointInfo(prev_pt)); } else { // current_traverse->push_back(PointInfo(prev_pt)); } } if (is_surface) { // current_surface_traverse->push_back(PointInfo(pt, date)); } else { // current_traverse->push_back(PointInfo(pt, date)); } //Create a line psLine* line = new psLine(previousStation, currentStation); Lines.append(line); previousStation = currentStation; prev_pt = pt; pending_move = false; break; } case img_LABEL: { // int flags = survey->flags; // if (flags & img_SFLAG_ENTRANCE) { // flags ^= (img_SFLAG_ENTRANCE | LFLAG_ENTRANCE); // } // LabelInfo* label = new LabelInfo(pt, wxString(survey->label, wxConvUTF8), flags); // if (label->IsEntrance()) { // m_NumEntrances++; // } // if (label->IsFixedPt()) { // m_NumFixedPts++; // } // if (label->IsExportedPt()) { // m_NumExportedPts++; // } // m_Labels.push_back(label); QVector3D position(pt.x, pt.y, pt.z); QString stationName = QString::fromLocal8Bit(survey->label); currentStation = stationLookup.findStation(stationName); if(currentStation == NULL) { currentStation = new psStation(); currentStation->setPosition(position); currentStation->setName(stationName); stationLookup.addStation(currentStation); } else { } break; } case img_XSECT: { // if (!current_tube) { // // Start new current_tube. // tubes.push_back(vector()); // current_tube = &tubes.back(); // } // // FIXME: avoid linear search... // list::const_iterator i = m_Labels.begin(); // wxString label(survey->label, wxConvUTF8); // while (i != m_Labels.end() && (*i)->GetText() != label) ++i; // if (i == m_Labels.end()) { // // Unattached cross-section - ignore for now. // printf("unattached cross-section\n"); // if (current_tube->size() == 1) // tubes.resize(tubes.size() - 1); // current_tube = NULL; // break; // } // int date = survey->days1; // if (date != -1) { // date += (survey->days2 - date) / 2; // if (date < m_DateMin) m_DateMin = date; // if (date > datemax) datemax = date; // } // current_tube->push_back(XSect(**i, date, survey->l, survey->r, survey->u, survey->d)); break; } case img_XSECT_END: // Finish off current_tube. // If there's only one cross-section in the tube, just // discard it for now. FIXME: we should handle this // when we come to skinning the tubes. // if (current_tube && current_tube->size() == 1) // tubes.resize(tubes.size() - 1); // current_tube = NULL; break; case img_ERROR_INFO: { if (survey->E == 0.0) { // Currently cavern doesn't spot all articulating traverses // so we assume that any traverse with no error isn't part // of a loop. FIXME: fix cavern! break; } // m_HasErrorInformation = true; // list::reverse_iterator t; // t = surface_traverses.rbegin(); // while (n_surface_traverses) { // assert(t != surface_traverses.rend()); // t->n_legs = survey->n_legs; // t->length = survey->length; // t->E = survey->E; // t->H = survey->H; // t->V = survey->V; // --n_surface_traverses; // ++t; // } // t = traverses.rbegin(); // while (n_traverses) { // assert(t != traverses.rend()); // t->n_legs = survey->n_legs; // t->length = survey->length; // t->E = survey->E; // t->H = survey->H; // t->V = survey->V; // --n_traverses; // ++t; // } break; } case img_BAD: { // m_Labels.clear(); // // FIXME: Do we need to reset all these? - Olly // m_NumFixedPts = 0; // m_NumExportedPts = 0; // m_NumEntrances = 0; // m_HasUndergroundLegs = false; // m_HasSurfaceLegs = false; // img_close(survey); // wxString m = wxString::Format(wmsg(img_error()), file.c_str()); // wxGetApp().ReportError(m); return; } default: break; } } while (result != img_STOP); Stations = stationLookup.allStations(); // //Finished // QList stations = stationLookup.allStations(); // foreach(psStation* station, stations) { // qDebug() << "Parsed station:" << station->name() << station->position(); // } }