Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+997
@@ -0,0 +1,997 @@
|
||||
/**
|
||||
* Handler for player data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2017-02-20
|
||||
*/
|
||||
|
||||
#include "handler_aes_data.h"
|
||||
|
||||
#include <CentralEffectSimulation/handler_participant.h>
|
||||
#include <CentralEffectSimulation/handler_building_data.h>
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QPointF>
|
||||
#include <QPolygonF>
|
||||
#include <QTimer>
|
||||
#include <QTransform>
|
||||
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsUtilsCore/qpoint3d.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
#define TIMEDIFFVALID 3000
|
||||
|
||||
namespace CesBuildings
|
||||
{
|
||||
|
||||
HandlerAesData::HandlerAesData(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<CentralEffectSimulation::HandlerBuildingData> &buildingDataHandler,
|
||||
QObject *parent)
|
||||
|
||||
: QObject(parent)
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_handlerBuildingData(buildingDataHandler)
|
||||
, m_logger(CentralEffectSimulation::getLogger("Plugin.Buildings.HandlerAesData"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HandlerAesData::~HandlerAesData()
|
||||
{
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
bool HandlerAesData::init()
|
||||
{
|
||||
auto dtcAes = m_ddsHandler->dtcAes();
|
||||
|
||||
dtcAes->enableChargeEffect();
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::chargeEffectChanged,
|
||||
this, &HandlerAesData::onChargeEffectChanged);
|
||||
|
||||
dtcAes->enableExplosionSingle();
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged,
|
||||
this, &HandlerAesData::onExplosionSingleChanged);
|
||||
|
||||
dtcAes->enableAirSupportImpact();
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::airSupportImpactChanged,
|
||||
this, &HandlerAesData::onAirSupportImpactChanged);
|
||||
|
||||
dtcAes->enableTriggeredImpacts();
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::triggeredImpactsChanged,
|
||||
this, &HandlerAesData::onTriggeredImpactsChanged);
|
||||
|
||||
dtcAes->waitForHistoricalDataAesItemView(1000);
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &HandlerAesData::onAesItemViewChanged);
|
||||
|
||||
dtcAes->enableEffects();
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::effectsChanged,
|
||||
this, &HandlerAesData::onEffectsChanged, Qt::UniqueConnection);
|
||||
|
||||
dtcAes->enableBoobyTrap();
|
||||
connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::boobyTrapChanged,
|
||||
this, &HandlerAesData::onBoobyTrapChanged, Qt::UniqueConnection);
|
||||
|
||||
// Get 'static' data for all AesItemView
|
||||
{
|
||||
auto cb = [this](const AreaEffectSimulation::AesItemView & aiv)
|
||||
{
|
||||
onAesItemViewChanged(aiv, DataModification::eAdded);
|
||||
};
|
||||
if (!dtcAes->aesItemViews(cb))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
|
||||
|
||||
void HandlerAesData::onBoobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onBoobyTrapChanged"
|
||||
<< " id=" << data.id()
|
||||
<< " impactPosition=" << data.impactPosition()
|
||||
<< " impactRadius=" << data.impactRadius()
|
||||
<< " effectStateId=" << data.effectStateId();
|
||||
|
||||
if (data.isDeleted()
|
||||
|| data.effectStateId() == AreaEffectSimulation::AesEffectState::EsRemoved
|
||||
|| modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
if (!data.triggered())
|
||||
return;
|
||||
|
||||
INFO_LOG(m_logger) << "HandlerParticipantBoobyTrap::onBoobyTrapChanged"
|
||||
<< " data.id=" << data.id()
|
||||
<< " effectStateId=" << data.effectStateId();
|
||||
|
||||
if (!data.effectStart().is_set())
|
||||
return;
|
||||
|
||||
if ((m_ddsHandler->currentPartitionTime() - (data.effectStart().get() + data.effectDuration())) > 2000)
|
||||
{
|
||||
INFO_LOG(m_logger) << "onBoobyTrap outdated";
|
||||
return;
|
||||
}
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
AreaEffectSimulation::AesType aesType = AreaEffectSimulation::AesType_def::AtBoobyTrap;
|
||||
m_ddsHandler->dtcAes()->aesItemViewFromEntityId(data.id(), aesType, itemView);
|
||||
|
||||
checkBuildingsHit(itemView);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ///////////////////////////////////
|
||||
// A E S (AreaEffectSimulation)
|
||||
// ///////////////////////////////////
|
||||
|
||||
void HandlerAesData::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onAesItemViewChanged"
|
||||
<< " data.aesTypeId()=" << data.aesTypeId();
|
||||
if (modType != DataModification::eAdded &&
|
||||
modType != DataModification::eModified)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Got AesItemView: " << data.effectStateId();
|
||||
if (data.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired)
|
||||
{
|
||||
INFO_LOG(m_logger) << "AesEffectState_def::EsExpired"
|
||||
<< " currentPartitionTime=" << m_ddsHandler->currentPartitionTime()
|
||||
<< " effectStart=" << data.effectStart()
|
||||
<< " diff = " << m_ddsHandler->currentPartitionTime() - data.effectStart() ;
|
||||
if (m_ddsHandler->currentPartitionTime() == 0)
|
||||
return;
|
||||
|
||||
if ((data.aesTypeId() == AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary)
|
||||
|| (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary))
|
||||
{
|
||||
|
||||
if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "AtOffRouteMineSecondary id=" << data.id() / 1000;
|
||||
auto offRouteMine = m_ddsHandler->dtcAes()->offRouteMine((int)(data.id() / 1000));
|
||||
if (!offRouteMine.effectStart().is_set())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "!offRouteMine.effectStart().is_set()";
|
||||
return;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << " currentPartitionTime=" << m_ddsHandler->currentPartitionTime()
|
||||
<< " effectStart=" << offRouteMine.effectStart()
|
||||
<< " effectDuration=" << offRouteMine.effectDuration()
|
||||
<< " diff = " << m_ddsHandler->currentPartitionTime() - (offRouteMine.effectStart().get() + offRouteMine.effectDuration()) ;
|
||||
|
||||
if ((m_ddsHandler->currentPartitionTime() - (offRouteMine.effectStart().get() + offRouteMine.effectDuration())) < 2000)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "AtBoobyTrapSecondary Mine wird ausgeloeset.";
|
||||
checkBuildingsHit(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "outdated return";
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "AtBoobyTrapSecondary id=" << data.id() / 1000;
|
||||
//auto offRouteMine = m_ddsHandler->dtcAes()->offRouteMine((int) (data.id() / 1000));
|
||||
auto boobyTrap = m_ddsHandler->dtcAes()->boobyTrap((int)(data.id() / 1000));
|
||||
if (!boobyTrap.effectStart().is_set())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "!offRouteMine.effectStart().is_set()";
|
||||
return;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << " currentPartitionTime=" << m_ddsHandler->currentPartitionTime()
|
||||
<< " effectStart=" << boobyTrap.effectStart()
|
||||
<< " effectDuration=" << boobyTrap.effectDuration()
|
||||
<< " diff = " << m_ddsHandler->currentPartitionTime() - (boobyTrap.effectStart().get() + boobyTrap.effectDuration()) ;
|
||||
|
||||
if ((m_ddsHandler->currentPartitionTime() - (boobyTrap.effectStart().get() + boobyTrap.effectDuration())) < 2000)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "AtBoobyTrapSecondary Mine wird ausgeloeset.";
|
||||
checkBuildingsHit(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "outdated return";
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "removeStates data";
|
||||
removeStates(data);
|
||||
DEBUG_LOG(m_logger) << "m_aesItemViewsUtm remove id" << data.aesItemId();
|
||||
m_aesItemViewsUtm.remove(data.aesItemId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandlerAesData::removeStates(const AreaEffectSimulation::AesItemView &data)
|
||||
{
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType_def::AtExplosionArea)
|
||||
return;
|
||||
DEBUG_LOG(m_logger) << "Remove aesItemId=" << data.aesItemId();
|
||||
// remove State for each building
|
||||
for (CentralEffectSimulation::BitfieldStates &bfs : m_bitfieldStatesBld)
|
||||
bfs.remove(data.aesItemId());
|
||||
} // end removeStates
|
||||
|
||||
void HandlerAesData::calculateBuildingExplosion(const AreaEffectSimulation::ChargeStruct &chargeStruct,
|
||||
const Core::GeoPosition2D& impactPosition,
|
||||
const int id)
|
||||
{
|
||||
const double impactRadius = m_ddsHandler->chargeTypeRadius(chargeStruct);
|
||||
DEBUG_LOG(m_logger) << "Handle ExplosionSingle (EsActivated)"
|
||||
<< ", m_handlerBuildingData.getFootprints().size =" << m_handlerBuildingData->getFootprints().size();
|
||||
|
||||
QHash<int, CentralEffectSimulation::HandlerBuildingData::Footprint> footprints = m_handlerBuildingData->getFootprints();
|
||||
|
||||
// Bounding-Box-Check
|
||||
// QMap<int, Footprint> m_handlerBuildingData.getFootprints();
|
||||
for (const CentralEffectSimulation::HandlerBuildingData::Footprint &footprint : qAsConst(footprints))
|
||||
{
|
||||
|
||||
const Core::GeoPosition2D impactPosition2D(impactPosition.lon(), impactPosition.lat());
|
||||
if (inFootprint(impactPosition, footprint, impactRadius))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ftc sendCESHitOnBuilding mseId = " << footprint.mseId
|
||||
<< " chargeTypeId = " << chargeStruct.chargeTypeId()
|
||||
<< " id = " << id
|
||||
<< " currentPartitionTime = " << m_ddsHandler->currentPartitionTime()
|
||||
<< " impactPosition2D.lon = " << impactPosition2D.lon()
|
||||
<< " impactPosition2D.lat = " << impactPosition2D.lat();
|
||||
|
||||
Buildings::SendCesHitOnBuildingRequest requestBld(
|
||||
footprint.mseId,
|
||||
chargeStruct.chargeTypeId(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(chargeStruct.chargeTypeId()).destructiveFactor(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(chargeStruct.chargeTypeId()).penetrationFactor(),
|
||||
id,
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
Core::GeoPosition(impactPosition2D.lon(), impactPosition2D.lat(), 0.0),
|
||||
QStringLiteral("properties").toStdString());
|
||||
m_ddsHandler->ftcBld()->sendCesHitOnBuildingRequest(requestBld, this);
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "Not sendCESHitOnBuilding mseId = " << footprint.mseId;
|
||||
|
||||
DEBUG_LOG(m_logger) << "boundingBoxImpact.contains(footprint)";
|
||||
|
||||
} // for
|
||||
|
||||
}
|
||||
|
||||
void HandlerAesData::startTimer(int id, int msec) {
|
||||
auto *timer = new QTimer(this);
|
||||
|
||||
timer->setProperty("chargeEffectId", id);
|
||||
// Timeout-Slot mit echtem SLOT
|
||||
connect(timer, &QTimer::timeout, this, &HandlerAesData::onStartTimeReached);
|
||||
timer->start(msec);
|
||||
DEBUG_LOG(m_logger) << "Timer " << id << " gestartet fuer " << msec << " ms.";
|
||||
}
|
||||
|
||||
void HandlerAesData::onStartTimeReached()
|
||||
{
|
||||
if (!sender())
|
||||
return;
|
||||
|
||||
bool bOk;
|
||||
int chargeEffectId = sender()->property("chargeEffectId").toInt(&bOk);
|
||||
if (!bOk)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Timer " << chargeEffectId << " ausgeloest!";
|
||||
|
||||
// Timer stoppen und loeschen
|
||||
AreaEffectSimulation::ChargeEffect data = m_chargeEffects.value(chargeEffectId);
|
||||
AreaEffectSimulation::ChargeStruct chargeStruct(data.chargeTypeId(),data.igniterTypeId(), data.igniterFunctionId());
|
||||
calculateBuildingExplosion(chargeStruct, data.position(), data.id());
|
||||
sender()->deleteLater();
|
||||
m_chargeEffects.remove(chargeEffectId);
|
||||
}
|
||||
|
||||
void HandlerAesData::onChargeEffectChanged(const AreaEffectSimulation::ChargeEffect &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "HandlerExplosions::onChargeEffectChanged";
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
const long long effectStart = data.effectStart();
|
||||
|
||||
DEBUG_LOG(m_logger) << "HandlerExplosions::onChargeEffectChanged"
|
||||
<< ", effectStart=" << effectStart
|
||||
<< ", currentPartitionTime=" << m_ddsHandler->currentPartitionTime();
|
||||
|
||||
|
||||
// Startzeit in der Vergangenheit: aktuelle Zeit - 3 Sekunden
|
||||
if ( effectStart < m_ddsHandler->currentPartitionTime() - TIMEDIFFVALID )
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Startzeit in der Vergangenheit: aktuelle Zeit - 3 Sekunden";
|
||||
return;
|
||||
}
|
||||
// Startzeit entspricht der aktuellen Zeit
|
||||
if ( effectStart > m_ddsHandler->currentPartitionTime() - TIMEDIFFVALID
|
||||
&& effectStart < m_ddsHandler->currentPartitionTime() + data.effectDuration() )
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Startzeit entspricht der aktuellen Zeit";
|
||||
AreaEffectSimulation::ChargeStruct chargeStruct;
|
||||
chargeStruct.chargeTypeId(data.chargeTypeId());
|
||||
chargeStruct.igniterTypeId(data.igniterTypeId());
|
||||
calculateBuildingExplosion(chargeStruct, data.position(), data.id());
|
||||
}
|
||||
// Startzeit in der Zukunft:
|
||||
else if (effectStart > m_ddsHandler->currentPartitionTime() + data.effectDuration())
|
||||
{
|
||||
// Start mit Timer
|
||||
DEBUG_LOG(m_logger) << "Startzeit in der Zukunft"
|
||||
<< ", id :" << data.id()
|
||||
<< ", duration=" << effectStart - m_ddsHandler->currentPartitionTime();
|
||||
m_chargeEffects.insert(data.id(), data);
|
||||
startTimer(data.id(), effectStart - m_ddsHandler->currentPartitionTime());
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "END onChargeEffectChanged";
|
||||
|
||||
}
|
||||
|
||||
void HandlerAesData::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType)
|
||||
{
|
||||
bool handleExplosion = false;
|
||||
if (modType != DataModification::eAdded &&
|
||||
modType != DataModification::eModified)
|
||||
{
|
||||
m_explosionSingleState.remove(data.id());
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsRemoved)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Remove SingleExplosion";
|
||||
m_explosionSingleState.remove(data.id());
|
||||
return;
|
||||
}
|
||||
// Only handle transitions from prepared or fired to activated
|
||||
if ((m_explosionSingleState.value(data.id()) == AreaEffectSimulation::AesEffectState_def::EsPrepared ||
|
||||
m_explosionSingleState.value(data.id()) == AreaEffectSimulation::AesEffectState_def::EsFired) &&
|
||||
data.effectStateId() == AreaEffectSimulation::AesEffectState_def::EsActivated)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Handle SingleExplosion";
|
||||
handleExplosion = true;
|
||||
}
|
||||
m_explosionSingleState.insert(data.id(), data.effectStateId());
|
||||
|
||||
DEBUG_LOG(m_logger) << "Got ExplosionSingle";
|
||||
if (handleExplosion)
|
||||
{
|
||||
calculateBuildingExplosion(data.chargeStruct(), data.impactPosition(), data.id());
|
||||
}
|
||||
} // onExplosionSingleChanged
|
||||
|
||||
void HandlerAesData::onAirSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Got onAirSupportImpactChanged()";
|
||||
AreaEffectSimulation::ExplosionSingle esData;
|
||||
esData.id(data.id());
|
||||
esData.chargeStruct().chargeTypeId(data.chargeStruct().chargeTypeId());
|
||||
esData.impactPosition(data.impactPosition());
|
||||
esData.effectStateId(data.effectStateId());
|
||||
onExplosionSingleChanged(esData, modType);
|
||||
}
|
||||
|
||||
void HandlerAesData::onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
|
||||
{
|
||||
if (modType != DataModification::eAdded &&
|
||||
modType != DataModification::eModified)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Got TriggeredImpacts";
|
||||
preCalculateImpacts(data);
|
||||
}
|
||||
|
||||
void HandlerAesData::onEffectsChanged(const AreaEffectSimulation::Effects &effects, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << " Got Effects " << effects;
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
if (effects.aesTypeId().underlying() != AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << " Got typechecked effects " << effects;
|
||||
|
||||
// calculate for every building of our exercise:
|
||||
const QHash<int, CentralEffectSimulation::HandlerBuildingData::Footprint> &footprints = m_handlerBuildingData->getFootprints();
|
||||
for (const CentralEffectSimulation::HandlerBuildingData::Footprint &footprint : qAsConst(footprints))
|
||||
{
|
||||
calculateImpacts(effects, footprint);
|
||||
}
|
||||
}
|
||||
|
||||
// ///////////////////////////////////
|
||||
// I S M (InfrastructureManagement)
|
||||
// ///////////////////////////////////
|
||||
|
||||
|
||||
// ///////////////////////////////////
|
||||
// Calculations:
|
||||
// ///////////////////////////////////
|
||||
|
||||
bool HandlerAesData::inBoundingBox(const Core::GeoPosition2D& impactPosition,
|
||||
const CentralEffectSimulation::HandlerBuildingData::Footprint &footprint,
|
||||
const double impactRadius) const
|
||||
{
|
||||
const QPointF impactPos(CentralEffectSimulation::geographic2Utm(impactPosition, footprint.zone));
|
||||
const QPolygonF polyBldgRadius({QPointF(footprint.boundingBoxPolyUtm.bottomLeft().rx() - impactRadius,
|
||||
footprint.boundingBoxPolyUtm.bottomLeft().ry() + impactRadius),
|
||||
QPointF(footprint.boundingBoxPolyUtm.topRight().rx() + impactRadius,
|
||||
footprint.boundingBoxPolyUtm.bottomLeft().ry() + impactRadius),
|
||||
QPointF(footprint.boundingBoxPolyUtm.topRight().rx() + impactRadius,
|
||||
footprint.boundingBoxPolyUtm.topRight().ry() - impactRadius),
|
||||
QPointF(footprint.boundingBoxPolyUtm.bottomLeft().rx() - impactRadius,
|
||||
footprint.boundingBoxPolyUtm.topRight().ry() - impactRadius)});
|
||||
|
||||
return (polyBldgRadius.containsPoint(impactPos, Qt::OddEvenFill));
|
||||
}
|
||||
|
||||
bool HandlerAesData::inFootprint(const Core::GeoPosition2D &geoPosition,
|
||||
const CentralEffectSimulation::HandlerBuildingData::Footprint &footPrint,
|
||||
const double radius) const
|
||||
{
|
||||
if ( !inBoundingBox( geoPosition, footPrint, radius))
|
||||
return false;
|
||||
const QPointF impact(CentralEffectSimulation::geographic2Utm(geoPosition, footPrint.zone));
|
||||
|
||||
// NT: Folgendes raubt zu viele Zeilen beim tail. Daher nehme ich es raus.
|
||||
// if (m_logger.isDebugEnabled())
|
||||
// {
|
||||
// const QPointF utmBuilding(CentralEffectSimulation::geographic2Utm(footPrint.geoPosition, footPrint.zone));
|
||||
// DEBUG_LOG(m_logger) << "Impact (x/y)=" << CentralEffectSimulation::debug(impact - utmBuilding);
|
||||
// for (int i = 0; i < footPrint.polyUtm.length(); i++)
|
||||
// DEBUG_LOG(m_logger) << " poly (x/y)=" << CentralEffectSimulation::debug(footPrint.polyUtm[i] - utmBuilding);
|
||||
// }
|
||||
|
||||
// Check, if hit direct on building
|
||||
if (footPrint.polyUtm.containsPoint(impact, Qt::OddEvenFill))
|
||||
return true;
|
||||
|
||||
// Check, if hit in munition-radius
|
||||
QPainterPath ppFp;
|
||||
ppFp.addPolygon(footPrint.polyUtm);
|
||||
QPainterPath ppCircle;
|
||||
ppCircle.addEllipse(impact, radius, radius);
|
||||
return ppFp.intersects(ppCircle);
|
||||
}
|
||||
|
||||
void HandlerAesData::preCalculateImpacts(const AreaEffectSimulation::TriggeredImpacts &data)
|
||||
{
|
||||
if (data.id() <= 0)
|
||||
return;
|
||||
DEBUG_LOG(m_logger) << "preCalculateImpacts";
|
||||
// Find AES ItemView and set Bounding-Box of Aes-Field
|
||||
|
||||
const int aesItemId = data.aesItemId();
|
||||
|
||||
// Search corresponding itemView. If not available no impact to participant.
|
||||
// Use dtcAes since sender (AES) publishes TriggeredImpacts and AesItemView
|
||||
//
|
||||
AreaEffectSimulation::AesItemView aesItemView;
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> dtcAes = m_ddsHandler->dtcAes();
|
||||
if (!dtcAes->aesItemViewFromEntityId(aesItemId, data.aesTypeId(), aesItemView))
|
||||
{
|
||||
static long msgCnt = 0;
|
||||
WARNING_LOG(m_logger) << "TriggeredExplosions.aesItemId=" << data.aesItemId() << " No aesItemView available"
|
||||
<< " (cnt=" << ++msgCnt << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
// Maybe ExlosionClusters Trajectory is hitting a building?
|
||||
// Vulnerability should be calculated
|
||||
|
||||
const QHash<int, CentralEffectSimulation::HandlerBuildingData::Footprint> &footprints = m_handlerBuildingData->getFootprints();
|
||||
for (const CentralEffectSimulation::HandlerBuildingData::Footprint &footprint : qAsConst(footprints))
|
||||
{
|
||||
calculateImpacts(data, aesItemView, footprint);
|
||||
} // for
|
||||
|
||||
}
|
||||
|
||||
void HandlerAesData::onSendCesHitOnBuildingReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
if (replyObject.error())
|
||||
WARNING_LOG(m_logger) << "Can not send hit on building to building service: " << replyObject()
|
||||
<< ", m_handlerBuildingData.getFootprints().size()" << m_handlerBuildingData->getFootprints().size();
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "onSendCesHitOnBuildingReply for id " << replyObject.id() << " success\n"
|
||||
<< " replyObject.str() = " << replyObject.str();
|
||||
}
|
||||
|
||||
void HandlerAesData::onSendCesHit3DonBuildingReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_handlerBuildingData.getFootprints() size " << m_handlerBuildingData->getFootprints().size();
|
||||
|
||||
if (replyObject.error())
|
||||
WARNING_LOG(m_logger) << "Can not send hit3D on building to building service: " << replyObject()
|
||||
<< ", m_handlerBuildingData.getFootprints().size()" << m_handlerBuildingData->getFootprints().size();
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "onSendCesHit3DonBuildingReply for id " << replyObject.id() << " success\n"
|
||||
<< " replyObject.str() = " << replyObject.str();
|
||||
}
|
||||
|
||||
void HandlerAesData::onSendCesHitInformationReply(const Core::FunctionReplyObject &reply)
|
||||
{
|
||||
if (reply.error())
|
||||
WARNING_LOG(m_logger) << "onSendCesHitInformationReply for id " << reply.id() << " failed: " << reply.str();
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "onSendCesHitInformationReply for id " << reply.id() << " successful";
|
||||
}
|
||||
|
||||
void HandlerAesData::onSetBuildingStatesReply(const Core::FunctionReplyObject &reply)
|
||||
{
|
||||
if (reply.error())
|
||||
WARNING_LOG(m_logger) << "onSetBuildingStatesReply for id " << reply.id() << " failed: " << reply.str();
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "onSetBuildingStatesReply for id " << reply.id() << " successful";
|
||||
}
|
||||
|
||||
// calculate impacts for one building
|
||||
void HandlerAesData::calculateImpacts(const AreaEffectSimulation::TriggeredImpacts &data, const AreaEffectSimulation::AesItemView &aesItemView,
|
||||
const CentralEffectSimulation::HandlerBuildingData::Footprint &footprint)
|
||||
{
|
||||
const int aesItemId = data.aesItemId();
|
||||
bool bIsExplosionCluster = false;
|
||||
ProjectDataManagement::IgniterFunctionBase ignFuncBase = ProjectDataManagement::IgniterFunctionBase::IfbImpact;
|
||||
|
||||
// check for correct AES type artillery only
|
||||
|
||||
static QVector<AreaEffectSimulation::AesType_def::type> s_relevantTypes =
|
||||
{
|
||||
AreaEffectSimulation::AesType_def::AtExplosionArea,
|
||||
AreaEffectSimulation::AesType_def::AtExplosionSingle,
|
||||
AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions,
|
||||
};
|
||||
|
||||
if (data.aesTypeId().underlying() == AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions)
|
||||
{
|
||||
bIsExplosionCluster = true;
|
||||
ignFuncBase = igniterFunctionBaseExplosionCluster(aesItemId); // assume that fuseType does not differ within a single ExplosionArea
|
||||
DEBUG_LOG(m_logger) << "Calculate, bIsExplosionCluster = " << bIsExplosionCluster
|
||||
<< ", ignFuncBase = " << ignFuncBase;
|
||||
}
|
||||
else if (s_relevantTypes.contains(data.aesTypeId().underlying()))
|
||||
DEBUG_LOG(m_logger) << "Calculate";
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "No Calculation";
|
||||
return;
|
||||
}
|
||||
|
||||
if (aesItemId != aesItemView.aesItemId())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "mismatch: "
|
||||
<< ", TriggeredExplosions.aesItemId=" << data.aesItemId()
|
||||
<< ", AesItemView.aesItemId=" << aesItemView.aesItemId();
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "calculateImpacts mseId=" << footprint.mseId << " aesItemId " << aesItemId
|
||||
<< ", bIsExplosionCluster = " << bIsExplosionCluster;
|
||||
|
||||
// get position(s) of impact(s):
|
||||
|
||||
CentralEffectSimulation::BitfieldStates &bitfieldStates = m_bitfieldStatesBld[footprint.mseId];
|
||||
QSet<int> &bitfieldState = bitfieldStates[aesItemId];
|
||||
for (int i : qAsConst(bitfieldState))
|
||||
DEBUG_LOG(m_logger) << "bitfieldState for " << aesItemId << ": " << i;
|
||||
|
||||
for (int32_t bitFieldIdx = 0; bitFieldIdx < data.impactCount(); ++bitFieldIdx)
|
||||
{
|
||||
// no break, because every bit can be a hit
|
||||
if (LtsUtils::BitArray::testBit(data.bitfield(), bitFieldIdx))
|
||||
continue;
|
||||
|
||||
// get position of impact to corresponding bit
|
||||
if (aesItemView.form().size() <= size_t(bitFieldIdx))
|
||||
continue;
|
||||
|
||||
const Core::GeoPosition &impactPosition = aesItemView.form()[bitFieldIdx];
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " impactPosition: lat/lon" << impactPosition.lat() << "/" << impactPosition.lon() << " z=" << impactPosition.z()
|
||||
<< " UTM=" << CentralEffectSimulation::debug(CentralEffectSimulation::geographic2Utm(impactPosition));
|
||||
|
||||
// check, if impact-pos + munition-radius touch the building
|
||||
// get radius of munition
|
||||
const double impactRadius = m_ddsHandler->chargeTypeRadius(aesItemView.chargeStruct());
|
||||
if (inFootprint(impactPosition, footprint, impactRadius))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "In Footprint of mseId = " << footprint.mseId;
|
||||
if (!bitfieldState.contains(bitFieldIdx))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_bitfieldStates.insert(aesItemId=" << aesItemId << ", bitfieldState)" << " bitFieldIdx=" << bitFieldIdx;
|
||||
bitfieldState.insert(bitFieldIdx);
|
||||
|
||||
DEBUG_LOG(m_logger) << "sendCesHit mseId = " << footprint.mseId
|
||||
<< ", aesItemId=" << aesItemId
|
||||
<< ", bitFieldIdx= " << bitFieldIdx
|
||||
<< ", ignFuncBase = " << ignFuncBase;
|
||||
|
||||
if (! qFuzzyIsNull(impactPosition.z()))
|
||||
{
|
||||
// since HandlerBuildingModel::handleDetonationLocationRequest has already
|
||||
// calculated to fuseType, the impactPosition is the detonationLocation:
|
||||
Core::GeoPosition detonationLocation = impactPosition;
|
||||
//
|
||||
|
||||
double detonationDistance = 0;
|
||||
switch (ignFuncBase.underlying())
|
||||
{
|
||||
case ProjectDataManagement::IgniterFunctionBase::IfbProximity:
|
||||
detonationDistance = -5;
|
||||
break;
|
||||
case ProjectDataManagement::IgniterFunctionBase::IfbImpact:
|
||||
detonationDistance = 0;
|
||||
break;
|
||||
case ProjectDataManagement::IgniterFunctionBase::IfbDelay:
|
||||
detonationDistance = 5;
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
|
||||
Buildings::SendCesHit3DonBuildingRequest requestBld(
|
||||
footprint.mseId,
|
||||
aesItemView.chargeStruct().chargeTypeId(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(aesItemView.chargeStruct().chargeTypeId()).destructiveFactor(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(aesItemView.chargeStruct().chargeTypeId()).penetrationFactor(),
|
||||
aesItemId,
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
impactPosition,
|
||||
detonationLocation,
|
||||
detonationDistance,
|
||||
QStringLiteral("properties").toStdString());
|
||||
|
||||
DEBUG_LOG(m_logger) << "sendCesHit3DonBuildingRequest for aesItemId=" << aesItemId
|
||||
<< " bitFieldIdx= " << bitFieldIdx
|
||||
<< ", requestBld= " << requestBld;
|
||||
|
||||
m_ddsHandler->ftcBld()->sendCesHit3DonBuildingRequest(requestBld, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// z-Value is 0 -> old / ! AtExplosionClusterSingleExplosions
|
||||
Buildings::SendCesHitOnBuildingRequest requestBld(
|
||||
footprint.mseId,
|
||||
aesItemView.chargeStruct().chargeTypeId(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(aesItemView.chargeStruct().chargeTypeId()).destructiveFactor(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(aesItemView.chargeStruct().chargeTypeId()).penetrationFactor(),
|
||||
aesItemId,
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
Core::GeoPosition(impactPosition.lon(), impactPosition.lat(), 0.0),
|
||||
QStringLiteral("properties").toStdString());
|
||||
|
||||
DEBUG_LOG(m_logger) << "sendCesHitOnBuildingRequest for aesItemId=" << aesItemId
|
||||
<< " bitFieldIdx= " << bitFieldIdx
|
||||
<< ", impactPosition= " << impactPosition;
|
||||
|
||||
m_ddsHandler->ftcBld()->sendCesHitOnBuildingRequest(requestBld, this);
|
||||
} // if (impactPosition.z() > 0)
|
||||
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "NOT in Footprint of mseId = " << footprint.mseId;
|
||||
// if (inFootprint(impactPosition
|
||||
} // foreach Impact
|
||||
} // for (int32_t bitFieldId
|
||||
}
|
||||
|
||||
void HandlerAesData::calculateImpacts(const AreaEffectSimulation::Effects &effects, const CentralEffectSimulation::HandlerBuildingData::Footprint &footprint)
|
||||
{
|
||||
if (effects.aesTypeId().underlying() != AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions)
|
||||
return;
|
||||
|
||||
const int aesItemId = effects.aesItemId();
|
||||
DEBUG_LOG(m_logger) << "calculateImpacts mseId=" << footprint.mseId << " data.aesItemId() " << aesItemId;
|
||||
|
||||
const AreaEffectSimulation::ExplosionCluster &ec = m_ddsHandler->dtcAes()->explosionCluster(effects.aesItemId());
|
||||
if (ec.id() != aesItemId)
|
||||
return;
|
||||
|
||||
const ProjectDataManagement::IgniterFunctionBase ignFuncBase = igniterFunctionBaseExplosionCluster(aesItemId);
|
||||
const double impactRadius = m_ddsHandler->chargeTypeRadius(ec.chargeStruct());
|
||||
|
||||
|
||||
CentralEffectSimulation::BitfieldStates &bitfieldStates = m_bitfieldStatesBld[footprint.mseId];
|
||||
QSet<int> &bitfieldState = bitfieldStates[aesItemId];
|
||||
|
||||
const std::vector<AreaEffectSimulation::SingleEffect> &singleEffectsRef = effects.singleEffects();
|
||||
int indexBitFieldIdx = -1;
|
||||
for (const AreaEffectSimulation::SingleEffect &singleEffect : qAsConst(singleEffectsRef))
|
||||
{
|
||||
++indexBitFieldIdx;
|
||||
|
||||
// just SesTriggered are relevant:
|
||||
if (singleEffect.singleEffectState() != AreaEffectSimulation::AesSingleEffectState_def::SesTriggered)
|
||||
continue;
|
||||
|
||||
// already processed?
|
||||
if (bitfieldState.contains(indexBitFieldIdx))
|
||||
continue;
|
||||
|
||||
// is building in range?
|
||||
const Core::GeoPosition &impactPositionGeo = singleEffect.position();
|
||||
if (!inFootprint(impactPositionGeo, footprint, impactRadius))
|
||||
continue;
|
||||
|
||||
|
||||
// Hier könnte man zunächst zwei-dimensional prüfen, ob ein anderes Bldg eine Verdeckung erzeugt zw.
|
||||
// a) Explosionsort (impactPosition) und
|
||||
// b) Grundriss (footprint) des Kandidaten
|
||||
// Diese Verdeckung würde die Wirkung auf den Kandidaten reduzieren.
|
||||
|
||||
// 2DpoylgonCentroid https://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon
|
||||
|
||||
const LtsCoordTrans::LtsCoordinate impactPos(impactPositionGeo);
|
||||
const QVector<int> &buildingIdsInBetween = findBuildingsBetween(impactPos, footprint);
|
||||
QString mseIdAsStr;
|
||||
for (auto mseId : buildingIdsInBetween)
|
||||
mseIdAsStr += QString(QStringLiteral("_coveredByMseId_%1;")).arg(mseId);
|
||||
DEBUG_LOG(m_logger) << "findBuildingsBetween returns mseIdAsStr =" << mseIdAsStr;
|
||||
|
||||
|
||||
const ProjectDataManagement::BuildingChargeEffect &bldgChargeEffect = m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(ec.chargeStruct().chargeTypeId());
|
||||
if (bldgChargeEffect.id() <= 0)
|
||||
ERROR_LOG(m_logger) << "getBuildingChargeEffectByChargeTypeId failed, chargeTypeId not found: =" << ec.chargeStruct().chargeTypeId();
|
||||
|
||||
|
||||
qint32 destructiveFactor = bldgChargeEffect.destructiveFactor();
|
||||
qint32 penetrationFactor = bldgChargeEffect.penetrationFactor();
|
||||
|
||||
if ((destructiveFactor <= 0) || (penetrationFactor <= 0))
|
||||
WARNING_LOG(m_logger) << "getBuildingChargeEffectByChargeTypeId failed, destructiveFactor or penetrationFactor invalid"
|
||||
<< ", destructiveFactor = " << destructiveFactor
|
||||
<< ", penetrationFactor = " << penetrationFactor;
|
||||
|
||||
|
||||
|
||||
if (!buildingIdsInBetween.empty())
|
||||
{
|
||||
destructiveFactor /= 2;
|
||||
penetrationFactor /= 2;
|
||||
}
|
||||
|
||||
QString properties = QStringLiteral("properties");
|
||||
properties += mseIdAsStr;
|
||||
|
||||
|
||||
const AreaEffectSimulation::AesZPlacement_def::type zPlacement = singleEffect.zPlacement().underlying();
|
||||
|
||||
if (zPlacement == AreaEffectSimulation::AesZPlacement_def::ZpDraped)
|
||||
{
|
||||
// z-Value is 0 -> old:
|
||||
Buildings::SendCesHitOnBuildingRequest requestBld(
|
||||
footprint.mseId,
|
||||
ec.chargeStruct().chargeTypeId(),
|
||||
destructiveFactor,
|
||||
penetrationFactor,
|
||||
aesItemId,
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
Core::GeoPosition(impactPositionGeo.lon(), impactPositionGeo.lat(), 0.0),
|
||||
properties.toStdString());
|
||||
|
||||
DEBUG_LOG(m_logger) << "sendCesHitOnBuildingRequest for aesItemId=" << aesItemId
|
||||
<< " bitFieldIdx= " << indexBitFieldIdx
|
||||
<< ", impactPositionGeo= " << impactPositionGeo
|
||||
<< ", chargeTypeId= " << ec.chargeStruct().chargeTypeId()
|
||||
<< ", destructiveFactor= " << destructiveFactor
|
||||
<< ", penetrationFactor= " << penetrationFactor;
|
||||
m_ddsHandler->ftcBld()->sendCesHitOnBuildingRequest(requestBld, this);
|
||||
bitfieldState.insert(indexBitFieldIdx);
|
||||
|
||||
}
|
||||
else if (zPlacement == AreaEffectSimulation::AesZPlacement_def::ZpAbsolute)
|
||||
{
|
||||
// since HandlerBuildingModel::handleDetonationLocationRequest has already
|
||||
// calculated to ignFuncBase, the impactPosition is the detonationLocation:
|
||||
Core::GeoPosition detonationLocation = impactPositionGeo;
|
||||
|
||||
double detonationDistance = 0;
|
||||
switch (ignFuncBase.underlying())
|
||||
{
|
||||
case ProjectDataManagement::IgniterFunctionBase::IfbProximity:
|
||||
detonationDistance = -5;
|
||||
break;
|
||||
case ProjectDataManagement::IgniterFunctionBase::IfbImpact:
|
||||
detonationDistance = 0;
|
||||
break;
|
||||
case ProjectDataManagement::IgniterFunctionBase::IfbDelay:
|
||||
detonationDistance = 5;
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
|
||||
|
||||
|
||||
Buildings::SendCesHit3DonBuildingRequest requestBld(
|
||||
footprint.mseId,
|
||||
ec.chargeStruct().chargeTypeId(),
|
||||
destructiveFactor,
|
||||
penetrationFactor,
|
||||
aesItemId,
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
impactPositionGeo,
|
||||
detonationLocation,
|
||||
detonationDistance,
|
||||
properties.toStdString());
|
||||
|
||||
DEBUG_LOG(m_logger) << "SendCesHit3DonBuildingRequest for aesItemId=" << aesItemId
|
||||
<< " bitFieldIdx= " << indexBitFieldIdx
|
||||
<< ", impactPosition= " << impactPositionGeo
|
||||
<< ", zPlacement= " << zPlacement
|
||||
<< ", chargeTypeId= " << ec.chargeStruct().chargeTypeId()
|
||||
<< ", destructiveFactor= " << destructiveFactor
|
||||
<< ", penetrationFactor= " << penetrationFactor;
|
||||
|
||||
m_ddsHandler->ftcBld()->sendCesHit3DonBuildingRequest(requestBld, this);
|
||||
bitfieldState.insert(indexBitFieldIdx);
|
||||
|
||||
} // if
|
||||
} // for
|
||||
}
|
||||
|
||||
void HandlerAesData::checkBuildingsHit(const AreaEffectSimulation::AesItemView &data)
|
||||
{
|
||||
const int exerciseId = m_ddsHandler->getExerciseId();
|
||||
QPolygonF polyGeo;
|
||||
|
||||
DEBUG_LOG(m_logger) << "checkBuildingsHit " << ", aesItemId=" << data.aesItemId();
|
||||
|
||||
DEBUG_LOG(m_logger) << "AtBoobyTrapSecondary data.form().size()=" << data.form().size();
|
||||
// BoobyTrap
|
||||
polyGeo.reserve(data.form().size());
|
||||
for (const auto &pointGeo : qAsConst(data.form()))
|
||||
{
|
||||
QPointF point;
|
||||
point.setX(pointGeo.lon());
|
||||
point.setY(pointGeo.lat());
|
||||
DEBUG_LOG(m_logger) << "point= " << point.x() << "/" << point.y();
|
||||
polyGeo.append(point);
|
||||
}
|
||||
|
||||
bool completeEnclosed = false;
|
||||
bool isGroundLevel = true;
|
||||
const QVector<int> &buildingIdsInside = m_ddsHandler->dtcIsm()->getBuildingByPolygon(exerciseId, polyGeo, completeEnclosed, isGroundLevel);
|
||||
|
||||
DEBUG_LOG(m_logger) << "buildingsInside.size=" << buildingIdsInside.size()
|
||||
<< " exerciseId=" << exerciseId;
|
||||
// only include buildings within the radius
|
||||
|
||||
for (const int buildingId : qAsConst(buildingIdsInside))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " BuildingId=" << buildingId;
|
||||
Buildings::Building tmpBldg;
|
||||
tmpBldg.buildingId(buildingId);
|
||||
|
||||
Core::GeoPosition impactPosition;
|
||||
if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary)
|
||||
{
|
||||
impactPosition.lat(m_ddsHandler->dtcAes()->boobyTrap(data.aesItemId()).impactPosition().lat());
|
||||
impactPosition.lon(m_ddsHandler->dtcAes()->boobyTrap(data.aesItemId()).impactPosition().lon());
|
||||
}
|
||||
else if (data.aesTypeId() == AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary)
|
||||
{
|
||||
int zone = -1;
|
||||
LtsCoordTrans::UtmCoordinate bottomLeft = LtsCoordTrans::UtmCoordinate::fromGeographic(data.boundingBoxBottomLeft().lon(), data.boundingBoxBottomLeft().lat(), zone);
|
||||
LtsCoordTrans::UtmCoordinate topRight = LtsCoordTrans::UtmCoordinate::fromGeographic(data.boundingBoxTopRight().lon(), data.boundingBoxTopRight().lat(), zone);
|
||||
|
||||
|
||||
LtsCoordTrans::UtmCoordinate impactPosPoint(topRight.zone, ((topRight.x + bottomLeft.x) / 2), ((topRight.y + bottomLeft.y) / 2), true);
|
||||
impactPosPoint.zone = topRight.zone;
|
||||
|
||||
QPointF pointGeo = impactPosPoint.geographic();
|
||||
impactPosition.lon(pointGeo.x());
|
||||
impactPosition.lat(pointGeo.y());
|
||||
DEBUG_LOG(m_logger) << "impactPosition lon/lat=" << impactPosition.lon() << "/" << impactPosition.lat()
|
||||
<< " impactPosPoint.zone" << impactPosPoint.zone
|
||||
<< " impactPosPoint=" << impactPosPoint.x << "/" << impactPosPoint.y
|
||||
<< " topRight=" << topRight.x << "/" << topRight.y
|
||||
<< " bottomLeft" << bottomLeft.x << "/" << bottomLeft.y;
|
||||
}
|
||||
|
||||
Buildings::SendCesHitOnBuildingRequest requestBld(
|
||||
tmpBldg.buildingId(),
|
||||
data.chargeStruct().chargeTypeId(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(data.chargeStruct().chargeTypeId()).destructiveFactor(),
|
||||
m_ddsHandler->dtcPdm()->getBuildingChargeEffectByChargeTypeId(data.chargeStruct().chargeTypeId()).penetrationFactor(),
|
||||
data.aesItemId(),
|
||||
m_ddsHandler->currentPartitionTime(),
|
||||
impactPosition,
|
||||
QStringLiteral("properties").toStdString());
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "sendCesHitOnBuildingRequest for aesItemId=" << data.aesItemId()
|
||||
<< ", impactPosition= " << impactPosition;
|
||||
m_ddsHandler->ftcBld()->sendCesHitOnBuildingRequest(requestBld, this);
|
||||
}
|
||||
}
|
||||
|
||||
QVector<int> HandlerAesData::findBuildingsBetween(const LtsCoordTrans::LtsCoordinate &impactPosition,
|
||||
const CentralEffectSimulation::HandlerBuildingData::Footprint &targetFootprint)
|
||||
{
|
||||
QVector<int> buildingIdsInBetween;
|
||||
|
||||
// use zone of impactPosition
|
||||
const LtsCoordTrans::UtmCoordinate &impactPositionUTM = impactPosition.utmCoordinate();
|
||||
const int zone = impactPositionUTM.zone;
|
||||
|
||||
const LtsCoordTrans::LtsCoordinate targetFootprintPos =
|
||||
LtsCoordTrans::LtsCoordinate::fromUtm(targetFootprint.polyUtm.first(), targetFootprint.zone, 0.0);
|
||||
|
||||
DEBUG_LOG(m_logger) << "findBuildingsBetween" << " START impactPosition " << impactPositionUTM.mgrs()
|
||||
<< ", maybe effected mseId is = " << targetFootprint.mseId
|
||||
<< " with targetFootprintPos = " << targetFootprintPos.utmCoordinate().mgrs();
|
||||
|
||||
// line between a) impactPosition and b) targetFootprintPos
|
||||
QPolygonF impactToFootprintLineMetric;
|
||||
impactToFootprintLineMetric.reserve(2);
|
||||
|
||||
|
||||
// // a) impactPosition
|
||||
// impactToFootprintLineMetric.append(impactPosition.utmCoordinateAsPointF(zone));
|
||||
// // b) targetFootprintPos
|
||||
// impactToFootprintLineMetric.append(targetFootprintPos.utmCoordinateAsPointF(zone));
|
||||
|
||||
// a) impactPosition
|
||||
impactToFootprintLineMetric.append(impactPosition.toUtm<QPointF>());
|
||||
// b) targetFootprintPos
|
||||
impactToFootprintLineMetric.append(targetFootprintPos.toUtm<QPointF>(zone));
|
||||
|
||||
|
||||
|
||||
|
||||
// check all exercise specific footprints except our:
|
||||
const QHash<int, CentralEffectSimulation::HandlerBuildingData::Footprint> &allFootprintsOfEx = m_handlerBuildingData->getFootprints();
|
||||
buildingIdsInBetween.reserve(allFootprintsOfEx.size());
|
||||
for (const CentralEffectSimulation::HandlerBuildingData::Footprint &footprintToCheck : qAsConst(allFootprintsOfEx))
|
||||
{
|
||||
// do not check ourself
|
||||
if (footprintToCheck.mseId == targetFootprint.mseId)
|
||||
continue;
|
||||
|
||||
// check intersection of
|
||||
// line between a) impactPosition and b) targetFootprintPos
|
||||
// and footprint
|
||||
// QPolygonF is your friend :-)
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
|
||||
const bool intersects = impactToFootprintLineMetric.intersected(footprintToCheck.polyUtm).size() > 0;
|
||||
#else
|
||||
const bool intersects = impactToFootprintLineMetric.intersects(footprintToCheck.polyUtm);
|
||||
#endif
|
||||
|
||||
DEBUG_LOG(m_logger) << "findBuildingsBetween"
|
||||
<< " to mseId " << footprintToCheck.mseId
|
||||
<< " with curFpTargetPos " << impactPosition.utmCoordinate().mgrs()
|
||||
<< " -> intersects = " << intersects;
|
||||
|
||||
if (intersects)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "findBuildingsBetween"
|
||||
<< " regarding impactPosition " << impactPositionUTM.mgrs()
|
||||
<< " and mseId " << targetFootprint.mseId
|
||||
<< " is concealed/covered by footpriont of mseId = " << footprintToCheck.mseId;
|
||||
buildingIdsInBetween.append(footprintToCheck.mseId);
|
||||
}
|
||||
} // for
|
||||
|
||||
|
||||
return buildingIdsInBetween;
|
||||
}
|
||||
|
||||
} // namespace CesBuildings
|
||||
Reference in new issue
Block a user