/** * Handler for the HMI language * $Id$ * $HeadURL$ * $Author$ */ #include "object_ncontamination.h" #include "meteo_data_provider.h" #include "Utils/polygons.h" #include namespace AreaEffectSimulation { ObjectNContamination::ObjectNContamination(MainHandler *mainHandler, QObject *parent) : ObjectBaseTmpl(mainHandler, QStringLiteral("NContamination"), parent) {} ObjectNContamination::~ObjectNContamination() { removeTopics(); } Core::FunctionReplyObject ObjectNContamination::createObject(const Database::AesNContamination &data) { Core::FunctionReplyObject ret = ObjectBaseTmpl::createObject(data); if (m_data.effectStateId == AesEffectState_def::EsActivated) m_updateWeatherData = true; return ret; } Core::FunctionReplyObject ObjectNContamination::updateObject(const Database::AesNContamination &data) { Core::FunctionReplyObject ret = ObjectBaseTmpl::updateObject(data); if (ret.error() || (isOnlyObjectNameModifiable() && (data.id > 0))) // data.id > 0 -> negative values from oc always get a full update return ret; // only allow some fields auto tmpData(m_data); tmpData.id = std::abs(data.id); tmpData.name = data.name; tmpData.effectStart = data.effectStart; tmpData.effectDuration = data.effectDuration; tmpData.impactPosition = data.impactPosition; tmpData.impactRadius = data.impactRadius; tmpData.borderLengthInner = data.borderLengthInner; tmpData.borderLengthOuter = data.borderLengthOuter; tmpData.spanAngle = data.spanAngle; tmpData.rotationAngle = data.rotationAngle; tmpData.detonationValue = data.detonationValue; tmpData.participantId = data.participantId; tmpData.partyId = data.partyId; tmpData.chargeTypeId = data.chargeTypeId; tmpData.effectStateId = data.effectStateId; // overwrite for oc tmpData.weatherSourceId = data.weatherSourceId; tmpData.properties = data.properties; if (!m_mainHandler->db()->update(tmpData)) return Core::FunctionReplyObject(data.id, tr_lts("dds", "Error updating N contamination with id %1 in database.")).arg(m_data.id); m_data = std::move(tmpData); m_publishDataTimer->start(); checkEnterNewState(); return Core::FunctionReplyObject(data.id); // data not m_data for the possible negative id in the oc-laptop } bool ObjectNContamination::removeObjectFromDb() { return m_mainHandler->db()->removeAesNContamination(m_data.id); } void ObjectNContamination::onUpdateWeatherData() { if (effectState() == AesEffectState::EsExpired || effectState() == AesEffectState::EsRemoved) return; // check if weather data changed MeteoDataManagement::MeteoData md; if (m_data.weatherSourceId == AesWeatherSource::AwsDynamic) md = m_mainHandler->meteoData()->getNearestWeather(Core::GeoPosition2D(m_data.impactPosition.x(), m_data.impactPosition.y())); else md = m_mainHandler->meteoData()->getStaticWeather(); if (m_data.weatherSourceId != AesWeatherSource::AwsNone) { m_data.rotationAngle = fmod(md.windDirection() + 180.0, 360.0); m_publishDataTimer->start(); } m_updateWeatherData = true; return; } void ObjectNContamination::onPublishData() { ObjectBaseTmpl::onPublishData(); if (!m_mainHandler->db()->update(m_data)) ERROR_LOG(m_logger) << "Error updating AesIndirectFireSingle-data in database"; if (m_data.effectStateId == AesEffectState_def::EsActivated && !m_updateWeatherData) onUpdateWeatherData(); NContamination ddsData(m_data.id, m_data.name.toStdString(), effectState() == AesEffectState::EsRemoved, false, partitionTimeMSec(), {m_data.chargeTypeId,0,0}, m_data.effectDuration, toOptional(toMSec(m_data.effectStart)), m_data.effectStateId, m_data.effectSourceId, toOptional(m_data.partyId), toOptional(m_data.participantId), m_data.effectMarkingInTa, m_data.externalId, m_data.isCentral, m_data.properties.toStdString(), Core::GeoPosition2D(m_data.impactPosition.x(), m_data.impactPosition.y()), m_data.borderLengthInner, m_data.borderLengthOuter, m_data.impactRadius, m_data.spanAngle, m_data.rotationAngle, m_data.detonationValue, m_data.weatherSourceId); m_mainHandler->dds()->dts()->publish(ddsData); publishAiv(); } void ObjectNContamination::publishAiv() { QPolygonF poly; if ((m_data.effectStateId == AesEffectState_def::EsCreated || m_data.effectStateId == AesEffectState_def::EsPrepared || m_data.effectStateId == AesEffectState_def::EsReceived) && m_data.weatherSourceId != AesWeatherSource_def::AwsNone) { Database::AesNContamination tmpData = m_data; tmpData.borderLengthInner = tmpData.impactRadius; tmpData.borderLengthOuter = 0.0; poly = Polygons::nContamination(tmpData); } else { poly = Polygons::nContamination(m_data); } const QRectF bounds(poly.boundingRect()); AesItemView aiv(m_aiv); aiv.aesItemId(m_data.id); aiv.chargeStruct().chargeTypeId(m_data.chargeTypeId); aiv.effectStart(toMSec(m_data.effectStart)); ddsVecFromPoly(poly, aiv.form()); aiv.boundingBoxBottomLeft(Core::GeoPosition2D(bounds.bottomLeft().x(), bounds.bottomLeft().y())); aiv.boundingBoxTopRight(Core::GeoPosition2D(bounds.topRight().x(), bounds.topRight().y())); aiv.aesTypeId(AesType::AtNContamination); aiv.effectStateId(effectState()); aiv.id(1000 * m_data.id + AesType::AtNContamination); if (m_data.partyId != 0) aiv.partyId(m_data.partyId); checkIsCentralAndPublish(aiv.form(), m_aiv.form(), m_data.isCentral); if (aiv != m_aiv) { aiv.sampleTime(partitionTimeMSec()); m_aiv = aiv; m_mainHandler->dds()->dts()->publish(aiv); emit newAiv(aiv); } } void ObjectNContamination::removeTopics() { auto dts = m_mainHandler->dds()->dts(); dts->removeNContaminationByKey(m_data.id); dts->removeAesItemViewByKey(1000 * m_data.id + AesType::AtNContamination); emit removeAiv(m_data.id); } QPolygonF ObjectNContamination::generateForm() { return Polygons::nContamination(m_data); } } // Namespace AreaEffectSimulation