862 lines
23 KiB
C++
Executable File
862 lines
23 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Custom ppm functions (extends tab_db_impl.cpp/.h)
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "ppm_dtc_impl_custom.h"
|
|
#include "ppm_common.h"
|
|
#include <DDS/DTC/generic_dtc.h>
|
|
#include <DDS/Generic/generic_data_reader.h>
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
#include <LtsUtilsCore/json_object.h>
|
|
|
|
#include <QJsonObject>
|
|
#include <QJsonParseError>
|
|
#include <QPolygonF>
|
|
#include <QSet>
|
|
#include <QVector>
|
|
|
|
namespace ParticipantManagement
|
|
{
|
|
namespace Interface
|
|
{
|
|
DtcImplCustom::DtcImplCustom(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector)
|
|
: DtcImpl(ddsConnector)
|
|
{
|
|
}
|
|
|
|
bool DtcImplCustom::rootTemplates(QVector<TemplateParticipant> &templateVector) const
|
|
{
|
|
if (!m_dtcTemplateParticipant)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error retrieving data topic TemplateParticipant";
|
|
return false;
|
|
}
|
|
|
|
for (const auto &sample : m_dtcTemplateParticipant->readAlive())
|
|
{
|
|
if (sample.data().superiorTemplateId() == 0)
|
|
templateVector.append(sample.data());
|
|
}
|
|
|
|
return !templateVector.isEmpty();
|
|
}
|
|
|
|
bool DtcImplCustom::templateParticipantsFromTemplateId(int rootTemplateId, QVector<TemplateParticipant> &templateVector)
|
|
{
|
|
templateVector.append(inferiorTemplates(rootTemplateId));
|
|
return !templateVector.isEmpty();
|
|
}
|
|
|
|
TemplateData DtcImplCustom::convertFromParticipantTemplateToTemplateData(const TemplateParticipant &inputTemplate) const
|
|
{
|
|
TemplateData outputData;
|
|
TemplateBase &out = outputData;
|
|
out = inputTemplate;
|
|
// in cases where the ids are not updated by the treeModel
|
|
outputData.modId(inputTemplate.templateId());
|
|
outputData.superiorModId(inputTemplate.superiorTemplateId());
|
|
|
|
return outputData;
|
|
}
|
|
|
|
ParticipantData Interface::DtcImplCustom::convertParticipantToParticipantData(const Participant &inputParticipant) const
|
|
{
|
|
ParticipantData outputData;
|
|
ParticipantBase &out = outputData;
|
|
out = inputParticipant;
|
|
// in cases where the ids are not updated by the treeModel
|
|
outputData.modId(inputParticipant.id());
|
|
outputData.superiorModId(inputParticipant.superiorId());
|
|
|
|
return outputData;
|
|
}
|
|
|
|
ParticipantManagement::StateInformation DtcImplCustom::youngestStateInformation(
|
|
const std::vector<ParticipantManagement::StateInformation> &stateList /*, bool debug*/) const
|
|
{
|
|
return ParticipantManagement::youngestStateInformation(stateList /*, true, true, debug*/);
|
|
}
|
|
|
|
ParticipantManagement::SanitationResult DtcImplCustom::proceduresDone(const std::vector<StateInformation> &stateList) const
|
|
{
|
|
return ParticipantManagement::proceduresDone(stateList);
|
|
}
|
|
|
|
QMap<int, Participant> DtcImplCustom::units() const
|
|
{
|
|
QMap<int, Participant> ret;
|
|
if (!m_dtcType)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error retrieving data topic Type";
|
|
return ret;
|
|
}
|
|
|
|
if (!m_dtcParticipant)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error retrieving data topic Participant";
|
|
return ret;
|
|
}
|
|
|
|
QSet<int> unitTypeIds;
|
|
for (const auto &sample : m_dtcType->readAlive())
|
|
{
|
|
if (sample.data().typeClass() == TypeClass::Unit || sample.data().typeClass() == TypeClass::SupportUnit)
|
|
unitTypeIds.insert(sample.data().id());
|
|
}
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (unitTypeIds.contains(sample.data().typeId()))
|
|
ret.insert(sample.data().id(), sample.data());
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool DtcImplCustom::participantIdsByUnit(int unitId, const QMap<int, Participant> &participants, QSet<int> &participantIds)
|
|
{
|
|
const ParticipantManagement::Participant unit(participants.value(unitId));
|
|
if (unit.id() != unitId)
|
|
return false;
|
|
|
|
const ParticipantManagement::Type unitType(type(unit.typeId()));
|
|
if (unitType.typeClass() != ParticipantManagement::TypeClass::Unit && unitType.typeClass() != ParticipantManagement::TypeClass::SupportUnit)
|
|
return false;
|
|
|
|
participantIds += recursiveInferiosForParticipant(unitId, participants);
|
|
return true;
|
|
}
|
|
|
|
bool DtcImplCustom::visibleParties(QMap<int32_t, Party> &visibleParties, const QVector<int> &filter) const
|
|
{
|
|
if (!m_dtcParty)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error retrieving data topic Party";
|
|
return false;
|
|
}
|
|
|
|
const bool bAll = (filter.size() == 1 && filter.first() == -1);
|
|
for (const auto &sample : m_dtcParty->readAlive())
|
|
if (bAll || filter.contains(sample.data().id()))
|
|
visibleParties.insert(sample.data().id(), sample);
|
|
|
|
return true;
|
|
}
|
|
|
|
QString DtcImplCustom::hierarchyFromParticipant(int participantId) { return lookUpHierachy(participantId, participants()); }
|
|
|
|
QString DtcImplCustom::hierarchyFromParticipant(int participantId, const QMap<int, Participant> &participants) const
|
|
{
|
|
return lookUpHierachy(participantId, participants);
|
|
}
|
|
|
|
bool DtcImplCustom::isEquipmentNumberInUse(int equipmentNumber, int &exerciseId) const
|
|
{
|
|
if (!m_dtcEquipmentExerciseMapping)
|
|
return true; // we're not sure - return true ...
|
|
|
|
for (const auto &sample : m_dtcEquipmentExerciseMapping->readAlive())
|
|
{
|
|
for (const Equipment2ParticipantId &e2p : sample.data().mapping())
|
|
{
|
|
if (e2p.equipmentNumber() == equipmentNumber)
|
|
{
|
|
exerciseId = sample.data().exerciseId();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DtcImplCustom::isTypeInUse(int typeId) const
|
|
{
|
|
if (!m_dtcParticipant)
|
|
return true; // we're not sure - return true ...
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (sample.data().typeId() == typeId)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int DtcImplCustom::participantIdByEquipmentNumber(int equipmentNumber) const
|
|
{
|
|
if (!m_dtcParticipant)
|
|
return -1;
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (sample.data().equipmentNumber().is_set() && sample.data().equipmentNumber().get() == equipmentNumber)
|
|
return sample.data().id();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int DtcImplCustom::equipmentNumberByParticipantId(int participantId) const
|
|
{
|
|
if (!m_dtcParticipant)
|
|
return -1;
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (sample.data().id() == participantId)
|
|
{
|
|
if (sample.data().equipmentNumber().is_set())
|
|
return sample.data().equipmentNumber().get();
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int DtcImplCustom::uasMissionIdByEquipmentNumber(int equipmentNumber) const
|
|
{
|
|
if (m_dtcMissionPlan == nullptr)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
const int participantId = participantIdByEquipmentNumber(equipmentNumber);
|
|
if (participantId < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
for (const auto &sample : m_dtcMissionPlan->readAlive())
|
|
{
|
|
if (sample.data().participantId() == participantId)
|
|
{
|
|
return sample.data().id();
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int DtcImplCustom::partyIdFromForceIdentifier(HlaForceIdentifierEnum inputForceIdentifier) const
|
|
{
|
|
if (!m_dtcParty)
|
|
return -1;
|
|
|
|
for (const auto &sample : m_dtcParty->readAlive())
|
|
{
|
|
if (sample.data().hlaForceIdentifier() == inputForceIdentifier)
|
|
return sample.data().id();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
ConnectState DtcImplCustom::saaConnectedState(const int partyId)
|
|
{
|
|
ConnectState ret = ConnectState::Undefined;
|
|
if (!isPartyEnabled())
|
|
{
|
|
enableParty();
|
|
waitForHistoricalDataParty(10);
|
|
}
|
|
|
|
if (!m_dtcParty)
|
|
return ret;
|
|
|
|
for (const auto &sample : m_dtcParty->readAlive())
|
|
{
|
|
if (partyId != sample.data().id())
|
|
continue;
|
|
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(sample.data().properties()));
|
|
QJsonObject prop = doc.object();
|
|
QJsonObject propAdler;
|
|
if (prop.contains(QStringLiteral("Adler")))
|
|
{
|
|
propAdler = prop[QStringLiteral("Adler")].toObject();
|
|
if (propAdler.contains(QStringLiteral("saaConnectedState")))
|
|
return static_cast<ConnectState::inner_enum>(propAdler[QStringLiteral("saaConnectedState")].toInt());
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
QVector<int> DtcImplCustom::getSubordinatesByParticipant(const int participantId)
|
|
{
|
|
QVector<int> result;
|
|
if (!m_dtcParticipant)
|
|
return result;
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (sample.data().superiorId() == participantId)
|
|
result.append(sample.data().id());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
QVector<int> DtcImplCustom::getParticipantsByPolygon(const QPolygonF &polygon, bool includeUnits, bool includeOc)
|
|
{
|
|
QVector<int> participantsInPolygon;
|
|
QSet<int> unitTypeIds;
|
|
|
|
if (!isParticipantPositionEnabled())
|
|
{
|
|
enableParticipantPosition();
|
|
waitForHistoricalDataParticipantPosition(10);
|
|
}
|
|
|
|
if (!includeUnits)
|
|
{
|
|
if (!isTypeEnabled())
|
|
{
|
|
enableType();
|
|
waitForHistoricalDataType(10);
|
|
}
|
|
for (const auto &sample : m_dtcType->readAlive())
|
|
{
|
|
if (sample.data().typeClass() == TypeClass::Unit || sample.data().typeClass() == TypeClass::SupportUnit)
|
|
unitTypeIds.insert(sample.data().id());
|
|
}
|
|
}
|
|
|
|
participantsInPolygon.reserve(m_dtcParticipantPosition->readAlive().length());
|
|
|
|
for (const auto ¤tPosition : m_dtcParticipantPosition->readAlive())
|
|
{
|
|
if (!includeUnits && unitTypeIds.contains(currentPosition.data().participantTypeId()))
|
|
continue;
|
|
|
|
if (!includeOc && currentPosition.data().partyId() == 1) // partyId 1 = OC
|
|
continue;
|
|
|
|
const Core::GeoPosition ¤tGeoPosition = currentPosition.data().pos();
|
|
const QPointF positionPoint(currentGeoPosition.lon(), currentGeoPosition.lat());
|
|
|
|
if (polygon.containsPoint(positionPoint, Qt::OddEvenFill))
|
|
participantsInPolygon.append(currentPosition.data().participantId());
|
|
}
|
|
|
|
return participantsInPolygon;
|
|
}
|
|
|
|
// All Participant-Ids of Type UAS
|
|
QVector<int> DtcImplCustom::getUasIds()
|
|
{
|
|
QVector<int> result;
|
|
if (!m_dtcParticipant)
|
|
return result;
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (isTypeUas(sample.data().typeId()))
|
|
{
|
|
result.append(sample.data().id());
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
UAS DtcImplCustom::getUasByParticipantId(int participantId, int exerciseId) const
|
|
{
|
|
ParticipantManagement::UAS uas;
|
|
uas.id(-1); // if not found
|
|
|
|
for (const auto &sample : m_dtcUAS->readAlive())
|
|
{
|
|
if (sample.data().participantId() != participantId)
|
|
continue;
|
|
if (sample.data().exerciseId() != exerciseId)
|
|
continue;
|
|
uas = sample;
|
|
break;
|
|
}
|
|
return uas;
|
|
}
|
|
|
|
MissionAction DtcImplCustom::currentMissionAction(int missionPlanId) const
|
|
{
|
|
ParticipantManagement::MissionAction missionAction;
|
|
missionAction.planId(0); // default compare value in case nothing found
|
|
for (const auto &sample : m_dtcMissionPlan->readAlive())
|
|
{
|
|
if (sample.data().id() != missionPlanId)
|
|
continue;
|
|
const std::vector<ParticipantManagement::MissionItem> &items = sample.data().items();
|
|
for (const auto &item : items)
|
|
{
|
|
if (item.fulfilled() > 0)
|
|
continue;
|
|
const std::vector<ParticipantManagement::MissionAction> &actions = item.actions();
|
|
for (const auto &action : actions)
|
|
{
|
|
if (action.fulfilled() > 0)
|
|
continue;
|
|
return action;
|
|
}
|
|
}
|
|
}
|
|
return missionAction;
|
|
}
|
|
|
|
ParticipantManagement::Participant DtcImplCustom::getParticipantByInternalName(int partyId, const QString &unitName, const QString &internalName) const
|
|
{
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (sample.data().partyId() != partyId)
|
|
continue;
|
|
if (sample.data().isDeleted())
|
|
continue;
|
|
if (sample.data().name() != unitName.toStdString())
|
|
continue;
|
|
// Found Unit
|
|
|
|
// looking for Unit only?
|
|
if (internalName.isEmpty())
|
|
{
|
|
return sample;
|
|
}
|
|
|
|
for (auto inferiorId : sample.data().inferiorIds())
|
|
{
|
|
const auto &inferiorParticipant = m_participantCont.value(inferiorId);
|
|
if (inferiorParticipant.id() <= 0 || inferiorParticipant.isDeleted())
|
|
continue;
|
|
if (inferiorParticipant.name() == internalName.toStdString())
|
|
return inferiorParticipant;
|
|
}
|
|
}
|
|
|
|
return ParticipantManagement::Participant();
|
|
}
|
|
|
|
QSet<int> DtcImplCustom::recursiveInferiosForParticipant(int32_t participantId, const QMap<int, Participant> &participants)
|
|
{
|
|
QSet<int> result;
|
|
auto it = participants.find(participantId);
|
|
if (it == participants.end())
|
|
return result;
|
|
|
|
result += participantId;
|
|
const Participant &p = it.value();
|
|
for (int childId : p.inferiorIds())
|
|
result += recursiveInferiosForParticipant(childId, participants);
|
|
return result;
|
|
}
|
|
|
|
QString DtcImplCustom::lookUpHierachy(int participantId, const QMap<int, Participant> &participants)
|
|
{
|
|
if (participantId <= 0)
|
|
return QString();
|
|
|
|
const auto itPart = participants.find(participantId);
|
|
if (itPart == participants.end())
|
|
return QString();
|
|
const auto &part = itPart.value();
|
|
|
|
QString supStr = lookUpHierachy(part.superiorId(), participants);
|
|
QString ret = QString::fromStdString(part.designator());
|
|
// First separator is "./"
|
|
if (part.superiorId() == 0)
|
|
return (ret + QLatin1String("./"));
|
|
|
|
if (supStr.endsWith(QLatin1String("./")))
|
|
return (supStr + ret);
|
|
|
|
return (supStr.isEmpty() ? ret : supStr + QLatin1Char(',') + ret);
|
|
}
|
|
|
|
// private
|
|
QVector<TemplateParticipant> DtcImplCustom::inferiorTemplates(int templateId)
|
|
{
|
|
QVector<TemplateParticipant> retVector;
|
|
const TemplateParticipant participant = templateParticipant(templateId);
|
|
retVector.append(participant);
|
|
|
|
if (participant.inferiorIds().is_set())
|
|
{
|
|
retVector.reserve(participant.inferiorIds().get().size() + retVector.size());
|
|
for (int inferiorId : participant.inferiorIds().get())
|
|
retVector.append(inferiorTemplates(inferiorId));
|
|
}
|
|
|
|
return retVector;
|
|
}
|
|
|
|
bool DtcImplCustom::isTypePatientSimulator(int typeId) const
|
|
{
|
|
if (!m_dtcParticipant)
|
|
return false;
|
|
|
|
for (const auto &sample : m_dtcParticipant->readAlive())
|
|
{
|
|
if (sample.data().typeId() == typeId)
|
|
{
|
|
const std::string &str = sample.data().properties();
|
|
if (str.size() > 0 && getNeedsIp(str) && getNeedsPort(str))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DtcImplCustom::isAdlerType(int typeId) const
|
|
{
|
|
if (!m_dtcType)
|
|
return false;
|
|
|
|
for (const Type &type : m_dtcType->readAlive())
|
|
{
|
|
if (type.id() != typeId)
|
|
continue;
|
|
const auto &prob = type.properties();
|
|
|
|
QJsonParseError parserError;
|
|
const QByteArray props(QByteArray::fromRawData(prob.c_str(), prob.size()));
|
|
const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError));
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
return false;
|
|
|
|
const QJsonObject obj(doc.object());
|
|
const auto val = obj.value(QStringLiteral("isMovable"));
|
|
if (val.isNull() || !val.isBool())
|
|
return false;
|
|
return !val.toBool();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DtcImplCustom::isArtilleryType(int typeId) const
|
|
{
|
|
if (!m_dtcType)
|
|
return false;
|
|
|
|
for (const Type &type : m_dtcType->readAlive())
|
|
{
|
|
if (type.id() != typeId)
|
|
continue;
|
|
const auto &prob = type.properties();
|
|
|
|
QJsonParseError parserError;
|
|
const QByteArray props(QByteArray::fromRawData(prob.c_str(), prob.size()));
|
|
const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError));
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
return false;
|
|
|
|
const QJsonObject obj(doc.object());
|
|
const auto val = obj.value(QStringLiteral("isArtillery"));
|
|
if (val.isNull() || !val.isBool())
|
|
return false;
|
|
return val.toBool();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DtcImplCustom::isEditable(int typeId) const
|
|
{
|
|
if (!m_dtcType)
|
|
return false;
|
|
|
|
for (const Type &type : m_dtcType->readAlive())
|
|
{
|
|
if (type.id() != typeId)
|
|
continue;
|
|
const auto &prob = type.properties();
|
|
|
|
QJsonParseError parserError;
|
|
const QByteArray props(QByteArray::fromRawData(prob.c_str(), prob.size()));
|
|
const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError));
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
return false;
|
|
|
|
const QJsonObject obj(doc.object());
|
|
const auto val = obj.value(QStringLiteral("isEditable"));
|
|
if (val.isNull() || !val.isBool())
|
|
return true;
|
|
return val.toBool();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DtcImplCustom::isAdlerVerbund(int typeId) const
|
|
{
|
|
if (!m_dtcType)
|
|
return false;
|
|
|
|
for (const Type &type : m_dtcType->readAlive())
|
|
{
|
|
if (type.id() != typeId)
|
|
continue;
|
|
const auto &prob = type.properties();
|
|
|
|
QJsonParseError parserError;
|
|
const QByteArray props(QByteArray::fromRawData(prob.c_str(), prob.size()));
|
|
const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError));
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
return false;
|
|
|
|
const QJsonObject obj(doc.object());
|
|
const auto val = obj.value(QStringLiteral("isAdlerVerbund"));
|
|
if (val.isNull() || !val.isBool())
|
|
return false;
|
|
return val.toBool();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DtcImplCustom::isPartyAdlerVerbund(int partyId) const
|
|
{
|
|
if (!m_dtcParty)
|
|
return false;
|
|
|
|
for (const Party &party : m_dtcParty->readAlive())
|
|
{
|
|
if (party.id() != partyId)
|
|
continue;
|
|
const auto &prob = party.properties();
|
|
|
|
QJsonParseError parserError;
|
|
const QByteArray props(QByteArray::fromRawData(prob.c_str(), prob.size()));
|
|
const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError));
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
return false;
|
|
|
|
const QJsonObject obj(doc.object());
|
|
if (!obj.contains(QStringLiteral("Adler")))
|
|
return false;
|
|
|
|
const QJsonObject adlerObj = obj[QStringLiteral("Adler")].toObject();
|
|
const auto val = adlerObj.value(QStringLiteral("isVerbund"));
|
|
if (val.isNull() || !val.isBool())
|
|
return false;
|
|
|
|
return val.toBool();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Type DtcImplCustom::getTypeFromAdlerType(const QString &adlerTypeName, bool isUnit, bool isVerbund)
|
|
{
|
|
Type ret;
|
|
|
|
if (!m_dtcType)
|
|
return ret;
|
|
|
|
for (const Type &type : m_dtcType->readAlive())
|
|
{
|
|
if (isUnit && type.typeClass() != TypeClass::Unit)
|
|
continue;
|
|
if (!isUnit && type.typeClass() != TypeClass::WeaponSystem)
|
|
continue;
|
|
const auto &prob = type.properties();
|
|
QJsonParseError parserError;
|
|
const QByteArray props(QByteArray::fromRawData(prob.c_str(), prob.size()));
|
|
const QJsonDocument doc(QJsonDocument::fromJson(props, &parserError));
|
|
if (parserError.error != QJsonParseError::NoError)
|
|
continue;
|
|
|
|
const QJsonObject obj(doc.object());
|
|
const auto val = obj.value(QStringLiteral("adlerType"));
|
|
if (val.isNull() || !val.isString())
|
|
continue;
|
|
|
|
if (val.toString() != adlerTypeName)
|
|
continue;
|
|
|
|
if (isAdlerVerbund(type.id()) != isVerbund)
|
|
continue;
|
|
// Found exact Type
|
|
DEBUG_LOG(m_logger) << "--- "
|
|
<< "Found exact type --> typeId= " << type.id() << " ---";
|
|
return type;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Properties in table ppm.ppm_type
|
|
bool DtcImplCustom::isTypeUas(int typeId)
|
|
{
|
|
if (!m_dtcType)
|
|
return false;
|
|
|
|
if (!isTypeEnabled())
|
|
{
|
|
enableType();
|
|
waitForHistoricalDataType(10);
|
|
}
|
|
|
|
for (const auto &sample : m_dtcType->readAlive())
|
|
{
|
|
// DEBUG_LOG(m_logger) << " sample equipmentTypeId=" << sample.data().equipmentTypeId();
|
|
if (sample.data().id() == typeId)
|
|
{
|
|
const std::string &str = sample.data().properties();
|
|
if (str.size() > 0 && getIsUAS(str))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UAS DtcImplCustom::getUasByParticipantId(int participantId, int exerciseId)
|
|
{
|
|
|
|
if (!isUASEnabled())
|
|
{
|
|
enableUAS();
|
|
waitForHistoricalDataUAS();
|
|
}
|
|
|
|
if (!m_dtcUAS)
|
|
return {};
|
|
|
|
for (const auto &sample : m_dtcUAS->readAlive())
|
|
{
|
|
if (sample.data().participantId() != participantId)
|
|
continue;
|
|
if (sample.data().exerciseId() != exerciseId)
|
|
continue;
|
|
return sample;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
int DtcImplCustom::getParticipantFromPrf(int prf) const
|
|
{
|
|
DEBUG_LOG(m_logger) << "getParticipantFromPrf prf=" << prf;
|
|
|
|
if (!m_dtcParticipant)
|
|
return -1;
|
|
|
|
for (const DynamicParticipantData &sample : m_dtcDynamicParticipantData->readAlive())
|
|
{
|
|
for (const auto &designation : qAsConst(sample.designations()))
|
|
{
|
|
DEBUG_LOG(m_logger) << " code=" << designation.code();
|
|
if (designation.code() == prf)
|
|
{
|
|
DEBUG_LOG(m_logger) << " return code=" << designation.code();
|
|
return sample.participantId();
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int DtcImplCustom::getPrfFromParticipant(int participantId) const
|
|
{
|
|
DEBUG_LOG(m_logger) << "getPrfFromParticipant participantId=" << participantId;
|
|
if (!m_dtcParticipant)
|
|
return -1;
|
|
|
|
for (const DynamicParticipantData &sample : m_dtcDynamicParticipantData->readAlive())
|
|
{
|
|
if (participantId == sample.participantId())
|
|
{
|
|
DEBUG_LOG(m_logger) << "participantId=" << sample.participantId() << " designations.size()=" << sample.designations().size();
|
|
for (const auto &designation : qAsConst(sample.designations()))
|
|
{
|
|
DEBUG_LOG(m_logger) << " code=" << designation.code();
|
|
if (designation.code() > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << " return code=" << designation.code();
|
|
return designation.code();
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool DtcImplCustom::getNeedsIp(const std::string &s) const
|
|
{
|
|
QJsonParseError jError;
|
|
QJsonDocument doc(QJsonDocument::fromJson(s.c_str(), &jError));
|
|
if (jError.error != QJsonParseError::NoError || !doc.isObject())
|
|
{
|
|
return false;
|
|
}
|
|
QJsonObject obj(doc.object());
|
|
return obj[QStringLiteral("needsIP")].toBool();
|
|
}
|
|
|
|
bool DtcImplCustom::getNeedsPort(const std::string &s) const
|
|
{
|
|
QJsonParseError jError;
|
|
QJsonDocument doc(QJsonDocument::fromJson(s.c_str(), &jError));
|
|
if (jError.error != QJsonParseError::NoError || !doc.isObject())
|
|
{
|
|
return false;
|
|
}
|
|
QJsonObject obj(doc.object());
|
|
return obj[QStringLiteral("needsPort")].toBool();
|
|
}
|
|
|
|
QMap<double, int> DtcImplCustom::sortByDistance(const double lon, const double lat, const QVector<int> &participantIds)
|
|
{
|
|
DEBUG_LOG(m_logger) << " DtcImplCustom::sortByDistance";
|
|
int zone = -1;
|
|
|
|
if (!isParticipantPositionEnabled())
|
|
{
|
|
enableParticipantPosition();
|
|
waitForHistoricalDataParticipantPosition(10);
|
|
}
|
|
QMap<double, int> distanceMapSorted;
|
|
|
|
for (const auto ¤tPosition : m_dtcParticipantPosition->readAlive())
|
|
{
|
|
if (participantIds.contains(currentPosition.data().participantId()))
|
|
{
|
|
auto pOrigin = LtsCoordTrans::UtmCoordinate::fromGeographic(lon, lat, zone);
|
|
auto pPos = LtsCoordTrans::UtmCoordinate::fromGeographic(currentPosition.data().pos().lon(), currentPosition.data().pos().lat(), zone);
|
|
double distance = LtsCoordTrans::distance(pPos, pOrigin);
|
|
DEBUG_LOG(m_logger) << distance;
|
|
// Save distance and particiapnt Id into temporar map.
|
|
// the map is sorted so we can use that later instead of writing a sort method vor a vec
|
|
// for now
|
|
distanceMapSorted.insert(distance, currentPosition.data().participantId());
|
|
DEBUG_LOG(m_logger) << "insert distance=" << distance << ", participantId=" << currentPosition.data().participantId();
|
|
}
|
|
}
|
|
|
|
QMapIterator<double, int> it(distanceMapSorted);
|
|
while (it.hasNext())
|
|
{
|
|
it.next();
|
|
DEBUG_LOG(m_logger) << "distance=" << it.key() << ", participantId=" << it.value();
|
|
}
|
|
|
|
return distanceMapSorted;
|
|
}
|
|
|
|
bool DtcImplCustom::getIsUAS(const std::string &s) const
|
|
{
|
|
QJsonParseError jError;
|
|
QJsonDocument doc(QJsonDocument::fromJson(s.c_str(), &jError));
|
|
if (jError.error != QJsonParseError::NoError || !doc.isObject())
|
|
{
|
|
return false;
|
|
}
|
|
QJsonObject obj(doc.object());
|
|
return obj[QStringLiteral("isUAS")].toBool();
|
|
}
|
|
|
|
} // namespace Interface
|
|
} // namespace ParticipantManagement
|