347 lines
13 KiB
C++
Executable File
347 lines
13 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Read all xml config files
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
|
*/
|
|
|
|
|
|
#include "vwm_xml_reader.h"
|
|
#include "vwm_building_room_geometry.h"
|
|
#include <logger.h>
|
|
#include <QFile>
|
|
#include <QDomDocument>
|
|
#include <QSet>
|
|
#include <bcu_xml_reader.h>
|
|
|
|
namespace BuildingControlUnit
|
|
{
|
|
namespace VWM
|
|
{
|
|
namespace XmlReader
|
|
{
|
|
|
|
static NGL::INGLLogger &logger()
|
|
{
|
|
return BuildingControlUnit::getLogger("XmlReader");
|
|
}
|
|
|
|
static Charge parseCharge(const QDomElement &domCharge)
|
|
{
|
|
Charge charge;
|
|
charge.id = getTagText(domCharge, QStringLiteral("Id")).toInt();
|
|
charge.chargeTypeId = getTagText(domCharge, QStringLiteral("ChargeTypeId")).toInt();
|
|
charge.destructiveFactor = getTagText(domCharge, QStringLiteral("DestructiveFactor")).toInt();
|
|
charge.penetrationEffect = getTagText(domCharge, QStringLiteral("PenetrationEffect")).toInt();
|
|
charge.effectSoundId = getTagText(domCharge, QStringLiteral("EffectSound")).toInt();
|
|
charge.difcueLight = getTagText(domCharge, QStringLiteral("DifcueLight")).toInt() != 0;
|
|
charge.difcuePyro = getTagText(domCharge, QStringLiteral("DifcuePyro")).toInt() != 0;
|
|
if (hasTagText(domCharge, QStringLiteral("showHitLine")))
|
|
charge.showHitLine = getTagText(domCharge, QStringLiteral("showHitLine")).toInt() != 0;
|
|
else
|
|
charge.showHitLine = true;
|
|
DEBUG_LOG(logger()) << "Charge: " << charge;
|
|
//if (charge.destructiveFactor <= 0)
|
|
// throw XmlReaderException(QStringLiteral("Destructive factor for charge %1 <= 0 which is not allowed!").arg(charge.id));
|
|
//if (charge.penetrationEffect < 0)
|
|
// throw XmlReaderException(QStringLiteral("Penetration effect for charge %1 < 0 which is not allowed!").arg(charge.id));
|
|
return charge;
|
|
}
|
|
|
|
bool readCharges(const QString &fn, QMap<int, Charge> &charges)
|
|
{
|
|
charges.clear();
|
|
const QDomElement domRoot = readFile(fn, QStringLiteral("Charges"));
|
|
if (domRoot.isNull())
|
|
return false;
|
|
|
|
QDomElement domChargeType = domRoot.firstChildElement(QStringLiteral("Charge"));
|
|
while (!domChargeType.isNull())
|
|
{
|
|
try
|
|
{
|
|
const Charge c = parseCharge(domChargeType);
|
|
charges.insert(c.chargeTypeId, c);
|
|
}
|
|
catch (const XmlReaderException &ex)
|
|
{
|
|
QString errorString = QLatin1String("Error reading charge type: ") + QLatin1String(ex.what());
|
|
ERROR_LOG(logger()) << errorString;
|
|
return false;
|
|
}
|
|
domChargeType = domChargeType.nextSiblingElement(domChargeType.tagName());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static LtsUtils::QPoint3D getCoord3D(const QDomElement &domCoord)
|
|
{
|
|
LtsUtils::QPoint3D ret;
|
|
ret.rx() = getTagText(domCoord, QStringLiteral("X")).toDouble();
|
|
ret.ry() = getTagText(domCoord, QStringLiteral("Y")).toDouble();
|
|
ret.rz() = getTagText(domCoord, QStringLiteral("Z")).toDouble();
|
|
|
|
// Ein Runden auf cm hat auch Nachteile:
|
|
// So kommt es vor, das Polygone (in mm) um lineare Abhängigkeiten reduziert
|
|
// werden können, aber wenn diese auf cm gerundet sind, nicht mehr!!!
|
|
// Siehe Lts/Proxies/Buildings/BuildingControlUnit/VWM/vwm_math_unit_test.cpp
|
|
/*static const QVector<LtsUtils::QPoint3D> polyBldg1103_205_5_ORG({
|
|
{11.639, 6.026, 5.412}, // idx=0
|
|
{11.639, 2.607, 5.513}, // idx=1 // problem: linear dependent -> wird erkannt
|
|
{11.639, 1.690, 5.540}, // idx=2
|
|
{14.659, 1.694, 5.539}, // idx=3
|
|
{14.659, 6.026, 5.412} // idx=4
|
|
});
|
|
static const QVector<LtsUtils::QPoint3D> polyBldg1103_205_5_ROUNDED({
|
|
{11.64, 6.03, 5.41}, // idx=0
|
|
{11.64, 2.61, 5.51}, // idx=1 // problem: linear dependent -> wird erkannt
|
|
{11.64, 1.69, 5.54}, // idx=2
|
|
{14.66, 1.69, 5.54}, // idx=3
|
|
{14.66, 6.03, 5.41} // idx=4
|
|
});
|
|
*/
|
|
// ret.setX( roundf(ret.x() * 100) / 100 );
|
|
// ret.setY( roundf(ret.y() * 100) / 100 );
|
|
// ret.setZ( roundf(ret.z() * 100) / 100 );
|
|
|
|
return ret;
|
|
}
|
|
|
|
static NeighbourRoom parseNeighbourRoom(const QDomElement &domNeighbour)
|
|
{
|
|
NeighbourRoom ret;
|
|
ret.setId(getTagText(domNeighbour, QStringLiteral("RoomId")).toInt());
|
|
ret.setTransitionFactor(getTagText(domNeighbour, QStringLiteral("TransitionFactor")).toDouble());
|
|
DEBUG_LOG(logger()) << " NeighbourRoom id=" << ret.id() << ", transitionFactor=" << ret.transitionFactor();
|
|
return ret;
|
|
}
|
|
|
|
static ExclusionZone parseExclusionZone(const QDomElement &domeExclusionZone)
|
|
{
|
|
ExclusionZone ret;
|
|
QVector<LtsUtils::QPoint3D> poly;
|
|
|
|
ret.setProtectiveFactor(getTagText(domeExclusionZone, QStringLiteral("ExclusionZoneProtectiveFactor")).toInt());
|
|
DEBUG_LOG(logger()) << " ExclusionZone protectiveFactor= " << ret.protectiveFactor();
|
|
QDomElement domExclusionZoneElement = domeExclusionZone.firstChildElement(QStringLiteral("ExclusionZoneElement"));
|
|
while (!domExclusionZoneElement.isNull())
|
|
{
|
|
poly.clear();
|
|
QDomElement domPolygonPoint = domExclusionZoneElement.firstChildElement(QStringLiteral("PolygonPoint"));
|
|
while (!domPolygonPoint.isNull())
|
|
{
|
|
poly += getCoord3D(domPolygonPoint);
|
|
domPolygonPoint = domPolygonPoint.nextSiblingElement(domPolygonPoint.tagName());
|
|
}
|
|
ret.elements() += poly;
|
|
domExclusionZoneElement = domExclusionZoneElement.nextSiblingElement(domExclusionZoneElement.tagName());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static OuterWall parseOuterWall(const QDomElement &domOuterWall)
|
|
{
|
|
OuterWall ret;
|
|
QVector<LtsUtils::QPoint3D> poly;
|
|
|
|
// try {
|
|
// }
|
|
// catch (...)
|
|
// {
|
|
// ERROR_LOG(logger()) << " OuterWall protectiveFactor set to Default = 200 for bldg_3100";
|
|
// ret.setProtectiveFactor(0);
|
|
// }
|
|
|
|
ret.setProtectiveFactor(getTagText(domOuterWall, QStringLiteral("OuterWallProtectiveFactor")).toInt());
|
|
|
|
DEBUG_LOG(logger()) << " OuterWall protectiveFactor=" << ret.protectiveFactor();
|
|
{
|
|
DEBUG_LOG(logger()) << " OuterWallAreaElements:";
|
|
QDomElement domPolygonPoints = domOuterWall.firstChildElement(QStringLiteral("OuterWallAreaElement"));
|
|
while (!domPolygonPoints.isNull())
|
|
{
|
|
poly.clear();
|
|
QDomElement domPolygonPoint = domPolygonPoints.firstChildElement(QStringLiteral("PolygonPoint"));
|
|
while (!domPolygonPoint.isNull())
|
|
{
|
|
poly += getCoord3D(domPolygonPoint);
|
|
domPolygonPoint = domPolygonPoint.nextSiblingElement(domPolygonPoint.tagName());
|
|
}
|
|
ret.elements() += poly;
|
|
domPolygonPoints = domPolygonPoints.nextSiblingElement(domPolygonPoints.tagName());
|
|
}
|
|
}
|
|
{
|
|
QDomElement domExclusionZones = domOuterWall.firstChildElement(QStringLiteral("ExclusionZones"));
|
|
QDomElement domExclusionZone = domExclusionZones.firstChildElement(QStringLiteral("ExclusionZone"));
|
|
DEBUG_LOG(logger()) << " ExclusionZones:";
|
|
while (!domExclusionZone.isNull())
|
|
{
|
|
ret.exclusionZones() += parseExclusionZone(domExclusionZone);
|
|
domExclusionZone = domExclusionZone.nextSiblingElement(domExclusionZone.tagName());
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static Room parseRoom(const QDomElement &domRoom)
|
|
{
|
|
Room ret;
|
|
|
|
ret.setId(getTagText(domRoom, QStringLiteral("RoomId")).toInt());
|
|
DEBUG_LOG(logger()) << "Parsing Room id=" << ret.id();
|
|
{
|
|
QDomElement domNeighbours = domRoom.firstChildElement(QStringLiteral("NeighborRooms"));
|
|
QDomElement domNeighbour = domNeighbours.firstChildElement(QStringLiteral("NeighborRoom"));
|
|
while (!domNeighbour.isNull())
|
|
{
|
|
const NeighbourRoom n = parseNeighbourRoom(domNeighbour);
|
|
|
|
auto itNeighbourRoom = ret.neighbours().find(n.id()); // for sanity
|
|
if (itNeighbourRoom.value().id() == n.id())
|
|
{
|
|
WARNING_LOG(logger()) << "Room with id " << n.id()
|
|
<< " listed twice neighbour of room " << ret.id();
|
|
}
|
|
|
|
ret.neighbours().insert(n.id(), n);
|
|
domNeighbour = domNeighbour.nextSiblingElement(domNeighbour.tagName());
|
|
}
|
|
}
|
|
{
|
|
QDomElement domOuterWalls = domRoom.firstChildElement(QStringLiteral("RoomOuterWalls"));
|
|
QDomElement domOuterWall = domOuterWalls.firstChildElement(QStringLiteral("OuterWall"));
|
|
while (!domOuterWall.isNull())
|
|
{
|
|
const OuterWall w = parseOuterWall(domOuterWall);
|
|
ret.outerWalls() += w;
|
|
domOuterWall = domOuterWall.nextSiblingElement(domOuterWall.tagName());
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool readBuilding(const QDomElement &domRoot, Building &cfg)
|
|
{
|
|
if (domRoot.isNull())
|
|
return false;
|
|
|
|
cfg.rooms().clear();
|
|
|
|
try
|
|
{
|
|
cfg.setName(getTagText(domRoot, QStringLiteral("BuildingName")));
|
|
cfg.setModelId(getTagText(domRoot, QStringLiteral("ModelId")).toInt());
|
|
cfg.setBuildingProtectionLevel(getTagText(domRoot, QStringLiteral("BuildingProtectionLevel")).toDouble());
|
|
cfg.setExclusionZoneProtectionLevel(getTagText(domRoot, QStringLiteral("ExclusionZoneProtectionLevel")).toInt());
|
|
cfg.setOuterWallProtectionLevel(getTagText(domRoot, QStringLiteral("OuterWallProtectionLevel")).toInt());
|
|
DEBUG_LOG(logger()) << "**********************";
|
|
DEBUG_LOG(logger()) << "*** BUILDING: ***";
|
|
DEBUG_LOG(logger()) << "**********************";
|
|
|
|
DEBUG_LOG(logger()) << "readBuilding name=" << cfg.name();
|
|
DEBUG_LOG(logger()) << "readBuilding modelId=" << cfg.modelId();
|
|
DEBUG_LOG(logger()) << "readBuilding buildingProtectionLevel=" << cfg.buildingProtectionLevel();
|
|
DEBUG_LOG(logger()) << "readBuilding exclusionZoneProtectionLevel=" << cfg.exclusionZoneProtectionLevel();
|
|
DEBUG_LOG(logger()) << "readBuilding outerWallProtectionLevel=" << cfg.outerWallProtectionLevel();
|
|
|
|
|
|
QDomElement domRooms = domRoot.firstChildElement(QStringLiteral("Rooms"));
|
|
QDomElement domRoom = domRooms.firstChildElement(QStringLiteral("Room"));
|
|
while (!domRoom.isNull())
|
|
{
|
|
try
|
|
{
|
|
const Room r = parseRoom(domRoom);
|
|
cfg.rooms().insert(r.id(), r);
|
|
}
|
|
catch (const XmlReaderException &ex)
|
|
{
|
|
QString errorString = QLatin1String("Error reading room config: ") + QLatin1String(ex.what());
|
|
ERROR_LOG(logger()) << errorString;
|
|
return false;
|
|
}
|
|
domRoom = domRoom.nextSiblingElement(domRoom.tagName());
|
|
}
|
|
}
|
|
catch (const XmlReaderException &ex)
|
|
{
|
|
QString errorString = QLatin1String("Error reading BSMConfiguration: ") + QLatin1String(ex.what());
|
|
ERROR_LOG(logger()) << errorString;
|
|
return false;
|
|
}
|
|
|
|
QMap<int, Room> rooms = cfg.rooms();
|
|
QMap<int, Room>::iterator room = rooms.begin();
|
|
while (room != rooms.end())
|
|
{
|
|
auto itNeighbourRoom = room.value().neighbours().find(room.value().id());
|
|
if (room.value().id() == itNeighbourRoom.value().id())
|
|
{
|
|
WARNING_LOG(logger()) << "Room with id " << itNeighbourRoom.value().id()
|
|
<< " was defined as neighbour of itself!";
|
|
}
|
|
|
|
QMap<int, NeighbourRoom> &neighbours = room.value().neighbours();
|
|
QMap<int, NeighbourRoom>::iterator neighbour = neighbours.begin();
|
|
while (neighbour != neighbours.end())
|
|
{
|
|
auto itRoom = rooms.find(neighbour.value().id());
|
|
if (neighbour.value().id() != itRoom.value().id())
|
|
{
|
|
WARNING_LOG(logger()) << "Could not find room with id " << neighbour.value().id()
|
|
<< " which was defined as neighbour of room " << room.value().id();
|
|
}
|
|
++neighbour;
|
|
}
|
|
++room;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool readBuilding(const QString &fn, Building &cfg)
|
|
{
|
|
const QDomElement domRoot = readFile(fn, QStringLiteral("BuildingVulnerability"));
|
|
return readBuilding(domRoot, cfg);
|
|
}
|
|
|
|
bool readBuilding(const QByteArray &data, Building &cfg)
|
|
{
|
|
QDomDocument doc;
|
|
QString errorMsg;
|
|
int errorLine;
|
|
int errorColumn;
|
|
if (!doc.setContent(data, &errorMsg, &errorLine, &errorColumn))
|
|
{
|
|
ERROR_LOG(logger()) << "Line=" << errorLine << ", Column=" << errorColumn << ": " << errorMsg;
|
|
return false;
|
|
} // if
|
|
const QDomElement domRoot = doc.documentElement();
|
|
return readBuilding(domRoot, cfg);
|
|
}
|
|
|
|
bool readBuildingGeometry(const QDomElement &domRoot, BuildingRoomGeometry &bldgGeometry)
|
|
{
|
|
if (domRoot.isNull())
|
|
return false;
|
|
|
|
const QDomElement &domHdr = domRoot.firstChildElement(QStringLiteral("Header"));
|
|
const QDomElement &domGroup = domHdr.firstChildElement(QStringLiteral("Group"));
|
|
|
|
return bldgGeometry.init(domGroup);
|
|
}
|
|
|
|
bool readBuildingGeometry(const QString &fn, BuildingRoomGeometry &bldgGeometry)
|
|
{
|
|
const QDomElement domRoot = readFile(fn, QStringLiteral("STREIF"));
|
|
return readBuildingGeometry(domRoot, bldgGeometry);
|
|
}
|
|
|
|
} // namespace XmlReader
|
|
} // namespace VWM
|
|
} // namespace BuildingControlUnit
|