Files
qt5-legatus-legacy/Lts/Services/InfrastructureManagement/ism_dtc_impl_custom_p.h
T
2026-08-13 18:33:10 +02:00

131 lines
3.7 KiB
C++
Executable File

/**
* @RDE_HEADER@
* ISM Custom functions, private extensions
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, SLSE, 2025-01-07
*/
#pragma once
#include "ism_dtc_impl_custom.h"
#include <LtsCoordinate/lts_coord_vector.h>
#include <QHash>
#include <QPolygonF>
#include <QTransform>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
namespace Interface
{
// improve QPolygonF DtcImplCustom::getUtmFootprintById(int mseId, int &zone, bool isGroundLevel)
class MainFootPrintCache
{
public:
MainFootPrintCache() = default;
void init(DtcImplCustom *dtcCustom)
{
m_dtcCustom = dtcCustom;
}
const QPolygonF &getUtmFootprintById(int mseId, bool isGroundLevel, int &zoneOut) const
{
if (!load(mseId, isGroundLevel, zoneOut))
return m_cache[{-1, true}].first; // empty
const auto &cacheData = m_cache[{mseId, isGroundLevel}];
zoneOut = cacheData.second;
return cacheData.first;
}
bool load(int mseId, bool isGroundLevel, int &zoneOut) const
{
if (m_cache.contains({mseId, isGroundLevel}))
return true;
const MainStructureElement &mse = m_dtcCustom->mainStructureElement(mseId);
if (mse.id() != mseId)
return false;
const MainFootprint &mf = m_dtcCustom->mainFootprint(mseId);
if (mf.id() != mseId)
return {};
// determine the zone (using the mse.geoPosition())
const auto &utm = LtsCoordTrans::UtmCoordinate::fromGeographic(QPointF(mse.geoPosition().lon(), mse.geoPosition().lat()));
zoneOut = utm.zone;
//
// get all elements according m_isGroundLevel
//
// relative:
const std::vector<InfrastructureManagement::FootprintElement> &mfElements = mf.elements();
QPolygonF poly;
poly.reserve(mfElements.size());
for (const InfrastructureManagement::FootprintElement &element : qAsConst(mfElements))
{
// if different, continue
if (isGroundLevel != element.isGroundLevel())
continue;
const auto &relPos = element.relPosition();
poly.push_back(QPointF(relPos.offsetX(), relPos.offsetY()));
}
// Get other footprint if groundLevel footprint is not available
if (poly.isEmpty() && isGroundLevel)
{
for (const InfrastructureManagement::FootprintElement &element : qAsConst(mfElements))
{
const auto &relPos = element.relPosition();
poly.push_back(QPointF(relPos.offsetX(), relPos.offsetY()));
}
}
// old:
// // rotate poly
// QTransform trans;
// trans.rotate(mse.angle());
// poly = trans.map(poly);
// const auto utm = LtsCoordTrans::UtmCoordinate::fromGeographic(QPointF(mse.geoPosition().lon(), mse.geoPosition().lat()), zone);
// zone = utm.zone;
// const QPointF utmFpPosition(utm.x, utm.y);
// QPolygonF retPolyUtm;
// retPolyUtm.reserve(poly.size());
// for (const QPointF &point : qAsConst(poly))
// {
// const QPointF finalUtmPoint(utmFpPosition + point);
// retPolyUtm.push_back(finalUtmPoint);
// DEBUG_LOG(m_logger) << "utmPoint x: " << finalUtmPoint.x() << " utmPoint.y : " << finalUtmPoint.y();
// }
// easier to write and without additional QPolygonF
// rotate,and translate poly
QTransform trans;
trans.translate(utm.x, utm.y);
trans.rotate(mse.angle());
poly = trans.map(poly);
// finally: store in cache
m_cache[ {mseId, isGroundLevel}] = {poly, zoneOut};
return true;
}
private:
DtcImplCustom *m_dtcCustom{nullptr};
mutable QHash<QPair<int, bool>, QPair<QPolygonF, int>> m_cache;
// mseId, ground <poly , zone>
};
} //Interface
} // namespace InfrastructureManagement