/** * @RDE_HEADER@ * Interface * $Id$ * $HeadURL$ * $Author$ */ #include "ncontamination_to_map.h" #include #include 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 it(m_simId2UniqueMapId); while (it.hasNext()) { it.next(); const UniqueMapId uniqueMapId = it.value(); RefPointer mapObj = m_objFac.get(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 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 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; } }