204 lines
7.9 KiB
C++
Executable File
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
|