Files
qt5-legatus-legacy/Lts/Services/InfrastructureManagement/object_main_structure_element.cpp
T
2026-08-13 18:33:10 +02:00

795 lines
30 KiB
C++
Executable File

/**
* @RDE_HEADER@
* ISM Object Main Structure Element
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "object_main_structure_element.h"
#include "handler_main_structure_element.h"
#include "object_structure_element.h"
#include "main_handler.h"
#include "handler_mounting_point_asset.h"
#include "convert_db_to_dds.h"
#include <ngldb/dbtransaction.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsUtilsCore/json_object.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <QJsonObject>
#include <QTimer>
namespace
{
inline bool isValidJsonObject(const std::string &json)
{
return LtsUtils::JsonObject::fromJson(json).isValid();
}
inline int parentFromPath(const std::vector<int32_t> &path)
{
if (path.size() < 2)
return -1;
return path.at(path.size() - 2);
}
} // anonymous namespace
using namespace InfrastructureManagement;
//----------------------------------------------------------------------------------------------------
ObjectMainStructureElement::ObjectMainStructureElement(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectMainStructureElement"))
{
}
//-------------------------------------------------------------------------------------------------------------
ObjectMainStructureElement::ObjectMainStructureElement(const Database::IsmMainStructureElement &dbData,
MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectMainStructureElement"))
, m_data(Database::convert(dbData))
{
m_data.elements().reserve(100); // sadly dds::vector has neither squeeze() nor is using over-provisioning... :(
m_footprint.id(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
ObjectMainStructureElement::~ObjectMainStructureElement()
{
qDeleteAll(m_objectStructureElements);
}
//------------------------------------------------------------------------------------------------------------
bool ObjectMainStructureElement::isValid() const
{
return m_data.id() > 0;
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::updatePosition(const Core::GeoPosition &position)
{
MainStructureElement data(m_data);
data.geoPosition(position);
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-data into database"));
m_data = data;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::setBridgeStatus(const BridgeStatus &st)
{
MainStructureElement data(m_data);
QJsonObject jsonObj;
jsonObj[QStringLiteral("bridgeStatus")] = st.underlying();
QJsonDocument doc(jsonObj);
data.properties(doc.toJson().toStdString());
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-properties into database"));
m_data = data;
DEBUG_LOG(m_logger) << "Properties changed for Id: " << m_data.id();
return Core::FunctionReplyObject(m_data.id());
}
/*!
* \brief ObjectMainStructureElement::deleteEGCUOverrides
* \param data
* \param oldExerciseId
* \param newExerciseId
* \param modifiedStructureElements
* \author Niklas Schmidt
* \details If a building with egcu's change/lose their exercise, the relay information in database will be deleted,
* so the buttons in ECGU Info dialog got there initial state
* \return
*/
std::vector<StructureElement> ObjectMainStructureElement::deleteEGCUOverrides(const MainStructureElement &data, int oldExerciseId, int newExerciseId, QSet<int> &modifiedStructureElements)
{
if(oldExerciseId == newExerciseId)
return data.elements();
std::vector<InfrastructureManagement::StructureElement> resElements;
for(auto element : data.elements())
{
if (element.mountingPointTypeId() == MountingPointType::EffectGenerationControlUnit)
{
QJsonObject structureEleProps = QJsonDocument::fromJson(QByteArray::fromStdString(element.properties())).object();
if(structureEleProps.contains(QStringLiteral("Overrides")))
{
QJsonObject overrides = structureEleProps.value(QStringLiteral("Overrides")).toObject();
if(overrides.contains(QStringLiteral("relays")))
{
QJsonArray relays = overrides.value(QStringLiteral("relays")).toArray();
if(relays.size() > 0)
{
QJsonObject relaysResult;
//QJsonArray resultList;
for(int i = 0; i < relays.size(); ++i)
{
//QJsonObject resultObj = relays[i].toObject();
//resultObj.insert(resultObj.keys().at(0), 0);
//resultList.append(resultObj);
}
//relaysResult[QStringLiteral("relays")] = resultList;
structureEleProps[QStringLiteral("Overrides")] = relaysResult;
element.properties(QString::fromUtf8(QJsonDocument(structureEleProps).toJson()).toStdString());
modifiedStructureElements.insert(element.id());
}
}
}
}
resElements.push_back(element);
}
return resElements;
}
//------------------------------------------------------------------------------------------------------------
void ObjectMainStructureElement::noticeNewProperties(bool remove)
{
if (!m_mainHandler->getHandlerMountingPointAsset().get())
{
QTimer::singleShot(3000, this, [this, remove]()
{
noticeNewProperties(remove);
});
return;
}
std::vector<int32_t> exercises;
if (!remove)
exercises = getAvailableInExercise();
for (const auto &ele : m_data.elements())
{
if (ele.structureElementTypeId() == StructureElementType::MountingPoint)
m_mainHandler->getHandlerMountingPointAsset()->setAvailableInExerciseForAssetOnMountingPoint(ele.id(), exercises);
}
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::createObject(const MainStructureElementModifyRequest &request)
{
if (!isValidJsonObject(request.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement with invalid JSON properties"));
m_data = MainStructureElement();
m_footprint = MainFootprint();
m_data.name(request.name());
m_data.description(request.description());
m_data.geoPosition(request.geoPosition());
m_data.angle(request.angle());
m_data.modelId(request.modelId());
m_data.externalWlsId(request.externalWlsId());
m_data.groupId(request.groupId());
m_data.elements(request.elements());
m_data.properties(request.properties());
m_data.structureElementTypeId(request.structureElementTypeId());
DBTransaction trans(db()->database());
m_data.isUsed(false);
// Insert MainStructure Element
Database::IsmMainStructureElement dbData(toDbData(m_data));
if (!db()->insert(dbData))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmMainStructureElement-data into database"));
m_data.id(dbData.id);
// Insert Structure Elements
QVector<ObjectStructureElement *> objSeVec;
objSeVec.reserve(m_data.elements().size());
auto fro = createStructureElements(m_data, objSeVec);
if (fro.error())
return fro;
ObjectStructureElement *objStructureElementBuilding = objSeVec.first();
// Insert Footprint Elements
m_footprint.id(m_data.id()); // = buildingId, important for remove etc.
m_footprint.structureElementId(objStructureElementBuilding->getId());
m_footprint.name(m_data.name()); // footprint name = building name
if (request.footprint().is_set())
{
const auto &fp = request.footprint().get();
for (size_t i = 0; i < fp.size(); ++i)
{
FootprintElement fpElem = fp.at(i);
const Core::RelativePosition &relPos = fpElem.relPosition();
Database::IsmStructureElementFootprint footprint;
footprint.indexNo = i;
footprint.relPosition = LtsUtils::QPoint3D(relPos.offsetX(), relPos.offsetY(), relPos.offsetZ());
footprint.structureElementId = objStructureElementBuilding->getId();
if (!db()->insert(footprint))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElementFootprint-data into database"));
fpElem.id(footprint.id);
m_footprint.elements().resize(m_footprint.elements().size()+1, fpElem);
}
}
DEBUG_LOG(m_logger) << "m_footprint.elements().size() = " << m_footprint.elements().size();
if (!db()->update(toDbData(m_data)))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-data into database"));
fro = updatePaths(m_data, objSeVec, request.childParentRelations());
if (fro.error())
return fro;
DEBUG_LOG(m_logger) << "New Id: " << m_data.id();
trans.commit();
if (m_data.properties().size())
noticeNewProperties();
m_mainHandler->getHandlerMainStructureElement()->addedStructureElements(m_objectStructureElements);
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::updateObject(const MainStructureElementModifyRequest &request)
{
if (!isValidJsonObject(request.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement with invalid JSON properties"));
if (!isValid())
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Object not valid/blocked"));
bool hasNewProps = m_data.properties() != request.properties();
MainStructureElement data(m_data);
QJsonObject objRequest = QJsonDocument::fromJson(QByteArray::fromStdString(request.properties())).object();
QJsonObject objCurrent = QJsonDocument::fromJson(QByteArray::fromStdString(data.properties())).object();
int newExerciseId = objRequest.value(QStringLiteral("available_in_exercise")).toArray().at(0).toInt();
int currentExerciseId = objCurrent.value(QStringLiteral("available_in_exercise")).toArray().at(0).toInt();
data.name(request.name());
data.description(request.description());
data.geoPosition(request.geoPosition());
data.angle(request.angle());
data.modelId(request.modelId());
data.externalWlsId(request.externalWlsId());
data.groupId(request.groupId());
data.properties(request.properties());
data.structureElementId(request.structureElementId());
data.structureElementTypeId(request.structureElementTypeId());
// when we want to allow insert / update / remove for SE:
// data.elements(request.elements());
QSet<int> modifiedStructureElements;
bool bStructureElementCountChanged = false;
std::vector<int> childParentMapping;
const auto oldStructureElements = m_objectStructureElements;
if (request.elements().size() != 0)
{
if (request.elements().size() != data.elements().size())
{
bStructureElementCountChanged = true;
QHash<int, size_t> parentId2Index;
childParentMapping.resize(request.elements().size());
data.elements(request.elements());
for (size_t i = 0; i < request.elements().size(); ++i)
{
StructureElement &newElem = data.elements().at(i);
if (!isValidJsonObject(newElem.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "StructureElement with invalid JSON properties"));
parentId2Index[newElem.id()] = i;
childParentMapping[i] = parentId2Index.value(parentFromPath(newElem.path()));
// Do *not* modify the those
if (!isStructureElementDeletable(newElem))
continue;
newElem.id(0);
}
}
else
{
for (size_t i = 0; i < request.elements().size(); ++i)
{
const StructureElement &newElem = request.elements().at(i);
if (!isValidJsonObject(newElem.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "StructureElement with invalid JSON properties"));
StructureElement &oldElem = data.elements()[i];
if (oldElem.id() != newElem.id() && newElem.id() != 0)
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Adding / Removing Structure elements not (yet) supported"));
if (oldElem == newElem)
continue;
modifiedStructureElements += oldElem.id();
// currently we only support modifing these values:
oldElem.displayName(newElem.displayName());
oldElem.barcode(newElem.barcode());
oldElem.mountingPointId(newElem.mountingPointId());
oldElem.mountingPointTypeId(newElem.mountingPointTypeId());
oldElem.relPosition(newElem.relPosition());
oldElem.structureElementTypeId(newElem.structureElementTypeId());
oldElem.properties(newElem.properties());
DEBUG_LOG(m_logger) << "add " << oldElem.id() << " to modifiedStructureElements" << oldElem;
}
}
}
MainFootprint mfData(m_footprint);
bool bUpdateFootprintNeeded = false;
if (request.footprint().is_set())
{
const auto &fpReq = request.footprint().get();
bUpdateFootprintNeeded = fpReq.size() != mfData.elements().size();
if (!bUpdateFootprintNeeded)
{
for (size_t i = 0; i < fpReq.size(); ++i)
{
if (fpReq.at(i) != mfData.elements().at(i))
{
bUpdateFootprintNeeded = true;
break;
}
}
}
}
//The modifiedStructureElements need to be filled
data.elements(deleteEGCUOverrides(data, currentExerciseId, newExerciseId, modifiedStructureElements));
DBTransaction trans(db()->database());
if (bStructureElementCountChanged)
{
DEBUG_LOG(m_logger) << "Re-creating structure elements for " << data.id();
QVector<ObjectStructureElement *> objSeVec;
objSeVec.reserve(data.elements().size());
auto fro = createStructureElements(data, objSeVec);
if (fro.error())
return fro;
fro = updatePaths(data, objSeVec, childParentMapping);
if (fro.error())
return fro;
}
else
{
for (const auto &dataSe : data.elements())
{
if (!modifiedStructureElements.contains(dataSe.id()))
continue;
InfrastructureManagement::ObjectStructureElement *objSe = m_objectStructureElements.value(dataSe.id());
if (!objSe)
WARNING_LOG(m_logger) << "Internal Error: can not find structure element with id " << dataSe.id();
else
objSe->updateObject(dataSe);
}
}
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-data into database"));
DEBUG_LOG(m_logger) << "bUpdateFootprintNeeded = " << bUpdateFootprintNeeded;
if (bUpdateFootprintNeeded)
{
// remove old footprint data
for (const FootprintElement &elem : m_footprint.elements())
db()->removeIsmStructureElementFootprint(elem.id());
// add new footprint data
Database::IsmStructureElementFootprint sef;
sef.structureElementId = getStructureElementId();
for (size_t i = 0; i < mfData.elements().size(); ++i)
{
FootprintElement &elem = mfData.elements()[i];
const Core::RelativePosition &relPos = elem.relPosition();
sef.indexNo = i;
sef.relPosition = LtsUtils::QPoint3D(relPos.offsetX(),
relPos.offsetY(),
relPos.offsetZ());
if (!db()->insert(sef))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmStructureElementFootprint-data into database"));
elem.id(sef.id);
m_footprint.elements().resize(m_footprint.elements().size()+1, elem);
}
}
DEBUG_LOG(m_logger) << "mfData.elements().size() = " << mfData.elements().size();
trans.commit();
if (bStructureElementCountChanged)
{
m_mainHandler->getHandlerMainStructureElement()->removedStructureElements(oldStructureElements);
m_mainHandler->getHandlerMainStructureElement()->addedStructureElements(m_objectStructureElements);
QMap<int, ObjectStructureElement*> newObjectStructureElements;
for (ObjectStructureElement *ose : qAsConst(m_objectStructureElements))
{
// only delete the old ones
// and also not the one for the mse and bcu
if (!oldStructureElements.contains(ose->getId()) ||
!isStructureElementDeletable(ose->getData()))
{
newObjectStructureElements[ose->getId()] = ose;
continue;
}
ose->removeObject();
delete ose;
}
m_objectStructureElements = newObjectStructureElements;
}
m_data = data;
m_footprintNeedsUpdate = (m_footprint != mfData);
m_footprint = mfData;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
if (hasNewProps)
noticeNewProperties();
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::removeObject()
{
/* done in Handler MSE
for (auto dataSe : m_data.elements())
{
if (!db()->removeIsmStructureElement(dataSe.id()))
return Core::FunctionReplyObject(dataSe.id(), tr_lts("dds", "StructureElement %1 can not be removed from DB")).arg(dataSe.id());
}
*/
if (!db()->removeIsmMainStructureElement(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MainStructureElement with id %1 can not be removed from DB")).arg(m_data.id());
dts()->removeMainStructureElementByKey(m_data.id());
dts()->removeMainFootprintByKey(m_footprint.id());
for (ObjectStructureElement *ose : qAsConst(m_objectStructureElements))
{
ose->removeObject();
delete ose;
}
m_objectStructureElements.clear();
m_data = MainStructureElement();
m_footprint = MainFootprint();
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
void ObjectMainStructureElement::onPublishData()
{
INFO_LOG(m_logger) << "Publish IsmMainStructureElement-data to dds (" << m_data.id() << ") ...";
dts()->publish(m_data);
DEBUG_LOG(m_logger) << "m_footprint.elements().size() = " << m_footprint.elements().size();
if (m_footprint.elements().size() == 0)
{
if (m_footprint.id() != 0)
dts()->removeMainFootprintByKey(m_footprint.id());
}
else if (m_footprintNeedsUpdate)
dts()->publish(m_footprint);
m_footprintNeedsUpdate = false;
}
//------------------------------------------------------------------------------------------------------------
ObjectStructureElement *ObjectMainStructureElement::createStructureElementObject(const Database::IsmStructureElement &dbData)
{
ObjectStructureElement *ifs(new ObjectStructureElement(m_mainHandler, this));
Core::FunctionReplyObject ret = ifs->createObject(dbData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
return nullptr;
}
// top level types: Building, ApproachingPoint, Announcement, MeteoDataUnit, RadioStation, Bridge
if (isTopLevel(dbData.structureElementTypeId))
{
m_data.structureElementId(ifs->getId());
m_data.structureElementTypeId(dbData.structureElementTypeId);
if (dbData.structureElementTypeId == StructureElementType::Building)
{
m_footprintNeedsUpdate |= (m_footprint.structureElementId() != ifs->getId());
m_footprint.structureElementId(ifs->getId());
auto name = dbData.name.toStdString();
m_footprintNeedsUpdate |= (m_footprint.name() != name);
m_footprint.name(name);
}
}
ifs->updateGeoPosition();
int last = m_data.elements().size();
// ifs->getData() to retrieve the correct geo position
m_data.elements().resize(last + 1, ifs->getData());
m_objectStructureElements.insert(ifs->getId(), ifs);
return ifs;
}
//------------------------------------------------------------------------------------------------------------
const ObjectStructureElement *ObjectMainStructureElement::getMainStructureElementMountingPoint() const
{
// search for mounting point for building (direct below building)
for (const ObjectStructureElement *ose : m_objectStructureElements)
{
const auto &data = ose->getData();
if (data.structureElementTypeId() == InfrastructureManagement::StructureElementType::MountingPoint &&
data.mountingPointTypeId() == InfrastructureManagement::MountingPointType::BuildingControlUnit)
return ose;
}
return nullptr;
}
//------------------------------------------------------------------------------------------------------------
void ObjectMainStructureElement::setFootprintData(const std::vector<FootprintElement> &elements)
{
m_footprintNeedsUpdate |= (m_footprint.elements() != elements);
m_footprint.elements() = elements;
}
//------------------------------------------------------------------------------------------------------------
QJsonArray ObjectMainStructureElement::getAvailableInExerciseJsonArray() const
{
return LtsUtils::JsonObject::fromJson(m_data.properties()).object().value(QLatin1String("available_in_exercise")).toArray();
}
//------------------------------------------------------------------------------------------------------------
int ObjectMainStructureElement::getBridgeStatus() const
{
return LtsUtils::JsonObject::fromJson(m_data.properties()).object().value(QLatin1String("bridgeStatus")).toInt();
}
//------------------------------------------------------------------------------------------------------------
std::vector<int32_t> ObjectMainStructureElement::getAvailableInExercise() const
{
const QJsonArray jsonArray = getAvailableInExerciseJsonArray();
std::vector<int32_t> result;
result.reserve(jsonArray.size());
for (const auto &ele : jsonArray)
result.push_back(ele.toInt());
return result;
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::createStructureElements(MainStructureElement &mse,
QVector<ObjectStructureElement *> &objSeVec)
{
if (mse.elements().size() == 0)
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement without StructureElements"));
ObjectStructureElement *objStructureElementBuilding = nullptr;
int rootStructureElementId = -1;
const Core::GeoPosition &geoPositionBase = m_data.geoPosition();
const auto mseBaseCoord(LtsCoordTrans::UtmCoordinate::fromGeographic(geoPositionBase.lon(), geoPositionBase.lat()));
for (size_t i = 0; i < mse.elements().size(); ++i)
{
StructureElement &dataSe = mse.elements()[i];
if (!isValidJsonObject(dataSe.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "StructureElement with invalid JSON properties"));
DEBUG_LOG(m_logger) << "#CreateStructureElement: " << dataSe.displayName();
Database::IsmStructureElement dbDataSe(InfrastructureManagement::ObjectStructureElement::toDbData(dataSe));
dbDataSe.mainStructureElementId = mse.id();
// id + 1 to make sure the path does not exist when we update the paths with the correct values
const int seDummyParentId = rootStructureElementId < 0 ? mse.id() : rootStructureElementId + 1;
dbDataSe.path = LtsUtils::IntArray(std::vector<int>({seDummyParentId, static_cast<int>(i)})); // dummy path for unique constraint
// DEBUG_LOG(m_logger) << "dbDataSe.path: " << mse.id() << ", " << i;
if (dataSe.id() == 0)
{
if (!db()->insert(dbDataSe))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElement-data into database"));
}
else
{
if (!db()->update(dbDataSe))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElement-data into database"));
}
// filled with the first inserted structure element (== building structure element)
if (rootStructureElementId < 0)
rootStructureElementId = dbDataSe.id;
ObjectStructureElement *objSe = nullptr;
if (dataSe.id() == 0)
objSe = m_objectStructureElements.value(dataSe.id());
if (!objSe)
objSe = new ObjectStructureElement(Database::convert(dbDataSe), m_mainHandler, this);
// first one is buildingSE per definition (checked outside)
if (objStructureElementBuilding == nullptr)
{
objStructureElementBuilding = objSe;
// make sure to be consistent (will be updated later when se.path is updated)
objStructureElementBuilding->getData().mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
}
// in two containers - need a sorted one for path updates
objSeVec += objSe;
m_objectStructureElements.insert(objSe->getId(), objSe);
// update GeoPos
objSe->updateGeoPosition(mseBaseCoord, geoPositionBase.z(), m_data.angle());
dataSe.geoPosition() = objSe->getGeoPosition();
}
if (!objStructureElementBuilding)
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement without valid StructureElements"));
mse.structureElementId(objStructureElementBuilding->getId());
mse.structureElementTypeId(objStructureElementBuilding->getStructureElementTypeId());
DEBUG_LOG(m_logger) << "(Re)Created " << mse.elements().size() << " structure elements";
return Core::FunctionReplyObject();
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::updatePaths(MainStructureElement &mse,
const QVector<ObjectStructureElement *> &objSeVec,
const std::vector<int> &childParentMapping)
{
// now update parent - child relations
const int buildingId = mse.id();
// update first element (building SE)
{
ObjectStructureElement *objSe = objSeVec.at(0);
StructureElement seData = objSe->getData();
seData.path().clear();
seData.path().resize(1, seData.id());
seData.mainStructureElementId(buildingId);
objSe->updateObject(seData);
DEBUG_LOG(m_logger) << "UpdatePaths Building = " << seData.displayName();
// update mse.elements
mse.elements()[0] = objSe->getData();
}
for (int i = 1; i < objSeVec.size(); ++i)
{
const int parentIdx = childParentMapping.at(i);
ObjectStructureElement *objSe = objSeVec.at(i);
// sanity check
if (parentIdx < 0 || parentIdx >= i)
return Core::FunctionReplyObject(objSe->getId(), tr_lts("dds", "Error updating path information for structure element"));
DEBUG_LOG(m_logger) << "UpdatePath for element " << objSe->getName();
// create our path
std::vector<int> path = objSeVec.at(parentIdx)->getPath();
QString p;
for (int ii : path)
p += QString::number(ii) + QStringLiteral(",");
DEBUG_LOG(m_logger) << "## Parent path = " << p ;
path.resize(path.size() + 1, objSe->getId());
p += QString::number(objSe->getId());
// update db
StructureElement seData = objSe->getData();
DEBUG_LOG(m_logger) << "Updated path for element: " << seData.displayName() << ", path = " << p;
seData.path(path);
seData.mainStructureElementId(buildingId);
const Core::FunctionReplyObject fro = objSe->updateObject(seData);
if (fro.error())
return fro;
// update mse.elements
mse.elements()[i] = objSe->getData();
}
DEBUG_LOG(m_logger) << "Updated paths for " << objSeVec.size() << " structure elements";
return Core::FunctionReplyObject();
}
//------------------------------------------------------------------------------------------------------------
bool ObjectMainStructureElement::isStructureElementDeletable(const StructureElement &se)
{
if (se.structureElementTypeId() == InfrastructureManagement::StructureElementType::Building)
return false;
if (se.structureElementTypeId() == InfrastructureManagement::StructureElementType::MountingPoint &&
se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::BuildingControlUnit)
return false;
return true;
}
// -------------------------------------------------------------------------------------------------------
// convert methods
// -------------------------------------------------------------------------------------------------------
// InfrastructureManagement::MainStructureElement => Database::IsmMainStructureElement
Database::IsmMainStructureElement ObjectMainStructureElement::toDbData(const MainStructureElement &ddsData)
{
Database::IsmMainStructureElement dbData;
dbData.id = ddsData.id();
dbData.name = QString::fromStdString(ddsData.name());
dbData.description = QString::fromStdString(ddsData.description());
dbData.geoPosition = LtsUtils::QPoint3D(ddsData.geoPosition().lon(), ddsData.geoPosition().lat(), ddsData.geoPosition().z());
dbData.angle = ddsData.angle();
dbData.modelId = ddsData.modelId();
dbData.externalWlsId = ddsData.externalWlsId();
dbData.groupId = ddsData.groupId();
dbData.properties = QString::fromStdString(ddsData.properties());
return dbData;
}
//------------------------------------------------------------------------------------------------------------
bool ObjectMainStructureElement::isTopLevel(InfrastructureManagement::StructureElementType structureElementTypeId)
{
if (structureElementTypeId == StructureElementType::Building ||
structureElementTypeId == StructureElementType::ApproachingPoint ||
structureElementTypeId == StructureElementType::Announcement ||
structureElementTypeId == StructureElementType::MeteoDataUnit ||
structureElementTypeId == StructureElementType::RadioStation ||
structureElementTypeId == StructureElementType::Bridge)
return true;
return false;
}