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

356 lines
12 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Guez Nasat NineLiner 9Liner
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "guez_nasat_9liner.h"
#include <Map/object_factory.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <MathUtils/simple_helper.h>
#include <Common/PluginInterfaces/gui_plugin_interface.h> // for method "getForeignGuiInterface"
// Qt
#include <QPolygonF>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QTimer>
namespace SituationMap
{
int32_t GuezNasat9Liner2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
{
return ddsData.id();
}
GuezNasat9Liner2SituationMap::GuezNasat9Liner2SituationMap(ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName)
: BaseClass(objFac, layername, drawOrder, loggerName)
, FilterClass(loggerName, this)
, m_pluginProvider(nullptr)
, m_notifyTimer(new QTimer(this))
{
m_notifyTimer->setInterval(500);
m_notifyTimer->setSingleShot(true);
connect(m_notifyTimer, &QTimer::timeout,
this, &GuezNasat9Liner2SituationMap::updateAllItems);
}
GuezNasat9Liner2SituationMap::~GuezNasat9Liner2SituationMap()
{
m_notifyTimer->stop();
}
bool GuezNasat9Liner2SituationMap::init(PluginProvider *pluginProvider)
{
if (!pluginProvider)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no pluginProvider";
return false;
}
m_pluginProvider = pluginProvider;
m_gnaDtc = pluginProvider->gnaDtc();
if (!m_gnaDtc)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_gnaDtc";
return false;
}
m_gnaDtc->enableNasat9Liner();
// m_gnaDtc->waitForHistoricalDataNasat9Liner(); // blocks ???
m_ppmDtc = pluginProvider->ppmDtc();
if (!m_ppmDtc)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_ppmDtc";
return false;
}
// FilterManagement:
FilterClass::init(m_pluginProvider);
// PartitionTime
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
this, &GuezNasat9Liner2SituationMap::onPartitionTimeChanged);
return true;
}
bool GuezNasat9Liner2SituationMap::run()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!m_gnaDtc)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
return false;
}
// PPM
{
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
this, &GuezNasat9Liner2SituationMap::onParticipantChanged, Qt::UniqueConnection);
// get:
m_ppmDtc->participants([this](const ParticipantManagement::Participant &data)
{
onParticipantChanged(data, DataModification::eAdded);
});
}
// GNA
{
connect(m_gnaDtc.get(), &GuezNasat::Interface::Dtc::nasat9LinerChanged,
this, &GuezNasat9Liner2SituationMap::handleChanged, Qt::UniqueConnection);
// get:
m_gnaDtc->nasat9Liners([this](const GuezNasat::Nasat9Liner & data)
{
handleChanged(data, DataModification::eAdded);
});
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool GuezNasat9Liner2SituationMap::isElapsed(const GuezNasat::Nasat9Liner &ddsData) const
{
// true -> hide
// false -> show
DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData;
if (BaseClass::isElapsed(ddsData))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData << " HIDE";
return true;
}
// GUEZE-1676: Nineliner sollen zeitlich wie Trefferlinien angezeigt werden
// replace checkbox by slider, so 'isCurrent' is outdated:
DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData << " SHOW";
return false;
}
bool GuezNasat9Liner2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
{
// if(!m_bldInfoIfc)
// return false;
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
if (simIds.isEmpty())
return true;
// m_bldInfoIfc->showInfoWindow(simIds);
return true;
}
bool GuezNasat9Liner2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
{
if (!m_gnaDtc)
return false;
int32_t simIdOut = -1;
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
return false;
umodOut = UnifiedMapObjectData();
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
if (mapObj.valid())
umodOut.m_image = mapObj->previewImage();
umodOut.m_description1 = QString::fromStdString(m_gnaDtc->nasat9Liner(simIdOut).name());
return true;
}
void GuezNasat9Liner2SituationMap::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " pId=" << data.id()
<< " parytIdOld=" << m_participantToPartyId.value(data.id(), -1)
<< " parytId=" << data.partyId()
<< ", m_participantToPartyId.size()=" << m_participantToPartyId.size();
const int simId = data.id();
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
m_participantToPartyId[simId] = data.partyId();
break;
case DataModification::eRemoved:
m_ddsDataContainer.remove(simId);
break;
}
// what can change?
// - participant moves from one party to another
//
// schedule slot updateAllItems
m_notifyTimer->start();
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_participantToPartyId.size()=" << m_participantToPartyId.size();
}
bool GuezNasat9Liner2SituationMap::handleChanged(const Sim2SituationMap::DDS_T &ddsData, DataModification modType)
{
m_notifyTimer->start();
updateDdsDataContainer(ddsData, modType); // helpfull for FilterManagement/onSymbolAppearanceSettingsChanged
return BaseClass::handleChanged(ddsData, modType);
}
bool GuezNasat9Liner2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
RefPointer<MAP_T> mapObj)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " id=" << ddsData.id()
<< " name=" << ddsData.name()
<< " isCurrent=" << ddsData.isCurrent()
<< " initialPoint=" << ddsData.initialPoint()
<< " targetPosition=" << ddsData.targetPosition()
<< " participantId=" << ddsData.participantId()
<< " m_participantToPartyId.size()=" << m_participantToPartyId.size()
<< " partyId.size()=" << m_participantToPartyId.value(ddsData.participantId(), -1);
mapObj->setPickable(false);
// show just the ObjectAppearance::Technical
mapObj->setVisibility(ObjectAppearance::Tactical, false);
// PartyId, if not available yet it will be updated later
// (via onParticipantChanged and m_notifyTimer)
mapObj->setPartyId(m_participantToPartyId.value(ddsData.participantId(), -1));
TextStyle ts = mapObj->textStyle();
ts.setHorizontalAlignment(HorizontalAlignment::Center);
mapObj->setTextStyle(ts);
MAP_T::NineLinerData data;
data.initialPoint = Point3D(ddsData.initialPoint().lon(), ddsData.initialPoint().lat(), .0);
data.targetPosition = Point3D(ddsData.targetPosition().lon(), ddsData.targetPosition().lat(), .0);
data.fah = ddsData.finalAttackHeading();
data.fahLow = ddsData.finalAttackHeadingLow();
data.fahHigh = ddsData.finalAttackHeadingHigh();
data.friendliesBearing = ddsData.friendliesBearing();
data.friendliesDistance = ddsData.friendliesDistance();
mapObj->setNineLinerData(data);
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool GuezNasat9Liner2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
{
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
(m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec != newSas.symbolSettings.nasatNineLinerDisplayLengthMSec);
}
void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
for (const GuezNasat::Nasat9Liner &nineLiner : qAsConst(m_ddsDataContainer))
{
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(nineLiner.id());
if (!mapObj.valid())
continue;
handleSymbolAppearanceSettings(mapObj, nineLiner);
} // for
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
}
void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
{
if (!mapObj.valid())
return;
const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId());
handleSymbolAppearanceSettings(mapObj, m_ddsDataContainer.value(simId));
// Since svc GNA updates sample_time for outdated nineLiner(isCurrent==false),
// (see handler_nasat_nine_liner.cpp) following workaround is obsolete:
// bool bIsRealCurrent = true;
// int32_t simIdOut = -1;
// if (uniqueMapId2SimId(mapObj->uniqueMapId(), simIdOut))
// {
// const DDS_T ddsData = m_ddsDataContainer[simIdOut];
// qint64 youngestSampleTime = getYoungestSampleTimeOfCurrentForParticipant(ddsData.participantId());
// if (youngestSampleTime == ddsData.sampleTime())
// {
// DEBUG_LOG(m_logger) << LOGFUNCTION << " IS YOUNGEST ITEM " << simIdOut;
// bIsRealCurrent = true;
// } else {
// DEBUG_LOG(m_logger) << LOGFUNCTION << " IS NOT YOUNGEST ITEM " << simIdOut;
// bIsRealCurrent = false;
// }
// }
}
void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings(RefPointer<Sim2SituationMap::MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData)
{
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
const bool isVisi = visibleByDisplayLength(m_pluginProvider->partitionTime(), ddsData.sampleTime());
if (mapObj->visibility() != isVisi)
{
mapObj->setVisibility(isVisi);
if (!mapObj->updateView())
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
<< " mapObj = " << mapObj->debugInfo();
}
}
bool GuezNasat9Liner2SituationMap::visibleByDisplayLength(const qint64 newPartitionTime, const qint64 stateTime) const
{
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " newPartitionTime = " << newPartitionTime
<< " stateTime = " << stateTime
<< " age = " << (newPartitionTime - stateTime)
<< " nasatNineLinerDisplayLengthMSec = " << m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec;
if (m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec < 0)
return true;
return (newPartitionTime - stateTime) <= m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec; // all msec
}
void GuezNasat9Liner2SituationMap::onPartitionTimeChanged()
{
handleSymbolAppearanceSettings();
}
void GuezNasat9Liner2SituationMap::updateAllItems()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
for (const DDS_T &ddsData : qAsConst(m_ddsDataContainer))
{
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(ddsData.id());
if (!mapObj.valid())
continue;
updateElementImpl(ddsData, mapObj);
handleSymbolAppearanceSettings(mapObj);
if (!mapObj->updateView())
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed for "<< mapObj->debugInfo();
} // for
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
}
}