701 lines
27 KiB
C++
Executable File
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 <QtCore/QFile>
|
|
#include <QtCore/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 = static_cast<int>(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 = static_cast<int>(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
|