Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Common/LtsElevation/lts_elevation_manager.cpp
T
2026-10-03 09:20:13 +02:00

588 lines
19 KiB
C++

#include "lts_elevation_manager.h"
#ifdef BUILD_RTI
#include <AssetManagement/asm_data_plugin_interface.h>
#include <ExerciseManagement/exm_data_plugin_interface.h>
#include <Viewer/SituationMap/ElevationMap/elevation_map_manager.h>
#include <Viewer/SituationMap/Common/resource_path.h>
#include <QDir>
#include <QHash>
#include <QSharedPointer>
#include <QUrl>
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_UNDEFINED ==
(int)LtsElevation::LineOfSight::LOS_UNDEFINED,
"LineOfSight mismatch");
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_ERROR ==
(int)LtsElevation::LineOfSight::LOS_ERROR,
"LineOfSight mismatch");
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_VISIBLE ==
(int)LtsElevation::LineOfSight::LOS_VISIBLE,
"LineOfSight mismatch");
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_INVISIBLE ==
(int)LtsElevation::LineOfSight::LOS_INVISIBLE,
"LineOfSight mismatch");
#endif
namespace LtsElevation
{
class LtsElevationManager;
using LtsElevatioMgrMapTrainingAreaId = QMap<int, LTS_ELEVATION_MANAGER_TYPE>;
static LtsElevatioMgrMapTrainingAreaId& ltsElevatioMgrMapTrainingAreaId()
{
static LtsElevatioMgrMapTrainingAreaId s_ltsElevatioMgrMapTrainingAreaId;
return s_ltsElevatioMgrMapTrainingAreaId;
}
static void cleanupLtsElevatioMgrMapTrainingAreaId()
{
qDeleteAll(ltsElevatioMgrMapTrainingAreaId());
ltsElevatioMgrMapTrainingAreaId().clear();
}
LtsElevatioMgrMapTrainingAreaId& getLtsElevationMgrMapTrainingAreaId()
{
if (ltsElevatioMgrMapTrainingAreaId().isEmpty())
qAddPostRoutine(cleanupLtsElevatioMgrMapTrainingAreaId);
return ltsElevatioMgrMapTrainingAreaId();
}
static long s_counter{0};
class LtsElevationManager::Private
{
public:
Private() = default;
~Private()
{
#ifdef BUILD_RTI
delete m_elevationManager;
#endif
}
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
#ifdef BUILD_RTI
std::shared_ptr<AssetManagement::Interface::Dtc> m_asmDtc;
SituationMap::ElevationMapManager* m_elevationManager{nullptr};
#endif
QStringList m_filePaths_rough_to_fine;
};
LtsElevationManager::LtsElevationManager()
: QObject(nullptr)
, d(new Private)
, m_logger(getLogger("LtsElevationManager"))
{
++s_counter;
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START, s_counter=" << s_counter << " this=" << this;
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END, s_counter=" << s_counter << " this=" << this;
}
LtsElevationManager::~LtsElevationManager()
{
--s_counter;
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START, s_counter=" << s_counter << " this=" << this;
delete d;
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END, s_counter=" << s_counter << " this=" << this;
}
LTS_ELEVATION_MANAGER_TYPE
LtsElevationManager::createInstance(int exerciseId, const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
#ifdef BUILD_RTI
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc
#else
const std::shared_ptr<void>& asmDtc
#endif
)
{
LOGGER_T logger = getLogger("LtsElevationManager");
TRACE_LOG(logger) << Q_FUNC_INFO << " START, exerciseId=" << exerciseId;
if (exerciseId < 0)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " exerciseId invalid, exerciseId=" << exerciseId;
return nullptr;
}
// Qt5 logic restored (the qt6 port had dropped the exerciseId->trainingAreaId
// caching and always returned nullptr here).
#ifdef BUILD_RTI
int trainingAreaId = -1;
// remember for future calls
// (so createInstance should work WITHOUT dtcs)
// Idea: MainHandler: createInstance with exerciseId and valid dtcs
// Plugin or simular: createInstance with exerciseId and no dtcs
static QHash<int, int> s_exIdToTaIdStore;
const auto exTaIt = s_exIdToTaIdStore.find(exerciseId);
if (exTaIt != s_exIdToTaIdStore.end())
{
// CASE 1:
// already created:
trainingAreaId = *exTaIt;
}
else
{
// CASE 2:
// ... or create on demand:
if (!exmDtc || !asmDtc)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " no dtcs for exerciseId=" << exerciseId
<< ", asmDtc=" << asmDtc
<< ", exmDtc=" << exmDtc;
return nullptr;
}
// exId to taId
trainingAreaId = exerciseIdToTrainingAreaId(exerciseId, exmDtc);
if (trainingAreaId <= 0)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " Error getting trainingAreaId"
<< ", exerciseId=" << exerciseId
<< ", trainingAreaId=" << trainingAreaId;
return nullptr;
}
// store and remember:
s_exIdToTaIdStore[exerciseId] = trainingAreaId;
}
// CASE 1: Following should work even with invalid asmDtc:
LTS_ELEVATION_MANAGER_TYPE temp = createInstanceForTrainingAreaId(trainingAreaId, asmDtc);
if (!temp)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " Error on createInstanceForTrainingAreaId"
<< ", exerciseId=" << exerciseId
<< ", trainingAreaId=" << trainingAreaId;
return nullptr;
}
// add exmDtc
temp->initDDS(exmDtc, asmDtc);
TRACE_LOG(logger) << Q_FUNC_INFO << " END, exerciseId=" << exerciseId;
return temp;
#else
Q_UNUSED(exmDtc);
Q_UNUSED(asmDtc);
ERROR_LOG(logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, cannot create instance";
return nullptr;
#endif
}
LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::getInstance(int exerciseId)
{
return LtsElevationManager::createInstance(exerciseId);
}
#ifdef BUILD_RTI
LTS_ELEVATION_MANAGER_TYPE
LtsElevationManager::createInstanceForTrainingAreaId(int trainingAreaId,
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc)
{
LOGGER_T logger = getLogger("LtsElevationManager");
TRACE_LOG(logger) << Q_FUNC_INFO << " START, trainingAreaId=" << trainingAreaId;
if (trainingAreaId < 0)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " trainingAreaId invalid, trainingAreaId=" << trainingAreaId;
return nullptr;
}
LtsElevatioMgrMapTrainingAreaId& map = getLtsElevationMgrMapTrainingAreaId();
QMap<int, LTS_ELEVATION_MANAGER_TYPE>::iterator it = map.find(trainingAreaId);
if (it != map.end())
{
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances: " << map.size();
return it.value();
}
if (!asmDtc)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " no dtcs for trainingAreaId=" << trainingAreaId << ", asmDtc=" << asmDtc;
return nullptr;
}
LTS_ELEVATION_MANAGER_TYPE temp = new LtsElevationManager();
temp->initDDS(nullptr, asmDtc);
const QStringList& filenames = temp->getFilenamesForTrainingArea(trainingAreaId);
if (filenames.isEmpty())
{
ERROR_LOG(logger) << Q_FUNC_INFO << " no filenames for trainingAreaId=" << trainingAreaId;
delete temp;
return nullptr;
}
bool bInitFilenames = temp->init(filenames);
if (!bInitFilenames)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " bInitFilenames failed for trainingAreaId=" << trainingAreaId;
delete temp;
return nullptr;
}
map.insert(trainingAreaId, temp);
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances now: " << map.size();
TRACE_LOG(logger) << Q_FUNC_INFO << " END, trainingAreaId=" << trainingAreaId;
return map[trainingAreaId];
}
#endif
LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::createInstanceUnitTest(int id,
const QStringList& filePaths_rough_to_fine)
{
LOGGER_T logger = getLogger("LtsElevationManager");
LtsElevatioMgrMapTrainingAreaId& map = getLtsElevationMgrMapTrainingAreaId();
QMap<int, LTS_ELEVATION_MANAGER_TYPE>::iterator it = map.find(id);
if (it != map.end())
{
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances: " << map.size();
return it.value();
}
LTS_ELEVATION_MANAGER_TYPE temp = new LtsElevationManager();
bool bInitFilenames = temp->init(filePaths_rough_to_fine);
if (!bInitFilenames)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " bInitFilenames failed for id=" << id;
delete temp;
return nullptr;
}
map.insert(id, temp);
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances now: " << map.size();
TRACE_LOG(logger) << Q_FUNC_INFO << " END, trainingAreaId=" << id;
return map[id];
}
void LtsElevationManager::cleanupAll()
{
LOGGER_T logger = getLogger("LtsElevationManager");
TRACE_LOG(logger) << Q_FUNC_INFO << " START";
cleanupLtsElevatioMgrMapTrainingAreaId();
TRACE_LOG(logger) << Q_FUNC_INFO << " END";
}
#ifdef BUILD_RTI
void LtsElevationManager::initDDS(const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc)
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
d->m_exmDtc = exmDtc;
if (d->m_exmDtc)
d->m_exmDtc->waitForHistoricalDataExercise(1000);
d->m_asmDtc = asmDtc;
if (d->m_asmDtc)
d->m_asmDtc->waitForHistoricalDataTrainingArea(1000);
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
}
#else
void LtsElevationManager::initDDS(const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
const std::shared_ptr<void>& asmDtc)
{
Q_UNUSED(exmDtc);
Q_UNUSED(asmDtc);
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START (BUILD_RTI=OFF, no DDS init)";
// BUILD_RTI=OFF: No DDS initialization
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
}
#endif
#ifdef BUILD_RTI
QStringList LtsElevationManager::getFilenamesForExercise(int exerciseId)
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
if (!d->m_exmDtc || !d->m_asmDtc)
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " no dtcs"
<< ", exerciseId=" << exerciseId;
return {};
}
int trainingAreaId = exerciseIdToTrainingAreaId(exerciseId, d->m_exmDtc);
if (trainingAreaId <= 0)
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " Error getting trainingAreaId"
<< ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId;
return {};
}
QStringList filePaths_rough_to_fine = getFilenamesForTrainingArea(trainingAreaId);
TRACE_LOG(m_logger) << Q_FUNC_INFO
<< " END, filePaths_rough_to_fine=" << filePaths_rough_to_fine.join(QStringLiteral(";"));
return filePaths_rough_to_fine;
}
QStringList LtsElevationManager::getFilenamesForTrainingArea(int trainingAreaId)
{
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
if (!d->m_asmDtc)
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " no dtcs"
<< ", trainingAreaId=" << trainingAreaId;
return {};
}
QStringList filePaths_rough_to_fine;
{
d->m_asmDtc->waitForHistoricalDataTrainingArea(1000);
const AssetManagement::TrainingArea& ta = d->m_asmDtc->trainingArea(trainingAreaId);
if (ta.id != trainingAreaId)
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " Error on s_asmDtc->trainingArea"
<< ", trainingAreaId=" << trainingAreaId;
return {};
}
const std::vector<AssetManagement::MapDescription>& mdVec = ta.elevation;
filePaths_rough_to_fine.reserve(mdVec.size());
for (const AssetManagement::MapDescription& md : std::as_const(mdVec))
{
QUrl url(QString::fromStdString(md.url));
QString filePathAbs = url.toLocalFile();
if (QDir::isRelativePath(filePathAbs))
filePathAbs = SituationMap::getResourcePath() + QStringLiteral("/elevation/") + filePathAbs;
filePaths_rough_to_fine.append(filePathAbs);
}
}
TRACE_LOG(m_logger) << Q_FUNC_INFO
<< " END, filePaths_rough_to_fine=" << filePaths_rough_to_fine.join(QStringLiteral(";"));
return filePaths_rough_to_fine;
}
#else
QStringList LtsElevationManager::getFilenamesForExercise(int /*exerciseId*/)
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, getFilenamesForExercise not available";
return {};
}
QStringList LtsElevationManager::getFilenamesForTrainingArea(int /*trainingAreaId*/)
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, getFilenamesForTrainingArea not available";
return {};
}
#endif
bool LtsElevationManager::init(const QStringList& filePaths_rough_to_fine)
{
#ifdef BUILD_RTI
delete d->m_elevationManager;
d->m_elevationManager = new SituationMap::ElevationMapManager();
int cnt = d->m_elevationManager->init(filePaths_rough_to_fine);
if (cnt != filePaths_rough_to_fine.size())
{
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
return false;
}
return true;
#else
Q_UNUSED(filePaths_rough_to_fine);
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, init not available";
return false;
#endif
}
#ifdef BUILD_RTI
int LtsElevationManager::exerciseIdToTrainingAreaId(int exerciseId,
const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc)
{
LOGGER_T logger = getLogger("LtsElevationManager");
if (!exmDtc)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " no dtcs"
<< ", exerciseId=" << exerciseId;
return -1;
}
int trainingAreaId = -1;
{
exmDtc->waitForHistoricalDataExercise(1000);
const ExerciseManagement::Exercise& exm = exmDtc->exercise(exerciseId);
if (exm.id != exerciseId)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " Error on m_exmDtc->exercise"
<< ", exerciseId=" << exerciseId;
return -1;
}
trainingAreaId = exm.trainingAreaId;
if (trainingAreaId <= 0)
{
ERROR_LOG(logger) << Q_FUNC_INFO << " Error getting trainingAreaId"
<< ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId;
return -1;
}
}
return trainingAreaId;
}
#else
int LtsElevationManager::exerciseIdToTrainingAreaId(int exerciseId,
const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc)
{
Q_UNUSED(exerciseId);
Q_UNUSED(exmDtc);
LOGGER_T logger = getLogger("LtsElevationManager");
ERROR_LOG(logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, cannot convert exerciseId to trainingAreaId";
return -1;
}
#endif
bool LtsElevationManager::waitForInitialization()
{
#ifdef BUILD_RTI
if (!d->m_elevationManager)
return false;
return d->m_elevationManager->waitForInitialization();
#else
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, waitForInitialization not available";
return false;
#endif
}
bool LtsElevationManager::isValid() const
{
#ifdef BUILD_RTI
if (!d->m_elevationManager)
return false;
return d->m_elevationManager->isValid();
#else
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, isValid not available";
return false;
#endif
}
double LtsElevationManager::elevation(double lon_rad, double lat_rad, double defaultValue, bool* bIsCovered) const
{
#ifdef BUILD_RTI
if (!d->m_elevationManager)
return defaultValue;
return d->m_elevationManager->elevation(lon_rad, lat_rad, defaultValue, bIsCovered);
#else
Q_UNUSED(lon_rad);
Q_UNUSED(lat_rad);
Q_UNUSED(bIsCovered);
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, elevation not available";
return defaultValue;
#endif
}
LineOfSight LtsElevationManager::lineOfSightCalculation(const LtsUtils::QPoint3D& startPointGeo_absZ,
const LtsUtils::QPoint3D& endPointGeo_absZ)
{
#ifdef BUILD_RTI
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START"
<< ", startPointGeo_absZ = " << startPointGeo_absZ
<< ", endPointGeo_absZ = " << endPointGeo_absZ;
if (!isValid())
{
ERROR_LOG(m_logger) << Q_FUNC_INFO << " Error, LtsElevationManager not valid";
return LineOfSight::LOS_ERROR;
}
SituationMap::ElevationMapManager::LineOfSight eleMapMgrResult =
d->m_elevationManager->lineOfSightCalculation(startPointGeo_absZ, endPointGeo_absZ);
LtsElevation::LineOfSight result = static_cast<LtsElevation::LineOfSight>(eleMapMgrResult);
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END"
<< ", startPointGeo = " << startPointGeo_absZ << ", endPointGeo = " << endPointGeo_absZ
<< " -> LineOfSight " << result;
return result;
#else
Q_UNUSED(startPointGeo_absZ);
Q_UNUSED(endPointGeo_absZ);
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, lineOfSightCalculation not available";
return LineOfSight::LOS_ERROR;
#endif
}
LineOfSight LtsElevationManager::lineOfSightCalculation(const QPointF& startPointGeo, double startHat,
const QPointF& endPointGeo, double endHat)
{
#ifdef BUILD_RTI
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START"
<< ", startPointGeo = " << startPointGeo << ", startHat = " << startHat
<< ", endPointGeo = " << endPointGeo << ", endHat = " << endHat;
SituationMap::ElevationMapManager::LineOfSight eleMapMgrResult =
d->m_elevationManager->lineOfSightCalculation(startPointGeo, startHat, endPointGeo, endHat);
LtsElevation::LineOfSight result = static_cast<LtsElevation::LineOfSight>(eleMapMgrResult);
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END"
<< ", startPointGeo = " << startPointGeo << ", startHat = " << startHat
<< ", endPointGeo = " << endPointGeo << ", endHat = " << endHat << " -> LineOfSight "
<< static_cast<int>(eleMapMgrResult);
return result;
#else
Q_UNUSED(startPointGeo);
Q_UNUSED(startHat);
Q_UNUSED(endPointGeo);
Q_UNUSED(endHat);
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, lineOfSightCalculation not available";
return LineOfSight::LOS_ERROR;
#endif
}
const QString toString(const LineOfSight& value)
{
switch (value)
{
case LineOfSight::LOS_UNDEFINED:
return QStringLiteral("LOS_UNDEFINED");
case LineOfSight::LOS_ERROR:
return QStringLiteral("LOS_ERROR");
case LineOfSight::LOS_VISIBLE:
return QStringLiteral("LOS_VISIBLE");
case LineOfSight::LOS_INVISIBLE:
return QStringLiteral("LOS_INVISIBLE");
}
Q_ASSERT(false);
return QStringLiteral("LineOfSightERROR");
}
std::ostream& operator<<(std::ostream& stream, const LineOfSight value)
{
stream << toString(value).toStdString();
return stream;
}
} // namespace LtsElevation