356 lines
12 KiB
C++
Executable File
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();
|
|
}
|
|
|
|
}
|
|
|