/** * Handler for player data * $Id$ * $HeadURL$ * $Author$ * Created by gr, SLSE, 2017-02-20 */ #include "handler_participant_gas_pipe.h" #include #include #include namespace CentralEffectSimulationGasPipes { HandlerParticipantGasPipe::HandlerParticipantGasPipe(const std::shared_ptr &ddsHandler, const std::shared_ptr &participantHandler, QObject *parent) : QObject(parent) , m_ddsHandler(ddsHandler) , m_handlerParticipant(participantHandler) // , m_handlerAesData(aesDataHandler) , m_gasPipes() , m_requestMap() , m_timer(new QTimer(this)) , m_logger(CentralEffectSimulation::getLogger("Plugin.VirtualMines.HandlerParticipantGasPipe")) { m_timer->setSingleShot(true); connect(m_timer, &QTimer::timeout, this, &HandlerParticipantGasPipe::sendFtcCesHitRequestTimeout); } // end of ctor() //----------------------------------------------------------------------------- HandlerParticipantGasPipe::~HandlerParticipantGasPipe() { } // end of dtor() //----------------------------------------------------------------------------- bool HandlerParticipantGasPipe::init() { INFO_LOG(m_logger) << "HandlerParticipantGasPipe::init"; auto dtcAes = m_ddsHandler->dtcAes(); dtcAes->waitForHistoricalDataGasPipe(2000); dtcAes->enableAesItemView(); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged, this, &HandlerParticipantGasPipe::onAesItemViewChanged); dtcAes->enableGasPipe(); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::gasPipeChanged, this, &HandlerParticipantGasPipe::onGasPipeChanged); //connect(m_handlerParticipant.get(), &HandlerParticipant::newIndoorPosition, // this, &HandlerParticipantGasPipe::onParticipantPositionChanged); //connect(m_handlerParticipant.get(), &HandlerParticipant::newOutdoorPosition, // this, &HandlerParticipantGasPipe::onParticipantPositionChanged); // Get 'static' data for all onAesItemView { auto cb = [this](const AreaEffectSimulation::AesItemView & aiv) { onAesItemViewChanged(aiv, DataModification::eAdded); }; if (!dtcAes->aesItemViews(cb)) return false; } INFO_LOG(m_logger) << "HandlerParticipantGasPipe::init() finished. "; return true; } // end of init() //----------------------------------------------------------------------------- // /////////////////////////////////// // A E S (AreaEffectSimulation) // /////////////////////////////////// void HandlerParticipantGasPipe::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType) { INFO_LOG(m_logger) << "HandlerParticipantGasPipe::onAesItemViewChanged"; // if (data.aesTypeId() != AreaEffectSimulation::AesType_def::AtGasPipe) return; const int aesItemId = data.aesItemId(); DEBUG_LOG(m_logger) << "Got AesItemView id: " << aesItemId << ", type: " << data.aesTypeId() << ", effectState: " << data.effectStateId() << ", modType: " << modType; if (modType == DataModification::eRemoved) { m_gasPipes.remove(aesItemId); return; } if (modType == DataModification::eAdded || modType == DataModification::eModified) { const AreaEffectSimulation::AesEffectState &effectState = data.effectStateId(); switch (effectState.underlying()) { case AreaEffectSimulation::AesEffectState_def::EsActivated: { CentralEffectSimulation::AesItemViewUtm prevData; const double impactRadius = 0; prevData.aesItemId = 0; const CentralEffectSimulation::AesItemViewUtm gasPipeUtm = CentralEffectSimulation::AesItemViewUtm::create(data, prevData, impactRadius); m_gasPipes.insert(data.aesItemId(), gasPipeUtm); DEBUG_LOG(m_logger) << "Check each participant"; // Check each participant const auto partPosMap = m_handlerParticipant->positions(); for (const auto &participantPos : partPosMap) { if (m_handlerParticipant->isOutdated(participantPos)) { DEBUG_LOG(m_logger) << "isOutdated participantId=" << participantPos.participantId(); continue; } const CentralEffectSimulation::AesItemViewUtm gasPipe = m_gasPipes.value(data.aesItemId()); calculateGasPipeParticipant(gasPipe, participantPos); } break; } default: { DEBUG_LOG(m_logger) << "remove GasPipe"; m_gasPipes.remove(aesItemId); } } return; } } // onAesItemViewChanged void HandlerParticipantGasPipe::onGasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType) { INFO_LOG(m_logger) << "HandlerParticipantGasPipe::onGasPipeChanged id=" << data.id(); if (modType == DataModification::eRemoved) { return; } } bool HandlerParticipantGasPipe::insideGasPipeArea(const QPolygonF &polygonf, const QPointF &participantPos) const { DEBUG_LOG(m_logger) << "pos to check: " << CentralEffectSimulation::debug(participantPos) ; return polygonf.containsPoint(participantPos, Qt::OddEvenFill); } void HandlerParticipantGasPipe::calculateGasPipeParticipant(const CentralEffectSimulation::AesItemViewUtm &gasPipe, const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition) { //const AesItemViewUtm gasPipe = m_gasPipes.value(itemView.aesItemId()); const QPointF partPosGeo = CentralEffectSimulation::geographic2Utm(participantPosition.pos(), gasPipe.zone); DEBUG_LOG(m_logger) << "calculateGasPipeParticipant itemView.id=" << gasPipe.aesItemId << " participantId=" << participantPosition.participantId(); DEBUG_LOG(m_logger) << "gasPipe id = " << gasPipe.aesItemId << ", Box bottomLeft = " << CentralEffectSimulation::debug(gasPipe.boundingBoxBottomLeft) << ", topRight = " << CentralEffectSimulation::debug(gasPipe.boundingBoxTopRight); const QPolygonF boundingBoxGasPipe({QPointF(gasPipe.boundingBoxBottomLeft.x(), gasPipe.boundingBoxBottomLeft.y()), QPointF(gasPipe.boundingBoxTopRight.x(), gasPipe.boundingBoxBottomLeft.y()), QPointF(gasPipe.boundingBoxTopRight.x(), gasPipe.boundingBoxTopRight.y()), QPointF(gasPipe.boundingBoxBottomLeft.x(), gasPipe.boundingBoxTopRight.y()) }); if (!boundingBoxGasPipe.containsPoint(partPosGeo, Qt::OddEvenFill)) { DEBUG_LOG(m_logger) << "not in boundingBox"; return; } const bool result = insideGasPipeArea(gasPipe.form, partPosGeo); DEBUG_LOG(m_logger) << "result gasPipe Explosion = " << result; if (result) { DEBUG_LOG(m_logger) << "sendParticipantEvent"; sendParticipantEvent(gasPipe, participantPosition, ProjectDataManagement::EventType_def::HitGasPipe); DEBUG_LOG(m_logger) << "sendParticipantHit"; sendParticipantHit(gasPipe, participantPosition, ProjectDataManagement::EventType_def::HitGasPipe); } } void HandlerParticipantGasPipe::onParticipantPositionChanged(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &partPos) { bool result = false; // Bounding Box von der Linie DEBUG_LOG(m_logger) << "ParicipantPos " << " participantId=" << partPos.participantId() << " participantTypeId=" << partPos.participantTypeId() << " participantPos: lat=" << partPos.pos().lat() << " lon=" << partPos.pos().lon() << " Anzahl GasPipes=" << m_gasPipes.size(); for (const CentralEffectSimulation::AesItemViewUtm &gasPipe : qAsConst(m_gasPipes)) { calculateGasPipeParticipant(gasPipe, partPos); const QPointF partPosGeo = CentralEffectSimulation::geographic2Utm(partPos.pos(), gasPipe.zone); DEBUG_LOG(m_logger) << "gasPipe id = " << gasPipe.aesItemId << ", Box bottomLeft = " << CentralEffectSimulation::debug(gasPipe.boundingBoxBottomLeft) << ", topRight = " << CentralEffectSimulation::debug(gasPipe.boundingBoxTopRight); // if (!m_gasPipes.value(gasPipe.aesItemId).containsPoint(partPosGeo, Qt::OddEvenFill)) // continue; result = insideGasPipeArea(gasPipe.form, partPosGeo); DEBUG_LOG(m_logger) << "result gasPipe Explosion = " << result<< gasPipe.aesItemId; if (result) sendParticipantEvent(gasPipe, partPos, ProjectDataManagement::EventType_def::HitGasPipe); } } // end of onParticipantPositionChanged() //----------------------------------------------------------------------------- // /////////////////////////////////// // P D M (ProjectDataManagement) // /////////////////////////////////// // Search for corresponding aesItemView // Check for all participants wheter he is in the explosion area void HandlerParticipantGasPipe::sendParticipantEvent(const CentralEffectSimulation::AesItemViewUtm &gasPipe, const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition, const ProjectDataManagement::EventType eventType) { ParticipantManagement::TypeClass typeClass = m_handlerParticipant->typeClassFromTypeId(participantPosition.participantTypeId()); if (typeClass == ParticipantManagement::TypeClass_def::Unit || typeClass == ParticipantManagement::TypeClass_def::SupportUnit || typeClass == ParticipantManagement::TypeClass_def::SupportEntity || typeClass == ParticipantManagement::TypeClass_def::Unknown) return; int equipmentNumber = m_ddsHandler->participantId2EquipNo(participantPosition.participantId()); if (equipmentNumber <= 0) return; const AreaEffectSimulation::GasPipe &gp = m_ddsHandler->dtcAes()->gasPipe(gasPipe.aesItemId); CentralEffectSimulation::ParticipantEvent pe; DEBUG_LOG(m_logger) << "sendParticipantEvent participantId=" << participantPosition.participantId() << " lat= " << participantPosition.pos().lat() << " lon= " << participantPosition.pos().lon() << " equipmentNumber=" << equipmentNumber << " eventType=" << eventType; pe.id(m_ddsHandler->getParticipantEventId()); pe.eventTypeId(eventType); pe.participantId(participantPosition.participantId()); pe.eventTime(participantPosition.sampleTime()); pe.aesItemId(gasPipe.aesItemId); pe.partyId(participantPosition.partyId()); pe.aesName(gp.name()); pe.equipmentNumber(equipmentNumber); pe.position(participantPosition.pos()); m_ddsHandler->dtsCes()->publish(pe); qint64 id = pe.id(); QTimer::singleShot(1 * 60 * 1000, this, [id, this]() { m_ddsHandler->dtsCes()->removeParticipantEventByKey(id); }); } void HandlerParticipantGasPipe::sendParticipantHit(const CentralEffectSimulation::AesItemViewUtm &gasPipe, const CentralEffectSimulation::HandlerParticipant::CesParticipantData &participantPosition, const ProjectDataManagement::EventType eventType) { const int equipNo = m_ddsHandler->participantId2EquipNo(participantPosition.participantId()); const int participantId = participantPosition.participantId(); const int originatorEquipNo = 0; DEBUG_LOG(m_logger) << "sendParticipantHit participantId=" << participantId << " equipmentNumber=" << equipNo; Core::GeoPosition position; position.lat(participantPosition.pos().lat()); position.lon(participantPosition.pos().lon()); const TrainingAreaBase::TabPosition pos(position, participantPosition.reportingSource(), 0, 0); //pos.position(position); //pos.reportingSource(participantPosition.reportingSource()); TrainingAreaBase::SendCesHitRequest requestTab( equipNo, // equipmentNumber participantId, // participantId gasPipe.chargeTypeId, // chargeTypeId gasPipe.aesItemId, // aesId originatorEquipNo, // originatorEquipmentNumber 100, // IED heavy pos, gasPipe.effectStart, // effectTime eventType, gasPipe.partyId, // originPartyId 0 ); m_requestMap.insert(equipNo, requestTab); if (!m_timer->isActive() && !m_requestMap.isEmpty()) m_timer->start(1000); } void HandlerParticipantGasPipe::onSendCesHitReply(const Core::FunctionReplyObject &replyObject) { //if (replyObject.error()) // WARNING_LOG(m_logger) << "Can not send hit on participant to training area: " << replyObject(); //else DEBUG_LOG(m_logger) << "onSendCesHitReply for id " << replyObject.id() << " success"; } void HandlerParticipantGasPipe::sendFtcCesHitRequestTimeout() { auto ftcTab = m_ddsHandler->ftcTab(); for (const TrainingAreaBase::SendCesHitRequest &hr : qAsConst(m_requestMap)) { DEBUG_LOG(m_logger) << "sendFtcCesHitRequestTimeout: " << hr; ftcTab->sendCesHitRequest(hr, this); } m_requestMap.clear(); } } // namespace CentralEffectSimulationGasPipes