Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,378 @@
/**
* Building Model
* $Id$
* $HeadURL$
* $Author$
* Created by Gerlinde Rudolphus, ESZS, 2016-04-14
*/
#include "ces_building_model.h"
#include <Buildings/BuildingControlUnit/VWM/vwm_xml_reader.h>
#include <Buildings/BuildingControlUnit/VWM/vwm_math.h>
#include <LtsUtilsCore/dds_vector.h>
#include <float.h>
#include <QLineF>
#include <QDebug>
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
bool intersects(const QLineF &line1, const QLineF &line2)
{
const QPointF a = line1.p2() - line1.p1();
const QPointF b = line2.p1() - line2.p2();
const QPointF c = line1.p1() - line2.p1();
const qreal denominator = a.y() * b.x() - a.x() * b.y();
if (denominator == 0 || !std::isfinite(denominator))
return false;
const qreal reciprocal = 1 / denominator;
const qreal na = (b.y() * c.x() - b.x() * c.y()) * reciprocal;
if (na < 0 || na > 1)
return false;
const qreal nb = (a.x() * c.y() - a.y() * c.x()) * reciprocal;
if (nb < 0 || nb > 1)
return false;
return true;
}
#endif
namespace CesBuildings
{
/*************************************************************************************************
* Static methods *
*************************************************************************************************/
bool BuildingModel::isValid(const LtsUtils::QPoint3D &point)
{
return point != invalidPosition();
}
bool BuildingModel::isValid(const Core::GeoPosition &point)
{
return !qFuzzyIsNull(point.lon()) && !qFuzzyIsNull(point.lat()) && point.z() > invalidGeoPosition().z();
}
LtsUtils::QPoint3D BuildingModel::invalidPosition()
{
return BuildingControlUnit::VWM::Math::invalidPosition();
}
Core::GeoPosition BuildingModel::invalidGeoPosition()
{
return Core::GeoPosition(0., 0., -10000.);
}
/*************************************************************************************************
* Ctor, dtor and init *
*************************************************************************************************/
BuildingModel::BuildingModel(QObject *parent)
: QObject(parent)
, BuildingControlUnit::VWM::Building()
, m_logger(CentralEffectSimulation::getLogger(QStringLiteral("BuildingModel")))
{
}
BuildingModel::~BuildingModel()
{
}
bool BuildingModel::init(
const InfrastructureManagement::MainFootprint &mfp, const InfrastructureManagement::MainStructureElement &mse,
const QByteArray &vmd,
const int buildingId
)
{
m_buildingId = buildingId;
TRACE_LOG(m_logger) << LOGFUNCTION << " START, m_buildingId=" << m_buildingId;
m_angle = mse.angle() * M_PI / 180.;
m_refPosGeo = mse.geoPosition();
m_refPosUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(mse.geoPosition().lon(), mse.geoPosition().lat());
m_refPos = {m_refPosUtm.x, m_refPosUtm.y, m_refPosGeo.z()};
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, m_buildingId=" << m_buildingId
<< ", m_angle=" << m_angle
<< ", m_refPosGeo=" << m_refPosGeo
<< ", m_refPos=" << m_refPos;
for (const InfrastructureManagement::FootprintElement &footprintElement : qAsConst(mfp.elements()))
m_footprint << QPointF(footprintElement.relPosition().offsetX(), footprintElement.relPosition().offsetY());
if (m_footprint.isEmpty())
{
ERROR_LOG(m_logger) << "Error reading MainFootprint for building " << m_buildingId;
return false;
} // if
m_boundingRect = m_footprint.boundingRect();
// const std::vector<uint8_t> &data = vmd.vulnerabilityData();
// QByteArray array = qUncompress(QByteArray::fromRawData(reinterpret_cast<const char*>(&data[0]), data.size()));
if (!BuildingControlUnit::VWM::XmlReader::readBuilding(vmd, *this))
{
ERROR_LOG(m_logger) << "Error reading VulnerabilityModelData for building " << m_buildingId;
return false;
} // if
m_height = DBL_MIN;
const QMap<int, BuildingControlUnit::VWM::Room> &roomMap = rooms();
for (const BuildingControlUnit::VWM::Room &room : qAsConst(roomMap))
for (const BuildingControlUnit::VWM::OuterWall &outerWall : qAsConst(room.outerWalls()))
for (const BuildingControlUnit::VWM::WallElement &wallElement : qAsConst(outerWall.elements()))
for (const LtsUtils::QPoint3D &point : qAsConst(wallElement))
if (point.z() > m_height)
m_height = point.z();
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_buildingId=" << m_buildingId;
return true;
}
/*************************************************************************************************
* Intersection calculations *
*************************************************************************************************/
bool BuildingModel::hasIntersectionSimplified(const LtsUtils::QPoint3D &start, const LtsUtils::QPoint3D &end) const
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_buildingId=" << m_buildingId
<< ", start=" << start << ", end=" << end;
// keep origin of QRect (topLeft) in mind:
static const QLineF topLine = QLineF(m_boundingRect.topRight(), m_boundingRect.topLeft());
static const QLineF leftLine = QLineF(m_boundingRect.topLeft(), m_boundingRect.bottomLeft());
static const QLineF bottomLine = QLineF(m_boundingRect.bottomLeft(), m_boundingRect.bottomRight());
static const QLineF rightLine = QLineF(m_boundingRect.bottomRight(), m_boundingRect.topRight());
// qCritical() << " topLine" << topLine;
// qCritical() << " leftLine" << leftLine;
// qCritical() << " bottomLine" << bottomLine;
// qCritical() << " rightLine" << rightLine;
// qCritical() << " start.z()" << start.z();
// qCritical() << " end.z()" << end.z();
// qCritical() << " m_height" << m_height;
// over the building?
if (start.z() > m_height && end.z() > m_height)
return false;
const QPointF start2D(start.x(), start.y());
const QPointF end2D(end.x(), end.y());
const QLineF startToEnd = QLineF(start2D, end2D);
// qCritical() << " startToEnd" << startToEnd;
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QPointF dummy;
if (startToEnd.intersects(topLine, &dummy) != QLineF::BoundedIntersection &&
startToEnd.intersects(leftLine, &dummy) != QLineF::BoundedIntersection &&
startToEnd.intersects(bottomLine, &dummy) != QLineF::BoundedIntersection &&
startToEnd.intersects(rightLine, &dummy) != QLineF::BoundedIntersection &&
!m_boundingRect.contains(start2D) && !m_boundingRect.contains(end2D))
#else
if (!intersects(startToEnd, topLine) && !intersects(startToEnd, leftLine) &&
!intersects(startToEnd, bottomLine) && !intersects(startToEnd, rightLine) &&
!m_boundingRect.contains(start2D) && !m_boundingRect.contains(end2D))
#endif
return false;
// qCritical() << " intersects done";
QPolygonF poly;
poly << start2D;
poly << end2D;
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
if (!m_footprint.intersects(poly))
#else
if (m_footprint.intersected(poly).isEmpty())
#endif
return false;
// qCritical() << " hasIntersectionSimplified -> return true";
return true;
}
bool BuildingModel::hasIntersectionSimplified(const Core::GeoPosition &start, const Core::GeoPosition &end) const
{
return hasIntersectionSimplified(fromGeographic(start), fromGeographic(end));
}
bool BuildingModel::hasIntersectionSimplified(const QVector<LtsUtils::QPoint3D> &trajectory) const
{
for (int i = 1; i < trajectory.size(); ++i)
if (hasIntersectionSimplified(trajectory[i - 1], trajectory[i]))
return true;
return false;
}
bool BuildingModel::hasIntersectionSimplified(const std::vector<Core::GeoPosition> &trajectory) const
{
for (unsigned int i = 1; i < trajectory.size(); ++i)
if (hasIntersectionSimplified(trajectory[i - 1], trajectory[i]))
return true;
return false;
}
bool BuildingModel::hasIntersection(const LtsUtils::QPoint3D &start, const LtsUtils::QPoint3D &end) const
{
if (!hasIntersectionSimplified(start, end))
return false;
bool bHasIntersection = BuildingControlUnit::VWM::Math::hasIntersection(start, end, rooms());
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_buildingId=" << m_buildingId
<< ", start=" << start << ", end=" << end
<< ", rooms().size()" << rooms().size()
<< ", bHasIntersection=" << bHasIntersection;
return bHasIntersection;
}
bool BuildingModel::hasIntersection(const Core::GeoPosition &start, const Core::GeoPosition &end) const
{
return hasIntersection(fromGeographic(start), fromGeographic(end));
}
bool BuildingModel::hasIntersection(const QVector<LtsUtils::QPoint3D> &trajectory) const
{
for (int i = 1; i < trajectory.size(); ++i)
if (hasIntersection(trajectory[i - 1], trajectory[i]))
return true;
return false;
}
bool BuildingModel::hasIntersection(const std::vector<Core::GeoPosition> &trajectory) const
{
for (unsigned int i = 1; i < trajectory.size(); ++i)
if (hasIntersection(trajectory[i - 1], trajectory[i]))
return true;
return false;
}
Core::GeoPosition BuildingModel::intersection(const LtsUtils::QPoint3D &start, const LtsUtils::QPoint3D &end) const
{
const LtsUtils::QPoint3D point = BuildingControlUnit::VWM::Math::intersection(start, end, rooms());
return !isValid(point) ? invalidGeoPosition() : toGeographic(point);
}
Core::GeoPosition BuildingModel::intersection(const Core::GeoPosition &start, const Core::GeoPosition &end) const
{
return intersection(fromGeographic(start), fromGeographic(end));
}
Core::GeoPosition BuildingModel::intersection(const QVector<LtsUtils::QPoint3D> &trajectory) const
{
for (int i = 1; i < trajectory.size(); ++i)
{
Core::GeoPosition pos = intersection(trajectory[i - 1], trajectory[i]);
if (!isValid(pos))
continue;
return pos;
} // for
return {};
}
Core::GeoPosition BuildingModel::intersection(const std::vector<Core::GeoPosition> &trajectory) const
{
for (unsigned int i = 1; i < trajectory.size(); ++i)
{
Core::GeoPosition pos = intersection(fromGeographic(trajectory[i - 1]), fromGeographic(trajectory[i]));
if (!isValid(pos))
continue;
return pos;
} // for
return {};
}
/*************************************************************************************************
* Coordinate transformations *
*************************************************************************************************/
LtsUtils::QPoint3D BuildingModel::fromGeographic(const Core::GeoPosition &point) const
{
// qCritical() << " point.z = " << point.z();
// qCritical() << " m_refPos = " << m_refPos.x() << " - " << m_refPos.y() << " - " << m_refPos.z();
const LtsCoordTrans::UtmCoordinate utm = LtsCoordTrans::UtmCoordinate::fromGeographic(point.lon(), point.lat());
// qCritical() << " utm = " << utm.mgrs(7);
return toReference({utm.x, utm.y, point.z()});
}
QVector<LtsUtils::QPoint3D> BuildingModel::fromGeographic(const std::vector<Core::GeoPosition> &points) const
{
QVector<LtsUtils::QPoint3D> ret;
ret.reserve(points.size());
for (const Core::GeoPosition &point : qAsConst(points))
ret.append(fromGeographic(point));
return ret;
}
Core::GeoPosition BuildingModel::toGeographic(const LtsUtils::QPoint3D &point) const
{
const QPointF geoPos2D = m_refPosUtm.geographic(point.rotated(m_angle, LtsUtils::QPoint3D::Axis::Z).toPointF());
return Core::GeoPosition(geoPos2D.x(), geoPos2D.y(), point.z() + m_refPos.z());
}
std::vector<Core::GeoPosition> BuildingModel::toGeographic(const QVector<LtsUtils::QPoint3D> &points) const
{
std::vector<Core::GeoPosition> ret;
ret.reserve(points.size());
for (const LtsUtils::QPoint3D &point : qAsConst(points))
ret.push_back(toGeographic(point));
return ret;
}
LtsUtils::QPoint3D BuildingModel::fromReference(const LtsUtils::QPoint3D &point) const
{
return point.rotated(m_angle, LtsUtils::QPoint3D::Axis::Z) + m_refPos;
}
QVector<LtsUtils::QPoint3D> BuildingModel::fromReference(const QVector<LtsUtils::QPoint3D> &points) const
{
QVector<LtsUtils::QPoint3D> ret;
ret.reserve(points.size());
for (const LtsUtils::QPoint3D &point : qAsConst(points))
ret.append(fromReference(point));
return ret;
}
LtsUtils::QPoint3D BuildingModel::toReference(const LtsUtils::QPoint3D &point) const
{
return (point - m_refPos).rotated(-m_angle, LtsUtils::QPoint3D::Axis::Z);
}
QVector<LtsUtils::QPoint3D> BuildingModel::toReference(const QVector<LtsUtils::QPoint3D> &points) const
{
QVector<LtsUtils::QPoint3D> ret;
ret.reserve(points.size());
for (const LtsUtils::QPoint3D &point : qAsConst(points))
ret.append(toReference(point));
return ret;
}
/*************************************************************************************************
* Overloaded operators *
*************************************************************************************************/
bool BuildingModel::operator ==(const BuildingModel &other) const
{
return m_buildingId == other.m_buildingId;
}
bool BuildingModel::operator !=(const BuildingModel &other) const
{
return m_buildingId != other.m_buildingId;
}
} // namespace CesBuildings