diff --git a/src/AnalyzeView/ExifParser.cc b/src/AnalyzeView/ExifParser.cc index f2a2f9f08766..56fb1fd8f207 100644 --- a/src/AnalyzeView/ExifParser.cc +++ b/src/AnalyzeView/ExifParser.cc @@ -101,7 +101,7 @@ double readTime(const QByteArray &buf) return (tagTime.toMSecsSinceEpoch() / 1000.0); } -bool write(QByteArray &buf, const GeoTagWorker::cameraFeedbackPacket &geotag) +bool write(QByteArray &buf, const GeoTagWorker::CameraFeedbackPacket &geotag) { static const QByteArray app1Header("\xff\xe1", 2); diff --git a/src/AnalyzeView/ExifParser.h b/src/AnalyzeView/ExifParser.h index 10bc94bb6a64..0cfc6345bcc9 100644 --- a/src/AnalyzeView/ExifParser.h +++ b/src/AnalyzeView/ExifParser.h @@ -10,5 +10,5 @@ Q_DECLARE_LOGGING_CATEGORY(ExifParserLog) namespace ExifParser { double readTime(const QByteArray &buf); - bool write(QByteArray &buf, const GeoTagWorker::cameraFeedbackPacket &geotag); + bool write(QByteArray &buf, const GeoTagWorker::CameraFeedbackPacket &geotag); } // namespace ExifParser diff --git a/src/AnalyzeView/GeoTagController.cc b/src/AnalyzeView/GeoTagController.cc index a0457163ce57..1fa24172eae4 100644 --- a/src/AnalyzeView/GeoTagController.cc +++ b/src/AnalyzeView/GeoTagController.cc @@ -8,120 +8,135 @@ ****************************************************************************/ #include "GeoTagController.h" +#include "GeoTagWorker.h" #include "QGCLoggingCategory.h" #include +#include #include QGC_LOGGING_CATEGORY(GeoTagControllerLog, "qgc.analyzeview.geotagcontroller") -GeoTagController::GeoTagController() - : _progress(0) - , _inProgress(false) +GeoTagController::GeoTagController(QObject *parent) + : QObject(parent) + , _worker(new GeoTagWorker(this)) + , _workerThread(new QThread(this)) { - connect(&_worker, &GeoTagWorker::progressChanged, this, &GeoTagController::_workerProgressChanged); - connect(&_worker, &GeoTagWorker::error, this, &GeoTagController::_workerError); - connect(&_worker, &GeoTagWorker::started, this, &GeoTagController::inProgressChanged); - connect(&_worker, &GeoTagWorker::finished, this, &GeoTagController::inProgressChanged); + // qCDebug(GeoTagControllerLog) << Q_FUNC_INFO << this; + + (void) connect(_worker, &GeoTagWorker::progressChanged, this, &GeoTagController::_workerProgressChanged); + (void) connect(_worker, &GeoTagWorker::error, this, &GeoTagController::_workerError); + (void) connect(_workerThread, &QThread::started, this, &GeoTagController::inProgressChanged); + (void) connect(_workerThread, &QThread::finished, this, &GeoTagController::inProgressChanged); + + _worker->moveToThread(_workerThread); } GeoTagController::~GeoTagController() { + // qCDebug(GeoTagControllerLog) << Q_FUNC_INFO << this; +} + +void GeoTagController::cancelTagging() +{ + (void) QMetaObject::invokeMethod(_worker, "cancelTagging", Qt::AutoConnection); +} + +QString GeoTagController::logFile() const +{ + return _worker->logFile(); +} + +QString GeoTagController::imageDirectory() const +{ + return _worker->imageDirectory(); +} + +QString GeoTagController::saveDirectory() const +{ + return _worker->saveDirectory(); +} +bool GeoTagController::inProgress() const +{ + return _workerThread->isRunning(); } -void GeoTagController::setLogFile(QString filename) +void GeoTagController::setLogFile(const QString &filename) { - filename = QUrl(filename).toLocalFile(); - if (!filename.isEmpty()) { - _worker.setLogFile(filename); - emit logFileChanged(filename); + const QString logFile = QUrl(filename).toLocalFile(); + if (!logFile.isEmpty()) { + _worker->setLogFile(logFile); + emit logFileChanged(logFile); } } -void GeoTagController::setImageDirectory(QString dir) +void GeoTagController::setImageDirectory(const QString &dir) { - dir = QUrl(dir).toLocalFile(); - if (!dir.isEmpty()) { - _worker.setImageDirectory(dir); - emit imageDirectoryChanged(dir); - if(_worker.saveDirectory() == "") { - QDir saveDirectory = QDir(_worker.imageDirectory() + kTagged); - if(saveDirectory.exists()) { - _setErrorMessage(tr("Images have alreay been tagged. Existing images will be removed.")); + const QString imageDir = QUrl(dir).toLocalFile(); + if (!imageDir.isEmpty()) { + _worker->setImageDirectory(imageDir); + emit imageDirectoryChanged(imageDir); + if (_worker->saveDirectory().isEmpty()) { + const QDir saveDirectory = QDir(_worker->imageDirectory() + kTagged); + if (saveDirectory.exists()) { + _setErrorMessage(QStringLiteral("Images have alreay been tagged. Existing images will be removed.")); return; } } } - _errorMessage.clear(); - emit errorMessageChanged(_errorMessage); + + _setErrorMessage(QString()); } -void GeoTagController::setSaveDirectory(QString dir) +void GeoTagController::setSaveDirectory(const QString &dir) { - dir = QUrl(dir).toLocalFile(); + const QString saveDir = QUrl(dir).toLocalFile(); if (!dir.isEmpty()) { - _worker.setSaveDirectory(dir); - emit saveDirectoryChanged(dir); - //-- Check and see if there are images already there - QDir saveDirectory = QDir(_worker.saveDirectory()); + _worker->setSaveDirectory(saveDir); + emit saveDirectoryChanged(saveDir); + QDir saveDirectory = QDir(_worker->saveDirectory()); saveDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable); QStringList nameFilters; nameFilters << "*.jpg" << "*.JPG"; saveDirectory.setNameFilters(nameFilters); - QStringList imageList = saveDirectory.entryList(); - if(!imageList.isEmpty()) { - _setErrorMessage(tr("The save folder already contains images.")); + const QStringList imageList = saveDirectory.entryList(); + if (!imageList.isEmpty()) { + _setErrorMessage(QStringLiteral("The save folder already contains images.")); return; } } - _errorMessage.clear(); - emit errorMessageChanged(_errorMessage); + + _setErrorMessage(QString()); } void GeoTagController::startTagging() { - _errorMessage.clear(); - emit errorMessageChanged(_errorMessage); - QDir imageDirectory = QDir(_worker.imageDirectory()); - if(!imageDirectory.exists()) { - _setErrorMessage(tr("Cannot find the image directory.")); + _setErrorMessage(QString()); + + const QDir imageDirectory = QDir(_worker->imageDirectory()); + if (!imageDirectory.exists()) { + _setErrorMessage(QStringLiteral("Cannot find the image directory.")); return; } - if(_worker.saveDirectory() == "") { - QDir oldTaggedFolder = QDir(_worker.imageDirectory() + kTagged); - if(oldTaggedFolder.exists()) { + + if (_worker->saveDirectory().isEmpty()) { + QDir oldTaggedFolder = QDir(_worker->imageDirectory() + kTagged); + if (oldTaggedFolder.exists()) { oldTaggedFolder.removeRecursively(); - if(!imageDirectory.mkdir(_worker.imageDirectory() + kTagged)) { - _setErrorMessage(tr("Couldn't replace the previously tagged images")); + if (!imageDirectory.mkdir(_worker->imageDirectory() + kTagged)) { + _setErrorMessage(QStringLiteral("Couldn't replace the previously tagged images")); return; } } } else { - QDir saveDirectory = QDir(_worker.saveDirectory()); - if(!saveDirectory.exists()) { - _setErrorMessage(tr("Cannot find the save directory.")); + const QDir saveDirectory = QDir(_worker->saveDirectory()); + if (!saveDirectory.exists()) { + _setErrorMessage(QStringLiteral("Cannot find the save directory.")); return; } } - _worker.start(); -} -void GeoTagController::_workerProgressChanged(double progress) -{ - _progress = progress; - emit progressChanged(progress); -} - -void GeoTagController::_workerError(QString errorMessage) -{ - _errorMessage = errorMessage; - emit errorMessageChanged(errorMessage); -} - - -void GeoTagController::_setErrorMessage(const QString& error) -{ - _errorMessage = error; - emit errorMessageChanged(error); + (void) QMetaObject::invokeMethod(_workerThread, "start", Qt::AutoConnection); + (void) QMetaObject::invokeMethod(_worker, "process", Qt::AutoConnection); } diff --git a/src/AnalyzeView/GeoTagController.h b/src/AnalyzeView/GeoTagController.h index b1e5acfc793f..fa23fe37cc58 100644 --- a/src/AnalyzeView/GeoTagController.h +++ b/src/AnalyzeView/GeoTagController.h @@ -9,12 +9,13 @@ #pragma once +#include #include #include -#include #include -#include "GeoTagWorker.h" +class GeoTagWorker; +class QThread; Q_DECLARE_LOGGING_CATEGORY(GeoTagControllerLog) @@ -24,56 +25,53 @@ class GeoTagController : public QObject Q_OBJECT QML_ELEMENT -public: - GeoTagController(); - ~GeoTagController(); - Q_PROPERTY(QString logFile READ logFile WRITE setLogFile NOTIFY logFileChanged) Q_PROPERTY(QString imageDirectory READ imageDirectory WRITE setImageDirectory NOTIFY imageDirectoryChanged) Q_PROPERTY(QString saveDirectory READ saveDirectory WRITE setSaveDirectory NOTIFY saveDirectoryChanged) - /// Set to an error message is geotagging fails - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) - + Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) /// Progress indicator: 0-100 - Q_PROPERTY(double progress READ progress NOTIFY progressChanged) - + Q_PROPERTY(double progress READ progress NOTIFY progressChanged) /// true: Currently in the process of tagging - Q_PROPERTY(bool inProgress READ inProgress NOTIFY inProgressChanged) + Q_PROPERTY(bool inProgress READ inProgress NOTIFY inProgressChanged) + +public: + GeoTagController(QObject *parent = nullptr); + ~GeoTagController(); Q_INVOKABLE void startTagging(); - Q_INVOKABLE void cancelTagging() { _worker.cancelTagging(); } + Q_INVOKABLE void cancelTagging(); - QString logFile () const { return _worker.logFile(); } - QString imageDirectory () const { return _worker.imageDirectory(); } - QString saveDirectory () const { return _worker.saveDirectory(); } - double progress () const { return _progress; } - bool inProgress () const { return _worker.isRunning(); } - QString errorMessage () const { return _errorMessage; } + QString logFile() const; + QString imageDirectory() const; + QString saveDirectory() const; + double progress() const { return _progress; } + bool inProgress() const; + QString errorMessage() const { return _errorMessage; } - void setLogFile (QString file); - void setImageDirectory (QString dir); - void setSaveDirectory (QString dir); + void setLogFile(const QString &file); + void setImageDirectory(const QString &dir); + void setSaveDirectory(const QString &dir); signals: - void logFileChanged (QString logFile); - void imageDirectoryChanged (QString imageDirectory); - void saveDirectoryChanged (QString saveDirectory); - void progressChanged (double progress); - void inProgressChanged (); - void errorMessageChanged (QString errorMessage); + void logFileChanged(const QString &logFile); + void imageDirectoryChanged(const QString &imageDirectory); + void saveDirectoryChanged(const QString &saveDirectory); + void progressChanged(double progress); + void inProgressChanged(); + void errorMessageChanged(const QString &errorMessage); private slots: - void _workerProgressChanged (double progress); - void _workerError (QString errorMsg); - void _setErrorMessage (const QString& error); + void _workerProgressChanged(double progress) { if (progress != _progress) { _progress = progress; emit progressChanged(_progress); } } + void _setErrorMessage(const QString &errorMsg) { if (errorMsg != _errorMessage) { _errorMessage = errorMsg; emit errorMessageChanged(_errorMessage); } } + void _workerError(const QString &errorMsg) { _setErrorMessage(errorMsg); } private: - QString _errorMessage; - double _progress; - bool _inProgress; - - GeoTagWorker _worker; + QString _errorMessage; + double _progress = 0.; + bool _inProgress = false; + GeoTagWorker *_worker = nullptr; + QThread *_workerThread = nullptr; - static constexpr const char* kTagged = "/TAGGED"; + static constexpr const char *kTagged = "/TAGGED"; }; diff --git a/src/AnalyzeView/GeoTagWorker.cc b/src/AnalyzeView/GeoTagWorker.cc index ea9fb9515397..cdc254c529b8 100644 --- a/src/AnalyzeView/GeoTagWorker.cc +++ b/src/AnalyzeView/GeoTagWorker.cc @@ -17,19 +17,43 @@ QGC_LOGGING_CATEGORY(GeoTagWorkerLog, "qgc.analyzeview.geotagworker") -GeoTagWorker::GeoTagWorker() - : _cancel(false) +GeoTagWorker::GeoTagWorker(QObject *parent) + : QObject(parent) { + // qCDebug(GeoTagWorkerLog) << Q_FUNC_INFO << this; +} +GeoTagWorker::~GeoTagWorker() +{ + // qCDebug(GeoTagWorkerLog) << Q_FUNC_INFO << this; } -void GeoTagWorker::run() +void GeoTagWorker::process() { _cancel = false; emit progressChanged(1); - double nSteps = 5; - // Load Images + if (!_loadImages()) { + return; + } + + if (!_parseExif()) { + return; + } + + if (!_initParser()) { + return; + } + + if (!_triggerFiltering()) { + return; + } + + (void) _tagImages(); +} + +bool GeoTagWorker::_loadImages() +{ _imageList.clear(); QDir imageDirectory = QDir(_imageDirectory); imageDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable); @@ -38,45 +62,51 @@ void GeoTagWorker::run() nameFilters << "*.jpg" << "*.JPG"; imageDirectory.setNameFilters(nameFilters); _imageList = imageDirectory.entryInfoList(); - if(_imageList.isEmpty()) { - emit error(tr("The image directory doesn't contain images, make sure your images are of the JPG format")); - return; + if (_imageList.isEmpty()) { + emit error(QStringLiteral("The image directory doesn't contain images, make sure your images are of the JPG format")); + return false; } - emit progressChanged((100/nSteps)); + emit progressChanged(100. / kSteps); + return true; +} - // Parse EXIF +bool GeoTagWorker::_parseExif() +{ _imageTime.clear(); for (int i = 0; i < _imageList.size(); ++i) { QFile file(_imageList.at(i).absoluteFilePath()); if (!file.open(QIODevice::ReadOnly)) { - emit error(tr("Geotagging failed. Couldn't open an image.")); - return; + emit error(QStringLiteral("Geotagging failed. Couldn't open an image.")); + return false; } - QByteArray imageBuffer = file.readAll(); + const QByteArray imageBuffer = file.readAll(); file.close(); - _imageTime.append(ExifParser::readTime(imageBuffer)); + (void) _imageTime.append(ExifParser::readTime(imageBuffer)); - emit progressChanged((100/nSteps) + ((100/nSteps) / _imageList.size())*i); + emit progressChanged((100. / kSteps) + ((100. / kSteps) / _imageList.size()) * i); if (_cancel) { qCDebug(GeotaggingLog) << "Tagging cancelled"; - emit error(tr("Tagging cancelled")); - return; + emit error(QStringLiteral("Tagging cancelled")); + return false; } } - // Load log - bool isULog = _logFile.endsWith(".ulg", Qt::CaseSensitive); + return true; +} + +bool GeoTagWorker::_initParser() +{ + const bool isULog = _logFile.endsWith(".ulg", Qt::CaseSensitive); QFile file(_logFile); if (!file.open(QIODevice::ReadOnly)) { - emit error(tr("Geotagging failed. Couldn't open log file.")); - return; + emit error(QStringLiteral("Geotagging failed. Couldn't open log file.")); + return false; } - QByteArray log = file.readAll(); + const QByteArray log = file.readAll(); file.close(); - // Instantiate appropriate parser _triggerList.clear(); bool parseComplete = false; QString errorString; @@ -89,103 +119,108 @@ void GeoTagWorker::run() if (!parseComplete) { if (_cancel) { qCDebug(GeotaggingLog) << "Tagging cancelled"; - emit error(tr("Tagging cancelled")); - return; + emit error(QStringLiteral("Tagging cancelled")); + return false; } else { qCDebug(GeotaggingLog) << "Log parsing failed"; - errorString = tr("%1 - tagging cancelled").arg(errorString.isEmpty() ? tr("Log parsing failed") : errorString); + errorString = QStringLiteral("%1 - tagging cancelled").arg(errorString.isEmpty() ? QStringLiteral("Log parsing failed") : errorString); emit error(errorString); - return; + return false; } } - emit progressChanged(3*(100/nSteps)); + emit progressChanged(3. * (100. / kSteps)); - qCDebug(GeotaggingLog) << "Found " << _triggerList.count() << " trigger logs."; + qCDebug(GeotaggingLog) << "Found" << _triggerList.count() << "trigger logs."; if (_cancel) { qCDebug(GeotaggingLog) << "Tagging cancelled"; - emit error(tr("Tagging cancelled")); - return; + emit error(QStringLiteral("Tagging cancelled")); + return false; } - // Filter Trigger - if (!triggerFiltering()) { - qCDebug(GeotaggingLog) << "Geotagging failed in trigger filtering"; - emit error(tr("Geotagging failed in trigger filtering")); - return; + return true; +} + +bool GeoTagWorker::_triggerFiltering() +{ + _imageIndices.clear(); + _triggerIndices.clear(); + + if (_imageList.count() > _triggerList.count()) { + qCDebug(GeotaggingLog) << "Detected missing feedback packets."; + } else if (_imageList.count() < _triggerList.count()) { + qCDebug(GeotaggingLog) << "Detected missing image frames."; } - emit progressChanged(4*(100/nSteps)); + + for (int i = 0; i < _imageList.count() && i < _triggerList.count(); i++) { + (void) _imageIndices.append(static_cast(_triggerList[i].imageSequence)); + (void) _triggerIndices.append(i); + } + + emit progressChanged(4. * (100. / kSteps)); if (_cancel) { qCDebug(GeotaggingLog) << "Tagging cancelled"; - emit error(tr("Tagging cancelled")); - return; + emit error(QStringLiteral("Tagging cancelled")); + return false; } - // Tag images - auto maxIndex = std::min(_imageIndices.count(), _triggerIndices.count()); + return true; +} + +bool GeoTagWorker::_tagImages() +{ + qsizetype maxIndex = std::min(_imageIndices.count(), _triggerIndices.count()); maxIndex = std::min(maxIndex, _imageList.count()); - for(int i = 0; i < maxIndex; i++) { - int imageIndex = _imageIndices[i]; + for (int i = 0; i < maxIndex; i++) { + const int imageIndex = _imageIndices[i]; if (imageIndex >= _imageList.count()) { - emit error(tr("Geotagging failed. Requesting image #%1, but only %2 images present.").arg(imageIndex).arg(_imageList.count())); - return; + emit error(QStringLiteral("Geotagging failed. Requesting image #%1, but only %2 images present.").arg(imageIndex).arg(_imageList.count())); + return false; } + QFile fileRead(_imageList.at(_imageIndices[i]).absoluteFilePath()); if (!fileRead.open(QIODevice::ReadOnly)) { - emit error(tr("Geotagging failed. Couldn't open an image.")); - return; + emit error(QStringLiteral("Geotagging failed. Couldn't open an image.")); + return false; } QByteArray imageBuffer = fileRead.readAll(); fileRead.close(); if (!ExifParser::write(imageBuffer, _triggerList[_triggerIndices[i]])) { - emit error(tr("Geotagging failed. Couldn't write to image.")); - return; + emit error(QStringLiteral("Geotagging failed. Couldn't write to image.")); + return false; + } + + QFile fileWrite; + if (_saveDirectory.isEmpty()) { + fileWrite.setFileName(_imageDirectory + "/TAGGED/" + _imageList.at(_imageIndices[i]).fileName()); } else { - QFile fileWrite; - if(_saveDirectory == "") { - fileWrite.setFileName(_imageDirectory + "/TAGGED/" + _imageList.at(_imageIndices[i]).fileName()); - } else { - fileWrite.setFileName(_saveDirectory + "/" + _imageList.at(_imageIndices[i]).fileName()); - } - if (!fileWrite.open(QFile::WriteOnly)) { - emit error(tr("Geotagging failed. Couldn't write to an image.")); - return; - } - fileWrite.write(imageBuffer); - fileWrite.close(); + fileWrite.setFileName(_saveDirectory + "/" + _imageList.at(_imageIndices[i]).fileName()); + } + if (!fileWrite.open(QFile::WriteOnly)) { + emit error(QStringLiteral("Geotagging failed. Couldn't write to an image.")); + return false; } - emit progressChanged(4*(100/nSteps) + ((100/nSteps) / maxIndex)*i); + fileWrite.write(imageBuffer); + fileWrite.close(); + + emit progressChanged(4. * (100. / kSteps) + ((100. / kSteps) / maxIndex) * i); if (_cancel) { qCDebug(GeotaggingLog) << "Tagging cancelled"; - emit error(tr("Tagging cancelled")); - return; + emit error(QStringLiteral("Tagging cancelled")); + return false; } } if (_cancel) { qCDebug(GeotaggingLog) << "Tagging cancelled"; - emit error(tr("Tagging cancelled")); - return; + emit error(QStringLiteral("Tagging cancelled")); + return false; } emit progressChanged(100); -} -bool GeoTagWorker::triggerFiltering() -{ - _imageIndices.clear(); - _triggerIndices.clear(); - if(_imageList.count() > _triggerList.count()) { // Logging dropouts - qCDebug(GeotaggingLog) << "Detected missing feedback packets."; - } else if (_imageList.count() < _triggerList.count()) { // Camera skipped frames - qCDebug(GeotaggingLog) << "Detected missing image frames."; - } - for(int i = 0; i < _imageList.count() && i < _triggerList.count(); i++) { - _imageIndices.append(static_cast(_triggerList[i].imageSequence)); - _triggerIndices.append(i); - } return true; } diff --git a/src/AnalyzeView/GeoTagWorker.h b/src/AnalyzeView/GeoTagWorker.h index 4ce94d190fa9..8acb56897258 100644 --- a/src/AnalyzeView/GeoTagWorker.h +++ b/src/AnalyzeView/GeoTagWorker.h @@ -9,32 +9,29 @@ #pragma once -#include -#include -#include #include #include +#include +#include Q_DECLARE_LOGGING_CATEGORY(GeoTagWorkerLog) -class GeoTagWorker : public QThread +class GeoTagWorker : public QObject { Q_OBJECT public: - GeoTagWorker(); - - void setLogFile (const QString& logFile) { _logFile = logFile; } - void setImageDirectory (const QString& imageDirectory) { _imageDirectory = imageDirectory; } - void setSaveDirectory (const QString& saveDirectory) { _saveDirectory = saveDirectory; } + GeoTagWorker(QObject *parent = nullptr); + ~GeoTagWorker(); - QString logFile () const { return _logFile; } - QString imageDirectory () const { return _imageDirectory; } - QString saveDirectory () const { return _saveDirectory; } + QString logFile() const { return _logFile; } + void setLogFile(const QString &logFile) { _logFile = logFile; } + QString imageDirectory() const { return _imageDirectory; } + void setImageDirectory(const QString &imageDirectory) { _imageDirectory = imageDirectory; } + QString saveDirectory() const { return _saveDirectory; } + void setSaveDirectory(const QString &saveDirectory) { _saveDirectory = saveDirectory; } - void cancelTagging () { _cancel = true; } - - struct cameraFeedbackPacket { + struct CameraFeedbackPacket { double timestamp; double timestampUTC; uint32_t imageSequence; @@ -46,24 +43,31 @@ class GeoTagWorker : public QThread uint8_t captureResult; }; -protected: - void run() final; - signals: - void error (QString errorMsg); - void taggingComplete (); - void progressChanged (double progress); + void error(const QString &errorMsg); + void taggingComplete(); + void progressChanged(double progress); + +public slots: + void process(); + void cancelTagging() { _cancel = true; } private: - bool triggerFiltering(); + bool _loadImages(); + bool _parseExif(); + bool _initParser(); + bool _triggerFiltering(); + bool _tagImages(); + + bool _cancel = false; + QString _logFile; + QString _imageDirectory; + QString _saveDirectory; + QFileInfoList _imageList; + QList _imageTime; + QList _triggerList; + QList _imageIndices; + QList _triggerIndices; - bool _cancel; - QString _logFile; - QString _imageDirectory; - QString _saveDirectory; - QFileInfoList _imageList; - QList _imageTime; - QList _triggerList; - QList _imageIndices; - QList _triggerIndices; + static constexpr double kSteps = 5.; }; diff --git a/src/AnalyzeView/PX4LogParser.cc b/src/AnalyzeView/PX4LogParser.cc index f59e76bd06c3..4b79b36c7b2d 100644 --- a/src/AnalyzeView/PX4LogParser.cc +++ b/src/AnalyzeView/PX4LogParser.cc @@ -26,7 +26,7 @@ static constexpr const int triggerLengths[2] = {8, 4}; namespace PX4LogParser { -bool getTagsFromLog(const QByteArray& log, QList& cameraFeedback) +bool getTagsFromLog(const QByteArray& log, QList& cameraFeedback) { // extract header information: message lengths const uint8_t* iptr = reinterpret_cast(log.mid(log.indexOf(gposHeaderHeader) + 4, 1).constData()); @@ -51,7 +51,7 @@ bool getTagsFromLog(const QByteArray& log, QList(log.mid(index + triggerOffsets[0], triggerLengths[0]).data()); diff --git a/src/AnalyzeView/PX4LogParser.h b/src/AnalyzeView/PX4LogParser.h index 4d37a84c40a4..77695bd684c9 100644 --- a/src/AnalyzeView/PX4LogParser.h +++ b/src/AnalyzeView/PX4LogParser.h @@ -9,5 +9,5 @@ Q_DECLARE_LOGGING_CATEGORY(PX4LogParserLog) namespace PX4LogParser { - bool getTagsFromLog(const QByteArray &log, QList &cameraFeedback); + bool getTagsFromLog(const QByteArray &log, QList &cameraFeedback); } diff --git a/src/AnalyzeView/ULogParser.cc b/src/AnalyzeView/ULogParser.cc index 1398a2760ba2..59d4392b428d 100644 --- a/src/AnalyzeView/ULogParser.cc +++ b/src/AnalyzeView/ULogParser.cc @@ -13,7 +13,7 @@ QGC_LOGGING_CATEGORY(ULogParserLog, "qgc.analyzeview.ulogparser") namespace ULogParser { -bool getTagsFromLog(const QByteArray &log, QList &cameraFeedback, QString &errorMessage) +bool getTagsFromLog(const QByteArray &log, QList &cameraFeedback, QString &errorMessage) { errorMessage.clear(); @@ -42,7 +42,7 @@ bool getTagsFromLog(const QByteArray &log, QList subscription = data->subscription("camera_capture"); for (const TypedDataView &sample : *subscription) { - GeoTagWorker::cameraFeedbackPacket feedback = {0}; + GeoTagWorker::CameraFeedbackPacket feedback = {0}; try { feedback.timestamp = sample.at("timestamp").as() / 1.0e6; // to seconds diff --git a/src/AnalyzeView/ULogParser.h b/src/AnalyzeView/ULogParser.h index d69da61f691e..04d3488fb470 100644 --- a/src/AnalyzeView/ULogParser.h +++ b/src/AnalyzeView/ULogParser.h @@ -13,5 +13,5 @@ Q_DECLARE_LOGGING_CATEGORY(ULogParserLog) namespace ULogParser { /// Get GeoTags from a ULog /// @return true if failed, errorMessage set - bool getTagsFromLog(const QByteArray &log, QList &cameraFeedback, QString &errorMessage); + bool getTagsFromLog(const QByteArray &log, QList &cameraFeedback, QString &errorMessage); } // namespace ULogParser diff --git a/test/AnalyzeView/CMakeLists.txt b/test/AnalyzeView/CMakeLists.txt index a25b40124526..f7e443e3dcf7 100644 --- a/test/AnalyzeView/CMakeLists.txt +++ b/test/AnalyzeView/CMakeLists.txt @@ -4,6 +4,8 @@ qt_add_library(AnalyzeViewTest STATIC ExifParserTest.cc ExifParserTest.h + GeoTagControllerTest.cc + GeoTagControllerTest.h LogDownloadTest.cc LogDownloadTest.h MavlinkLogTest.cc diff --git a/test/AnalyzeView/ExifParserTest.cc b/test/AnalyzeView/ExifParserTest.cc index f5fc35e70f30..fc9845038a8f 100644 --- a/test/AnalyzeView/ExifParserTest.cc +++ b/test/AnalyzeView/ExifParserTest.cc @@ -31,7 +31,7 @@ void ExifParserTest::_writeTest() QByteArray imageBuffer = file.readAll(); file.close(); - struct GeoTagWorker::cameraFeedbackPacket data; + struct GeoTagWorker::CameraFeedbackPacket data; data.latitude = 37.225; data.longitude = -80.425; diff --git a/test/AnalyzeView/GeoTagControllerTest.cc b/test/AnalyzeView/GeoTagControllerTest.cc new file mode 100644 index 000000000000..5c5b0a7b0f32 --- /dev/null +++ b/test/AnalyzeView/GeoTagControllerTest.cc @@ -0,0 +1,56 @@ +#include "GeoTagControllerTest.h" +#include "GeoTagController.h" +#include "GeoTagWorker.h" + +#include + +void GeoTagControllerTest::_geoTagControllerTest() +{ + GeoTagController* const controller = new GeoTagController(this); + + /*controller->logFile() + controller->imageDirectory() + controller->saveDirectory() + controller->progress() + controller->inProgress() + controller->errorMessage() + + controller->setLogFile(const QString &file); + controller->setImageDirectory(const QString &dir); + controller->setSaveDirectory(const QString &dir); + + QSignalSpy spyGeoTagControllerLogFile(worker, &GeoTagWorker::progressChanged); + QSignalSpy spyGeoTagControllerImageDirectory(worker, &GeoTagWorker::error); + QSignalSpy spyGeoTagControllerSaveDirectory(worker, &GeoTagWorker::progressChanged); + QSignalSpy spyGeoTagControllerProgress(worker, &GeoTagWorker::progressChanged); + QSignalSpy spyGeoTagControllerInProgress(worker, &GeoTagWorker::progressChanged); + QSignalSpy spyGeoTagControllerError(worker, &GeoTagWorker::progressChanged); + + QCOMPARE(spyGeoTagControllerLogFile.wait(5000), true); + QCOMPARE(spyGeoTagControllerImageDirectory.wait(5000), true); + QCOMPARE(spyGeoTagControllerSaveDirectory.wait(5000), true); + QCOMPARE(spyGeoTagControllerProgress.wait(5000), true); + QCOMPARE(spyGeoTagControllerInProgress.wait(5000), true); + QCOMPARE(spyGeoTagControllerError.wait(5000), true);*/ +} + +void GeoTagControllerTest::_geoTagWorkerTest() +{ + GeoTagWorker* const worker = new GeoTagWorker(this); + + /*worker->setLogFile(":/SampleULog.ulg"); + worker->setImageDirectory("."); + worker->setSaveDirectory("."); + + worker->process(); + + worker->cancelTagging(); + + QSignalSpy spyGeoTagWorkerProgress(worker, &GeoTagWorker::progressChanged); + QSignalSpy spyGeoTagWorkerError(worker, &GeoTagWorker::error); + QSignalSpy spyGeoTagWorkerComplete(worker, &GeoTagWorker::taggingComplete); + + QCOMPARE(spyGeoTagWorkerProgress.wait(5000), true); + QCOMPARE(spyGeoTagWorkerError.wait(5000), true); + QCOMPARE(spyGeoTagWorkerComplete.wait(5000), true);*/ +} diff --git a/test/AnalyzeView/GeoTagControllerTest.h b/test/AnalyzeView/GeoTagControllerTest.h new file mode 100644 index 000000000000..e51b646bb18e --- /dev/null +++ b/test/AnalyzeView/GeoTagControllerTest.h @@ -0,0 +1,12 @@ +#pragma once + +#include "UnitTest.h" + +class GeoTagControllerTest : public UnitTest +{ + Q_OBJECT + +private slots: + void _geoTagControllerTest(); + void _geoTagWorkerTest(); +}; diff --git a/test/AnalyzeView/PX4LogParserTest.cc b/test/AnalyzeView/PX4LogParserTest.cc index 5a9416fffff3..70eb2709df77 100644 --- a/test/AnalyzeView/PX4LogParserTest.cc +++ b/test/AnalyzeView/PX4LogParserTest.cc @@ -12,11 +12,11 @@ void PX4LogParserTest::_getTagsFromLogTest() const QByteArray logBuffer = file.readAll(); file.close(); - QList cameraFeedback; + QList cameraFeedback; QVERIFY(PX4LogParser::getTagsFromLog(logBuffer, cameraFeedback)); QVERIFY(!cameraFeedback.isEmpty()); - GeoTagWorker::cameraFeedbackPacket firstCameraFeedback = cameraFeedback.first(); + GeoTagWorker::CameraFeedbackPacket firstCameraFeedback = cameraFeedback.first(); QVERIFY(!qFuzzyIsNull(firstCameraFeedback.timestamp)); QVERIFY(firstCameraFeedback.imageSequence != 0);*/ } diff --git a/test/AnalyzeView/ULogParserTest.cc b/test/AnalyzeView/ULogParserTest.cc index 065313339220..b83bcdc9e3d2 100644 --- a/test/AnalyzeView/ULogParserTest.cc +++ b/test/AnalyzeView/ULogParserTest.cc @@ -12,13 +12,13 @@ void ULogParserTest::_getTagsFromLogTest() const QByteArray logBuffer = file.readAll(); file.close(); - QList cameraFeedback; + QList cameraFeedback; QString errorMessage; QVERIFY(ULogParser::getTagsFromLog(logBuffer, cameraFeedback, errorMessage)); QVERIFY(errorMessage.isEmpty()); QVERIFY(!cameraFeedback.isEmpty()); - const GeoTagWorker::cameraFeedbackPacket firstCameraFeedback = cameraFeedback.constFirst(); + const GeoTagWorker::CameraFeedbackPacket firstCameraFeedback = cameraFeedback.constFirst(); // QVERIFY(!qFuzzyIsNull(firstCameraFeedback.timestamp)); QVERIFY(firstCameraFeedback.imageSequence != 0); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 24f743bcd454..ef75ce1f526c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,6 +29,7 @@ add_qgc_test(ADSBTest) add_subdirectory(AnalyzeView) add_qgc_test(ExifParserTest) +add_qgc_test(GeoTagControllerTest) # add_qgc_test(LogDownloadTest) # add_qgc_test(MavlinkLogTest) add_qgc_test(PX4LogParserTest) diff --git a/test/UnitTestList.cc b/test/UnitTestList.cc index 62476b9e8f91..7a408f67211d 100644 --- a/test/UnitTestList.cc +++ b/test/UnitTestList.cc @@ -17,6 +17,7 @@ // AnalyzeView #include "ExifParserTest.h" +#include "GeoTagControllerTest.h" // #include "MavlinkLogTest.h" // #include "LogDownloadTest.h" #include "PX4LogParserTest.h" @@ -113,6 +114,7 @@ int runTests(bool stress, QStringView unitTestOptions) // AnalyzeView UT_REGISTER_TEST(ExifParserTest) + UT_REGISTER_TEST(GeoTagControllerTest) // UT_REGISTER_TEST(MavlinkLogTest) // UT_REGISTER_TEST(LogDownloadTest) UT_REGISTER_TEST(PX4LogParserTest)