diff --git a/src/LogCompressor.cc b/src/LogCompressor.cc index 5c21e2038e570bc94b892d15233a4e340dc2045a..d683abd4bda0cbbebe9dcc598ffa51a5bd6e3291 100644 --- a/src/LogCompressor.cc +++ b/src/LogCompressor.cc @@ -45,7 +45,8 @@ LogCompressor::LogCompressor(QString logFileName, QString outFileName, int uasid running(true), currentDataLine(0), dataLines(1), - uasid(uasid) + uasid(uasid), + holeFillingEnabled(true) { } @@ -59,7 +60,7 @@ void LogCompressor::run() QList times;// = new QList(); QList finalTimes; - qDebug() << "LOG COMPRESSOR: Starting" << fileName; + //qDebug() << "LOG COMPRESSOR: Starting" << fileName; if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) { //qDebug() << "LOG COMPRESSOR: INPUT FILE DOES NOT EXIST"; @@ -89,7 +90,10 @@ void LogCompressor::run() // Accumulate map of keys // Data field name is at position 2 QString key = line.split(separator).at(2); - if (!keys->contains(key)) keys->append(key); + if (!keys->contains(key)) + { + keys->append(key); + } keyCounter++; } keys->sort(); @@ -98,15 +102,11 @@ void LogCompressor::run() QString spacer = ""; for (int i = 0; i < keys->length(); i++) { header += keys->at(i) + separator; - spacer += " " + separator; + spacer += separator; } emit logProcessingStatusChanged(tr("Log compressor: Dataset contains dimension: ") + header); - //qDebug() << header; - - //qDebug() << "NOW READING TIMES"; - // Find all times //in.reset(); file.reset(); @@ -158,16 +158,18 @@ void LogCompressor::run() // Get time quint64 time = static_cast(parts.first()).toLongLong(&ok); QString field = parts.at(2); + int fieldIndex = keys->indexOf(field); QString value = parts.at(3); - // Enforce NaN if no value is present - if (value.length() == 0 || value == "" || value == " " || value == "\t" || value == "\n") { - value = "NaN"; - } +// // Enforce NaN if no value is present +// if (value.length() == 0 || value == "" || value == " " || value == "\t" || value == "\n") { +// // Hole filling disabled, fill with NaN +// value = "NaN"; +// } // Get matching output line // Constraining the search area might result in not finding a key, // but it significantly reduces the time needed for the search - // setting a window of 1000 entries means that a 1 Hz data point + // setting a window of 100 entries means that a 1 Hz data point // can still be located quint64 offsetLimit = 100; quint64 offset; @@ -205,12 +207,54 @@ void LogCompressor::run() QString outLine = outLines->at(index); QStringList outParts = outLine.split(separator); // Replace measurement placeholder with current value - outParts.replace(keys->indexOf(field)+1, value); + outParts.replace(fieldIndex+1, value); outLine = outParts.join(separator); outLines->replace(index, outLine); } } + /////////////////////////// + // HOLE FILLING + + // If hole filling is enabled, run again through the whole file and replace holes + if (holeFillingEnabled) + { + // Build up the fill values - initialize to NaN + QStringList fillValues; + int fillCount = keys->count(); + for (int i = 0; i< fillCount; ++i) + { + fillValues.append("NaN"); + } + + // Run through all lines and replace with fill values + for (int index = 0; index < outLines->count(); ++index) + { + QString line = outLines->at(index); + QStringList fields = line.split(separator, QString::SkipEmptyParts); + // The fields line contains the timestamp + // index of the data fields therefore runs from 1 to n-1 + int fieldCount = fields.count(); + for (int i = 1; i < fillCount+1; ++i) + { + if (fieldCount < fillCount) fields.append(""); + + // Check if this is NaN + if (fields[i] == 0 || fields[i] == "" || fields[i] == "\t" || fields[i] == " " || fields[i] == "\n") + { + // Value was empty, replace it + fields.replace(i, fillValues[i-1]); + } + else + { + // Value was not NaN, use it as + // new fill value + fillValues.replace(i-1, fields[i]); + } + } + outLines->replace(index, fields.join(separator)); + } + } // Add header, write out file file.close(); @@ -222,9 +266,8 @@ void LogCompressor::run() } if (!outfile.open(QIODevice::WriteOnly | QIODevice::Text)) return; - outfile.write(QString(QString("unix_timestamp") + separator + header.replace(" ", "_") + QString("\n")).toLatin1()); + outfile.write(QString(QString("timestamp_ms") + separator + header.replace(" ", "_") + QString("\n")).toLatin1()); emit logProcessingStatusChanged(tr("Log Compressor: Writing output to file %1").arg(QFileInfo(outFileName).absoluteFilePath())); - //QString fileHeader = QString("unix_timestamp") + header.replace(" ", "_") + QString("\n"); // File output for (int i = 0; i < outLines->length(); i++) { diff --git a/src/LogCompressor.h b/src/LogCompressor.h index 5df91ce47baa6acfcb71d538a04bd42b6293ba62..072843b561f9c74bb249192d5e119a1823e8c0d1 100644 --- a/src/LogCompressor.h +++ b/src/LogCompressor.h @@ -22,6 +22,7 @@ protected: int currentDataLine; int dataLines; int uasid; + bool holeFillingEnabled; ///< Enables the filling of holes in the dataset with the previous value (or NaN if none exists) signals: /** @brief This signal is emitted once a logfile has been finished writing diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index 912858396d2d6251aec5c1edee5d22f2bd94b022..0491d493b438b8d2c4b11e81857c0789f0ac3321 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -310,7 +310,7 @@ void LinechartWidget::appendData(int uasId, QString curve, double value, quint64 qint64 time = usec - logStartTime; if (time < 0) time = 0; - logFile->write(QString(QString::number(time) + "\t" + QString::number(uasId) + "\t" + curve + "\t" + QString::number(value,'g',10) + "\n").toLatin1()); + logFile->write(QString(QString::number(time) + "\t" + QString::number(uasId) + "\t" + curve + "\t" + QString::number(value,'g',18) + "\n").toLatin1()); logFile->flush(); } } @@ -338,7 +338,7 @@ void LinechartWidget::appendData(int uasId, const QString& curve, const QString& qint64 time = usec - logStartTime; if (time < 0) time = 0; - logFile->write(QString(QString::number(time) + "\t" + QString::number(uasId) + "\t" + curve + "\t" + QString::number(value,'g',10) + "\n").toLatin1()); + logFile->write(QString(QString::number(time) + "\t" + QString::number(uasId) + "\t" + curve + "\t" + QString::number(value,'g',18) + "\n").toLatin1()); logFile->flush(); } } diff --git a/src/ui/map/QGCMapToolBar.cc b/src/ui/map/QGCMapToolBar.cc index 462d35a438b6efd38e923a878deb85d4995a0fd1..490a2cd74559712c8ac9ef30b707c4396c5b2ec0 100644 --- a/src/ui/map/QGCMapToolBar.cc +++ b/src/ui/map/QGCMapToolBar.cc @@ -18,6 +18,7 @@ void QGCMapToolBar::setMap(QGCMapWidget* map) { connect(ui->goToButton, SIGNAL(clicked()), map, SLOT(showGoToDialog())); connect(ui->goHomeButton, SIGNAL(clicked()), map, SLOT(goHome())); + connect(ui->lastPosButton, SIGNAL(clicked()), map, SLOT(loadSettings())); connect(map, SIGNAL(OnTileLoadStart()), this, SLOT(tileLoadStart())); connect(map, SIGNAL(OnTileLoadComplete()), this, SLOT(tileLoadEnd())); connect(map, SIGNAL(OnTilesStillToLoad(int)), this, SLOT(tileLoadProgress(int))); diff --git a/src/ui/map/QGCMapToolBar.ui b/src/ui/map/QGCMapToolBar.ui index 3189d50638ed164d2ae206e72d8e849e25311370..38f0151fe3c78a2f4f91bb0f75b7fd699f0c0ac1 100644 --- a/src/ui/map/QGCMapToolBar.ui +++ b/src/ui/map/QGCMapToolBar.ui @@ -41,6 +41,13 @@ + + + + Last Pos + + + diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc index 4e24d28062e12d4c338e612fe63163547cb628b8..95986810a3918269a4ab58ce97ced7ce593c5d14 100644 --- a/src/ui/map/QGCMapWidget.cc +++ b/src/ui/map/QGCMapWidget.cc @@ -112,7 +112,7 @@ void QGCMapWidget::showEvent(QShowEvent* event) connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateGlobalPosition())); updateTimer.start(maxUpdateInterval*1000); updateGlobalPosition(); - QTimer::singleShot(1, this, SLOT(loadSettings())); + //QTimer::singleShot(800, this, SLOT(loadSettings())); } void QGCMapWidget::hideEvent(QHideEvent* event)