/** * @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 #include #include #include #include #include #include #include #include namespace ParticipantManagement { namespace Interface { DtcImplCustom::DtcImplCustom(const std::shared_ptr &ddsConnector) : DtcImpl(ddsConnector) { } bool DtcImplCustom::rootTemplates(QVector &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 &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 &stateList /*, bool debug*/) const { return ParticipantManagement::youngestStateInformation(stateList /*, true, true, debug*/); } ParticipantManagement::SanitationResult DtcImplCustom::proceduresDone(const std::vector &stateList) const { return ParticipantManagement::proceduresDone(stateList); } QMap DtcImplCustom::units() const { QMap 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 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 &participants, QSet &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 &visibleParties, const QVector &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 &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(propAdler[QStringLiteral("saaConnectedState")].toInt()); } } return ret; } QVector DtcImplCustom::getSubordinatesByParticipant(const int participantId) { QVector 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 DtcImplCustom::getParticipantsByPolygon(const QPolygonF &polygon, bool includeUnits, bool includeOc) { QVector participantsInPolygon; QSet 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 DtcImplCustom::getUasIds() { QVector 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 &items = sample.data().items(); for (const auto &item : items) { if (item.fulfilled() > 0) continue; const std::vector &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 DtcImplCustom::recursiveInferiosForParticipant(int32_t participantId, const QMap &participants) { QSet 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 &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 DtcImplCustom::inferiorTemplates(int templateId) { QVector 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 DtcImplCustom::sortByDistance(const double lon, const double lat, const QVector &participantIds) { DEBUG_LOG(m_logger) << " DtcImplCustom::sortByDistance"; int zone = -1; if (!isParticipantPositionEnabled()) { enableParticipantPosition(); waitForHistoricalDataParticipantPosition(10); } QMap 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 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