/** * gas_pipe object * $Id$ * $HeadURL$ * $Author$ * Created by hjl, SLSE, 2017-06-14 */ #include "object_gas_pipe.h" #include "special_area_provider.h" #include #include "Utils/polygons.h" #include namespace AreaEffectSimulation { ObjectGasPipe::ObjectGasPipe(MainHandler *mainHandler, QObject *parent) : ObjectBaseTmpl(mainHandler, QStringLiteral("GasPipe"), parent) { DEBUG_LOG(m_logger) << " Start AreaEffectSimulation ObjectGasPipe."; } // end of ctor() //----------------------------------------------------------------------------- ObjectGasPipe::~ObjectGasPipe() { removeTopics(); } // end of dtor() //----------------------------------------------------------------------------- Core::FunctionReplyObject ObjectGasPipe::createObject(const Database::AesGasPipe &dbData, const std::vector &ddsSegments, const QVector &dbSegments) { DEBUG_LOG(m_logger) << "createObjectGasPipe."; m_data = dbData; m_data.operatorId = dbData.operatorId; m_data.partyId = dbData.partyId; m_data.effectStart = dbData.effectStart; m_data.effectStateId = AreaEffectSimulation::AesEffectState_def::EsCreated; m_data.effectDuration = dbData.effectDuration; m_data.chargeTypeId = 461; // 105 Dummy if (m_data.id <= 0) // new gasPipe { DBTransaction trans(m_mainHandler->db()->database()); // Only commit if >nothing< fails if (ddsSegments.size() == 0) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Could not create gasPipe without segments.")); // AesGasPipe in db eintragen if (!m_mainHandler->db()->insert(m_data)) // incl. insert new id in m_data return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error inserting AesGasPipe-data into database.")); // AesGasPipeSegment in db eintragen m_dbSegments.reserve(ddsSegments.size()); Database::AesGasPipeSegment dbSegment; for (size_t i = 0; i < ddsSegments.size(); ++i) { dbSegment.id = 0; // Reset for insert. Otherwise second segment cannot be inserted! dbSegment.gasPipeId = m_data.privGasPipeId; // db dbSegment.position = QPointF(ddsSegments[i].lon(), ddsSegments[i].lat()); dbSegment.positionIndex = i; if (!m_mainHandler->db()->insert(dbSegment)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error inserting AesGasPipeSegment-data into database.")); m_dbSegments.append(dbSegment); } trans.commit(); } else m_dbSegments = dbSegments; // Publish Data via DTS m_publishDataTimer->start(); checkEnterNewState(); return Core::FunctionReplyObject(m_data.id); } // end of createObject() //----------------------------------------------------------------------------- Core::FunctionReplyObject ObjectGasPipe::updateObject(const Database::AesGasPipe &dbData, const std::vector &ddsSegments) { if (ddsSegments.size() == 0) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Could not modify AesGasPipe without segments.")); DBTransaction trans(m_mainHandler->db()->database()); auto tmpDbData = m_data; // Todo noch weitere noetig ? tmpDbData.name = dbData.name; tmpDbData.operatorId = dbData.operatorId; tmpDbData.partyId = dbData.partyId; tmpDbData.effectStart = dbData.effectStart; tmpDbData.effectDuration = dbData.effectDuration; tmpDbData.width = dbData.width; tmpDbData.effectStateId = dbData.effectStateId; auto tmpDbSegments = m_dbSegments; const int newSegmentSize = ddsSegments.size(); // segment count increased for (int i = m_dbSegments.size(); i < newSegmentSize; ++i) { Database::AesGasPipeSegment dbSegment; dbSegment.gasPipeId = m_data.privGasPipeId; // db // will update segment.id if (!m_mainHandler->db()->insert(dbSegment)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error inserting AesGasPipeSegment-data into database.")); tmpDbSegments.append(dbSegment); } // segment count decreased for (int i = newSegmentSize; i < m_dbSegments.size(); ++i) { if (!m_mainHandler->db()->removeAesGasPipeSegment(m_dbSegments.at(i).id)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error removing AesGasPipeSegment-data into database.")); } tmpDbSegments.resize(newSegmentSize); // if count is decreased // update all segments in tmpDbSegments for (size_t i = 0; i < ddsSegments.size(); ++i) { tmpDbSegments[i].position = QPointF(ddsSegments[i].lon(), ddsSegments[i].lat()); tmpDbSegments[i].positionIndex = i; } // update all AesGasPipeSegments in database for (const Database::AesGasPipeSegment &segment : qAsConst(tmpDbSegments)) { if (!m_mainHandler->db()->update(segment)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error updating AesGasPipeSegment-data in database.")); } // update AesGasPipe in database if (!m_mainHandler->db()->update(tmpDbData)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Error updating AesGasPipe-data id %1 in database.")).arg(m_data.id); trans.commit(); m_data = tmpDbData; m_dbSegments = tmpDbSegments; // Publish Data via DTS m_publishDataTimer->start(); checkEnterNewState(); return Core::FunctionReplyObject(m_data.id); } // end of updateObject() //----------------------------------------------------------------------------- Core::FunctionReplyObject ObjectGasPipe::removeObject() { Core::FunctionReplyObject ret = ObjectBaseTmpl::removeObject(); if (ret.error()) return ret; // nur wegen db noetig um sie dort als geloescht zu hinterlegen onPublishData(); // DDS topics entfernen, wird zwar auch im dtor gemacht aber so ist es offensichtlicher removeTopics(); return ret; } // end of removeObject() //----------------------------------------------------------------------------- void ObjectGasPipe::onPublishData() { INFO_LOG(m_logger) << "Publish GasPipe-data to dds for id: " << m_data.id << " effectStateId: " << effectState(); ObjectBaseTmpl::onPublishData(); // Update Sample Time if (!m_mainHandler->db()->update(m_data)) ERROR_LOG(m_logger) << "Error updating AesGasPipe-data in database"; AreaEffectSimulation::GasPipe ddsData; ddsData.id(m_data.id); ddsData.name(m_data.name.toStdString()); ddsData.isDeleted(effectState() == AesEffectState::EsRemoved); ddsData.isUsed(false); ddsData.sampleTime(m_mainHandler->dds()->currentPartitionTimeMSec()); ddsData.chargeStruct().chargeTypeId(m_data.chargeTypeId); ddsData.effectDuration(m_data.effectDuration); ddsData.effectStart(toOptional(toMSec(m_data.effectStart))); ddsData.width(m_data.width); ddsData.effectStateId(effectState()); ddsData.partyId(toOptional(m_data.partyId)); ddsData.participantId(toOptional(m_data.participantId)); ddsData.isCentral(m_data.isCentral); dbSegment2DdsSegment(m_dbSegments, ddsData.segments()); if (!m_mainHandler->dds()->dts()->publish(ddsData)) ERROR_LOG(m_logger) << "Error publishing AesGasPipe-data to dds"; publishAiv(); } // end of onPublishData() //----------------------------------------------------------------------------- void ObjectGasPipe::publishAiv() { const QPolygonF poly = Polygons::gasPipe(m_dbSegments, m_data.width); const QRectF bounds(poly.boundingRect()); AesItemView aiv(m_aiv); aiv.aesItemId(m_data.id); aiv.chargeStruct().chargeTypeId(m_data.chargeTypeId); aiv.effectStart(partitionTimeMSec()); 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::AtGasPipe); aiv.effectStateId(effectState()); aiv.id(1000 * m_data.id + AesType::AtGasPipe); 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); } } // end of publishAiv() //----------------------------------------------------------------------------- void ObjectGasPipe::removeTopics() { auto dts = m_mainHandler->dds()->dts(); dts->removeGasPipeByKey(m_data.id); dts->removeAesItemViewByKey(1000 * m_data.id + AesType::AtGasPipe); } QPolygonF ObjectGasPipe::generateForm() { return Polygons::gasPipe(m_dbSegments, m_data.width); } } // Namespace AreaEffectSimulation