/** * @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 #include #include #include #include #include namespace { inline bool isValidJsonObject(const std::string &json) { return LtsUtils::JsonObject::fromJson(json).isValid(); } inline int parentFromPath(const std::vector &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")] = static_cast(st); 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 ObjectMainStructureElement::deleteEGCUOverrides(const MainStructureElement &data, int oldExerciseId, int newExerciseId, QSet &modifiedStructureElements) { if(oldExerciseId == newExerciseId) return data.elements; std::vector 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 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 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 modifiedStructureElements; bool bStructureElementCountChanged = false; std::vector childParentMapping; const auto oldStructureElements = m_objectStructureElements; if (request.elements.size() != 0) { if (request.elements.size() != data.elements.size()) { bStructureElementCountChanged = true; QHash 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 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 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 &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 ObjectMainStructureElement::getAvailableInExercise() const { const QJsonArray jsonArray = getAvailableInExerciseJsonArray(); std::vector result; result.reserve(jsonArray.size()); for (const auto &ele : jsonArray) result.push_back(ele.toInt()); return result; } //------------------------------------------------------------------------------------------------------------ Core::FunctionReplyObject ObjectMainStructureElement::createStructureElements(MainStructureElement &mse, QVector &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({seDummyParentId, static_cast(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 &objSeVec, const std::vector &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 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; }