/** * @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 #include #include 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 BuildingRoomGeometry::pointIsInWhichRooms(const LtsUtils::QPoint3D &pointToFind) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, pointToFind" << pointToFind << ", m_roomOutlines.size() " << m_roomOutlines.size(); QVector roomtIds; QMapIterator 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 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(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