Files
qt5-legatus-legacy/Lts/Plugins/SituationMapPlugin/Gui/SituationMap/AdapterDds/ncontamination_to_map.cpp
T
2026-08-13 18:33:10 +02:00

181 lines
6.2 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
#include "ncontamination_to_map.h"
#include <Map/map.h>
#include <Map/object_factory.h>
namespace SituationMap
{
//------------------------------------------------------------------------------
bool NContamination2SituationMap::run()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!m_aesDtc)
return false;
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::nContaminationChanged,
this, &NContamination2SituationMap::handleChanged, Qt::UniqueConnection);
// get:
m_aesDtc->nContaminations([this](const AreaEffectSimulation::NContamination &data)
{
handleChanged(data, DataModification::eAdded);
});
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
this, &NContamination2SituationMap::onPartitionTimeChanged, Qt::UniqueConnection);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return BaseClass::run();
}
void NContamination2SituationMap::onPartitionTimeChanged(qint64 newPartitionTime)
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START, newPartitionTime=" << newPartitionTime
// << ", exerciseId = " << m_pluginProvider->exerciseId()
// << ", workspaceId = " << m_pluginProvider->workspaceId()
// << ", this=" << this;
updateAllSpheres3D(newPartitionTime);
}
void NContamination2SituationMap::updateAllSpheres3D(qint64 newPartitionTime)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< ", m_simId2UniqueMapId.size = " << m_simId2UniqueMapId.size();
// iterate using m_simId2UniqueMapId vs using m_ddsDataContainer
// m_simId2UniqueMapId contains existing (map) objects
// m_ddsDataContainer may contain outdated elements (expired).
// But expired items are relevant for listOverviews...
// so iterate using m_simId2UniqueMapId:
QMapIterator<int32_t, UniqueMapId> it(m_simId2UniqueMapId);
while (it.hasNext())
{
it.next();
const UniqueMapId uniqueMapId = it.value();
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
if (!mapObj.valid())
continue;
const int simId = it.key();
const AreaEffectSimulation::NContamination &nCont = m_aesDtc->nContamination(simId);
if (nCont.id() != simId)
continue;
if (updateSphere3D(mapObj, nCont, newPartitionTime))
if (!mapObj->updateView())
WARNING_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " updateView failed";
} // while
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
}
bool NContamination2SituationMap::updateSphere3D(RefPointer<Sim2SituationMap::MAP_T> mapObj, const AreaEffectSimulation::NContamination &data, qint64 newPartitionTime)
{
const int32_t simId = data.id(); // simId of area ('parent')
if (!mapObj)
return false;
bool bUpdateRequired = false;
const bool bDesiredNewState = (data.effectStateId().underlying() == AreaEffectSimulation::AesEffectState_def::EsActivated) && // Assume, that NContamination will not expire within that 5 seconds...
((newPartitionTime - data.sampleTime() < 5000)); // 5000 = 5 sec
TRACE_LOG(m_logger) << LOGFUNCTION << ", START" << " simId = " << simId
<< ", sampleTime " << data.sampleTime()
<< ", bDesiredNewState " << bDesiredNewState;
// The sphere begins being displayed at the impact time, object has EffectState::Active.
// Accordingly impactPosition can _not_ change anymore!!!
// So we do not have to update the origin of the SceneMarker
// We can simplify and recognized the changes: ADDING or REMOVING the marker
// MSS has to be removed?
if (mapObj->hasDetonation() && !bDesiredNewState)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << ", START REMOVE " << " simId = " << simId;
mapObj->resetDetonation();
bUpdateRequired = true;
}
// MSS has to be added?
else if (!mapObj->hasDetonation() && bDesiredNewState)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << ", START ADD " << " simId = " << simId;
const Core::GeoPosition2D &geoPos = data.impactPosition();
Point3D markerOrigin(geoPos.lon(), geoPos.lat(), 0); // ToDo: impactPosition -> 3D
mapObj->setDetonation(markerOrigin, data.impactRadius());
bUpdateRequired = true;
}
TRACE_LOG(m_logger) << LOGFUNCTION << ", END" << " simId = " << simId;
return bUpdateRequired;
}
bool NContamination2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
RefPointer<MAP_T> mapObj)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// show just the ObjectAppearance::Technical
mapObj->setVisibility(ObjectAppearance::Tactical, false);
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
// if partyId is not set (like B,C agent), use default color
if (ddsData.partyId().is_set())
mapObj->setPartyId(ddsData.partyId().get());
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
updateSphere3D(mapObj, ddsData, m_pluginProvider->partitionTime());
const int32_t simId = ddsData.id();
AreaEffectSimulation::AesItemView itemView;
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtNContamination, itemView))
this->updateGeometry(itemView, mapObj);
else
{
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " no AesItemView (AtNContamination) found"
<< ", simId = " << simId
<< ", provide fallBackGeometry";
// provide fallbackGeometry to avoid errorMsg like 'incorrect number of positions'
mapObj->setPositions({{0.0, 0.0, .0},
{0.0, 0.1, .0},
{0.1, 0.1, .0},
{0.1, 0.0, .0}});
// do not return here, perform stuff like updateVisibility and so on
}
// 'Impact':
const Core::GeoPosition2D& impactPos2D = ddsData.impactPosition();
mapObj->setImpactOrigin(Point3D(impactPos2D.lon(), impactPos2D.lat(), 0.0));
updateVisibility(ddsData, mapObj);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
}