/** * @RDE_HEADER@ * Custom ppm functions (extends tab_db_impl.cpp/.h) * $Id$ * $HeadURL$ * $Author$ */ #include "ppm_dtc_impl_custom.h" #include #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 : std::as_const(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 : std::as_const(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