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

701 lines
27 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Parse building xml file and create MainStructureElementCreateRequest for the data
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-02-02
*/
#include "parse_building_xml.h"
#include <QDomDocument>
#include <QFile>
#include <QPointF>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <LtsUtilsCore/dds_vector.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class XmlImportException : public std::exception
{
public:
explicit XmlImportException(const QString &msg) noexcept
: m_msg(msg.toUtf8().data())
{}
~XmlImportException() = default;
virtual const char *what() const noexcept
{
return m_msg.c_str();
}
private:
const std::string m_msg;
};
//-------------------------------------------------------------------------------------------------------------
template <typename T>
static inline T positionFromElement(const QDomElement &elem)
{
return T(elem.attribute(QStringLiteral("X")).toDouble(),
elem.attribute(QStringLiteral("Y")).toDouble(),
elem.attribute(QStringLiteral("Z")).toDouble());
}
//-------------------------------------------------------------------------------------------------------------
ParseBuildingXml::ParseBuildingXml(const QString &xmlFilename,
const QString &vulnerabilityFilename,
const QString &egcuToRoomFilename,
const QString &soundAreaFilename,
const Core::GeoPosition &geoPosition,
double rotationAngleDegree)
: m_xmlFilename(xmlFilename)
, m_vulnerabilityFilename(vulnerabilityFilename)
, m_egcuToRoomFilename(egcuToRoomFilename)
, m_soundAreaFilename(soundAreaFilename)
, m_geoPosition(geoPosition)
, m_rotationAngleDegree(rotationAngleDegree)
, m_logger(getLogger("ParseBuildingXml"))
{
DEBUG_LOG(m_logger) << "m_soundAreaFilename=" << m_soundAreaFilename;
}
QJsonObject ParseBuildingXml::egcusToJson() const
{
DEBUG_LOG(m_logger) << "egcusToJson";
if (m_egcus.isEmpty())
return QJsonObject();
QJsonObject egcusToRooms;
QJsonArray egcus;
QJsonArray rooms;
for (const auto &egcu : m_egcus)
{
rooms = {};
for (const int room : egcu.rooms)
rooms += room;
QJsonObject json;
json[QStringLiteral("mountpointEgcu")] = egcu.mountpointEgcu;
json[QStringLiteral("rooms")] = rooms;
egcus += json;
}
egcusToRooms[QStringLiteral("egcusToRooms")] = egcus;
return egcusToRooms;
}
QJsonObject ParseBuildingXml::soundAreaToJson() const
{
DEBUG_LOG(m_logger) << "soundAreaToJson";
QJsonObject soundArea;
QJsonObject json;
QJsonObject jsonEgcu;
QJsonArray arrayGeometry;
for (const auto &point : m_soundArea.geometry)
{
json[QStringLiteral("lat")] = point.lat();
json[QStringLiteral("lon")] = point.lon();
arrayGeometry.append(json);
}
QJsonArray arrayEgcus;
for (const auto &id : m_soundArea.egcuMountpoints)
{
jsonEgcu[QStringLiteral("id")] = id;
arrayEgcus.append(jsonEgcu);
}
soundArea[QStringLiteral("id")] = m_soundArea.id;
soundArea[QStringLiteral("geometry")] = arrayGeometry;
soundArea[QStringLiteral("mainEgcuMountpoint")] = m_soundArea.mainEgcuMountpoint;
soundArea[QStringLiteral("egcuMountpoints")] = arrayEgcus;
return soundArea;
}
//-------------------------------------------------------------------------------------------------------------
bool ParseBuildingXml::parseXml()
{
DEBUG_LOG(m_logger) << "parseXml";
m_request = MainStructureElementModifyRequest();
m_request.properties("{}");
m_lastError.clear();
bool bRet = true;
parseXmlInternal();
// try
// {
// parseXmlInternal();
// if (!m_vulnerabilityFilename.isEmpty())
// {
// QDomDocument doc = openXml(m_vulnerabilityFilename);
// if (!doc.isNull())
// {
// const QByteArray compressed = qCompress(doc.toByteArray(), 9);
// m_request.vulnerabilityData(LtsUtils::convert<std::vector<uint8_t>>(compressed));
// }
// }
// }
// catch (const std::exception &ex)
// {
// m_lastError = QString::fromUtf8(ex.what());
// WARNING_LOG(m_logger) << "Error importing building: " << ex.what();
// m_request = MainStructureElementModifyRequest();
// return false;
// }
QJsonObject properties;
parseXmlEgcus();
QJsonObject egcus = egcusToJson();
properties[QStringLiteral("egcusToRooms")] = egcus[QStringLiteral("egcusToRooms")];
DEBUG_LOG(m_logger) << "parseXml vor isEmpty";
if (!m_soundAreaFilename.isEmpty())
{
DEBUG_LOG(m_logger) << "parseXml vor parseXmlSoundArea";
parseXmlSoundArea();
properties[QStringLiteral("soundArea")] = soundAreaToJson();
}
m_request.properties(QJsonDocument(properties).toJson(QJsonDocument::Compact).toStdString());
DEBUG_LOG(m_logger) << "Finished import for file " << m_xmlFilename;
return bRet;
}
//-------------------------------------------------------------------------------------------------------------
ParseBuildingXml::Egcu ParseBuildingXml::parseEgcu(const QDomElement &domEgcu)
{
ParseBuildingXml::Egcu ret;
INFO_LOG(m_logger) << "parseEgcu Egcu: = " << domEgcu.tagName();
QDomElement mountpoint = domEgcu.firstChildElement(QStringLiteral("Mountpoint"));
INFO_LOG(m_logger) << "Mountpoint=" << mountpoint.tagName();
QDomElement mountpointSubId = mountpoint.firstChildElement(QStringLiteral("SubId"));
INFO_LOG(m_logger) << "Mountpoint=" << mountpointSubId.tagName()
<< " SubId = " << mountpointSubId.attribute(QStringLiteral("SubId"))
<< " text= " << mountpointSubId.text();
ret.mountpointEgcu = mountpointSubId.text().toInt();
QDomElement rooms = domEgcu.firstChildElement(QStringLiteral("Rooms"));
INFO_LOG(m_logger) << "Rooms=" << rooms.tagName()
<< " SubId = " << rooms.attribute(QStringLiteral("SubId"))
<< " text = " << rooms.text();
QDomElement room = rooms.firstChildElement(QStringLiteral("SubId"));
for (; !room.isNull(); room = room.nextSiblingElement(room.tagName()))
{
INFO_LOG(m_logger) << "Room=" << room.tagName()
<< " SubId = " << room.attribute(QStringLiteral("SubId"))
<< " text = " << room.text();
ret.rooms.append(room.text().toInt());
}
return ret;
}
bool ParseBuildingXml::parseXmlEgcus()
{
m_lastError.clear();
bool bRet = true;
try
{
//parseXmlInternal();
INFO_LOG(m_logger) << "parseXmlEgcus " << m_egcuToRoomFilename;
if (!m_egcuToRoomFilename.isEmpty())
{
INFO_LOG(m_logger) << "openXml";
QDomDocument doc = openXml(m_egcuToRoomFilename);
if (!doc.isNull())
{
// Evaluate xml file and modify properties in m_request
QDomElement root = doc.documentElement();
INFO_LOG(m_logger) << "root.tagName()=" << root.tagName();
if (root.tagName() != QStringLiteral("EgcusToRooms"))
{
WARNING_LOG(m_logger) << "The file is not EgcusToRooms";
return false;
}
QDomElement domEgcu = root.firstChildElement(QStringLiteral("Egcu"));
if (domEgcu.isNull())
INFO_LOG(m_logger) << "Keine EGCU's";
for (; !domEgcu.isNull(); domEgcu = domEgcu.nextSiblingElement(domEgcu.tagName()))
{
INFO_LOG(m_logger) << "parseEgcus=" << domEgcu.tagName()
<< " text=" << domEgcu.text()
<< " Name=" << domEgcu.attribute(QStringLiteral("Name"));
const Egcu egcu = parseEgcu(domEgcu);
m_egcus.append(egcu);
}
}
}
}
catch (const std::exception &ex)
{
m_lastError = QString::fromUtf8(ex.what());
WARNING_LOG(m_logger) << "Error importing building: wrong XML-File EgcuToRooms: " << ex.what();
bRet = false;
}
return bRet;
}
//-------------------------------------------------------------------------------------------------------------
bool ParseBuildingXml::parseXmlSoundArea()
{
Core::GeoPosition geoPosition;
m_lastError.clear();
bool bRet = true;
try
{
//parseXmlInternal();
INFO_LOG(m_logger) << "parseXmlSoundArea " << m_soundAreaFilename;
if (!m_soundAreaFilename.isEmpty())
{
INFO_LOG(m_logger) << "openXml";
QDomDocument doc = openXml(m_soundAreaFilename);
if (!doc.isNull())
{
// Evaluate xml file and modify properties in m_request
QDomElement root = doc.documentElement();
INFO_LOG(m_logger) << "root.tagName()=" << root.tagName();
if (root.tagName() != QStringLiteral("SoundArea"))
{
WARNING_LOG(m_logger) << "The file is not SoundArea";
return false;
}
INFO_LOG(m_logger) << "parseSoundArea SoundArea: = " << root.tagName();
// Id
m_soundArea.id = root.firstChildElement(QStringLiteral("Id")).text().toInt();
INFO_LOG(m_logger) << "Id=" << m_soundArea.id;
// Geometry
QDomElement geometry = root.firstChildElement(QStringLiteral("Geometry"));
QDomElement point = geometry.firstChildElement(QStringLiteral("Point"));
for (; !point.isNull(); point = point.nextSiblingElement(point.tagName()))
{
INFO_LOG(m_logger) << "Point=" << point.tagName()
<< " lat = " << point.firstChildElement(QStringLiteral("lat")).text().toDouble()
<< " lon = " << point.firstChildElement(QStringLiteral("lon")).text().toDouble();
geoPosition.lat(point.firstChildElement(QStringLiteral("lat")).text().toDouble());
geoPosition.lon(point.firstChildElement(QStringLiteral("lon")).text().toDouble());
m_soundArea.geometry.push_back(geoPosition);
}
// MainEgcuMountpoint
m_soundArea.mainEgcuMountpoint = root.firstChildElement(QStringLiteral("MainEgcuMountpoint")).text().toInt();
DEBUG_LOG(m_logger) << "MainEgcuMountpoint Id=" << m_soundArea.mainEgcuMountpoint;
// MountpointsEgcu
QDomElement egcuMountpoints = root.firstChildElement(QStringLiteral("EgcuMountpoints"));
QDomElement id = egcuMountpoints.firstChildElement(QStringLiteral("Id"));
for (; !id.isNull(); id = id.nextSiblingElement(id.tagName()))
{
int mountpointEgcu = id.text().toInt();
DEBUG_LOG(m_logger) << "mountpointEgcu=" << mountpointEgcu;
m_soundArea.egcuMountpoints.push_back(mountpointEgcu);
}
}
}
}
catch (const std::exception &ex)
{
m_lastError = QString::fromUtf8(ex.what());
WARNING_LOG(m_logger) << "Error importing building: wrong XML-File EgcuToRooms: " << ex.what();
bRet = false;
}
return bRet;
}
//-------------------------------------------------------------------------------------------------------------
QDomDocument ParseBuildingXml::openXml(const QString &fileName) const
{
// check filename is empty
if (fileName.isEmpty())
throw XmlImportException(tr("Empty filename!"));
// check if metaFileName is a valid xml file
QFile f(fileName);
if (f.size() == 0)
return QDomDocument();
if (!f.open(QIODevice::ReadOnly))
throw XmlImportException(tr("Error opening file %1: %2").arg(fileName, f.errorString()));
// read Xml file
QDomDocument metaDoc;
int errLine = 0, errColumn = 0;
QString err;
if (!metaDoc.setContent(&f, &err, &errLine, &errColumn))
throw XmlImportException(tr("Error parsing file content: %1 at %2.%3").arg(err).arg(errLine).arg(errColumn));
// close metaFile
f.close();
return metaDoc;
}
//-------------------------------------------------------------------------------------------------------------
QVector<ParseBuildingXml::BuildingMetaInfo> ParseBuildingXml::parseMetaXml(const QString &metaXml) const
{
QVector<ParseBuildingXml::BuildingMetaInfo> ret;
const QDomDocument metaDoc = openXml(metaXml);
if (metaDoc.isNull())
return ret;
// parse metaDoc for building elements MetaData/Tag/Group/Feature+Orientation+Position+File
const QDomElement metaElem = getChildElement(metaDoc, QStringLiteral("MetaData"));
const QDomElement tagElem = getChildElement(metaElem, QStringLiteral("Tag"));
const QDomElement groupElem = getChildElement(tagElem, QStringLiteral("Group"));
QDomElement modelElem = getChildElement(groupElem, QStringLiteral("Model"));
for (; !modelElem.isNull(); modelElem = modelElem.nextSiblingElement(modelElem.tagName()))
{
const QDomElement orientationElem = getChildElement(modelElem, QStringLiteral("Orientation"));
const QDomElement posElem = getChildElement(modelElem, QStringLiteral("Position"));
const QDomElement streifElem = getChildElement(modelElem, QStringLiteral("STREIF"));
// read building file name, name, angle, position
ParseBuildingXml::BuildingMetaInfo info;
info.filename = streifElem.attribute(QLatin1String("Name"));
if (info.filename.isEmpty())
{
WARNING_LOG(m_logger) << "Empty filename (building)!";
continue;
}
info.rotationAngleDegree = orientationElem.attribute(QLatin1String("Angle")).toDouble(); // correct rotation?
INFO_LOG(m_logger) << "Found Building angle: " << info.rotationAngleDegree;
info.geoPosition = positionFromElement<Core::GeoPosition>(posElem);
INFO_LOG(m_logger) << "Found Building position: (" << info.geoPosition.lon() << ", ("
<< info.geoPosition.lat() << ", ("
<< info.geoPosition.z() << ")";
ret += info;
}
return ret;
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::parseXmlInternal()
{
const QDomDocument objDoc = openXml(m_xmlFilename);
if (objDoc.isNull())
throw XmlImportException(tr("xml file %1 is empty").arg(m_xmlFilename));
const QDomElement rootElem = objDoc.documentElement(); // STREIF
const QDomElement headerElem = getChildElement(rootElem, QStringLiteral("Header"));
const QDomElement baseGroupElem = getChildElement(headerElem, QStringLiteral("Group"));
DEBUG_LOG(m_logger) << "Start import for file " << m_xmlFilename;
m_request.angle(m_rotationAngleDegree);
m_request.geoPosition(m_geoPosition);
m_request.modelId(getInteger(getChildElement(baseGroupElem, QStringLiteral("ModelId")), QStringLiteral("Id")));
m_request.name(getChildElement(baseGroupElem, QStringLiteral("Name")).text().toStdString());
m_request.description(m_request.name());
INFO_LOG(m_logger) << "Importing building with name: " << m_request.name();
InfrastructureManagement::StructureElement seBuilding;
seBuilding.name(m_request.name());
seBuilding.displayName(m_request.name());
seBuilding.structureElementTypeId(InfrastructureManagement::StructureElementType::Building);
seBuilding.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
seBuilding.properties("{}");
addElementToRequest(seBuilding, -1);
InfrastructureManagement::StructureElement seMPBuilding;
seMPBuilding.name(m_request.name());
seMPBuilding.displayName(m_request.name());
m_buildingName = QString::fromStdString(seBuilding.displayName());
seMPBuilding.structureElementTypeId(InfrastructureManagement::StructureElementType::MountingPoint);
seMPBuilding.mountingPointTypeId(InfrastructureManagement::MountingPointType::BuildingControlUnit);
seMPBuilding.properties("{}");
addElementToRequest(seMPBuilding, 0);
//SWPA 2/22 - GUEZE-1459 - IO 2022.11.10 - do not import GV for new Guez Buildings
#ifndef GUEZ_MODE
InfrastructureManagement::StructureElement seGVBuilding;
seGVBuilding.name(m_request.name()+std::string("_gv"));
seGVBuilding.displayName(m_request.name()+std::string("_gv"));
seGVBuilding.structureElementTypeId(InfrastructureManagement::StructureElementType::MountingPoint);
seGVBuilding.mountingPointTypeId(InfrastructureManagement::MountingPointType::BuildingNetworkSwitch);
seGVBuilding.properties("{}");
addElementToRequest(seGVBuilding, 0);
#endif
// all below building, not below building bcu mounting point
const int parentIdx = 0;
importFootprint(baseGroupElem);
importExternalReferences(baseGroupElem, parentIdx);
importFloors(baseGroupElem, parentIdx);
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importFootprint(const QDomElement &parent)
{
QDomElement groupElem = parent.firstChildElement(QStringLiteral("Group"));
std::vector<InfrastructureManagement::FootprintElement> fp;
for (; !groupElem.isNull(); groupElem = groupElem.nextSiblingElement(groupElem.tagName()))
{
const QDomElement nameElement = getChildElement(groupElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("FOOTPRINT"), Qt::CaseInsensitive))
continue;
const QDomElement polygonElem = getChildElement(groupElem, QStringLiteral("Polygon"), false);
if (polygonElem.isNull())
continue;
QDomElement vertexElem = polygonElem.firstChildElement(QStringLiteral("Vertex"));
for (; !vertexElem.isNull(); vertexElem = vertexElem.nextSiblingElement(vertexElem.tagName()))
{
// TODO: xml hat keine Reihenfolge! Man kann es anhand der Namen sortieren
const QDomElement coordElem = vertexElem.firstChildElement(QStringLiteral("Coord"));
if (coordElem.isNull())
continue;
FootprintElement fpElem;
fpElem.relPosition() = positionFromElement<Core::RelativePosition>(coordElem);
fp.resize(fp.size() + 1, fpElem);
}
break;
}
if (fp.size() > 0)
m_request.footprint(std::move(fp));
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importExternalReferences(const QDomElement &parent,
int parentIdx)
{
QDomElement extRefElem = parent.firstChildElement(QStringLiteral("External_Reference"));
for (; !extRefElem.isNull(); extRefElem = extRefElem.nextSiblingElement(extRefElem.tagName()))
{
const StructureElement se = getStructureElement(extRefElem);
// we don't care about BCU Mounting positions inside xml file - we create our own
if (se.mountingPointTypeId() == MountingPointType::BuildingControlUnit)
{
INFO_LOG(m_logger) << "Ignoring xml-internal BuildingControl mounting point - not needed";
continue;
}
if (se.mountingPointTypeId() == MountingPointType::Unknown)
{
INFO_LOG(m_logger) << "Ignoring unknown mounting point type with subId " << se.mountingPointId();
continue;
}
INFO_LOG(m_logger) << "importExternalReferences: " << se.displayName() << ", parentIdx = " << parentIdx;
addElementToRequest(se, parentIdx);
}
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importFloors(const QDomElement &parent,
int parentIdx)
{
QDomElement floorElem = parent.firstChildElement(QStringLiteral("Group"));
for (; !floorElem.isNull(); floorElem = floorElem.nextSiblingElement(floorElem.tagName()))
{
const QDomElement nameElement = getChildElement(floorElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("floor_"), Qt::CaseInsensitive))
continue;
INFO_LOG(m_logger) << "importFloors: " << nameElement.text() << ", parentIdx = " << parentIdx;
StructureElement se;
se.name(nameElement.text().simplified().toStdString());
se.displayName(se.name());
se.structureElementTypeId(InfrastructureManagement::StructureElementType::Floor);
se.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
se.properties("{}");
// read base height from xml comment
const QDomElement commentElement = getChildElement(floorElem, QStringLiteral("Comment"), false);
DEBUG_LOG(m_logger) << "Comment = " << commentElement.text();
const QStringList comm = commentElement.text().split(QLatin1Char('='));
double baseHeight = 0.00;
if (comm.at(0) == QStringLiteral("base_height"))
baseHeight = comm.at(1).toDouble();
DEBUG_LOG(m_logger) << "base_height = " << baseHeight;
se.relPosition().offsetZ(baseHeight);
addElementToRequest(se, parentIdx);
const int curIdx = m_request.elements().size() - 1;
importRooms(floorElem, curIdx);
}
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importRooms(const QDomElement &parent,
int parentIdx)
{
QDomElement roomElem = parent.firstChildElement(QStringLiteral("Switch"));
for (; !roomElem.isNull(); roomElem = roomElem.nextSiblingElement(roomElem.tagName()))
{
const QDomElement nameElement = getChildElement(roomElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("SW_room_"), Qt::CaseInsensitive))
continue;
const int subId = getInteger(getChildElement(roomElem, QStringLiteral("SubId")), QStringLiteral("ID"));
StructureElement se;
se.name(nameElement.text().simplified().toStdString());
QString roomName = QString::fromStdString(se.name());
// displayed room names are too long
roomName.replace(QStringLiteral("SW_room"), QStringLiteral("R"));
INFO_LOG(m_logger) << "importRooms: " << roomName << ", parentIdx = " << parentIdx;
se.displayName(roomName.toStdString());
se.mountingPointId(subId);
se.structureElementTypeId(InfrastructureManagement::StructureElementType::Room);
se.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
se.properties("{}");
QDomElement subRoomElem = roomElem.firstChildElement(QStringLiteral("Group"));
if (!subRoomElem.isNull())
{
tryGetRoomBoundingBox(subRoomElem, se);
addElementToRequest(se, parentIdx);
const int curIdx = m_request.elements().size() - 1;
importExternalReferences(subRoomElem, curIdx);
DEBUG_LOG(m_logger) << "Room=" << se.name()
<< " Id=" << se.id()
<< " mountingPointId=" << se.mountingPointId();
}
else
{
addElementToRequest(se, parentIdx);
}
}
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::tryGetRoomBoundingBox(const QDomElement &subRoomElem, StructureElement &se)
{
const QDomElement min = getChildElement(subRoomElem, QStringLiteral("BBox_Min"));
const QDomElement max = getChildElement(subRoomElem, QStringLiteral("BBox_Max"));
if (min.isNull() || max.isNull())
return;
const auto minPos(positionFromElement<Core::RelativePosition>(min));
const auto maxPos(positionFromElement<Core::RelativePosition>(min));
se.relPosition(Core::RelativePosition((minPos.offsetX() + maxPos.offsetX()) / 2,
(minPos.offsetY() + maxPos.offsetY()) / 2,
(minPos.offsetZ() + maxPos.offsetZ()) / 2));
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::addElementToRequest(const StructureElement &se,
int parentIdx)
{
const size_t size = m_request.elements().size();
m_request.elements().resize(size + 1, se);
m_request.childParentRelations().resize(size + 1, parentIdx);
}
//-------------------------------------------------------------------------------------------------------------
InfrastructureManagement::MountingPointType ParseBuildingXml::mptFromSubId(int subId)
{
enum ExternalReference
{
NONE = 0,
REF_MOD = 11000,
ZEG = 12000,
CAMERA_OUT = 13000,
CAMERA_IN = 14000,
IPS_OUT = 15000,
IPS_IN = 16000,
Unknown1 = 17000,
ANNOUNCEMENT_Unit = 26000,
EGCU = 27000,
Unknown2 = 28000
};
if (subId > Unknown2)
return MountingPointType::Unknown;
if (subId > EGCU)
return MountingPointType::EffectGenerationControlUnit;
if (subId > ANNOUNCEMENT_Unit)
return MountingPointType::AnnouncementUnit;
if (subId > Unknown1)
return MountingPointType::Unknown;
if (subId > IPS_IN)
return MountingPointType::IndoorIPS;
if (subId > IPS_OUT)
return MountingPointType::OutdoorIPS;
if (subId > CAMERA_IN)
return MountingPointType::IndoorCamera;
if (subId > CAMERA_OUT)
return MountingPointType::OutdoorCamera;
if (subId > ZEG)
return MountingPointType::BuildingControlUnit;
if (subId > REF_MOD)
return MountingPointType::BuildingSensorModule;
return MountingPointType::Unknown;
}
//-------------------------------------------------------------------------------------------------------------
StructureElement ParseBuildingXml::getStructureElement(const QDomElement &element) const
{
const int subId = getInteger(getChildElement(element, QStringLiteral("SubId")), QStringLiteral("ID"));
StructureElement se;
se.relPosition(positionFromElement<Core::RelativePosition>(getChildElement(element, QStringLiteral("Coord"))));
se.orientation(positionFromElement<Core::Orientation>(getChildElement(element, QStringLiteral("Dir")))); // xyz=hpr?
se.mountingPointTypeId(mptFromSubId(subId));
se.structureElementTypeId(InfrastructureManagement::StructureElementType::MountingPoint);
se.name(element.firstChildElement(QStringLiteral("Name")).text().simplified().toStdString());
QString displayName = m_buildingName;
displayName.append(QLatin1String(" - "));
displayName.append(QString::fromStdString(se.name()));
se.displayName(displayName.toStdString());
se.mountingPointId(subId);
se.properties("{}");
return se;
}
//-------------------------------------------------------------------------------------------------------------
template <typename T>
QDomElement ParseBuildingXml::getChildElement(const T &parent, const QString &childTag, bool bThrow) const
{
const QDomElement ret = parent.firstChildElement(childTag);
if (ret.isNull() && bThrow)
throw XmlImportException(tr("Invalid XML Structure - no '%1' tag (line %2:%3)")
.arg(childTag).arg(parent.lineNumber()).arg(parent.columnNumber()));
return ret;
}
//-------------------------------------------------------------------------------------------------------------
int ParseBuildingXml::getInteger(const QDomElement &element, const QString &attribute) const
{
bool bOk = true;
const int ret = element.attribute(attribute).toInt(&bOk);
if (!bOk)
throw XmlImportException(tr("Can not find attribute %1 in xml element %2 (line %3:%4)")
.arg(attribute, element.tagName()).arg(element.lineNumber()).arg(element.columnNumber()));
return ret;
}
} // namespace InfrastructureManagement