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,428 @@
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "buildings_to_map.h"
#include <Map/object_factory.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <MathUtils/simple_helper.h>
#include <Common/PluginInterfaces/gui_plugin_interface.h> // for method "getForeignGuiInterface"
#include <Plugins/Buildings/bld_info_gui_plugin_interface.h> // for Buildings::ForeignInfoGuiInterface
#include <ProjectDataManagement/pdm_to_string.h>
#include <InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
// Qt
#include <QPolygonF>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
namespace SituationMap
{
int32_t Building2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
{
return ddsData.id();
}
bool Building2SituationMap::init(PluginProvider *pluginProvider, bool enableDamageVisualization)
{
if (!pluginProvider ||
!pluginProvider->ismDtc())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no pluginProvider";
return false;
}
m_enableDamageVisualization = enableDamageVisualization;
m_pluginProvider = pluginProvider;
m_ismDtc = pluginProvider->ismDtc();
// optional
m_ismGuiIfc = pluginProvider->ismGuiIfc();
m_bldDtc = pluginProvider->bldDtc();
m_bldInfoIfc = pluginProvider->bldInfoIfc();
// FilterManagement:
FilterClass::init(m_pluginProvider);
return true;
}
bool Building2SituationMap::run()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!m_ismDtc)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
return false;
}
m_mseIdWithoutValidFootprint.clear();
// mainStructureElement
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainFootprintChanged,
this, &Building2SituationMap::onMainFootprintChanged);
// mainStructureElement
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
this, &Building2SituationMap::onMainStructureElementChanged);
// get:
m_ismDtc->mainStructureElements([this](const InfrastructureManagement::MainStructureElement & data)
{
onMainStructureElementChanged(data, DataModification::eAdded);
});
if (m_bldDtc)
connect(m_bldDtc.get(), &Buildings::Interface::Dtc::buildingStateChanged,
this, &Building2SituationMap::onBuildingStateChanged);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool Building2SituationMap::isElapsed(const InfrastructureManagement::MainStructureElement &ddsData) const
{
if (BaseClass::isElapsed(ddsData))
return true;
// skip MeteoDataUnit, RadioStation because they don´t have a footprint
// avoid something like: mainFootprint with id=" << mseId << " is not sufficiant."
const InfrastructureManagement::StructureElementType::inner_enum set = ddsData.structureElementTypeId().underlying();
if ((set == InfrastructureManagement::StructureElementType_def::MeteoDataUnit) ||
(set == InfrastructureManagement::StructureElementType_def::RadioStation) ||
(set == InfrastructureManagement::StructureElementType_def::ApproachingPoint)
)
return true;
// // skip MeteoDataUnit, because they don´t have a footprint
// const auto &elements = ddsData.elements();
// if (elements.size() < 1)
// return false;
// const InfrastructureManagement::StructureElement &element = elements.at(0);
// const InfrastructureManagement::MountingPointType& mpt = element.mountingPointTypeId();
// if (mpt == InfrastructureManagement::MountingPointType_def::MeteoDataUnit)
// return true;
// return false;
const qint32 mseId = ddsData.id();
const InfrastructureManagement::MainFootprint &mainFootprint = m_ismDtc->mainFootprint(mseId);
if (mainFootprint.elements().size() < 3)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " mainFootprint with id=" << mseId << " is not sufficiant."
<< " mainFootprint.elements().size() = " << mainFootprint.elements().size();
if (!m_mseIdWithoutValidFootprint.contains(mseId))
{
INFO_LOG(m_logger) << LOGFUNCTION << " Save for future mainFootPrintChanged..."
<< " (m_mseIdWithoutValidFootprint.size()=" << m_mseIdWithoutValidFootprint.size();
m_mseIdWithoutValidFootprint.append(mseId);
}
return true;
}
return false;
}
bool Building2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
{
if (!m_bldInfoIfc)
return false;
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
if (simIds.isEmpty())
return true;
// SWPÄ 2/22: buildingOutline are also visible.
// But do not open a bunch of bldgInfoWindows while selectByArea at MountingPointListDialog
// is optional so check in advance!
if (m_ismGuiIfc && m_ismGuiIfc->isInSelectionMode())
return true;
m_bldInfoIfc->showInfoWindow(simIds);
return true;
}
bool Building2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
{
if (!m_ismDtc)
return false;
int32_t buildingId = -1;
if (!this->uniqueMapId2SimId(uniqueMapId, buildingId))
return false;
umodOut = UnifiedMapObjectData();
umodOut.m_participantData.m_typeName = tr("Building");
umodOut.m_buildingData.buildingId = buildingId;
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
if (mapObj.valid())
umodOut.m_image = mapObj->previewImage();
if (m_bldDtc)
{
const Buildings::BuildingState &bldgState = m_bldDtc->buildingState(buildingId);
if (bldgState.id() == buildingId)
{
umodOut.m_participantData.m_vulnerabilityState = bldgState.vulnerabilityState().underlying();
umodOut.m_participantData.m_vulnerabilityString = ProjectDataManagement::toString(bldgState.vulnerabilityState());
}
}
umodOut.m_description1 = m_ismDtc->getBuildingDisplayName(buildingId);
return true;
}
void Building2SituationMap::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data,
DataModification modType)
{
const bool isResourceMgr = m_pluginProvider->appId() == LtsAppDescriptor::App::ResourceManager;
bool assignedToExercise = isResourceMgr || (m_ismDtc->isElementAssignedToExercise(data, m_pluginProvider->exerciseId()));
if (modType == DataModification::eAdded && !assignedToExercise)
return;
if (modType == DataModification::eModified && !assignedToExercise)
{
/*
* Was mse assigned to this exercise but someone removed the assignment?
* If yes, remove mse from situation map by changing the request to "eRemoved".
* If no, simply ignore the assignment.
*/
const int32_t simId = getSimId(data);
if (m_simId2UniqueMapId.contains(simId))
modType = DataModification::eRemoved;
else
return;
}
handleChanged(data, modType);
}
void Building2SituationMap::onMainFootprintChanged(const InfrastructureManagement::MainFootprint &data, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
if (data.elements().size() < 3)
return;
const int32_t mseId = data.id(); // mfpId == mseId
if (m_mseIdWithoutValidFootprint.contains(mseId))
{
// try again:
const InfrastructureManagement::MainStructureElement &mseData = m_ismDtc->mainStructureElement(mseId);
if (mseData.id() == mseId)
{
m_mseIdWithoutValidFootprint.removeAll(mseId);
onMainStructureElementChanged(mseData, DataModification::eAdded);
}
}
}
void Building2SituationMap::onBuildingStateChanged(const Buildings::BuildingState &data, DataModification modType)
{
Q_UNUSED(modType);
if (!m_enableDamageVisualization)
return;
// if (modType == DataModification::eRemoved)
// return;
const int buildingId = data.id(); // simId;
auto it = m_simId2UniqueMapId.constFind(buildingId);
if (it == m_simId2UniqueMapId.constEnd())
return; // maybe not assigned to out exercise?
// retrieve mapObj
const UniqueMapId uniqueMapId = it.value();
RefPointer<Sim2SituationMap::MAP_T> mapObj = m_objFac.get<Sim2SituationMap::MAP_T>(uniqueMapId);
if (!mapObj)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " not found in objFac"
<< " simId/buildingId = " << buildingId
<< " uniqueMapId = " << uniqueMapId ;
return;
}
if (!updateBldgDamage(mapObj, buildingId))
{
ERROR_LOG(m_logger) << LOGFUNCTION << " updateBldgDamage failed, "
<< " simId/buildingId = " << buildingId
<< " uniqueMapId = " << uniqueMapId;
return;
}
if (!mapObj->updateView())
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
<< " mapObj = " << mapObj->debugInfo();
}
bool Building2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
RefPointer<MAP_T> mapObj)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " id=" << ddsData.id()
<< " name=" << ddsData.name()
<< " geoPosition=" << ddsData.geoPosition()
<< " angle=" << ddsData.angle();
// typically, building are filled with gray. But the MapObjectIndicator is hard to see.
// so force a different color here:
mapObj->setForceMajorColor(Qt::black);
// show just the ObjectAppearance::Technical
mapObj->setVisibility(ObjectAppearance::Tactical, false);
const qint32 buildingId = getSimId(ddsData); // ddsData.id();
//
// retrieve absolut utm points of footprint (angle is already taken into account)
//
int zoneOut = -1;
bool isGroundLevel = false;
const QPolygonF &absUtmPositions2D = m_ismDtc->getUtmFootprintById(buildingId, zoneOut, isGroundLevel);
const Core::GeoPosition &geoPosition = ddsData.geoPosition();
const QPointF referencePointGeo(geoPosition.lon(), geoPosition.lat());
// utmPos -> geoPos
PositionCont absPositionsGeo;
absPositionsGeo.reserve(absUtmPositions2D.size());
for (const QPointF &absPosition : qAsConst(absUtmPositions2D))
{
const LtsCoordTrans::UtmCoordinate utmPos(zoneOut, absPosition.x(), absPosition.y());
const QPointF &pGeo = utmPos.geographic();
absPositionsGeo.append(Point3D::fromQPointF(pGeo));
} // for
DEBUG_LOG(m_logger) << "absPositionsGeo = " << absPositionsGeo;
mapObj->setPositions(absPositionsGeo);
// Identifier: Many buildings in a city lead to many (unreadable) identifiers -> filter flag is introduced
TextStyle ts = mapObj->textStyle();
ts.setHorizontalAlignment(HorizontalAlignment::Center);
mapObj->setTextStyle(ts);
// mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
mapObj->setIdentifier(m_ismDtc->getBuildingDisplayName(ddsData));
if (m_enableDamageVisualization && m_bldDtc)
{
// set FillStyle according damage
updateBldgDamage(mapObj, buildingId);
}
// display referencePoint:
mapObj->setMarker(Point3D::fromQPointF(referencePointGeo));
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool Building2SituationMap::updateBldgDamage(RefPointer<MAP_T> mapObj, qint32 buildingId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, buildingId=" << buildingId;
if (!m_bldDtc)
return false;
if (!mapObj)
return false;
const Buildings::BuildingState &bldgState = m_bldDtc->buildingState(buildingId);
const bool bIsContaminated = !bldgState.contaminationStates().empty();
// LineStyle
LineStyle ls = mapObj->lineStyle();
if (bIsContaminated)
ls.setLineColor(Qt::yellow);
else
ls.setLineColor(Qt::black);
mapObj->setLineStyle(ls);
// FillStyle
FillStyle fs = mapObj->fillStyle();
fs.setFillPattern(FillPattern::Solid);
int damagePercent = bldgState.damagePercent();
// Not found -> assume no damage
// In case of replay destruction, do not return false
if (bldgState.id() != buildingId)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId/buildingId = " << buildingId
<< " not found!! (mapObj = " << mapObj->debugInfo() << ")";
damagePercent = 0;
}
double opacity = 1.0;
if (damagePercent < 1)
opacity = 0.0;
else if (damagePercent < 20)
opacity = 0.2;
else if (damagePercent < 40)
opacity = 0.4;
else if (damagePercent < 60)
opacity = 0.6;
else if (damagePercent < 80)
opacity = 0.8;
QColor col = QColor(125, 125, 125, 125); // gray
if (opacity > 0.1)
{
col = Qt::red;
col.setAlphaF(opacity);
}
fs.setFillColor(col);
mapObj->setFillStyle(fs);
// refresh MapObjectSelectionWidget or similar:
emit mapObjectChanged(mapObj->uniqueMapId());
TRACE_LOG(m_logger) << LOGFUNCTION << " END, buildingId=" << buildingId
<< ", damagePercent=" << damagePercent
<< ", fillStyle=" << mapObj->fillStyle()
<< ", uniqueMapId=" << mapObj->uniqueMapId();
return true;
}
bool Building2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
{
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
(m_currentSymbolSettings.symbolSettings.showBuildingOutline != newSas.symbolSettings.showBuildingOutline) ||
(m_currentSymbolSettings.symbolSettings.showBuildingIdentifier != newSas.symbolSettings.showBuildingIdentifier);
}
void Building2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
{
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
mapObj->setVisibility(m_currentSymbolSettings.symbolSettings.showBuildingOutline);
mapObj->setIdentifierVisible(m_currentSymbolSettings.symbolSettings.showBuildingIdentifier);
}
}