diff --git a/src/blackmisc/simulation/interpolationlogger.cpp b/src/blackmisc/simulation/interpolationlogger.cpp index 158f31092..58e6cf243 100644 --- a/src/blackmisc/simulation/interpolationlogger.cpp +++ b/src/blackmisc/simulation/interpolationlogger.cpp @@ -7,6 +7,7 @@ */ #include "interpolationlogger.h" +#include "blackmisc/simulation/kmlutils.h" #include "blackmisc/aviation/callsign.h" #include "blackmisc/aviation/heading.h" #include "blackmisc/pq/angle.h" @@ -98,6 +99,7 @@ namespace BlackMisc CStatusMessageList msgs; const QString ts = QDateTime::currentDateTimeUtc().toString("yyyyMMddhhmmss"); + const QString htmlInterpolation = CInterpolationLogger::getHtmlInterpolationLog(interpolation); if (!htmlInterpolation.isEmpty()) { @@ -117,6 +119,31 @@ namespace BlackMisc const bool s = CFileUtils::writeStringToFile(htmlTemplate.arg(html.arg(parts.size()).arg(htmlParts)), fn); msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn)); } + + QString kml = CKmlUtils::wrapAsKmlDocument(CInterpolationLogger::getKmlChangedSituations(interpolation)); + if (!kml.isEmpty()) + { + const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1_changedSituations.kml").arg(ts)); + const bool s = CFileUtils::writeStringToFile(kml, fn); + msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn)); + } + + kml = CKmlUtils::wrapAsKmlDocument(CInterpolationLogger::getKmlInterpolatedSituations(interpolation)); + if (!kml.isEmpty()) + { + const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1_interpolatedSituations.kml").arg(ts)); + const bool s = CFileUtils::writeStringToFile(kml, fn); + msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn)); + } + + kml = CKmlUtils::wrapAsKmlDocument(CInterpolationLogger::getKmlElevations(interpolation)); + if (!kml.isEmpty()) + { + const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1_elevations.kml").arg(ts)); + const bool s = CFileUtils::writeStringToFile(kml, fn); + msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn)); + } + return msgs; } @@ -342,7 +369,7 @@ namespace BlackMisc u"" % log.cgAboveGround.valueRoundedWithUnit(ft, 0) % u"" % u"" % boolToYesNo(log.useParts) % u"" % (changedParts ? u"*" : u"") % - u"" % (log.useParts ? log.parts.toQString(true) : QString()) % u"" % + u"" % (!log.useParts || log.parts.isNull() ? QString() : log.parts.toQString(true).toHtmlEscaped()) % u"" % u"\n"; } @@ -350,6 +377,79 @@ namespace BlackMisc return u"\n" % tableHeader % tableRows % u"
\n"; } + QString CInterpolationLogger::getKmlChangedSituations(const QList &logs) + { + if (logs.isEmpty()) { return {}; } + + QString kml; + qint64 newPosTs = -1; + int n = 1; + const CKmlUtils::KMLSettings s(true, true); + + for (const SituationLog &log : logs) + { + const CAircraftSituation situationNew = log.newestInterpolationSituation(); + const bool changedNewPosition = (newPosTs != situationNew.getMSecsSinceEpoch()); + const bool recalc = log.interpolantRecalc; + if (!changedNewPosition && !recalc) { continue; } + newPosTs = situationNew.getMSecsSinceEpoch(); + kml += CKmlUtils::asPlacemark( + QStringLiteral("%1: %2 new pos: %3 recalc: %4").arg(n++).arg(situationNew.getFormattedUtcTimestampHmsz(), boolToYesNo(changedNewPosition), boolToYesNo(recalc)), + situationNew.toQString(true), + situationNew, s) % u"\n"; + } + + return kml; + } + + QString CInterpolationLogger::getKmlElevations(const QList &logs) + { + if (logs.isEmpty()) { return {}; } + + QString kml; + qint64 newPosTs = -1; + int n = 1; + const CKmlUtils::KMLSettings s(true, true); + + for (const SituationLog &log : logs) + { + const CAircraftSituation situationNew = log.newestInterpolationSituation(); + const bool changedNewPosition = (newPosTs != situationNew.getMSecsSinceEpoch()); + const bool recalc = log.interpolantRecalc; + if (!changedNewPosition && !recalc) { continue; } + if (!situationNew.hasGroundElevation()) { continue; } + newPosTs = situationNew.getMSecsSinceEpoch(); + kml += CKmlUtils::asPlacemark( + QStringLiteral("%1: %2 %3 %4 alt.cor: %5").arg(n++).arg( + situationNew.getFormattedUtcTimestampHmsz(), + situationNew.getGroundElevationPlane().getAltitude().toQString(true), + log.elevationInfo, log.altCorrection), + situationNew.getGroundElevationPlane().toQString(true), + situationNew.getGroundElevationPlane(), s) % u"\n"; + } + + return kml; + } + + QString CInterpolationLogger::getKmlInterpolatedSituations(const QList &logs) + { + if (logs.isEmpty()) { return {}; } + + const CKmlUtils::KMLSettings s(true, false); + QString coordinates; + for (const SituationLog &log : logs) + { + const CAircraftSituation situation = log.situationCurrent; + coordinates += CKmlUtils::asRawCoordinates(situation, s.withAltitude) % u"\n"; + } + + return + u"\n" + u"Interpolation " % QString::number(logs.size()) % u"entries\n" % + CKmlUtils::asLineString(coordinates, s) % + u"\n"; + } + QString CInterpolationLogger::getHtmlPartsLog(const QList &logs) { if (logs.isEmpty()) { return {}; } diff --git a/src/blackmisc/simulation/interpolationlogger.h b/src/blackmisc/simulation/interpolationlogger.h index 256df4b3f..04c39c144 100644 --- a/src/blackmisc/simulation/interpolationlogger.h +++ b/src/blackmisc/simulation/interpolationlogger.h @@ -198,6 +198,15 @@ namespace BlackMisc //! Get log as HTML table static QString getHtmlInterpolationLog(const QList &logs); + //! Get log as KML (changed situations) + static QString getKmlChangedSituations(const QList &logs); + + //! Get log as KML (elevations) + static QString getKmlElevations(const QList &logs); + + //! Get log as KML (changed situations) + static QString getKmlInterpolatedSituations(const QList &logs); + //! Get log as HTML table static QString getHtmlPartsLog(const QList &logs);