#include "lts_elevation_manager.h" #include #include #include #include #include #include #include #include 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"); namespace LtsElevation { class LtsElevationManager; using LtsElevatioMgrMapTrainingAreaId = QMap; static LtsElevatioMgrMapTrainingAreaId <sElevatioMgrMapTrainingAreaId() { 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() { delete m_elevationManager; } std::shared_ptr m_exmDtc; std::shared_ptr m_asmDtc; QStringList m_filePaths_rough_to_fine; SituationMap::ElevationMapManager *m_elevationManager{nullptr}; }; LtsElevationManager::LtsElevationManager() : QObject(nullptr) , d(new Private) , m_logger(getLogger("LtsElevationManager")) { ++s_counter; TRACE_LOG(m_logger) << LOGFUNCTION << " START, s_counter=" << s_counter << " this=" << this; TRACE_LOG(m_logger) << LOGFUNCTION << " END, s_counter=" << s_counter << " this=" << this; } LtsElevationManager::~LtsElevationManager() { --s_counter; TRACE_LOG(m_logger) << LOGFUNCTION << " START, s_counter=" << s_counter << " this=" << this; delete d; TRACE_LOG(m_logger) << LOGFUNCTION << " END, s_counter=" << s_counter << " this=" << this; } LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::createInstance(int exerciseId, const std::shared_ptr &exmDtc, const std::shared_ptr &asmDtc) { LOGGER_T logger = getLogger("LtsElevationManager"); TRACE_LOG(logger) << LOGFUNCTION << " START, exerciseId=" << exerciseId; if (exerciseId < 0) { ERROR_LOG(logger) << LOGFUNCTION << " exerciseId invalid, exerciseId=" << exerciseId; return nullptr; } int trainingAreaId = -1; static QHash s_exIdToTaIdStore; const auto exTaIt = s_exIdToTaIdStore.find(exerciseId); if (exTaIt != s_exIdToTaIdStore.end()) { trainingAreaId = *exTaIt; } else { if (!exmDtc || !asmDtc) { ERROR_LOG(logger) << LOGFUNCTION << " no dtcs for exerciseId=" << exerciseId << ", asmDtc=" << asmDtc << ", exmDtc=" << exmDtc; return nullptr; } trainingAreaId = exerciseIdToTrainingAreaId(exerciseId, exmDtc); if (trainingAreaId <= 0) { ERROR_LOG(logger) << LOGFUNCTION << " Error getting trainingAreaId" << ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId; return nullptr; } s_exIdToTaIdStore[exerciseId] = trainingAreaId; } LTS_ELEVATION_MANAGER_TYPE temp = createInstanceForTrainingAreaId(trainingAreaId, asmDtc); if (!temp) { ERROR_LOG(logger) << LOGFUNCTION << " Error on createInstanceForTrainingAreaId" << ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId; return nullptr; } temp->initDDS(exmDtc, asmDtc); TRACE_LOG(logger) << LOGFUNCTION << " END, exerciseId=" << exerciseId; return temp; } LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::getInstance(int exerciseId) { return LtsElevationManager::createInstance(exerciseId); } LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::createInstanceForTrainingAreaId(int trainingAreaId, const std::shared_ptr &asmDtc) { LOGGER_T logger = getLogger("LtsElevationManager"); TRACE_LOG(logger) << LOGFUNCTION << " START, trainingAreaId=" << trainingAreaId; if (trainingAreaId < 0) { ERROR_LOG(logger) << LOGFUNCTION << " trainingAreaId invalid, trainingAreaId=" << trainingAreaId; return nullptr; } LtsElevatioMgrMapTrainingAreaId &map = getLtsElevationMgrMapTrainingAreaId(); QMap::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) << LOGFUNCTION << " 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) << LOGFUNCTION << " no filenames for trainingAreaId=" << trainingAreaId; delete temp; return nullptr; } bool bInitFilenames = temp->init(filenames); if (!bInitFilenames) { ERROR_LOG(logger) << LOGFUNCTION << " 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) << LOGFUNCTION << " END, trainingAreaId=" << trainingAreaId; return map[trainingAreaId]; } LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::createInstanceUnitTest(int id, const QStringList &filePaths_rough_to_fine) { LOGGER_T logger = getLogger("LtsElevationManager"); LtsElevatioMgrMapTrainingAreaId &map = getLtsElevationMgrMapTrainingAreaId(); QMap::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) << LOGFUNCTION << " 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) << LOGFUNCTION << " END, trainingAreaId=" << id; return map[id]; } void LtsElevationManager::cleanupAll() { LOGGER_T logger = getLogger("LtsElevationManager"); TRACE_LOG(logger) << LOGFUNCTION << " START"; cleanupLtsElevatioMgrMapTrainingAreaId(); TRACE_LOG(logger) << LOGFUNCTION << " END"; } void LtsElevationManager::initDDS(const std::shared_ptr &exmDtc, const std::shared_ptr &asmDtc) { TRACE_LOG(m_logger) << LOGFUNCTION << " 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) << LOGFUNCTION << " END"; } QStringList LtsElevationManager::getFilenamesForExercise(int exerciseId) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!d->m_exmDtc || !d->m_asmDtc) { ERROR_LOG(m_logger) << LOGFUNCTION << " no dtcs" << ", exerciseId=" << exerciseId; return {}; } int trainingAreaId = exerciseIdToTrainingAreaId(exerciseId, d->m_exmDtc); if (trainingAreaId <= 0) { ERROR_LOG(m_logger) << LOGFUNCTION << " Error getting trainingAreaId" << ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId; return {}; } QStringList filePaths_rough_to_fine = getFilenamesForTrainingArea(trainingAreaId); TRACE_LOG(m_logger) << LOGFUNCTION << " 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) << LOGFUNCTION << " START"; if (!d->m_asmDtc) { ERROR_LOG(m_logger) << LOGFUNCTION << " 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) << LOGFUNCTION << " Error on s_asmDtc->trainingArea" << ", trainingAreaId=" << trainingAreaId; return {}; } const std::vector &mdVec = ta.elevation(); filePaths_rough_to_fine.reserve(mdVec.size()); for (const AssetManagement::MapDescription &md : qAsConst(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) << LOGFUNCTION << " END, filePaths_rough_to_fine=" << filePaths_rough_to_fine.join(QStringLiteral(";")); return filePaths_rough_to_fine; } bool LtsElevationManager::init(const QStringList &filePaths_rough_to_fine) { 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) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; FATAL_LOG(m_logger) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; FATAL_LOG(m_logger) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; FATAL_LOG(m_logger) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; FATAL_LOG(m_logger) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; FATAL_LOG(m_logger) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; FATAL_LOG(m_logger) << LOGFUNCTION << " ERROR, not all files could be loaded !!!"; return false; } return true; } int LtsElevationManager::exerciseIdToTrainingAreaId(int exerciseId, const std::shared_ptr &exmDtc) { LOGGER_T logger = getLogger("LtsElevationManager"); if (!exmDtc) { ERROR_LOG(logger) << LOGFUNCTION << " no dtcs" << ", exerciseId=" << exerciseId; return {}; } int trainingAreaId = -1; { exmDtc->waitForHistoricalDataExercise(1000); const ExerciseManagement::Exercise &exm = exmDtc->exercise(exerciseId); if (exm.id() != exerciseId) { ERROR_LOG(logger) << LOGFUNCTION << " Error on m_exmDtc->exercise" << ", exerciseId=" << exerciseId; return {}; } trainingAreaId = exm.trainingAreaId(); if (trainingAreaId <= 0) { ERROR_LOG(logger) << LOGFUNCTION << " Error getting trainingAreaId" << ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId; return -1; } } return trainingAreaId; } bool LtsElevationManager::waitForInitialization() { if (!d->m_elevationManager) return false; return d->m_elevationManager->waitForInitialization(); } bool LtsElevationManager::isValid() const { if (!d->m_elevationManager) return false; return d->m_elevationManager->isValid(); } double LtsElevationManager::elevation(double lon_rad, double lat_rad, double defaultValue, bool *bIsCovered) const { if (!d->m_elevationManager) return defaultValue; return d->m_elevationManager->elevation(lon_rad, lat_rad, defaultValue, bIsCovered); } LineOfSight LtsElevationManager::lineOfSightCalculation(const LtsUtils::QPoint3D &startPointGeo_absZ, const LtsUtils::QPoint3D &endPointGeo_absZ) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << ", startPointGeo_absZ = " << startPointGeo_absZ << ", endPointGeo_absZ = " << endPointGeo_absZ; if (!isValid()) { ERROR_LOG(m_logger) << LOGFUNCTION << " 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(eleMapMgrResult); TRACE_LOG(m_logger) << LOGFUNCTION << " END" << ", startPointGeo = " << startPointGeo_absZ << ", endPointGeo = " << endPointGeo_absZ << " -> LineOfSight " << result; return result; } LineOfSight LtsElevationManager::lineOfSightCalculation(const QPointF &startPointGeo, double startHat, const QPointF &endPointGeo, double endHat) { TRACE_LOG(m_logger) << LOGFUNCTION << " 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(eleMapMgrResult); TRACE_LOG(m_logger) << LOGFUNCTION << " END" << ", startPointGeo = " << startPointGeo << ", startHat = " << startHat << ", endPointGeo = " << endPointGeo << ", endHat = " << endHat << " -> LineOfSight " << static_cast(eleMapMgrResult); return result; } 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; } }