Files
qt5-legatus-legacy/Lts/Proxies/Buildings/BuildingControlUnit/VWM/vwm_building_room_geometry.cpp
T
2026-08-13 18:33:10 +02:00

204 lines
7.9 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Building VWM info
* $Id$
* $HeadURL$
* $Author$
* Created by Gerlinde Rudolphus, SLSA, 2017-01-15
*/
#include "vwm_building_room_geometry.h"
#include "bcu_xml_reader.h"
#include <LtsUtilsCore/qpoint3d.h>
#include <QDebug>
#include <algorithm>
namespace BuildingControlUnit
{
namespace VWM
{
BuildingRoomGeometry::BuildingRoomGeometry()
: m_logger(BuildingControlUnit::getLogger("VWM.BuildingRoomGeometry"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
BuildingRoomGeometry::~BuildingRoomGeometry()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool BuildingRoomGeometry::init(const QDomElement &domRoot)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
parse(domRoot);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
QVector<int> BuildingRoomGeometry::pointIsInWhichRooms(const LtsUtils::QPoint3D &pointToFind)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, pointToFind" << pointToFind
<< ", m_roomOutlines.size() " << m_roomOutlines.size();
QVector<int> roomtIds;
QMapIterator<int, RoomOutlineData> it(m_roomOutlines);
while (it.hasNext())
{
it.next();
const int roomId = it.key();
const RoomOutlineData &rod = it.value();
DEBUG_LOG(m_logger) << LOGFUNCTION << " check room " << roomId << " (check maxZ " << rod.maxZ << " ; minZ " << rod.minZ;
if (m_logger.isDebugEnabled())
qCritical() << " check room " << roomId << ", outline: " << rod.outline;
if (rod.outline.containsPoint( {pointToFind.x(), pointToFind.y()}, Qt::OddEvenFill))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " within room " << roomId;
if ((rod.maxZ > pointToFind.z()) &&
(pointToFind.z() > rod.minZ))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " found roomId: " << roomId
<< " pointToFind: " << pointToFind.x() << " , " << pointToFind.y();
roomtIds.append(roomId);
}
}
} // while
TRACE_LOG(m_logger) << LOGFUNCTION << " END, roomtIds.size() " << roomtIds.size();
return roomtIds;
}
static QDomElement getChildElement(const QDomElement &parent, const QString &childTag, bool bThrow = true)
{
const QDomElement ret = parent.firstChildElement(childTag);
if (ret.isNull() && bThrow)
throw BuildingControlUnit::XmlReaderException(QStringLiteral("Invalid XML Structure - no '%1' tag").arg(childTag));
return ret;
}
static int getInteger(const QDomElement &element, const QString &attribute)
{
bool bOk = true;
const int ret = element.attribute(attribute).toInt(&bOk);
if (!bOk)
throw BuildingControlUnit::XmlReaderException(QStringLiteral("Can not find attribute %1 in xml element %2 (line %3:%4)")
.arg(attribute, element.tagName()).arg(element.lineNumber()).arg(element.columnNumber()));
return ret;
}
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());
}
static inline bool checkRange(double d)
{
return (fabs(d) < 10000000);
}
static inline LtsUtils::QPoint3D positionFromElement(const QDomElement &elem)
{
bool bOkX, bOkY, bOkZ;
auto ret (LtsUtils::QPoint3D(elem.attribute(QStringLiteral("X")).toDouble(&bOkX),
elem.attribute(QStringLiteral("Y")).toDouble(&bOkY),
elem.attribute(QStringLiteral("Z")).toDouble(&bOkZ)));
if (!bOkX || !checkRange(ret.x()))
throw BuildingControlUnit::XmlReaderException(QStringLiteral("invalid value for X: %1 (line %2:%3)")
.arg(elem.attribute(QStringLiteral("X"))).arg(elem.lineNumber()).arg(elem.columnNumber()));
if (!bOkY || !checkRange(ret.y()))
throw BuildingControlUnit::XmlReaderException(QStringLiteral("invalid value for Y: %1 (line %2:%3)")
.arg(elem.attribute(QStringLiteral("Y"))).arg(elem.lineNumber()).arg(elem.columnNumber()));
if (!bOkZ || !checkRange(ret.z()))
throw BuildingControlUnit::XmlReaderException(QStringLiteral("invalid value for Z: %1 (line %2:%3)")
.arg(elem.attribute(QStringLiteral("Z"))).arg(elem.lineNumber()).arg(elem.columnNumber()));
return ret;
}
bool BuildingRoomGeometry::parse(const QDomElement &domGroup)
{
NGL::INGLLogger &loggerParse = BuildingControlUnit::getLogger("VWM.BuildingRoomGeometry.parse");
QDomElement domGroup1 = getChildElement(domGroup, QStringLiteral("Group"));
for ( ; !domGroup1.isNull(); domGroup1 = domGroup1.nextSiblingElement(domGroup1.tagName()))
{
const QDomElement nameElement = getChildElement(domGroup1, QStringLiteral("Name"), false);
DEBUG_LOG(loggerParse) << " * nameElement: " << nameElement.text();
QDomElement domSwitch = getChildElement(domGroup1, QStringLiteral("Switch"), false);
for ( ; !domSwitch.isNull(); domSwitch = domSwitch.nextSiblingElement(domSwitch.tagName()))
{
const QDomElement roomNameElement = getChildElement(domSwitch, QStringLiteral("Name"), false);
DEBUG_LOG(loggerParse) << " ** roomNameElement: " << roomNameElement.text();
const int roomId = getInteger(getChildElement(domSwitch, QStringLiteral("SubId")), QStringLiteral("ID"));
DEBUG_LOG(loggerParse) << " ** roomId: " << roomId;
QDomElement domGroup2 = getChildElement(domSwitch, QStringLiteral("Group"), false);
for ( ; !domGroup2.isNull(); domGroup2 = domGroup2.nextSiblingElement(domGroup2.tagName()))
{
const QDomElement &domBBMin = getChildElement(domGroup2, QStringLiteral("BBox_Min"));
const QDomElement &domBBMax = getChildElement(domGroup2, QStringLiteral("BBox_Max"));
const LtsUtils::QPoint3D &roomBBoxMin = positionFromElement(domBBMin);
const LtsUtils::QPoint3D &roomBBoxMax = positionFromElement(domBBMax);
DEBUG_LOG(loggerParse) << " ** roomBBoxMin: " << roomBBoxMin;
QDomElement domGroup3 = getChildElement(domGroup2, QStringLiteral("Group"), false); // some bldgs does not have anmother group, e.g. 1104
for ( ; !domGroup3.isNull(); domGroup3 = domGroup3.nextSiblingElement(domGroup3.tagName()))
{
const QDomElement domPoly = getChildElement(domGroup3, QStringLiteral("Polygon"), false);
if (domPoly.isNull())
continue;
// DEBUG_LOG(loggerParse) << " *** domPoly2.isNull() " << domPoly.isNull();
QDomElement vertexElem = domPoly.firstChildElement(QStringLiteral("Vertex"));
QPolygonF outlinePolygon;
for (; !vertexElem.isNull(); vertexElem = vertexElem.nextSiblingElement(vertexElem.tagName()))
{
const QDomElement coordElem = vertexElem.firstChildElement(QStringLiteral("Coord"));
if (coordElem.isNull())
continue;
const LtsUtils::QPoint3D &coord = positionFromElement<LtsUtils::QPoint3D>(coordElem);
outlinePolygon.append(coord.toPointF());
DEBUG_LOG(loggerParse) << " **** coord = " << coord.x() << " , " << coord.y() << " , " << coord.z();
} // for
RoomOutlineData rod;
rod.minZ = roomBBoxMin.z();
rod.maxZ = roomBBoxMax.z();
rod.outline = outlinePolygon;
m_roomOutlines.insert(roomId, rod);
DEBUG_LOG(loggerParse) << " *** insert roomId " << roomId << ", rod with " << outlinePolygon.size();
} // for
} // for
} // for
} // for
return true;
}
} // namespace VWM
} // namespace BuildingControlUnit