141 lines
4.1 KiB
C++
Executable File
141 lines
4.1 KiB
C++
Executable File
|
|
|
|
|
|
#include "positions_cnr.h"
|
|
#include <utility>
|
|
#include "exercise_manager.h"
|
|
#include "helper.h"
|
|
#include <AudioVideoManagement/avm_dtc.h>
|
|
#include <ParticipantManagement/ppm.hpp>
|
|
#include <LtsUtils/LtsUtilsCore/outdated_position.h>
|
|
#include <QtGlobal>
|
|
#include <QDateTime>
|
|
#include <QSet>
|
|
|
|
namespace
|
|
{
|
|
|
|
QSet<int> participantIdsFromParty(const QMap<int32_t, ParticipantManagement::Participant> &participants, int partyId, bool isGlobal)
|
|
{
|
|
QSet<int> ret;
|
|
if (isGlobal)
|
|
{
|
|
ret.reserve(participants.size());
|
|
for (const auto &p : participants)
|
|
ret += p.id();
|
|
}
|
|
else
|
|
{
|
|
for (const auto &participant : participants)
|
|
if (participant.partyId() == partyId)
|
|
ret += participant.id();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
namespace CombatNetRadio
|
|
{
|
|
|
|
PositionsCnr::PositionsCnr(int exerciseId, ExerciseManager *exerciseManager, ParticipantManagement::Interface::Dtc *ppmDtc, AudioVideoManagement::Interface::Dtc *avmDtc)
|
|
: m_exerciseId(exerciseId)
|
|
, m_exerciseManager(exerciseManager)
|
|
, m_ppmDtc(ppmDtc)
|
|
, m_avmDtc(avmDtc)
|
|
{
|
|
Q_ASSERT(exerciseId > 0);
|
|
Q_ASSERT(exerciseManager);
|
|
Q_ASSERT(ppmDtc);
|
|
Q_ASSERT(avmDtc);
|
|
}
|
|
|
|
WebSocketInterface::Messages::PositionsCnrMessage::PositionsCnrMessageData PositionsCnr::data() const
|
|
{
|
|
WebSocketInterface::Messages::PositionsCnrMessage::PositionsCnrMessageData positionsData;
|
|
|
|
positionsData.time = QDateTime::currentDateTime().toString(Qt::ISODate);
|
|
|
|
boost::optional<AudioVideoManagement::FrequencyPlanning> plan = activePlan();
|
|
if (!plan)
|
|
return positionsData;
|
|
|
|
for (const auto &entry : plan->data())
|
|
{
|
|
AudioVideoManagement::CnrConfig cnrConfig = m_avmDtc->cnrConfig(entry.cnrConfigId());
|
|
AudioVideoManagement::CnrChannel cnrChannel = m_avmDtc->cnrChannel(cnrConfig.cnrChannelId());
|
|
|
|
positionsData.radioCircuit.push_back({toRcIdString(cnrChannel), positionsFor(cnrConfig)});
|
|
}
|
|
|
|
return positionsData;
|
|
}
|
|
|
|
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> PositionsCnr::positionsForGlobal(const AudioVideoManagement::CnrConfig &config) const
|
|
{
|
|
bool isGlobal = !config.exerciseId().is_set();
|
|
Q_ASSERT(isGlobal);
|
|
return positionsForLocal(config);
|
|
}
|
|
|
|
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> PositionsCnr::positionsFor(const AudioVideoManagement::CnrConfig &config) const
|
|
{
|
|
bool isLocal = config.exerciseId().is_set();
|
|
if (isLocal)
|
|
return positionsForLocal(config);
|
|
else
|
|
return m_exerciseManager->positionsForGlobal(config);
|
|
}
|
|
|
|
|
|
|
|
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> PositionsCnr::positionsForLocal(const AudioVideoManagement::CnrConfig &config) const
|
|
{
|
|
auto allParticipants = m_ppmDtc->participants();
|
|
|
|
QSet<int> participantIdsInUnit;
|
|
if (config.unitId().is_set())
|
|
m_ppmDtc->participantIdsByUnit(config.unitId().get(), allParticipants, participantIdsInUnit);
|
|
else
|
|
{
|
|
bool isGlobal = !config.exerciseId().is_set();
|
|
participantIdsInUnit = participantIdsFromParty(allParticipants, config.partyId(), isGlobal);
|
|
}
|
|
|
|
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
|
|
|
QVector<WebSocketInterface::Messages::ReplyMessage::LonLatPoint> positions;
|
|
for (int participantId : std::as_const(participantIdsInUnit))
|
|
{
|
|
const ParticipantManagement::Participant &participant = allParticipants.value(participantId);
|
|
if (!participant.equipmentNumber().is_set())
|
|
continue;
|
|
|
|
const ParticipantManagement::Type &type = m_ppmDtc->type(participant.typeId());
|
|
if (type.radioCount() < 1)
|
|
continue;
|
|
|
|
const auto &pos = m_ppmDtc->participantPosition(participantId);
|
|
if (pos.participantId() != participantId)
|
|
continue;
|
|
|
|
if (LtsUtils::isPositionTimeOutdated(now, pos.sampleTime()))
|
|
continue;
|
|
|
|
positions.push_back({toDeg(pos.pos().lon()), toDeg(pos.pos().lat())});
|
|
}
|
|
|
|
return positions;
|
|
}
|
|
|
|
boost::optional<AudioVideoManagement::FrequencyPlanning> PositionsCnr::activePlan() const
|
|
{
|
|
AudioVideoManagement::ActiveFrequencyPlanning activePlanning = m_avmDtc->activeFrequencyPlanning(m_exerciseId);
|
|
if (activePlanning.exerciseId() != m_exerciseId)
|
|
return boost::none;
|
|
return m_avmDtc->frequencyPlanning(activePlanning.frequencyPlanningId());
|
|
}
|
|
|
|
}
|