Adds initial intermediate qt6 porting state
This commit is contained in:
11247 files changed
+1891537
No files matched your search
+197
@@ -0,0 +1,197 @@
|
||||
|
||||
|
||||
|
||||
#include "explosion_single_central_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <Map/bounding_box.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <ParticipantManagement/Data/ppm_data_plugin.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
ExplosionSingleCentral2SituationMap::ExplosionSingleCentral2SituationMap(PdmHandler *pdmHandler, ObjectFactory &objFac, const QString &layername, const char *loggerName)
|
||||
: BaseClass(objFac, layername, loggerName)
|
||||
, m_pdmHandler(pdmHandler)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExplosionSingleCentral2SituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!BaseClass::init(pluginProvider) ||
|
||||
!pluginProvider->ppmDtc())
|
||||
return false;
|
||||
|
||||
m_ppmDtc = pluginProvider->ppmDtc();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionSingleCentral2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (! m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleCentralChanged,
|
||||
this, &ExplosionSingleCentral2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->explosionSingleCentrals([this](const AreaEffectSimulation::ExplosionSingleCentral & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &ExplosionSingleCentral2SituationMap::itemViewChangedESC, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
void ExplosionSingleCentral2SituationMap::itemViewChangedESC(const AreaEffectSimulation::AesItemView &data, DataModification mod)
|
||||
{
|
||||
|
||||
|
||||
if (mod != DataModification::eAdded && mod != DataModification::eModified)
|
||||
return;
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType::AtExplosionSingleCentral)
|
||||
return;
|
||||
|
||||
const int32_t simId = data.aesItemId();
|
||||
if (simId < 0)
|
||||
return;
|
||||
|
||||
const auto uniqueMapId = this->simId2UniqueMapId(simId);
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " skip due to invalid map id";
|
||||
return;
|
||||
}
|
||||
|
||||
RefPointer<MAP_TYPE> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not find map object for aes item with simId " << simId;
|
||||
return;
|
||||
}
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionSingleCentral, itemView))
|
||||
{
|
||||
updateDetonation(itemView, mapObj);
|
||||
if (!mapObj->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " aesItemId = " << data.aesItemId() << " updateView failed";
|
||||
}
|
||||
}
|
||||
|
||||
bool ExplosionSingleCentral2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
int partyId = -1;
|
||||
|
||||
if (ddsData.participantId().is_set())
|
||||
{
|
||||
const int pId = ddsData.participantId().get();
|
||||
const ParticipantManagement::Participant &participant = m_ppmDtc->participant(pId);
|
||||
if (participant.id() == pId)
|
||||
partyId = participant.partyId();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ddsData.partyId().is_set())
|
||||
partyId = ddsData.partyId().get();
|
||||
}
|
||||
|
||||
if (partyId < 0 )
|
||||
partyId = 0;
|
||||
mapObj->setPartyId(partyId);
|
||||
|
||||
const bool changeToActive = (ddsData.effectStateId().underlying()==AreaEffectSimulation::AesEffectState_def::EsActivated) &&
|
||||
(static_cast<int>(mapObj->aesState()) < static_cast<int>(AreaEffectSimulation::AesEffectState_def::EsActivated));
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionSingleCentralTrajectory, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtExplosionSingle) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
const Core::GeoPosition2D &impactPos2D = ddsData.impactPosition();
|
||||
mapObj->setImpactOrigin(Point3D(impactPos2D.lon(), impactPos2D.lat(), 0.0));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionSingleCentral, itemView))
|
||||
updateDetonation(itemView, mapObj);
|
||||
|
||||
if (changeToActive)
|
||||
mapObj->startDetonationAnimation();
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionSingleCentral2SituationMap::updateDetonation(const AreaEffectSimulation::AesItemView &itemView, RefPointer<Aes2SituationMap::MAP_TYPE> mapObj)
|
||||
{
|
||||
const int32_t simId = itemView.aesItemId();
|
||||
if (simId < 0)
|
||||
return false;
|
||||
if (itemView.form().size() != 2)
|
||||
return false;
|
||||
|
||||
|
||||
const Core::GeoPosition &form0 = itemView.form().front();
|
||||
const Core::GeoPosition &form1 = itemView.form().back();
|
||||
SingleFireCentral::DetonationData dd;
|
||||
dd.m_origin = Point3D(form0.lon(), form0.lat(), form0.z());
|
||||
|
||||
const LtsCoordTrans::UtmCoordinate utm0 = LtsCoordTrans::UtmCoordinate::fromGeographic(form0.lon(), form0.lat());
|
||||
const LtsCoordTrans::UtmCoordinate utm1 = LtsCoordTrans::UtmCoordinate::fromGeographic(form1.lon(), form1.lat());
|
||||
|
||||
|
||||
|
||||
|
||||
dd.m_radius = (LtsUtils::QPoint3D(utm0.x, utm0.y, form0.z()) - LtsUtils::QPoint3D(utm1.x, utm1.y, form1.z())).length();
|
||||
|
||||
mapObj->setDetonation(dd);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/single_fire_central.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PdmHandler;
|
||||
|
||||
class ExplosionSingleCentral2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<ExplosionSingleCentral2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::ExplosionSingleCentral;
|
||||
using MAP_TYPE = SituationMap::SingleFireCentral;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory;
|
||||
};
|
||||
|
||||
class ExplosionSingleCentral2SituationMap final : public Aes2SituationMap<ExplosionSingleCentral2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<ExplosionSingleCentral2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
ExplosionSingleCentral2SituationMap(PdmHandler *pdmHandler,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
const char *loggerName);
|
||||
|
||||
bool init(PluginProvider *pluginProvider) override;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::ExplosionSingleCentral &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->explosionSingleCentrals(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
void itemViewChangedESC(const AreaEffectSimulation::AesItemView &data, DataModification mod);
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool updateDetonation(const AreaEffectSimulation::AesItemView &itemView,
|
||||
RefPointer<MAP_TYPE> mapObj);
|
||||
|
||||
PdmHandler *m_pdmHandler = nullptr;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+2013
File diff suppressed because it is too large.
Load diff
+301
@@ -0,0 +1,301 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "unified_map_object_data.h"
|
||||
#include "plugin_provider.h"
|
||||
#include "map_object_type.h"
|
||||
#include "resource_manager_mode.h"
|
||||
#include <Map/situation_map_types.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
#include <Common/ref_pointer.h>
|
||||
|
||||
|
||||
#include <Plugins/ProjectDataManagement/pdm_data_plugin_interface.h>
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
class AbstractMapObject;
|
||||
class AirSupportImpact2SituationMap;
|
||||
|
||||
class Building2SituationMap;
|
||||
class BuildingHitlineInfo2SituationMap;
|
||||
class BuildingOutline;
|
||||
class GeoImage;
|
||||
class BuildingContamination;
|
||||
class BuildingOwnership;
|
||||
class GuezIed2SituationMap;
|
||||
class GuezNasat9Liner2SituationMap;
|
||||
class HitlineInfo2SituationMap;
|
||||
class Map;
|
||||
class TrainingAreaToSituationMap;
|
||||
class SpecialAreaToSituationMap;
|
||||
class MountingPointToMap;
|
||||
class SoundAreaToMap;
|
||||
class MSEPointToMap;
|
||||
class MSEBridgeToMap;
|
||||
class MovementTrackManager;
|
||||
class Participant;
|
||||
class Participant2SituationMap;
|
||||
class PdmHandler;
|
||||
class Sim2SituationMapBase;
|
||||
class ShootbackAreaToSituationMap;
|
||||
class Polygon;
|
||||
class EmergencyCallToMap;
|
||||
class ChargeEffectToMap;
|
||||
class SingleFire;
|
||||
|
||||
|
||||
|
||||
class AdapterDds : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit AdapterDds(QObject *parent = nullptr);
|
||||
virtual ~AdapterDds();
|
||||
|
||||
|
||||
|
||||
|
||||
bool init(Map *map, PluginProvider *pluginProvider, QPointer<SituationMap::MovementTrackManager> &movementTrackMgr, bool resourceMode);
|
||||
|
||||
bool initRenderer3D_AesExtrusion();
|
||||
bool initRenderer3D_AesCentral_Booby(const QString &layernameAesCentral, const QVector<int> &aesTypesForReRunIfPartyColorChanges);
|
||||
|
||||
|
||||
bool assignUniqueValueRendererAesCentral(const QString &layername);
|
||||
|
||||
|
||||
bool assignUniqueValueRendererAesCentral3DExtrusion(const QString &layername);
|
||||
|
||||
bool run();
|
||||
bool isRunning() const;
|
||||
bool stop();
|
||||
|
||||
void clearObjects();
|
||||
|
||||
|
||||
|
||||
|
||||
ResourceManagerMode resourceManagerMode() const;
|
||||
bool setResourceManagerMode(ResourceManagerMode rmm);
|
||||
|
||||
|
||||
|
||||
|
||||
bool showExpiredEmergencyCalls(bool bShowExpired);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool uniqueMapId2SimId(UniqueMapId uniqueMapIdIn, int32_t &simIdOut);
|
||||
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapIdIn, UnifiedMapObjectData &umodOut) const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdParticipant(int32_t simId) const;
|
||||
RefPointer<Participant> simId2Participant(int32_t simId);
|
||||
|
||||
QPointer<MovementTrackManager> movementTrackManager() const { return m_movementTrackManager; }
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdAes(int32_t simId) const;
|
||||
RefPointer<AbstractMapObject> simId2Aes(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdBuilding(int32_t simId) const;
|
||||
RefPointer<BuildingOutline> simId2Building(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdBridge(int32_t simId) const;
|
||||
RefPointer<BuildingOutline> simId2Bridge(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdMountingPoint(int32_t simId) const;
|
||||
RefPointer<GeoImage> simId2MountingPoint(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdGuezIed(int32_t simId) const;
|
||||
RefPointer<Participant> simId2GuezIed(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdChargeEffect(int32_t simId) const;
|
||||
RefPointer<SingleFire> simId2ChargeEffect(int32_t simId);
|
||||
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdTrainingArea(int32_t simId) const;
|
||||
RefPointer<SituationMap::Polygon> simId2TrainingArea(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdSpecialArea(int32_t simId) const;
|
||||
RefPointer<SituationMap::Polygon> simId2SpecialArea(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapIdShootbackArea(int32_t simId) const;
|
||||
RefPointer<SituationMap::Polygon> simId2ShootbackArea(int32_t simId);
|
||||
|
||||
|
||||
UniqueMapId simId2UniqueMapId(MapObjectType mot, int32_t simId) const;
|
||||
QVector<UniqueMapId> simIds2UniqueMapIds(MapObjectType mot, QVector<int32_t> simIds) const;
|
||||
RefPointer<AbstractMapObject> simId2MapObject(MapObjectType mot, int32_t simId);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Sim2SituationMapBase *situationMapBase(MapObjectType mot) const;
|
||||
bool setMapObjectSelected(MapObjectType mot, const QVector<int> &entityIds, bool selection = true);
|
||||
bool clearMapObjectSelection(MapObjectType mot = MapObjectType::MOT_Undefined);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool isBuildingOwnershipSupported() const;
|
||||
bool isBuildingOwnershipVisible() const;
|
||||
bool setBuildingOwnershipVisible(bool visible);
|
||||
|
||||
|
||||
|
||||
|
||||
bool isBuildingContaminationSupported() const;
|
||||
bool isBuildingContaminationVisible() const;
|
||||
bool setBuildingContaminationVisible(bool visible);
|
||||
|
||||
|
||||
|
||||
|
||||
bool enableFireEventFlashing(bool enable);
|
||||
bool isFireEventFlashingEnabled() const;
|
||||
|
||||
|
||||
|
||||
bool setOwnPositionVisible(bool enable);
|
||||
bool isOwnPositionVisible() const;
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
void mapObjectChanged(UniqueMapId uniqueMapId);
|
||||
void mapObjectRemoved(UniqueMapId uniqueMapId);
|
||||
|
||||
void participantPositionChanged(const int32_t participantId, const Point3D &newPos);
|
||||
void resourceManagerModeChanged(ResourceManagerMode newMode);
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
void restart() { stop(); run(); }
|
||||
void restartIfRunning()
|
||||
{
|
||||
if (!this->isRunning())
|
||||
return;
|
||||
restart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void onSymbolDictionaryChanged();
|
||||
|
||||
|
||||
|
||||
|
||||
bool onMapObjectClicked(const RefPointer<AbstractMapObject> &mapObject);
|
||||
bool onMapObjectClicked(UniqueMapId uniqueMapId);
|
||||
bool onMapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds);
|
||||
|
||||
|
||||
|
||||
|
||||
void onMapObjectChangedUpdateDrawOrder(UniqueMapId uniqueMapId);
|
||||
void onMapObjectRemoved(UniqueMapId uniqueMapId);
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
void onParticipantOwnPositionChanged(const Point3D &newPos, int64_t sampleTime);
|
||||
|
||||
private:
|
||||
void startChangedDelayTimer();
|
||||
void startOwnPositionOutdatedTimer();
|
||||
QList<Sim2SituationMapBase *> listOfSim2Map() const;
|
||||
QList<Sim2SituationMapBase *> listOfAes2Map() const;
|
||||
|
||||
private:
|
||||
bool m_isShowOwnPosition{true};
|
||||
bool m_isRunning{false};
|
||||
QTimer *m_changedDelayTimer{nullptr};
|
||||
QTimer *m_ownPositionOutdatedTimer{nullptr};
|
||||
|
||||
|
||||
QPointer<Map> m_map;
|
||||
PdmHandler *m_pdmHandler{nullptr};
|
||||
PluginProvider *m_pluginProvider{nullptr};
|
||||
|
||||
|
||||
QSharedPointer<Participant2SituationMap> m_particpants;
|
||||
QMap<int32_t, long> m_participantId2uniqueMapId;
|
||||
QPointer<SituationMap::MovementTrackManager> m_movementTrackManager;
|
||||
QSharedPointer<HitlineInfo2SituationMap> m_hitlineInfo2SituationMap;
|
||||
QSharedPointer<BuildingHitlineInfo2SituationMap> m_bldHitlineInfo2SituationMap;
|
||||
|
||||
|
||||
|
||||
QMap<int, Sim2SituationMapBase *> m_aes2MapCont;
|
||||
QMap<UniqueMapId, qint64> m_startTimeMap;
|
||||
|
||||
QSharedPointer<ChargeEffectToMap> m_chargeEffects;
|
||||
|
||||
|
||||
QSharedPointer<EmergencyCallToMap> m_emergencyCalls;
|
||||
|
||||
|
||||
|
||||
QSharedPointer<TrainingAreaToSituationMap> m_trainingAreas;
|
||||
|
||||
|
||||
QSharedPointer<BuildingOwnership> m_buildingOwnership;
|
||||
QSharedPointer<BuildingContamination> m_buildingContamination;
|
||||
|
||||
|
||||
QSharedPointer<MountingPointToMap> m_mountingPoints;
|
||||
QSharedPointer<SoundAreaToMap> m_soundAreas;
|
||||
QSharedPointer<Building2SituationMap> m_buildings;
|
||||
QSharedPointer<MSEPointToMap> m_msePoints;
|
||||
QSharedPointer<MSEBridgeToMap> m_mseBridges;
|
||||
QSharedPointer<SpecialAreaToSituationMap> m_specialAreas;
|
||||
|
||||
|
||||
QSharedPointer<GuezIed2SituationMap> m_guezIeds;
|
||||
|
||||
|
||||
QSharedPointer<GuezNasat9Liner2SituationMap> m_guezNasat9Liner;
|
||||
|
||||
|
||||
QSharedPointer<ShootbackAreaToSituationMap> m_shootbackAreas;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+548
@@ -0,0 +1,548 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_aes_plugin_interface.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <AreaEffectSimulation/aes_info_gui_plugin_interface.h>
|
||||
#include <FilterManagement/flt_data_plugin_aes_display_filter.h>
|
||||
#include <Map/abstract_effect_simulation.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
inline PositionCont form2PosCont(const std::vector<Core::GeoPosition2D> &form)
|
||||
{
|
||||
PositionCont ret;
|
||||
ret.reserve(form.size());
|
||||
for (const auto &pos : form)
|
||||
ret.push_back({pos.lon(), pos.lat(), 0.0});
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline PositionCont form2PosCont(const std::vector<Core::GeoPosition> &form)
|
||||
{
|
||||
PositionCont ret;
|
||||
ret.reserve(form.size());
|
||||
for (const auto &pos : form)
|
||||
ret.push_back({pos.lon(), pos.lat(), pos.z()});
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline PositionCont form2PosCont(const QPolygonF &form)
|
||||
{
|
||||
PositionCont ret;
|
||||
ret.reserve(form.size());
|
||||
for (const auto &pos : form)
|
||||
ret.push_back({pos.x(), pos.y(), 0.0});
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline SituationMap::AesEffectState effectState2aesState(AreaEffectSimulation::AesEffectState effectState)
|
||||
{
|
||||
SituationMap::AesEffectState aesState = AesEffectState::Unknown;
|
||||
|
||||
switch (effectState.underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesEffectState_def::EsUnknown:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsError:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsExpired:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsRemoved:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsPaused:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsReceived:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsCreated:
|
||||
aesState = AesEffectState::Created;
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsFired:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsPrepared:
|
||||
aesState = AesEffectState::Prepared;
|
||||
break;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsActivated:
|
||||
aesState = AesEffectState::Activated;
|
||||
break;
|
||||
}
|
||||
return aesState;
|
||||
}
|
||||
|
||||
template <typename SUPER>
|
||||
struct Aes2SituationMapTraits;
|
||||
|
||||
template <typename SUPER>
|
||||
class Aes2SituationMap : public Sim2SituationMap<typename Aes2SituationMapTraits<SUPER>::DDS_TYPE, typename Aes2SituationMapTraits<SUPER>::MAP_TYPE>
|
||||
, protected FilterManagement::AesDisplayFilter::FilterChangedCallback
|
||||
, protected DdsFilterHandling<typename Aes2SituationMapTraits<SUPER>::MAP_TYPE>
|
||||
{
|
||||
public:
|
||||
using DDS_TYPE = typename Aes2SituationMapTraits<SUPER>::DDS_TYPE;
|
||||
using MAP_TYPE = typename Aes2SituationMapTraits<SUPER>::MAP_TYPE;
|
||||
using BaseClass = Sim2SituationMap<DDS_TYPE, MAP_TYPE>;
|
||||
using FilterClass = DdsFilterHandling<MAP_TYPE>;
|
||||
|
||||
Aes2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, 0, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
{}
|
||||
|
||||
Aes2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
{}
|
||||
|
||||
~Aes2SituationMap()
|
||||
{
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->removeChangedCallback(this);
|
||||
}
|
||||
|
||||
void setIsVisibleByExternalCallback(const std::function<bool(int32_t, bool&)> &isVisibleByExternalCallback)
|
||||
{
|
||||
m_isVisibleByExternalCallback = isVisibleByExternalCallback;
|
||||
}
|
||||
|
||||
int32_t getSimId(const DDS_TYPE &ddsData) const override
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
virtual bool init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->aesDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
m_aesDtc = m_pluginProvider->aesDtc();
|
||||
m_aesInfoIfc = m_pluginProvider->aesInfoIfc();
|
||||
|
||||
|
||||
FilterClass::init(pluginProvider);
|
||||
auto fltAesIfc = m_pluginProvider->fltAesIfc();
|
||||
if (fltAesIfc)
|
||||
{
|
||||
m_displayFilter = fltAesIfc->aesFilterForOperator(m_pluginProvider->operatorId(),
|
||||
m_pluginProvider->workspaceId());
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->addChangedCallback(this);
|
||||
}
|
||||
|
||||
m_pluginProvider->disconnect(this);
|
||||
QObject::connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &Aes2SituationMap::partitionTimeChanged);
|
||||
QObject::connect(m_pluginProvider, &PluginProvider::workspaceIdChanged,
|
||||
this, &Aes2SituationMap::onWorkspaceIdChanged);
|
||||
|
||||
#ifdef USE_OBJECTAPPEARANCE_VECTOR
|
||||
|
||||
m_objectAppearanceVisibility += ObjectAppearance::Technical;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool run() override
|
||||
{
|
||||
QObject::connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &Aes2SituationMap::itemViewChanged, Qt::UniqueConnection);
|
||||
return true;
|
||||
}
|
||||
|
||||
void stop() override
|
||||
{
|
||||
QObject::disconnect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &Aes2SituationMap::partitionTimeChanged);
|
||||
m_aesDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override
|
||||
{
|
||||
auto sp = m_aesInfoIfc.lock();
|
||||
if (!sp)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = this->uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
sp->showInfoWindow(simIds, Aes2SituationMapTraits<SUPER>::aesType);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
qint64 startTime(UniqueMapId uniqueMapId) const override
|
||||
{
|
||||
if (!m_aesDtc)
|
||||
return -1;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return -1;
|
||||
return effectStartTimeFromSimId(simIdOut);
|
||||
}
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override
|
||||
{
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
umodOut.m_participantData.m_typeName = QObject::tr("Area Effect Simulation");
|
||||
RefPointer<MAP_TYPE> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const SUPER *derived = static_cast<const SUPER*>(this);
|
||||
const auto cb = [simIdOut, &umodOut](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
if (data.partyId().is_set())
|
||||
umodOut.m_partyId = data.partyId().get();
|
||||
|
||||
umodOut.m_description1 = QString::fromStdString(data.name());
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return derived->iterateAesData(cb);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void onWorkspaceIdChanged(const QString &newWorkspaceId) override
|
||||
{
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->removeChangedCallback(this);
|
||||
m_displayFilter = nullptr;
|
||||
|
||||
auto fltAesIfc = m_pluginProvider->fltAesIfc();
|
||||
if (!fltAesIfc)
|
||||
return;
|
||||
|
||||
const auto opId = m_pluginProvider->operatorId();
|
||||
const auto wsId = m_pluginProvider->workspaceId();
|
||||
FilterClass::onWorkspaceIdChanged(newWorkspaceId);
|
||||
|
||||
m_displayFilter = fltAesIfc->aesFilterForOperator(opId, wsId);
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->addChangedCallback(this);
|
||||
}
|
||||
|
||||
qint64 effectStartTimeFromSimId(int simId) const
|
||||
{
|
||||
qint64 effectStart = -1;
|
||||
const SUPER *derived = static_cast<const SUPER*>(this);
|
||||
const auto cb = [simId, &effectStart](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
if (data.id() == simId)
|
||||
{
|
||||
if (data.effectStart().is_set())
|
||||
effectStart = data.effectStart().get();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
derived->iterateAesData(cb);
|
||||
|
||||
return effectStart;
|
||||
}
|
||||
|
||||
void visibilityFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
if (Aes2SituationMapTraits<SUPER>::aesType != aesType)
|
||||
return;
|
||||
|
||||
SUPER *derived = static_cast<SUPER*>(this);
|
||||
const auto cb = [derived](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
derived->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
derived->iterateAesData(cb);
|
||||
}
|
||||
|
||||
bool isElapsed(const DDS_TYPE &ddsData) const override
|
||||
{
|
||||
const AreaEffectSimulation::AesEffectState &aesEffectState = ddsData.effectStateId();
|
||||
if (ddsData.isDeleted())
|
||||
return true;
|
||||
if (aesEffectState == AreaEffectSimulation::AesEffectState_def::EsRemoved)
|
||||
return true;
|
||||
if (aesEffectState == AreaEffectSimulation::AesEffectState_def::EsExpired)
|
||||
{
|
||||
if (!ddsData.effectStart().is_set())
|
||||
return true;
|
||||
const auto effectEnd = ddsData.effectStart().get() + ddsData.effectDuration();
|
||||
const auto afterGlow = m_displayFilter ? m_displayFilter->maxAfterglowDurationMSec() : 0;
|
||||
return (m_pluginProvider->partitionTime() > effectEnd + afterGlow);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void partitionTimeChanged()
|
||||
{
|
||||
const int partitionTimeSec = m_pluginProvider->partitionTime() / 1000;
|
||||
|
||||
bool bCleanup = (partitionTimeSec % 10) == 0;
|
||||
|
||||
SUPER *derived = static_cast<SUPER*>(this);
|
||||
const auto cb = [this, bCleanup](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (data.isDeleted())
|
||||
return false;
|
||||
if (data.effectStateId() != AreaEffectSimulation::AesEffectState_def::EsExpired)
|
||||
return false;
|
||||
|
||||
|
||||
if (bCleanup)
|
||||
{
|
||||
if (!m_simId2UniqueMapId.contains(getSimId(data)))
|
||||
return false;
|
||||
if (isElapsed(data))
|
||||
this->removeElement(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
derived->iterateAesData(cb);
|
||||
}
|
||||
|
||||
void itemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification mod)
|
||||
{
|
||||
|
||||
|
||||
if (mod != DataModification::eAdded && mod != DataModification::eModified)
|
||||
return;
|
||||
if (data.aesTypeId() != Aes2SituationMapTraits<SUPER>::aesType)
|
||||
return;
|
||||
|
||||
const auto uniqueMapId = this->simId2UniqueMapId(data.aesItemId());
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " skip due to invalid map id";
|
||||
return;
|
||||
}
|
||||
|
||||
RefPointer<MAP_TYPE> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not find map object for aes item with id " << data.aesItemId();
|
||||
return;
|
||||
}
|
||||
updateGeometry(data, mapObj);
|
||||
}
|
||||
|
||||
public:
|
||||
void updateVisibility()
|
||||
{
|
||||
onAesDisplayFilterChanged(Aes2SituationMapTraits<SUPER>::aesType);
|
||||
}
|
||||
|
||||
protected:
|
||||
void updateVisibility(const DDS_TYPE &data)
|
||||
{
|
||||
const auto uniqueMapId = this->simId2UniqueMapId(getSimId(data));
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isElapsed(data))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " skip due to isElapsed map id/simId: " << data.id();
|
||||
return;
|
||||
}
|
||||
|
||||
RefPointer<MAP_TYPE> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not find map object for aes item with id " << getSimId(data);
|
||||
return;
|
||||
}
|
||||
updateVisibility(data, mapObj);
|
||||
}
|
||||
|
||||
virtual bool updateVisibility(const DDS_TYPE &data, RefPointer<MAP_TYPE> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << this->getSimId(data);
|
||||
if (!mapObj)
|
||||
return false;
|
||||
|
||||
bool isReferenced = false;
|
||||
bool isVisibleByExternal = true;
|
||||
if (m_isVisibleByExternalCallback)
|
||||
{
|
||||
isVisibleByExternal = false;
|
||||
isReferenced = m_isVisibleByExternalCallback(this->getSimId(data), isVisibleByExternal);
|
||||
DEBUG_LOG(m_logger) << " simId = " << this->getSimId(data)
|
||||
<< " isReferenced = " << isReferenced
|
||||
<< " isVisibleByExternal = " << isVisibleByExternal;
|
||||
if (!isReferenced)
|
||||
isVisibleByExternal = true;
|
||||
}
|
||||
|
||||
bool bIsVisibleByFilter = true;
|
||||
if (!isReferenced && m_displayFilter)
|
||||
{
|
||||
bIsVisibleByFilter = isVisibleByFilter(data);
|
||||
}
|
||||
|
||||
#ifdef USE_OBJECTAPPEARANCE_VECTOR
|
||||
|
||||
Q_FOREACH(const auto appearance, m_objectAppearanceVisibility)
|
||||
{
|
||||
const bool bOldVisibility = mapObj->visibility(appearance);
|
||||
if (bOldVisibility != isVisibile)
|
||||
{
|
||||
mapObj->setVisibility(appearance, isVisibile);
|
||||
changed = true;
|
||||
mapObj->updateView();
|
||||
DEBUG_LOG(m_logger) << "Set visibility for object " << data.id() << " to " << (isVisibile ? "visible" : "invisible");
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
{
|
||||
bool isVisibile = isVisibleByExternal && bIsVisibleByFilter;
|
||||
const bool bOldVisibility = mapObj->visibility();
|
||||
if (bOldVisibility != isVisibile)
|
||||
{
|
||||
mapObj->setVisibility(isVisibile);
|
||||
mapObj->updateView();
|
||||
DEBUG_LOG(m_logger) << "Set visibility for object " << data.id() << " to " << (isVisibile ? "visible" : "invisible");
|
||||
this->emit_visibilityHasChangedSignal();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isVisibleByFilter(const DDS_TYPE &data) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
const auto es = data.effectStart().is_set() ? data.effectStart().get() : 0;
|
||||
const auto partyId = data.partyId().is_set() ? data.partyId().get() : -1;
|
||||
bool isVisibleByFilter = partyId > 0 ? FilterClass::m_currentSymbolSettings.symbolSettings.symbolPartyAppearance.value(partyId).isVisible : true;
|
||||
if (isVisibleByFilter)
|
||||
isVisibleByFilter = m_displayFilter->isVisible(Aes2SituationMapTraits<SUPER>::aesType,
|
||||
data.effectStateId(),
|
||||
data.chargeStruct().chargeTypeId(),
|
||||
partyId,
|
||||
data.isCentral(),
|
||||
es,
|
||||
data.effectDuration(),
|
||||
m_pluginProvider->partitionTime());
|
||||
return isVisibleByFilter;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override
|
||||
{
|
||||
if (Aes2SituationMapTraits<SUPER>::aesType != aesType.underlying())
|
||||
return;
|
||||
|
||||
SUPER *derived = static_cast<SUPER*>(this);
|
||||
const auto cb = [this](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (data.isDeleted())
|
||||
return false;
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
derived->iterateAesData(cb);
|
||||
}
|
||||
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
if (FilterClass::m_currentSymbolSettings.symbolSettings.symbolPartyAppearance !=
|
||||
newSas.symbolSettings.symbolPartyAppearance)
|
||||
return true;
|
||||
return (FilterClass::m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_TYPE> &mapObj) override
|
||||
{
|
||||
|
||||
|
||||
mapObj->setScale(FilterClass::m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
|
||||
void symbolAppearanceSettingsChangedPostOperation() override
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " symbolAppearanceSettingsChangedPostOperation START";
|
||||
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual bool updateGeometry(const AreaEffectSimulation::AesItemView &data,
|
||||
RefPointer<MAP_TYPE> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START" << " data.aesTypeId()=" << data.aesTypeId()
|
||||
<< ", m_debugInfo " << mapObj->debugInfo();
|
||||
|
||||
mapObj->setPositions(form2PosCont(data.form()));
|
||||
|
||||
if (!mapObj->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " aesItemId = " << data.aesItemId() << " updateView failed";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using BaseClass::m_simId2UniqueMapId;
|
||||
using BaseClass::m_logger;
|
||||
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
|
||||
std::weak_ptr<AreaEffectSimulation::ForeignInfoGuiInterface> m_aesInfoIfc;
|
||||
PluginProvider *m_pluginProvider = nullptr;
|
||||
std::shared_ptr<FilterManagement::AesDisplayFilter> m_displayFilter;
|
||||
std::function<bool(int32_t, bool&)> m_isVisibleByExternalCallback = nullptr;
|
||||
|
||||
#ifdef USE_OBJECTAPPEARANCE_VECTOR
|
||||
QVector<ObjectAppearance> m_objectAppearanceVisibility;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
|
||||
#include "air_support_impact_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <Map/bounding_box.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
AirSupportImpact2SituationMap::AirSupportImpact2SituationMap(PdmHandler *pdmHandler, ObjectFactory &objFac, const QString &layername, const char *loggerName)
|
||||
: BaseClass(objFac, layername, loggerName)
|
||||
, m_pdmHandler(pdmHandler)
|
||||
{
|
||||
}
|
||||
|
||||
bool AirSupportImpact2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (! m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::airSupportImpactChanged,
|
||||
this, &AirSupportImpact2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->airSupportImpacts([this](const AreaEffectSimulation::AirSupportImpact & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool AirSupportImpact2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtAirSupportImpact, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtAirSupportImpact) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
const Core::GeoPosition2D &impactPos2D = ddsData.impactPosition();
|
||||
mapObj->setImpactOrigin(Point3D(impactPos2D.lon(), impactPos2D.lat(), 0.0));
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/single_fire.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PdmHandler;
|
||||
|
||||
class AirSupportImpact2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<AirSupportImpact2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::AirSupportImpact;
|
||||
using MAP_TYPE = SituationMap::SingleFire;
|
||||
static const AreaEffectSimulation::AesType::type aesType = AreaEffectSimulation::AesType::AtAirSupportImpact;
|
||||
};
|
||||
|
||||
class AirSupportImpact2SituationMap final : public Aes2SituationMap<AirSupportImpact2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<AirSupportImpact2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
AirSupportImpact2SituationMap(PdmHandler *pdmHandler,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
const char *loggerName);
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::AirSupportImpact &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->airSupportImpacts(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
PdmHandler *m_pdmHandler = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "alarm_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace SituationMap;
|
||||
|
||||
|
||||
QImage renderEmergencyCallSymbol()
|
||||
{
|
||||
int size = 200;
|
||||
QImage image(size, size, QImage::Format_ARGB32);
|
||||
image.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QPen pen(Qt::white);
|
||||
pen.setWidth(10);
|
||||
painter.setPen(pen);
|
||||
|
||||
painter.setBrush(QBrush(Qt::red));
|
||||
painter.drawEllipse(QPointF(image.rect().center()),
|
||||
image.rect().width() * 0.45,
|
||||
image.rect().height() * 0.45);
|
||||
|
||||
painter.setPen(QPen(Qt::white));
|
||||
|
||||
QFont font = painter.font();
|
||||
font.setBold(true);
|
||||
font.setPixelSize(75);
|
||||
painter.setFont(font);
|
||||
|
||||
QPointF pos(image.width() * 0.125,
|
||||
image.height() * 0.625);
|
||||
|
||||
painter.drawText(pos, QLatin1String("SOS"));
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool AlarmToMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider)
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
m_almDtc = m_pluginProvider->almDtc();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AlarmToMap::run()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Starting to run";
|
||||
|
||||
this->stop();
|
||||
|
||||
if (m_almDtc)
|
||||
{
|
||||
connect(m_almDtc.get(), &AlarmManagement::Interface::Dtc::notificationChanged,
|
||||
this, &AlarmToMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_almDtc->notifications([this](const AlarmManagement::Notification & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AlarmToMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping";
|
||||
if (m_almDtc)
|
||||
m_almDtc->disconnect(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool AlarmToMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << " isElapsed";
|
||||
|
||||
|
||||
|
||||
|
||||
if (data.eventType().underlying() != ProjectDataManagement::EventType_def::EmergencyCall)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t AlarmToMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool AlarmToMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION
|
||||
<< ", id " << ddsData.id();
|
||||
|
||||
mapObj->setPickable(false);
|
||||
mapObj->setDrawOrder(-1);
|
||||
|
||||
|
||||
mapObj->setIdentifier(QStringLiteral("SOS_%1").arg(ddsData.equipmentNumber()));
|
||||
|
||||
TextStyle textStyle;
|
||||
textStyle.setSize(20);
|
||||
textStyle.setTextColor(Qt::red);
|
||||
textStyle.setTextOutlineColor(Qt::white);
|
||||
textStyle.setTextOutlineWidth(5);
|
||||
mapObj->setTextStyle(textStyle);
|
||||
|
||||
|
||||
const Core::GeoPosition &geoPos = ddsData.position();
|
||||
mapObj->setOrigin(Point3D(geoPos.lon(), geoPos.lat(), geoPos.z()));
|
||||
|
||||
|
||||
mapObj->setProxyImage(renderEmergencyCallSymbol(), QSize(50, 50));
|
||||
|
||||
emit alarmUpdated(mapObj->identifier(), Point3D(geoPos.lon(), geoPos.lat(), geoPos.z()));
|
||||
|
||||
return true;
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AlarmManagement/alm_data_plugin_interface.h>
|
||||
#include <MapObjects/geo_image.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
class AlarmToMap final : public Sim2SituationMap<AlarmManagement::Notification, SituationMap::GeoImage>
|
||||
, protected DdsFilterHandling<SituationMap::GeoImage>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<AlarmManagement::Notification, SituationMap::GeoImage>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::GeoImage>;
|
||||
|
||||
public:
|
||||
AlarmToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
signals:
|
||||
void alarmUpdated(const QString &name, const Point3D &geoPosition);
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider;
|
||||
std::shared_ptr<AlarmManagement::Interface::Dtc> m_almDtc;
|
||||
|
||||
};
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
|
||||
|
||||
|
||||
#include "bccontamination_to_map.h"
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool BCContamination2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::bCContaminationChanged,
|
||||
this, &BCContamination2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->bCContaminations([this](const AreaEffectSimulation::BCContamination &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool BCContamination2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
else
|
||||
{
|
||||
mapObj->setLineStyle(LineStyle(Qt::yellow, 2));
|
||||
mapObj->setFillStyle(FillStyle(Qt::yellow, FillPattern::Null));
|
||||
}
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtBCContamination, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtBCContamination) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
const Core::GeoPosition2D& impactPos2D = ddsData.impactPosition();
|
||||
mapObj->setImpactOrigin(Point3D(impactPos2D.lon(), impactPos2D.lat(), 0.0));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int height = ddsData.upperOffset();
|
||||
if (height > 0)
|
||||
mapObj->setExtrusionHeight(height);
|
||||
else
|
||||
mapObj->setExtrusionHeight();
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
|
||||
#include <MapObjects/single_fire.h>
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class BCContamination2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<BCContamination2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::BCContamination;
|
||||
using MAP_TYPE = SituationMap::SingleFire;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtBCContamination;
|
||||
};
|
||||
|
||||
class BCContamination2SituationMap final : public Aes2SituationMap<BCContamination2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<BCContamination2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::BCContamination &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->bCContaminations(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+362
@@ -0,0 +1,362 @@
|
||||
|
||||
|
||||
|
||||
#include "booby_traps_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/map.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool BoobyTrap2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::boobyTrapChanged,
|
||||
this, &BoobyTrap2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &BoobyTrap2SituationMap::onAesItemViewChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->boobyTraps([this](const AreaEffectSimulation::BoobyTrap &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &BoobyTrap2SituationMap::onPartitionTimeChanged, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
|
||||
void BoobyTrap2SituationMap::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, " << " data.aesTypeId()=" << data.aesTypeId() << " modType=" << modType;
|
||||
|
||||
|
||||
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType::AtBoobyTrapSecondary)
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
|
||||
const int32_t simId = data.aesItemId();
|
||||
if (simId < 0)
|
||||
return;
|
||||
|
||||
|
||||
updateSecondary(simId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " data.aesTypeId()=" << data.aesTypeId() << " modType=" << modType;
|
||||
}
|
||||
|
||||
void BoobyTrap2SituationMap::onPartitionTimeChanged(qint64 newPartitionTime)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
updateAllDetonationSpheres(newPartitionTime);
|
||||
}
|
||||
|
||||
void BoobyTrap2SituationMap::updateAllDetonationSpheres(qint64 newPartitionTime)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", m_simId2UniqueMapId.size = " << m_simId2UniqueMapId.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QMapIterator<int32_t, UniqueMapId> it(m_simId2UniqueMapId);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const UniqueMapId uniqueMapId = it.value();
|
||||
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
const int simId = it.key();
|
||||
const AreaEffectSimulation::BoobyTrap &boobyTrap = m_aesDtc->boobyTrap(simId);
|
||||
if (boobyTrap.id() != simId)
|
||||
continue;
|
||||
|
||||
if (updateDetonationSphere3D(mapObj, boobyTrap, newPartitionTime))
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " updateView failed";
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BoobyTrap2SituationMap::updateDetonationSphere3D(RefPointer<Sim2SituationMap::MAP_T> mapObj, const AreaEffectSimulation::BoobyTrap &data, qint64 newPartitionTime)
|
||||
{
|
||||
const int32_t simId = data.id();
|
||||
|
||||
if (!mapObj)
|
||||
return false;
|
||||
|
||||
bool bUpdateRequired = false;
|
||||
|
||||
const bool bDesiredNewState = data.triggered() && ((newPartitionTime - data.sampleTime() < 5000));
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", START" << " simId = " << simId
|
||||
<< ", sampleTime " << data.sampleTime()
|
||||
<< ", bDesiredNewState " << bDesiredNewState;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef RENDERER_APPROACH
|
||||
|
||||
if (mapObj->has3DMarkerRenderer() && !bDesiredNewState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", START REMOVE " << " simId = " << simId;
|
||||
mapObj->set3DMarkerRenderer(Point3D(), QVariantMap());
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
else if (!mapObj->has3DMarkerRenderer() && bDesiredNewState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", START ADD " << " simId = " << simId;
|
||||
|
||||
const Core::GeoPosition2D &geoPos = data.impactPosition();
|
||||
Point3D markerOrigin(geoPos.lon(), geoPos.lat(), 0);
|
||||
|
||||
QVariantMap attribMap;
|
||||
QString attribValue;
|
||||
|
||||
const QColor &majorColor = mapObj->majorColor();
|
||||
attribValue = QString(QStringLiteral("Impact_Color_%1")).arg(majorColor.name());
|
||||
attribMap.insert(QStringLiteral("IMPACT_COLOR"), attribValue);
|
||||
|
||||
double radius = std::max(data.impactRadius(), 10.0);
|
||||
attribValue = QString(QStringLiteral("Impact_Radius_%1")).arg(radius);
|
||||
attribMap.insert(QStringLiteral("IMPACT_RADIUS"), attribValue);
|
||||
|
||||
LayerFactory::UniqueValueDataAesCentral::TYPE type{LayerFactory::UniqueValueDataAesCentral::TYPE::SPHERE};
|
||||
if (data.centralAngle().is_set())
|
||||
type = LayerFactory::UniqueValueDataAesCentral::TYPE::CONE;
|
||||
|
||||
attribValue = QString(QStringLiteral("Impact_Type_%1")).arg(LayerFactory::toString(type));
|
||||
attribMap.insert(QStringLiteral("IMPACT_TYPE"), attribValue);
|
||||
|
||||
|
||||
int heading = 0;
|
||||
if (data.rotationAngle().is_set())
|
||||
heading = static_cast<int>(data.rotationAngle().get());
|
||||
attribMap.insert(QStringLiteral("HEADING"), ((heading+90)%360));
|
||||
attribMap.insert(QStringLiteral("PITCH"), 0);
|
||||
attribMap.insert(QStringLiteral("ROLL"), 90);
|
||||
|
||||
|
||||
|
||||
mapObj->set3DMarkerRenderer(markerOrigin, attribMap);
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
if (mapObj->has3DMarkerSceneSymbol() && !bDesiredNewState)
|
||||
{
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << ", START REMOVE " << " simId = " << simId;
|
||||
mapObj->set3DMarkerSceneSymbol(Point3D(), {});
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
else if (!mapObj->has3DMarkerSceneSymbol() && bDesiredNewState)
|
||||
{
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << ", START ADD " << " simId = " << simId;
|
||||
|
||||
const Core::GeoPosition2D &geoPos = data.impactPosition();
|
||||
Point3D markerOrigin(geoPos.lon(), geoPos.lat(), 0);
|
||||
|
||||
VirtualMine::SceneSymbolData ssData;
|
||||
|
||||
const QColor &majorColor = mapObj->majorColor();
|
||||
ssData.color = majorColor;
|
||||
|
||||
ssData.radius = std::max(data.impactRadius(), 10.0);
|
||||
|
||||
|
||||
ssData.cone = data.centralAngle().is_set();
|
||||
|
||||
int heading = 0;
|
||||
if (data.rotationAngle().is_set())
|
||||
heading = static_cast<int>(data.rotationAngle().get());
|
||||
|
||||
ssData.heading = (heading+90)%360;
|
||||
ssData.pitch = 0.0;
|
||||
ssData.roll = 90;
|
||||
|
||||
mapObj->set3DMarkerSceneSymbol(markerOrigin, ssData);
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", END" << " simId = " << simId;
|
||||
return bUpdateRequired;
|
||||
}
|
||||
|
||||
bool BoobyTrap2SituationMap::updateSecondary(int32_t simId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", START" << " simId = " << simId;
|
||||
if (simId < 0)
|
||||
return false;
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId = " << simId << " (maybe expired)";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView dataAesItemView;
|
||||
AreaEffectSimulation::BoobyTrap trap;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtBoobyTrapSecondary, dataAesItemView))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " AesItemViewForSecondary found :-) ";
|
||||
trap = m_aesDtc->boobyTrap(dataAesItemView.aesItemId());
|
||||
} else {
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " no AesItemViewForSecondary found. :-( ";
|
||||
}
|
||||
|
||||
|
||||
if ((dataAesItemView.aesItemId() == simId) &&
|
||||
(trap.id() == simId) &&
|
||||
trap.triggered())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " setSubsidiaryLine";
|
||||
VirtualMine::OptionalData optData;
|
||||
optData.closed = true;
|
||||
mapObj->setSubsidiaryLine(0,
|
||||
form2PosCont(dataAesItemView.form()), optData);
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " removeSubsidiaryLine";
|
||||
mapObj->removeSubsidiaryLine(0);
|
||||
}
|
||||
|
||||
if (!mapObj->updateView()) {
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " updateView failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", END" << " simId = " << simId
|
||||
<< " trap.triggered(" << trap.triggered();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BoobyTrap2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtBoobyTrap, itemView))
|
||||
{
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
updateDetonationSphere3D(mapObj, ddsData, m_pluginProvider->partitionTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtBoobyTrap) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
updateSecondary(simId);
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BoobyTrap2SituationMap::isVisibleByFilter(const DDS_TYPE &data) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
const auto es = data.effectStart().is_set() ? data.effectStart().get() : 0;
|
||||
const auto partyId = data.partyId().is_set() ? data.partyId().get() : -1;
|
||||
bool isVisibleByFilter = partyId > 0 ? FilterClass::m_currentSymbolSettings.symbolSettings.symbolPartyAppearance.value(partyId).isVisible : true;
|
||||
if (isVisibleByFilter)
|
||||
isVisibleByFilter = m_displayFilter->isVisible(AreaEffectSimulation::AesType_def::AtMineArea,
|
||||
data.effectStateId(),
|
||||
data.chargeStruct().chargeTypeId(),
|
||||
partyId,
|
||||
data.isCentral(),
|
||||
es,
|
||||
data.effectDuration(),
|
||||
m_pluginProvider->partitionTime());
|
||||
|
||||
return isVisibleByFilter;
|
||||
}
|
||||
|
||||
void BoobyTrap2SituationMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
if ((AreaEffectSimulation::AesType_def::AtBoobyTrap != aesType.underlying()) &&
|
||||
(AreaEffectSimulation::AesType_def::AtMineArea != aesType.underlying()))
|
||||
return;
|
||||
|
||||
const auto cb = [this](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (data.isDeleted())
|
||||
return false;
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
iterateAesData(cb);
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/virtual_mine.h>
|
||||
#include <QObject>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BoobyTrap2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<BoobyTrap2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::BoobyTrap;
|
||||
using MAP_TYPE = SituationMap::VirtualMine;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtBoobyTrap;
|
||||
};
|
||||
|
||||
class BoobyTrap2SituationMap final : public Aes2SituationMap<BoobyTrap2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<BoobyTrap2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::BoobyTrap &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->boobyTraps(cb);
|
||||
}
|
||||
protected Q_SLOTS:
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
protected:
|
||||
void updateAllDetonationSpheres(qint64 newPartitionTime);
|
||||
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType);
|
||||
|
||||
protected:
|
||||
bool updateDetonationSphere3D(RefPointer<MAP_T> mapObj, const AreaEffectSimulation::BoobyTrap &data, qint64 newPartitionTime);
|
||||
bool updateSecondary(int32_t simId);
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool isVisibleByFilter(const DDS_TYPE &data) const override;
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
};
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
|
||||
|
||||
|
||||
#include "borderline_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool Borderline2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::borderlineChanged,
|
||||
this, &Borderline2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->borderlines([this](const AreaEffectSimulation::Borderline &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool Borderline2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
|
||||
LineStyle ls = mapObj->lineStyle();
|
||||
ls.setLineWidth(2);
|
||||
mapObj->setLineStyle(ls);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtBorderline, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtBorderline) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/polyline.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Borderline2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<Borderline2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::Borderline;
|
||||
using MAP_TYPE = SituationMap::Polyline;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtBorderline;
|
||||
};
|
||||
|
||||
class Borderline2SituationMap final : public Aes2SituationMap<Borderline2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<Borderline2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
|
||||
|
||||
bool isElapsed(const DDS_TYPE &ddsData) const override
|
||||
{
|
||||
return (ddsData.operatorId() > 0 && m_pluginProvider->operatorId() != ddsData.operatorId());
|
||||
}
|
||||
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::Borderline &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->borderlines(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+659
@@ -0,0 +1,659 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "building_contamination.h"
|
||||
#include <Map/map.h>
|
||||
#include <Map/object_factory.h>
|
||||
#include <MapObjects/cube.h>
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <MathUtils/simple_helper.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define USE_BUFFER_APPROACH
|
||||
#ifdef USE_BUFFER_APPROACH
|
||||
# include <arcgis/PolygonBuilder.h>
|
||||
# include <arcgis/GeometryEngine.h>
|
||||
#endif
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
class BuildingContamination::Private
|
||||
{
|
||||
public:
|
||||
explicit Private() = default;
|
||||
|
||||
~Private() = default;
|
||||
|
||||
|
||||
QMap<int32_t, Buildings::BuildingState> m_buildingStateData;
|
||||
|
||||
Map *m_map = nullptr;
|
||||
|
||||
|
||||
QMap<QPair<int, int>, UniqueMapId> m_bldgFlr2UniqueMapId;
|
||||
|
||||
bool m_visible = false;
|
||||
int m_drawOrder = 0;
|
||||
|
||||
|
||||
|
||||
static QPair<int, int> createKey(int buildingId, int floorId)
|
||||
{
|
||||
return {buildingId, floorId};
|
||||
}
|
||||
|
||||
static int buildingIdOfKey(const QPair<int, int> &keyData)
|
||||
{
|
||||
return keyData.first;
|
||||
}
|
||||
|
||||
|
||||
RefPointer<Cube> getCreateCube(int buildingId, int floorId)
|
||||
{
|
||||
const QPair<int, int> &key = createKey(buildingId, floorId);
|
||||
const UniqueMapId uniqueMapId = m_bldgFlr2UniqueMapId.value(key, INVALID_MAP_ID);
|
||||
|
||||
if (!SituationMap::isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
const QString &layernameForCubes = m_map->layerFactory().layernameForCubes();
|
||||
const QString &key_debugInfo = QStringLiteral("bldg_%1-flr%2").arg(buildingId).arg(floorId);
|
||||
|
||||
RefPointer<Cube> cube =
|
||||
m_map->objectFactory().create<Cube>(layernameForCubes, key_debugInfo);
|
||||
|
||||
if (cube.valid())
|
||||
m_bldgFlr2UniqueMapId[key] = cube->uniqueMapId();
|
||||
return cube;
|
||||
}
|
||||
return m_map->objectFactory().get<Cube>(uniqueMapId);
|
||||
}
|
||||
|
||||
void removeCube(int buildingId = -1)
|
||||
{
|
||||
QMutableMapIterator<QPair<int, int>, UniqueMapId> mapIt(m_bldgFlr2UniqueMapId);
|
||||
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
|
||||
const QPair<int, int> &key = mapIt.key();
|
||||
int curBuildingId = buildingIdOfKey(key);
|
||||
|
||||
if ((buildingId < 0) ||
|
||||
(buildingId == curBuildingId)
|
||||
)
|
||||
{
|
||||
UniqueMapId uMapId = mapIt.value();
|
||||
SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uMapId);
|
||||
if (mapObj)
|
||||
mapObj->removeMySelf();
|
||||
|
||||
|
||||
mapIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool updateVisibility(int buildingId = -1)
|
||||
{
|
||||
bool success = true;
|
||||
QMutableMapIterator<QPair<int, int>, UniqueMapId> mapIt(m_bldgFlr2UniqueMapId);
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
|
||||
const QPair<int, int> &key = mapIt.key();
|
||||
int curBuildingId = buildingIdOfKey(key);
|
||||
|
||||
if ((buildingId < 0) ||
|
||||
(buildingId == curBuildingId)
|
||||
)
|
||||
{
|
||||
UniqueMapId uMapId = mapIt.value();
|
||||
SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uMapId);
|
||||
if (mapObj)
|
||||
{
|
||||
mapObj->setVisibility(m_visible);
|
||||
if (!mapObj->updateView())
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BuildingContamination::BuildingContamination(int drawOrder, QObject *parent)
|
||||
: BaseClass(parent)
|
||||
, m_logger(getLogger("BuildingContamination"))
|
||||
, d(new Private())
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
d->m_drawOrder = drawOrder;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
BuildingContamination::~BuildingContamination()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
this->stop();
|
||||
|
||||
delete d;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingContamination::init(Map *map, PluginProvider *pluginProvider)
|
||||
{
|
||||
d->m_map = map;
|
||||
|
||||
if (!d->m_map)
|
||||
return false;
|
||||
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->cesDtc() ||
|
||||
!pluginProvider->ismDtc())
|
||||
return false;
|
||||
|
||||
m_bldDtc = pluginProvider->bldDtc();
|
||||
m_ismDtc = pluginProvider->ismDtc();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingContamination::removeAllObjects()
|
||||
{
|
||||
d->removeCube();
|
||||
}
|
||||
|
||||
bool BuildingContamination::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!d->m_map)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_map";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_bldDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_bldDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bldDtc->disconnect(this);
|
||||
|
||||
qRegisterMetaType<Buildings::BuildingState>("Buildings::BuildingState");
|
||||
|
||||
connect(m_bldDtc.get(), &Buildings::Interface::Dtc::buildingStateChanged,
|
||||
this, &BuildingContamination::onBuildingStateChanged, Qt::QueuedConnection);
|
||||
|
||||
|
||||
m_bldDtc->buildingStates([this](const Buildings::BuildingState & data)
|
||||
{
|
||||
onBuildingStateChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (false)
|
||||
{
|
||||
std::function<void(int, int, int)> fTriggerBuilding = [this](int partyId, int buildingId, int floorId)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
const PositionCont &absPositionsGeo = retrieveBuildingGeometry(buildingId, floorId);
|
||||
|
||||
|
||||
QMap<int, double> floorHeights = retrieveBuildingAbsHeight(buildingId);
|
||||
|
||||
|
||||
RefPointer<Cube> cube = d->getCreateCube(buildingId, floorId);
|
||||
if (!cube)
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no cube created";
|
||||
|
||||
cube->setVisibility(d->m_visible);
|
||||
cube->setDrawOrder(d->m_drawOrder);
|
||||
|
||||
cube->setPartyId(partyId);
|
||||
cube->setPositions(absPositionsGeo);
|
||||
const double height = floorHeights.value(floorId, 2.5 * floorId);
|
||||
cube->setHeight(height);
|
||||
|
||||
bool success = cube->updateView();
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " cube->updateView " << success;
|
||||
};
|
||||
|
||||
|
||||
fTriggerBuilding(24, 5, 1);
|
||||
fTriggerBuilding(-1, 5, 2);
|
||||
fTriggerBuilding(89, 5, 3);
|
||||
|
||||
}
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingContamination::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_bldDtc->disconnect(this);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingContamination::isVisible() const
|
||||
{
|
||||
return d->m_visible;
|
||||
}
|
||||
bool BuildingContamination::setVisible(bool visible)
|
||||
{
|
||||
d->m_visible = visible;
|
||||
bool succ = d->updateVisibility();
|
||||
return succ;
|
||||
}
|
||||
|
||||
void BuildingContamination::onBuildingStateChanged(const Buildings::BuildingState &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int buildingId = data.id();
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
|
||||
updateBuilding(buildingId);
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
|
||||
d->removeCube(buildingId);
|
||||
break;
|
||||
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void BuildingContamination::onResetBuildingState()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
d->removeCube();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void BuildingContamination::updateBuilding(int buildingId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "update Building " << buildingId;
|
||||
|
||||
const Buildings::BuildingState &bos = m_bldDtc->buildingState(buildingId);
|
||||
|
||||
|
||||
d->m_buildingStateData[buildingId] = bos;
|
||||
|
||||
const auto contaminations = bos.contaminationStates();
|
||||
|
||||
DEBUG_LOG(m_logger) << "Statecount " << contaminations.size();
|
||||
|
||||
|
||||
QSet<int> contaminatedFloors;
|
||||
for (const Buildings::ContaminationState &contaminationState : contaminations)
|
||||
{
|
||||
|
||||
QSet<int> rooms;
|
||||
for (const auto &room : contaminationState.rooms())
|
||||
{
|
||||
rooms.insert(room);
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "contaminated rooms " << rooms.size();
|
||||
|
||||
for (int room : rooms)
|
||||
{
|
||||
int floorIdContamination = findFloorIdByRoomId(room);
|
||||
if ( floorIdContamination == -1)
|
||||
continue;
|
||||
contaminatedFloors.insert(floorIdContamination);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "contaminated floors " << contaminatedFloors.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QMap<int, double> floorHeights = retrieveBuildingAbsHeight(buildingId);
|
||||
|
||||
|
||||
|
||||
QMapIterator<int, double> mapIt(floorHeights);
|
||||
int floorCounter = 0;
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
|
||||
|
||||
const int floorId = mapIt.key();
|
||||
|
||||
|
||||
const double height = mapIt.value();
|
||||
|
||||
|
||||
|
||||
const bool isContaminaed = contaminatedFloors.contains(floorId);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " floorId=" << floorId
|
||||
<< " height=" << height
|
||||
<< " partyId=" << isContaminaed;
|
||||
|
||||
|
||||
|
||||
const PositionCont &absPositionsGeo = retrieveBuildingGeometry(buildingId, ++floorCounter);
|
||||
|
||||
|
||||
RefPointer<Cube> cube = d->getCreateCube(buildingId, floorId);
|
||||
|
||||
cube->setVisibility(d->m_visible);
|
||||
cube->setDrawOrder(d->m_drawOrder);
|
||||
cube->setPartyId(-1);
|
||||
|
||||
if(isContaminaed)
|
||||
{
|
||||
cube->setPartyId(-2);
|
||||
QColor col(Qt::yellow);
|
||||
cube->setForceMajorColor(col.name());
|
||||
}
|
||||
cube->setPositions(absPositionsGeo);
|
||||
cube->setHeight(height);
|
||||
|
||||
if (!cube->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " cube->updateView() failed";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int BuildingContamination::findFloorIdByRoomId(int roomId) noexcept(false)
|
||||
{
|
||||
|
||||
auto roomToFloorCache = m_roomToFloorCache.constFind(roomId);
|
||||
if (roomToFloorCache != m_roomToFloorCache.constEnd())
|
||||
{
|
||||
|
||||
return roomToFloorCache.value();
|
||||
}
|
||||
|
||||
|
||||
|
||||
InfrastructureManagement::StructureElement roomSe;
|
||||
if (!m_ismDtc->getStructureElementById(roomId, roomSe))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "getStructureElementById roomId=" << roomId << " not found";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::vector<int32_t> path = roomSe.path();
|
||||
|
||||
for (const int parentSeId : path)
|
||||
{
|
||||
InfrastructureManagement::StructureElement parentSe;
|
||||
if (!getRoom(parentSeId, parentSe))
|
||||
continue;
|
||||
|
||||
|
||||
if (parentSe.structureElementTypeId().underlying() != InfrastructureManagement::StructureElementType_def::Floor)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
m_roomToFloorCache.insert(roomId, parentSeId);
|
||||
return parentSeId;
|
||||
}
|
||||
|
||||
throw QStringLiteral("findFloorId: floor id for room %1 not found").arg(roomSe.id());
|
||||
}
|
||||
|
||||
bool BuildingContamination::getRoom(int roomSeId, InfrastructureManagement::StructureElement &roomSe)
|
||||
{
|
||||
auto it = m_roomStructureElementCache.find(roomSeId);
|
||||
if (it != m_roomStructureElementCache.end())
|
||||
{
|
||||
|
||||
roomSe = *it;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_ismDtc->getStructureElementById(roomSeId, roomSe))
|
||||
{
|
||||
|
||||
m_roomStructureElementCache.insert(roomSeId, roomSe);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PositionCont BuildingContamination::retrieveBuildingGeometry(int buildingId, int floorId) const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " buildingId=" << buildingId
|
||||
<< " floorId=" << floorId;
|
||||
if (!m_ismDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_ismDtc";
|
||||
return PositionCont();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QVector<QPointF> relPositions;
|
||||
{
|
||||
const InfrastructureManagement::MainFootprint &mainFootprint = m_ismDtc->mainFootprint(buildingId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " mainFootprint.elements().size()=" << mainFootprint.elements().size();
|
||||
|
||||
relPositions.reserve(mainFootprint.elements().size());
|
||||
|
||||
for (const InfrastructureManagement::FootprintElement &element : mainFootprint.elements())
|
||||
{
|
||||
const auto &relPos = element.relPosition();
|
||||
relPositions += QPointF(relPos.offsetX(), relPos.offsetY());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef USE_BUFFER_APPROACH
|
||||
|
||||
{
|
||||
|
||||
const double distance = 0.5 + (100 - floorId) * 0.01;
|
||||
|
||||
const QPolygonF &massPoly = relPositions.toVector();
|
||||
const QPointF &massCenterPoint = massPoly.boundingRect().center();
|
||||
|
||||
|
||||
const double massCenterPointX = massCenterPoint.x();
|
||||
const double massCenterPointY = massCenterPoint.y();
|
||||
QMutableListIterator<QPointF> listIt(relPositions);
|
||||
while (listIt.hasNext())
|
||||
{
|
||||
QPointF &relPosition = listIt.next();
|
||||
|
||||
if (relPosition.x() < massCenterPointX)
|
||||
relPosition.rx() -= distance;
|
||||
else
|
||||
relPosition.rx() += distance;
|
||||
|
||||
|
||||
if (relPosition.y() < massCenterPointY)
|
||||
relPosition.ry() -= distance;
|
||||
else
|
||||
relPosition.ry() += distance;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PositionCont absPositionsGeo;
|
||||
|
||||
const InfrastructureManagement::MainStructureElement &mse = m_ismDtc->mainStructureElement(buildingId);
|
||||
|
||||
const Core::GeoPosition &geoPosition = mse.geoPosition();
|
||||
const QPointF &referencePointGeo = QPointF(geoPosition.lon(), geoPosition.lat());
|
||||
const LtsCoordTrans::UtmCoordinate &referencePointUTM = LtsCoordTrans::UtmCoordinate::fromGeographic(referencePointGeo);
|
||||
const double angleRad = mse.angle() * LtsCoordTrans::deg2rad();
|
||||
|
||||
|
||||
const QPointF center;
|
||||
absPositionsGeo.reserve(relPositions.size());
|
||||
for (const auto &relPosition : qAsConst(relPositions))
|
||||
{
|
||||
const QPointF &relPositionRotate = MathUtils::rotate(relPosition, center, angleRad);
|
||||
const QPointF &pGeo = referencePointUTM.geographic(relPositionRotate);
|
||||
absPositionsGeo.append(Point3D::fromQPointF(pGeo));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef USE_BUFFER_APPROACH
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const double distance = (100 - floorId) * 0.01;
|
||||
|
||||
|
||||
|
||||
Esri::ArcGISRuntime::PolygonBuilder polygonBuilder(Esri::ArcGISRuntime::SpatialReference::wgs84());
|
||||
constexpr double rad2deg = LtsCoordTrans::rad2deg();
|
||||
for (const Point3D &point : qAsConst(absPositionsGeo))
|
||||
polygonBuilder.addPoint(Esri::ArcGISRuntime::Point(point.x() * rad2deg,
|
||||
point.y() * rad2deg,
|
||||
point.z()));
|
||||
const Esri::ArcGISRuntime::Geometry &esriGeometry = polygonBuilder.toGeometry();
|
||||
|
||||
const Esri::ArcGISRuntime::Polygon &polyline =
|
||||
Esri::ArcGISRuntime::GeometryEngine::bufferGeodetic(esriGeometry,
|
||||
distance,
|
||||
Esri::ArcGISRuntime::LinearUnitId::Meters,
|
||||
0.1,
|
||||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||||
|
||||
if (polyline.parts().isEmpty())
|
||||
return absPositionsGeo;
|
||||
|
||||
const Esri::ArcGISRuntime::ImmutablePart &immutablePart = polyline.parts().part(0);
|
||||
const Esri::ArcGISRuntime::ImmutablePointCollection &pointCollection = immutablePart.points();
|
||||
const int size = pointCollection.size();
|
||||
|
||||
INFO_LOG(m_logger) << " pointCollection.size = " << pointCollection.size()
|
||||
<< " - buildingId = " << buildingId
|
||||
<< ", mse.name = " << mse.name();
|
||||
|
||||
absPositionsGeo.clear();
|
||||
absPositionsGeo.reserve(size);
|
||||
|
||||
for (const Esri::ArcGISRuntime::Point &esriP : pointCollection)
|
||||
{
|
||||
absPositionsGeo.append(Point3D(esriP.x() * LtsCoordTrans::deg2rad(),
|
||||
esriP.y() * LtsCoordTrans::deg2rad(),
|
||||
esriP.z()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return absPositionsGeo;
|
||||
}
|
||||
|
||||
QMap<int, double> BuildingContamination::retrieveBuildingAbsHeight(int buildingId) const
|
||||
{
|
||||
QMap<int, double> floorHeights;
|
||||
|
||||
const InfrastructureManagement::MainStructureElement &mse = m_ismDtc->mainStructureElement(buildingId);
|
||||
|
||||
|
||||
for (const InfrastructureManagement::StructureElement &element : mse.elements())
|
||||
{
|
||||
if (element.structureElementTypeId() != InfrastructureManagement::StructureElementType::Floor)
|
||||
continue;
|
||||
|
||||
const int floorId = element.id();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double height = element.geoPosition().z();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
floorHeights[floorId] = height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
QMutableMapIterator<int, double> mapIt(floorHeights);
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
QMap<int, double>::iterator curFloor = mapIt.next();
|
||||
if (mapIt.hasNext())
|
||||
{
|
||||
QMap<int, double>::iterator upperFloor = mapIt.peekNext();
|
||||
curFloor.value() = upperFloor.value();
|
||||
}
|
||||
else
|
||||
curFloor.value() += 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
return floorHeights;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include "plugin_provider.h"
|
||||
#include <Map/situation_map_types.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
#include <Plugins/Buildings/bld_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
class Map;
|
||||
|
||||
|
||||
class BuildingContamination : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
|
||||
explicit BuildingContamination(int drawOrder, QObject *parent = nullptr);
|
||||
~BuildingContamination();
|
||||
|
||||
bool init(Map *map, PluginProvider *pluginProvider);
|
||||
void clearInterfaces();
|
||||
void removeAllObjects();
|
||||
void clearObjects() { removeAllObjects(); }
|
||||
|
||||
bool run();
|
||||
void stop();
|
||||
|
||||
bool isVisible() const;
|
||||
bool setVisible(bool visible);
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onBuildingStateChanged(const Buildings::BuildingState &data, DataModification modType);
|
||||
|
||||
void onResetBuildingState();
|
||||
|
||||
|
||||
protected:
|
||||
void updateBuilding(int buildingId);
|
||||
int findFloorIdByRoomId(int roomId);
|
||||
bool getRoom(int roomSeId, InfrastructureManagement::StructureElement &roomSe);
|
||||
PositionCont retrieveBuildingGeometry(int buildingId, int floorId) const;
|
||||
QMap<int, double> retrieveBuildingAbsHeight(int buildingId) const;
|
||||
|
||||
|
||||
private:
|
||||
LOGGER_T m_logger;
|
||||
QMap<int , int > m_roomToFloorCache;
|
||||
QMap<int , InfrastructureManagement::StructureElement > m_roomStructureElementCache;
|
||||
|
||||
|
||||
class Private;
|
||||
|
||||
|
||||
Private *d = nullptr;
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<Buildings::Interface::Dtc> m_bldDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+657
@@ -0,0 +1,657 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "building_ownership.h"
|
||||
#include <Map/map.h>
|
||||
#include <Map/object_factory.h>
|
||||
#include <MapObjects/cube.h>
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <MathUtils/simple_helper.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
#define USE_BUFFER_APPROACH
|
||||
#ifdef USE_BUFFER_APPROACH
|
||||
# include <arcgis/PolygonBuilder.h>
|
||||
# include <arcgis/GeometryEngine.h>
|
||||
#endif
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BuildingGeometryCache
|
||||
{
|
||||
|
||||
|
||||
|
||||
struct KEY_T
|
||||
{
|
||||
KEY_T(int buildingId = -1, int floorId = -1)
|
||||
: m_buildingId(buildingId), m_floorId(floorId)
|
||||
{}
|
||||
|
||||
int m_buildingId{-1};
|
||||
int m_floorId{-1};
|
||||
|
||||
bool operator<(const KEY_T &other) const
|
||||
{
|
||||
return m_buildingId < other.m_buildingId
|
||||
|| ((m_buildingId == other.m_buildingId) && (m_floorId < other.m_floorId));
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
BuildingGeometryCache() = default;
|
||||
~BuildingGeometryCache() = default;
|
||||
|
||||
void init(BuildingOwnership *buildingOwnership)
|
||||
{
|
||||
m_buildingOwnership = buildingOwnership;
|
||||
}
|
||||
|
||||
PositionCont retrieveBuildingGeometry(int buildingId, int floorId) const
|
||||
{
|
||||
const KEY_T key(buildingId, floorId);
|
||||
loadGeometry(key);
|
||||
return m_cacheGeometry[key];
|
||||
};
|
||||
|
||||
QMap<int, double> retrieveBuildingAbsHeight(int buildingId) const
|
||||
{
|
||||
loadAbsHeight(buildingId);
|
||||
return m_cacheAbsHeight[buildingId];
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
void loadGeometry(const KEY_T &key) const
|
||||
{
|
||||
if (m_cacheGeometry.contains(key))
|
||||
return;
|
||||
m_cacheGeometry[key] = m_buildingOwnership->retrieveBuildingGeometryInternal(key.m_buildingId, key.m_floorId);
|
||||
}
|
||||
|
||||
void loadAbsHeight(int buildingId) const
|
||||
{
|
||||
if (m_cacheAbsHeight.contains(buildingId))
|
||||
return;
|
||||
m_cacheAbsHeight[buildingId] = m_buildingOwnership->retrieveBuildingAbsHeightInternal(buildingId);
|
||||
}
|
||||
|
||||
private:
|
||||
BuildingOwnership *m_buildingOwnership{nullptr};
|
||||
mutable QMap<KEY_T, PositionCont> m_cacheGeometry;
|
||||
mutable QMap<int, QMap<int, double>> m_cacheAbsHeight;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class BuildingOwnership::Private
|
||||
{
|
||||
public:
|
||||
explicit Private() = default;
|
||||
|
||||
~Private() = default;
|
||||
|
||||
|
||||
QMap<int32_t, CentralEffectSimulation::BuildingOwnership> m_ownershipData;
|
||||
|
||||
BuildingGeometryCache m_buildingGeometryCache;
|
||||
|
||||
Map *m_map = nullptr;
|
||||
|
||||
|
||||
QMap<QPair<int, int>, UniqueMapId> m_bldgFlr2UniqueMapId;
|
||||
|
||||
bool m_visible = false;
|
||||
int m_drawOrder = 0;
|
||||
|
||||
|
||||
|
||||
static QPair<int, int> createKey(int buildingId, int floorId)
|
||||
{
|
||||
return {buildingId, floorId};
|
||||
}
|
||||
|
||||
static int buildingIdOfKey(const QPair<int, int> &keyData)
|
||||
{
|
||||
return keyData.first;
|
||||
}
|
||||
|
||||
|
||||
RefPointer<Cube> getCreateCube(int buildingId, int floorId)
|
||||
{
|
||||
const QPair<int, int> &key = createKey(buildingId, floorId);
|
||||
const UniqueMapId uniqueMapId = m_bldgFlr2UniqueMapId.value(key, INVALID_MAP_ID);
|
||||
|
||||
if (!SituationMap::isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
const QString &layernameForCubes = m_map->layerFactory().layernameForCubes();
|
||||
const QString &key_debugInfo = QStringLiteral("bldg_%1-flr%2").arg(buildingId).arg(floorId);
|
||||
|
||||
RefPointer<Cube> cube =
|
||||
m_map->objectFactory().create<Cube>(layernameForCubes, key_debugInfo);
|
||||
|
||||
if (cube.valid())
|
||||
m_bldgFlr2UniqueMapId[key] = cube->uniqueMapId();
|
||||
return cube;
|
||||
}
|
||||
return m_map->objectFactory().get<Cube>(uniqueMapId);
|
||||
}
|
||||
|
||||
void removeCube(int buildingId = -1)
|
||||
{
|
||||
QMutableMapIterator<QPair<int, int>, UniqueMapId> mapIt(m_bldgFlr2UniqueMapId);
|
||||
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
|
||||
const QPair<int, int> &key = mapIt.key();
|
||||
int curBuildingId = buildingIdOfKey(key);
|
||||
|
||||
if ((buildingId < 0) ||
|
||||
(buildingId == curBuildingId)
|
||||
)
|
||||
{
|
||||
UniqueMapId uMapId = mapIt.value();
|
||||
SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uMapId);
|
||||
if (mapObj)
|
||||
mapObj->removeMySelf();
|
||||
|
||||
|
||||
mapIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool updateVisibility(int buildingId = -1)
|
||||
{
|
||||
bool success = true;
|
||||
QMutableMapIterator<QPair<int, int>, UniqueMapId> mapIt(m_bldgFlr2UniqueMapId);
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
|
||||
const QPair<int, int> &key = mapIt.key();
|
||||
int curBuildingId = buildingIdOfKey(key);
|
||||
|
||||
if ((buildingId < 0) ||
|
||||
(buildingId == curBuildingId)
|
||||
)
|
||||
{
|
||||
UniqueMapId uMapId = mapIt.value();
|
||||
SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uMapId);
|
||||
if (mapObj)
|
||||
{
|
||||
mapObj->setVisibility(m_visible);
|
||||
if (!mapObj->updateView())
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BuildingOwnership::BuildingOwnership(int drawOrder, QObject *parent)
|
||||
: BaseClass(parent)
|
||||
, m_logger(getLogger("BuildingOwnership"))
|
||||
, d(new Private())
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
d->m_drawOrder = drawOrder;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
BuildingOwnership::~BuildingOwnership()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
this->stop();
|
||||
|
||||
delete d;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingOwnership::init(Map *map, PluginProvider *pluginProvider)
|
||||
{
|
||||
d->m_map = map;
|
||||
|
||||
if (!d->m_map)
|
||||
return false;
|
||||
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->cesDtc() ||
|
||||
!pluginProvider->ismDtc())
|
||||
return false;
|
||||
|
||||
m_cesDtc = pluginProvider->cesDtc();
|
||||
m_ismDtc = pluginProvider->ismDtc();
|
||||
|
||||
d->m_buildingGeometryCache.init(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingOwnership::removeAllObjects()
|
||||
{
|
||||
d->removeCube();
|
||||
}
|
||||
|
||||
bool BuildingOwnership::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!d->m_map)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_map";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_cesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_cesDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cesDtc->disconnect(this);
|
||||
|
||||
qRegisterMetaType<CentralEffectSimulation::BuildingOwnership>("CentralEffectSimulation::BuildingOwnership");
|
||||
|
||||
connect(m_cesDtc.get(), &CentralEffectSimulation::Interface::Dtc::buildingOwnershipChanged,
|
||||
this, &BuildingOwnership::onBuildingOwnershipChanged, Qt::QueuedConnection);
|
||||
|
||||
|
||||
m_cesDtc->buildingOwnerships([this](const CentralEffectSimulation::BuildingOwnership & data)
|
||||
{
|
||||
onBuildingOwnershipChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (false)
|
||||
{
|
||||
std::function<void(int, int, int)> fTriggerBuilding = [this](int partyId, int buildingId, int floorId)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
const PositionCont &absPositionsGeo = retrieveBuildingGeometry(buildingId, floorId);
|
||||
|
||||
|
||||
QMap<int, double> floorHeights = retrieveBuildingAbsHeight(buildingId);
|
||||
|
||||
|
||||
RefPointer<Cube> cube = d->getCreateCube(buildingId, floorId);
|
||||
if (!cube)
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no cube created";
|
||||
|
||||
cube->setVisibility(d->m_visible);
|
||||
cube->setDrawOrder(d->m_drawOrder);
|
||||
|
||||
cube->setPartyId(partyId);
|
||||
cube->setPositions(absPositionsGeo);
|
||||
const double height = floorHeights.value(floorId, 2.5 * floorId);
|
||||
cube->setHeight(height);
|
||||
|
||||
bool success = cube->updateView();
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " cube->updateView " << success;
|
||||
};
|
||||
|
||||
|
||||
fTriggerBuilding(24, 5, 1);
|
||||
fTriggerBuilding(-1, 5, 2);
|
||||
fTriggerBuilding(89, 5, 3);
|
||||
|
||||
}
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingOwnership::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_cesDtc->disconnect(this);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingOwnership::isVisible() const
|
||||
{
|
||||
return d->m_visible;
|
||||
}
|
||||
bool BuildingOwnership::setVisible(bool visible)
|
||||
{
|
||||
d->m_visible = visible;
|
||||
bool succ = d->updateVisibility();
|
||||
return succ;
|
||||
}
|
||||
|
||||
void BuildingOwnership::onBuildingOwnershipChanged(const CentralEffectSimulation::BuildingOwnership &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int buildingId = data.buildingId();
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
|
||||
updateBuilding(buildingId);
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
|
||||
d->removeCube(buildingId);
|
||||
break;
|
||||
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void BuildingOwnership::onResetBuildingOwnership()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
d->removeCube();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void BuildingOwnership::updateBuilding(int buildingId)
|
||||
{
|
||||
|
||||
const CentralEffectSimulation::BuildingOwnership &bos = m_cesDtc->buildingOwnership(buildingId);
|
||||
|
||||
|
||||
d->m_ownershipData[buildingId] = bos;
|
||||
|
||||
const auto &ownerships = bos.ownerships();
|
||||
|
||||
|
||||
QMap<int, int> floor2Party;
|
||||
for (const CentralEffectSimulation::Ownership &ownership : ownerships)
|
||||
|
||||
if (ownership.partyId() > 0)
|
||||
floor2Party[ownership.floorId()] = ownership.partyId();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const QMap<int, double> &floorHeights = retrieveBuildingAbsHeight(buildingId);
|
||||
|
||||
|
||||
|
||||
QMapIterator<int, double> mapIt(floorHeights);
|
||||
int floorCounter = 0;
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
|
||||
|
||||
const int floorId = mapIt.key();
|
||||
|
||||
|
||||
const double height = mapIt.value();
|
||||
|
||||
|
||||
|
||||
const int partyId = floor2Party.value(floorId, -1);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " floorId=" << floorId
|
||||
<< " height=" << height
|
||||
<< " partyId=" << partyId;
|
||||
|
||||
|
||||
|
||||
const PositionCont &absPositionsGeo = retrieveBuildingGeometry(buildingId, ++floorCounter);
|
||||
|
||||
|
||||
RefPointer<Cube> cube = d->getCreateCube(buildingId, floorId);
|
||||
|
||||
cube->setVisibility(d->m_visible);
|
||||
cube->setDrawOrder(d->m_drawOrder);
|
||||
|
||||
cube->setPartyId(partyId);
|
||||
cube->setPositions(absPositionsGeo);
|
||||
cube->setHeight(height);
|
||||
|
||||
if (!cube->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " cube->updateView() failed";
|
||||
}
|
||||
}
|
||||
|
||||
PositionCont BuildingOwnership::retrieveBuildingGeometry(int buildingId, int floorId) const
|
||||
{
|
||||
return d->m_buildingGeometryCache.retrieveBuildingGeometry(buildingId, floorId);
|
||||
}
|
||||
|
||||
PositionCont BuildingOwnership::retrieveBuildingGeometryInternal(int buildingId, int floorId) const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " buildingId=" << buildingId
|
||||
<< " floorId=" << floorId;
|
||||
if (!m_ismDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_ismDtc";
|
||||
return PositionCont();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QVector<QPointF> relPositions;
|
||||
{
|
||||
const InfrastructureManagement::MainFootprint &mainFootprint = m_ismDtc->mainFootprint(buildingId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " mainFootprint.elements().size()=" << mainFootprint.elements().size();
|
||||
|
||||
relPositions.reserve(mainFootprint.elements().size());
|
||||
|
||||
const auto &fpElements = mainFootprint.elements();
|
||||
for (const InfrastructureManagement::FootprintElement &element : fpElements)
|
||||
{
|
||||
const auto &relPos = element.relPosition();
|
||||
relPositions += QPointF(relPos.offsetX(), relPos.offsetY());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef USE_BUFFER_APPROACH
|
||||
|
||||
{
|
||||
|
||||
const double distance = 0.5 + (100 - floorId) * 0.01;
|
||||
|
||||
const QPolygonF &massPoly = relPositions.toVector();
|
||||
const QPointF &massCenterPoint = massPoly.boundingRect().center();
|
||||
|
||||
|
||||
const double massCenterPointX = massCenterPoint.x();
|
||||
const double massCenterPointY = massCenterPoint.y();
|
||||
QMutableListIterator<QPointF> listIt(relPositions);
|
||||
while (listIt.hasNext())
|
||||
{
|
||||
QPointF &relPosition = listIt.next();
|
||||
|
||||
if (relPosition.x() < massCenterPointX)
|
||||
relPosition.rx() -= distance;
|
||||
else
|
||||
relPosition.rx() += distance;
|
||||
|
||||
|
||||
if (relPosition.y() < massCenterPointY)
|
||||
relPosition.ry() -= distance;
|
||||
else
|
||||
relPosition.ry() += distance;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PositionCont absPositionsGeo;
|
||||
|
||||
const InfrastructureManagement::MainStructureElement &mse = m_ismDtc->mainStructureElement(buildingId);
|
||||
|
||||
const Core::GeoPosition &geoPosition = mse.geoPosition();
|
||||
const QPointF &referencePointGeo = QPointF(geoPosition.lon(), geoPosition.lat());
|
||||
const LtsCoordTrans::UtmCoordinate referencePointUTM = LtsCoordTrans::UtmCoordinate::fromGeographic(referencePointGeo);
|
||||
const double angleRad = mse.angle() * LtsCoordTrans::deg2rad();
|
||||
|
||||
|
||||
const QPointF center;
|
||||
absPositionsGeo.reserve(relPositions.size());
|
||||
for (const auto &relPosition : qAsConst(relPositions))
|
||||
{
|
||||
const QPointF &relPositionRotate = MathUtils::rotate(relPosition, center, angleRad);
|
||||
const QPointF &pGeo = referencePointUTM.geographic(relPositionRotate);
|
||||
absPositionsGeo.append(Point3D::fromQPointF(pGeo));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef USE_BUFFER_APPROACH
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const double distance = (100 - floorId) * 0.01;
|
||||
|
||||
|
||||
|
||||
Esri::ArcGISRuntime::PolygonBuilder polygonBuilder(Esri::ArcGISRuntime::SpatialReference::wgs84());
|
||||
constexpr double rad2deg = LtsCoordTrans::rad2deg();
|
||||
for (const Point3D &point : qAsConst(absPositionsGeo))
|
||||
polygonBuilder.addPoint(Esri::ArcGISRuntime::Point(point.x() * rad2deg,
|
||||
point.y() * rad2deg,
|
||||
point.z()));
|
||||
const Esri::ArcGISRuntime::Geometry &esriGeometry = polygonBuilder.toGeometry();
|
||||
|
||||
const Esri::ArcGISRuntime::Polygon polyline =
|
||||
Esri::ArcGISRuntime::GeometryEngine::bufferGeodetic(esriGeometry,
|
||||
distance,
|
||||
Esri::ArcGISRuntime::LinearUnitId::Meters,
|
||||
0.1,
|
||||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||||
|
||||
if (polyline.parts().isEmpty())
|
||||
return absPositionsGeo;
|
||||
|
||||
const Esri::ArcGISRuntime::ImmutablePart &immutablePart = polyline.parts().part(0);
|
||||
const Esri::ArcGISRuntime::ImmutablePointCollection &pointCollection = immutablePart.points();
|
||||
const int size = pointCollection.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
absPositionsGeo.clear();
|
||||
absPositionsGeo.reserve(size);
|
||||
|
||||
for (const Esri::ArcGISRuntime::Point &esriP : pointCollection)
|
||||
{
|
||||
absPositionsGeo.append(Point3D(esriP.x() * LtsCoordTrans::deg2rad(),
|
||||
esriP.y() * LtsCoordTrans::deg2rad(),
|
||||
esriP.z()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return absPositionsGeo;
|
||||
}
|
||||
|
||||
QMap<int, double> BuildingOwnership::retrieveBuildingAbsHeight(int buildingId) const
|
||||
{
|
||||
return d->m_buildingGeometryCache.retrieveBuildingAbsHeight(buildingId);
|
||||
}
|
||||
|
||||
QMap<int, double> BuildingOwnership::retrieveBuildingAbsHeightInternal(int buildingId) const
|
||||
{
|
||||
QMap<int, double> floorHeights;
|
||||
|
||||
const InfrastructureManagement::MainStructureElement &mse = m_ismDtc->mainStructureElement(buildingId);
|
||||
|
||||
|
||||
for (const InfrastructureManagement::StructureElement &element : mse.elements())
|
||||
{
|
||||
if (element.structureElementTypeId() != InfrastructureManagement::StructureElementType::Floor)
|
||||
continue;
|
||||
|
||||
const int floorId = element.id();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double height = element.geoPosition().z();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
floorHeights[floorId] = height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
QMutableMapIterator<int, double> mapIt(floorHeights);
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
QMap<int, double>::iterator curFloor = mapIt.next();
|
||||
if (mapIt.hasNext())
|
||||
{
|
||||
QMap<int, double>::iterator upperFloor = mapIt.peekNext();
|
||||
curFloor.value() = upperFloor.value();
|
||||
}
|
||||
else
|
||||
curFloor.value() += 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
return floorHeights;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include "plugin_provider.h"
|
||||
#include <Map/situation_map_types.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
#include <Plugins/CentralEffectSimulation/ces_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
class Map;
|
||||
|
||||
|
||||
class BuildingOwnership : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
|
||||
explicit BuildingOwnership(int drawOrder, QObject *parent = nullptr);
|
||||
~BuildingOwnership();
|
||||
|
||||
bool init(Map *map, PluginProvider *pluginProvider);
|
||||
void clearInterfaces();
|
||||
void removeAllObjects();
|
||||
void clearObjects() { removeAllObjects(); }
|
||||
|
||||
bool run();
|
||||
void stop();
|
||||
|
||||
bool isVisible() const;
|
||||
bool setVisible(bool visible);
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onBuildingOwnershipChanged(const CentralEffectSimulation::BuildingOwnership &data, DataModification modType);
|
||||
|
||||
void onResetBuildingOwnership();
|
||||
|
||||
|
||||
protected:
|
||||
friend class BuildingGeometryCache;
|
||||
void updateBuilding(int buildingId);
|
||||
PositionCont retrieveBuildingGeometry(int buildingId, int floorId) const;
|
||||
PositionCont retrieveBuildingGeometryInternal(int buildingId, int floorId) const;
|
||||
|
||||
QMap<int, double> retrieveBuildingAbsHeight(int buildingId) const;
|
||||
QMap<int, double> retrieveBuildingAbsHeightInternal(int buildingId) const;
|
||||
|
||||
|
||||
private:
|
||||
LOGGER_T m_logger;
|
||||
|
||||
class Private;
|
||||
|
||||
|
||||
Private *d = nullptr;
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<CentralEffectSimulation::Interface::Dtc> m_cesDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+435
@@ -0,0 +1,435 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "buildinghitlineinfo_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
|
||||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
BuildingHitlineInfo2SituationMap::BuildingHitlineInfo2SituationMap(PdmHandler *pdmHandler,
|
||||
Participant2SituationMap *participant2SituationMap,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pdmHandler(pdmHandler)
|
||||
, m_participant2SituationMap(participant2SituationMap)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
BuildingHitlineInfo2SituationMap::~BuildingHitlineInfo2SituationMap()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
int32_t BuildingHitlineInfo2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->bldDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
m_bldDtc = pluginProvider->bldDtc();
|
||||
m_bldBuildingInfoIfc = pluginProvider->bldInfoIfc();
|
||||
m_ismDtc = pluginProvider->ismDtc();
|
||||
|
||||
if (!m_bldDtc)
|
||||
return false;
|
||||
if (!m_ismDtc)
|
||||
return false;
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &BuildingHitlineInfo2SituationMap::onPartitionTimeChanged);
|
||||
|
||||
|
||||
|
||||
|
||||
m_exerciseId = m_pluginProvider->exerciseId();
|
||||
m_buildingHeight.clear();
|
||||
|
||||
m_ismDtc->waitForHistoricalDataMainStructureElement(5000);
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
|
||||
this, &BuildingHitlineInfo2SituationMap::onMainStructureElementChanged);
|
||||
m_ismDtc->mainStructureElements([this](const InfrastructureManagement::MainStructureElement & data)
|
||||
{
|
||||
onMainStructureElementChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_bldDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_bldDtc.get(), &Buildings::Interface::Dtc::buildingHitLineInfoChanged,
|
||||
this, &BuildingHitlineInfo2SituationMap::onBuildingHitLineInfoChanged);
|
||||
|
||||
|
||||
m_bldDtc->buildingHitLineInfos([this](const Sim2SituationMap::DDS_T & ddsData)
|
||||
{
|
||||
onBuildingHitLineInfoChanged(ddsData, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingHitlineInfo2SituationMap::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_bldDtc)
|
||||
m_bldDtc->disconnect(this);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
if (!m_bldBuildingInfoIfc)
|
||||
return false;
|
||||
|
||||
const QVector<qint32> &hitLineIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (hitLineIds.isEmpty())
|
||||
return true;
|
||||
|
||||
m_bldBuildingInfoIfc->showHitLineInfoWindow(hitLineIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString BuildingHitlineInfo2SituationMap::chargeTypeIdentifier(const int32_t originatorChargeTypeId) const
|
||||
{
|
||||
if (!m_pdmHandler)
|
||||
return QStringLiteral("ctId_%1").arg(originatorChargeTypeId);
|
||||
|
||||
QString chargeTypeString = m_pdmHandler->trChargeTypeShortName(originatorChargeTypeId);
|
||||
if (chargeTypeString.isEmpty())
|
||||
return QStringLiteral("ctId_%1").arg(originatorChargeTypeId);
|
||||
return chargeTypeString;
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_bldDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [this, simIdOut, &umodOut](const Sim2SituationMap::DDS_T & ddsData) -> bool
|
||||
{
|
||||
if (ddsData.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_partyId = ddsData.originatorPartyId();
|
||||
const int32_t originatorChargeTypeId = ddsData.chargeTypeId();
|
||||
umodOut.m_description1 = chargeTypeIdentifier(originatorChargeTypeId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const Sim2SituationMap::DDS_T &ddsData)> cb1 = cb;
|
||||
return m_bldDtc->buildingHitLineInfos(cb1);
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::onBuildingHitLineInfoChanged(const Sim2SituationMap::DDS_T &ddsData,
|
||||
DataModification modType)
|
||||
{
|
||||
const bool bIsValid = !isElapsed(ddsData);
|
||||
if (bIsValid)
|
||||
updateDdsDataContainer(ddsData, modType);
|
||||
return handleChanged(ddsData, modType);
|
||||
}
|
||||
|
||||
void BuildingHitlineInfo2SituationMap::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &mse, DataModification modType)
|
||||
{
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
if (mse.modelId() != 0 && m_ismDtc->isElementAssignedToExercise(mse, m_exerciseId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_buildingHeight.insert id=" << mse.id() << " z=" << mse.geoPosition().z();
|
||||
m_buildingHeight.insert(mse.id(), mse.geoPosition().z());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
m_buildingHeight.remove(mse.id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isValidPos(const Core::GeoPosition &pos)
|
||||
{
|
||||
if (qFuzzyIsNull(pos.lat()) && qFuzzyIsNull(pos.lon()))
|
||||
return false;
|
||||
return !std::isnan(pos.lat()) && !std::isnan(pos.lon());
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << " isElapsed";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
const Core::GeoPosition &startGeoPos = data.originatorPos();
|
||||
if (!isValidPos(startGeoPos))
|
||||
return true;
|
||||
|
||||
const Core::GeoPosition &endGeoPos = data.buildingPos();
|
||||
if (!isValidPos(endGeoPos))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
const qint32 hitlineId = ddsData.id();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " id=" << hitlineId;
|
||||
|
||||
|
||||
mapObj->setVisibility(SituationMap::ObjectAppearance::Tactical, false);
|
||||
mapObj->rLineStyle().setLineWidth(3);
|
||||
|
||||
|
||||
LineStyle ls = mapObj->lineStyle();
|
||||
const SpecialChargeType sct = m_pdmHandler->isSpecialChargeType(ddsData.chargeTypeId());
|
||||
switch (sct)
|
||||
{
|
||||
case SpecialChargeType::LRF:
|
||||
ls.setLinePattern(LinePattern::Dot);
|
||||
break;
|
||||
case SpecialChargeType::LTD:
|
||||
ls.setLinePattern(LinePattern::Solid);
|
||||
break;
|
||||
case SpecialChargeType::NoneSpecial:
|
||||
default:
|
||||
ls.setLinePattern(LinePattern::Dash);
|
||||
}
|
||||
|
||||
mapObj->setLineStyle(ls);
|
||||
|
||||
|
||||
mapObj->setPartyId(ddsData.originatorPartyId());
|
||||
|
||||
|
||||
const int32_t originatorChargeTypeId = ddsData.chargeTypeId();
|
||||
mapObj->setIdentifier(chargeTypeIdentifier(originatorChargeTypeId));
|
||||
|
||||
|
||||
|
||||
const Core::GeoPosition &startGeoPos = ddsData.originatorPos();
|
||||
const Core::GeoPosition &endGeoPos = ddsData.buildingPos();
|
||||
|
||||
int bldgId = ddsData.buildingId();
|
||||
double buildingHeight = m_buildingHeight.value(bldgId, 0);
|
||||
|
||||
mapObj->setStartAndEndPoint(Point3D(startGeoPos.lon(), startGeoPos.lat(), startGeoPos.z()),
|
||||
Point3D(endGeoPos.lon(), endGeoPos.lat(), endGeoPos.z()-buildingHeight));
|
||||
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj, ddsData);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " id=" << hitlineId;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingHitlineInfo2SituationMap::onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part)
|
||||
{
|
||||
if ((part != FilterManagement::SymbolAppearanceSettings::Part::All) &&
|
||||
(part != FilterManagement::SymbolAppearanceSettings::Part::Symbol))
|
||||
return;
|
||||
|
||||
|
||||
const bool relevant = symbolAppearanceSettingsChangesAreRelevant(m_symbolAppearanceSettings->settings());
|
||||
|
||||
m_currentSymbolSettings = m_symbolAppearanceSettings->settings();
|
||||
|
||||
if (!relevant)
|
||||
return;
|
||||
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return qFuzzyCompare(m_currentSymbolSettings.symbolSettings.symbolScale, newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.symbolPartyAppearance != newSas.symbolSettings.symbolPartyAppearance) ||
|
||||
(m_currentSymbolSettings.symbolSettings.hitLineDisplayLengthMSec != newSas.symbolSettings.hitLineDisplayLengthMSec) ||
|
||||
(m_currentSymbolSettings.symbolSettings.lrfLineDisplayLengthMSec != newSas.symbolSettings.lrfLineDisplayLengthMSec) ||
|
||||
(m_currentSymbolSettings.symbolSettings.ltdLineDisplayLengthMSec != newSas.symbolSettings.ltdLineDisplayLengthMSec);
|
||||
}
|
||||
|
||||
void BuildingHitlineInfo2SituationMap::handleSymbolAppearanceSettings()
|
||||
{
|
||||
for (const Buildings::BuildingHitLineInfo &buildingHitline : qAsConst(m_ddsDataContainer))
|
||||
{
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(buildingHitline.id(), INVALID_MAP_ID);
|
||||
if (uniqueMapId == INVALID_MAP_ID)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << "Found a buildingHitline which is in internal map but has no map object...: " << buildingHitline.id();
|
||||
continue;
|
||||
}
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj, buildingHitline);
|
||||
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void BuildingHitlineInfo2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData)
|
||||
{
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
mapObj->setScale(filterSettings.symbolSettings.symbolScale);
|
||||
|
||||
bool bUncertain = false;
|
||||
const bool isVisi = isVisible(ddsData, &bUncertain);
|
||||
if (bUncertain)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
QTimer::singleShot(200, this, [this, ddsData]()
|
||||
{
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(ddsData.id());
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
handleSymbolAppearanceSettings(mapObj, ddsData);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (mapObj->visibility() != isVisi)
|
||||
{
|
||||
mapObj->setVisibility(isVisi);
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
}
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::isVisible(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const
|
||||
{
|
||||
return visibleBySymbolPartyAppearance(ddsData) &&
|
||||
visibleByHitLineDisplayLength(m_pluginProvider->partitionTime(), ddsData) &&
|
||||
visibleByParticipants(ddsData, bUncertain);
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
const auto spa = filterSettings.symbolSettings.symbolPartyAppearance.value(ddsData.originatorPartyId());
|
||||
return spa.isVisible;
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::visibleByParticipants(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (!m_participant2SituationMap)
|
||||
return true;
|
||||
|
||||
bool bParticipantExists = true;
|
||||
bool bRet = m_participant2SituationMap->isParticipantVisible(ddsData.originatorParticipantId(), &bParticipantExists);
|
||||
if (!bParticipantExists && bUncertain)
|
||||
*bUncertain = true;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool BuildingHitlineInfo2SituationMap::visibleByHitLineDisplayLength(const qint64 newPartitionTime, const DDS_T &ddsData) const
|
||||
{
|
||||
qint64 displayLength = m_currentSymbolSettings.symbolSettings.hitLineDisplayLengthMSec;
|
||||
|
||||
const SpecialChargeType sct = m_pdmHandler->isSpecialChargeType(ddsData.chargeTypeId());
|
||||
switch (sct)
|
||||
{
|
||||
case SpecialChargeType::LRF:
|
||||
displayLength = m_currentSymbolSettings.symbolSettings.lrfLineDisplayLengthMSec;
|
||||
break;
|
||||
case SpecialChargeType::LTD:
|
||||
displayLength = m_currentSymbolSettings.symbolSettings.ltdLineDisplayLengthMSec;
|
||||
break;
|
||||
case SpecialChargeType::NoneSpecial:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (displayLength < 0)
|
||||
return true;
|
||||
return (newPartitionTime - ddsData.sampleTime()) <= displayLength;
|
||||
}
|
||||
|
||||
void BuildingHitlineInfo2SituationMap::onPartitionTimeChanged()
|
||||
{
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include "participant_to_map.h"
|
||||
#include <Buildings/bld_dtc.h>
|
||||
#include <MapObjects/hit_line.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <Plugins/Buildings/bld_info_gui_plugin_interface.h>
|
||||
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_dtc.h>
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
class PdmHandler;
|
||||
|
||||
|
||||
class BuildingHitlineInfo2SituationMap final : public Sim2SituationMap<Buildings::BuildingHitLineInfo, SituationMap::HitLine>
|
||||
, protected DdsFilterHandling<SituationMap::HitLine>
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = SituationMap::Sim2SituationMap<Buildings::BuildingHitLineInfo, SituationMap::HitLine>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::HitLine>;
|
||||
|
||||
public:
|
||||
BuildingHitlineInfo2SituationMap(PdmHandler *pdmHandler,
|
||||
Participant2SituationMap *participant2SituationMap,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
~BuildingHitlineInfo2SituationMap();
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
QString chargeTypeIdentifier(const int32_t originatorChargeTypeId) const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
bool onBuildingHitLineInfoChanged(const Sim2SituationMap::DDS_T &ddsData, DataModification modType = DataModification::eAdded);
|
||||
void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &mse, DataModification modType);
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
bool isVisible(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const;
|
||||
bool visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
bool visibleByParticipants(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const;
|
||||
bool visibleByHitLineDisplayLength(const qint64 newPartitionTime, const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
void onPartitionTimeChanged();
|
||||
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) override;
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId());
|
||||
handleSymbolAppearanceSettings(mapObj, m_ddsDataContainer.value(simId));
|
||||
}
|
||||
|
||||
void handleSymbolAppearanceSettings();
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData);
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider = nullptr;
|
||||
std::shared_ptr<Buildings::Interface::Dtc> m_bldDtc;
|
||||
std::shared_ptr<Buildings::ForeignInfoGuiInterface> m_bldBuildingInfoIfc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
PdmHandler *m_pdmHandler = nullptr;
|
||||
|
||||
QPointer<Participant2SituationMap> m_participant2SituationMap;
|
||||
int m_exerciseId{-1};
|
||||
QHash < int32_t, double > m_buildingHeight;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#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>
|
||||
#include <Plugins/Buildings/bld_info_gui_plugin_interface.h>
|
||||
#include <ProjectDataManagement/pdm_to_string.h>
|
||||
#include <InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
|
||||
|
||||
#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();
|
||||
|
||||
m_ismGuiIfc = pluginProvider->ismGuiIfc();
|
||||
m_bldDtc = pluginProvider->bldDtc();
|
||||
|
||||
m_bldInfoIfc = pluginProvider->bldInfoIfc();
|
||||
|
||||
|
||||
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();
|
||||
|
||||
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainFootprintChanged,
|
||||
this, &Building2SituationMap::onMainFootprintChanged);
|
||||
|
||||
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
|
||||
this, &Building2SituationMap::onMainStructureElementChanged);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
|
||||
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();
|
||||
if (m_mseIdWithoutValidFootprint.contains(mseId))
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
const int buildingId = data.id();
|
||||
|
||||
auto it = m_simId2UniqueMapId.constFind(buildingId);
|
||||
if (it == m_simId2UniqueMapId.constEnd())
|
||||
return;
|
||||
|
||||
|
||||
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();
|
||||
|
||||
|
||||
|
||||
mapObj->setForceMajorColor(Qt::black);
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
const qint32 buildingId = getSimId(ddsData);
|
||||
|
||||
|
||||
|
||||
|
||||
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());
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "absPositionsGeo = " << absPositionsGeo;
|
||||
|
||||
mapObj->setPositions(absPositionsGeo);
|
||||
|
||||
|
||||
TextStyle ts = mapObj->textStyle();
|
||||
ts.setHorizontalAlignment(HorizontalAlignment::Center);
|
||||
mapObj->setTextStyle(ts);
|
||||
|
||||
mapObj->setIdentifier(m_ismDtc->getBuildingDisplayName(ddsData));
|
||||
|
||||
if (m_enableDamageVisualization && m_bldDtc)
|
||||
{
|
||||
|
||||
updateBldgDamage(mapObj, buildingId);
|
||||
}
|
||||
|
||||
|
||||
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 ls = mapObj->lineStyle();
|
||||
if (bIsContaminated)
|
||||
ls.setLineColor(Qt::yellow);
|
||||
else
|
||||
ls.setLineColor(Qt::black);
|
||||
mapObj->setLineStyle(ls);
|
||||
|
||||
|
||||
FillStyle fs = mapObj->fillStyle();
|
||||
fs.setFillPattern(FillPattern::Solid);
|
||||
|
||||
int damagePercent = bldgState.damagePercent();
|
||||
|
||||
|
||||
|
||||
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);
|
||||
if (opacity > 0.1)
|
||||
{
|
||||
col = Qt::red;
|
||||
col.setAlphaF(opacity);
|
||||
}
|
||||
fs.setFillColor(col);
|
||||
|
||||
mapObj->setFillStyle(fs);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Buildings/bld_dtc.h>
|
||||
#include <MapObjects/building_outline.h>
|
||||
|
||||
namespace Buildings
|
||||
{
|
||||
class ForeignInfoGuiInterface;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class Building2SituationMap final : public Sim2SituationMap<InfrastructureManagement::MainStructureElement, SituationMap::BuildingOutline>
|
||||
, protected DdsFilterHandling<SituationMap::BuildingOutline>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<InfrastructureManagement::MainStructureElement, SituationMap::BuildingOutline>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::BuildingOutline>;
|
||||
|
||||
public:
|
||||
explicit Building2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider, bool enableDamageVisualization);
|
||||
|
||||
bool run() override;
|
||||
void stop() override
|
||||
{
|
||||
if (m_ismDtc)
|
||||
m_ismDtc->disconnect(this);
|
||||
if (m_bldDtc)
|
||||
m_bldDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool isElapsed(const InfrastructureManagement::MainStructureElement &ddsData) const override;
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data,
|
||||
DataModification modType = DataModification::eAdded);
|
||||
void onMainFootprintChanged(const InfrastructureManagement::MainFootprint &data,
|
||||
DataModification modType = DataModification::eAdded);
|
||||
void onBuildingStateChanged(const Buildings::BuildingState &data, DataModification modType);
|
||||
|
||||
|
||||
protected:
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool updateBldgDamage(RefPointer<MAP_T> mapObj, qint32 buildingId);
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider = nullptr;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignResourceManagementGuiInterface> m_ismGuiIfc;
|
||||
std::shared_ptr<Buildings::Interface::Dtc> m_bldDtc;
|
||||
std::shared_ptr<Buildings::ForeignInfoGuiInterface> m_bldInfoIfc;
|
||||
|
||||
bool m_enableDamageVisualization = false;
|
||||
mutable QVector<int> m_mseIdWithoutValidFootprint;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+785
@@ -0,0 +1,785 @@
|
||||
|
||||
|
||||
|
||||
#include "charge_effect_to_map.h"
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <GuezIedManagement/gim_dtc.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <Map/map.h>
|
||||
#include <ParticipantManagement/Data/ppm_data_plugin.h>
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#define ADD_UNIQUE_MAP_ID_TO_NOTIFIY(uniqueMapId) addUniqueMapIdToNotifiy(uniqueMapId, __FILE__, __LINE__)
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK
|
||||
#define BENCHMARK_SETUP_AND_START() \
|
||||
QElapsedTimer elapsedTimer; \
|
||||
elapsedTimer.start();
|
||||
|
||||
#define BENCHMARK_RUN
|
||||
|
||||
|
||||
#define BENCHMARK_ALL_NOTIFIED
|
||||
|
||||
#else
|
||||
#define BENCHMARK_SETUP_AND_START()
|
||||
#endif
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
static int s_effect3dMaxDisplayDuration = 5000;
|
||||
|
||||
|
||||
ChargeEffectToMap::ChargeEffectToMap(ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName), FilterClass(loggerName, this), m_pluginProvider(nullptr), m_notifyTimer(new QTimer(this))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->setInterval(100);
|
||||
m_notifyTimer->setSingleShot(true);
|
||||
connect(m_notifyTimer, &QTimer::timeout, this, &ChargeEffectToMap::updateAllNotifiedItems);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
ChargeEffectToMap::~ChargeEffectToMap()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " [ChargeEffectToMap] Dtor called! ";
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->removeChangedCallback(this);
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!pluginProvider)
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
auto fltAesIfc = pluginProvider->fltAesIfc();
|
||||
if (fltAesIfc)
|
||||
{
|
||||
m_displayFilter = fltAesIfc->aesFilterForOperator(pluginProvider->operatorId(), pluginProvider->workspaceId());
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->addChangedCallback(this);
|
||||
}
|
||||
|
||||
onAesDisplayFilterChanged(AreaEffectSimulation::AesType_def::AtExplosionArea);
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged, this, &ChargeEffectToMap::onPartitionTimeChanged, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::run()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " Starting to run";
|
||||
this->stop();
|
||||
if (!m_pluginProvider->aesDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider->aesDtc()->enableEffectCluster();
|
||||
m_pluginProvider->aesDtc()->enableChargeEffect();
|
||||
m_pluginProvider->aesDtc()->enableTrajectoryTimeAware();
|
||||
|
||||
connect(m_pluginProvider->aesDtc().get(),
|
||||
&AreaEffectSimulation::Interface::Dtc::chargeEffectChanged,
|
||||
this,
|
||||
&ChargeEffectToMap::onChargeEffectChanged,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
connect(m_pluginProvider->aesDtc().get(),
|
||||
&AreaEffectSimulation::Interface::Dtc::trajectoryTimeAwareChanged,
|
||||
this,
|
||||
&ChargeEffectToMap::onTracjectoryChanged,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
m_pluginProvider->aesDtc()->chargeEffects([this](const AreaEffectSimulation::ChargeEffect &data) { handleChanged(data, DataModification::eAdded); });
|
||||
|
||||
m_pluginProvider->aesDtc()->trajectoryTimeAwares([this](const AreaEffectSimulation::TrajectoryTimeAware &data)
|
||||
{ onTracjectoryChanged(data, DataModification::eAdded); });
|
||||
|
||||
onAesDisplayFilterChanged(AreaEffectSimulation::AesType_def::AtExplosionArea);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_pluginProvider->aesDtc())
|
||||
m_pluginProvider->aesDtc()->disconnect(this);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
if (!m_pluginProvider->aesInfoIfc())
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
for (int chargeEffectId : simIds)
|
||||
m_pluginProvider->aesInfoIfc()->showChargeEffectInfoWindow(chargeEffectId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
int ChargeEffectToMap::getPartyIdFromOriginator(const int originatorId, const int originatorType) const
|
||||
{
|
||||
int partyId = -1;
|
||||
switch (originatorType)
|
||||
{
|
||||
case ProjectDataManagement::StateChangeOriginator::Participant:
|
||||
{
|
||||
const auto &participant = m_pluginProvider->ppmDtc()->participant(originatorId);
|
||||
partyId = participant.partyId();
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::StateChangeOriginator::Party:
|
||||
{
|
||||
partyId = originatorId;
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation:
|
||||
{
|
||||
AreaEffectSimulation::AesItem aesItem;
|
||||
if (m_pluginProvider->aesDtc()->aesItemFromId(originatorId, aesItem))
|
||||
partyId = aesItem.partyId().get();
|
||||
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::StateChangeOriginator::DusMine:
|
||||
{
|
||||
partyId = m_pluginProvider->aesDtc()->partyForDusMine(originatorId);
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::StateChangeOriginator::Unknown:
|
||||
case ProjectDataManagement::StateChangeOriginator::ObserverController:
|
||||
case ProjectDataManagement::StateChangeOriginator::Initialization:
|
||||
case ProjectDataManagement::StateChangeOriginator::ExerciseControl:
|
||||
{
|
||||
partyId = 1;
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::StateChangeOriginator::ImprovisedExplosiveDevice:
|
||||
{
|
||||
auto guezIedDtc = m_pluginProvider->gimDtc();
|
||||
if (guezIedDtc)
|
||||
{
|
||||
const GuezIedManagement::Ied &gIed = guezIedDtc->iedForEquipmentNumber(originatorId);
|
||||
if (gIed.id() > 0)
|
||||
partyId = gIed.partyId();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ProjectDataManagement::StateChangeOriginator::WoundTreatmentDevice:
|
||||
case ProjectDataManagement::StateChangeOriginator::MedicalTimeout:
|
||||
case ProjectDataManagement::StateChangeOriginator::MaintainanceDevice:
|
||||
case ProjectDataManagement::StateChangeOriginator::Sanitation:
|
||||
default:
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " originator state change for " << originatorType << " not (yet) implemented >>> "
|
||||
<< ", originatorId = " << originatorId;
|
||||
break;
|
||||
}
|
||||
|
||||
return (partyId < 0) ? 0 : partyId;
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_pluginProvider->aesDtc())
|
||||
return false;
|
||||
int simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [simIdOut, &umodOut](const AreaEffectSimulation::ChargeEffect &data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
QString desc = QStringLiteral("id: %1\time: %2");
|
||||
umodOut.m_description1 = desc.arg(data.id()).arg(QDateTime::fromMSecsSinceEpoch(data.sampleTime()).toString());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
std::function<bool(const AreaEffectSimulation::ChargeEffect &data)> cb1 = cb;
|
||||
return m_pluginProvider->aesDtc()->chargeEffects(cb1);
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::onPartitionTimeChanged(qint64 newPartitionTime)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, newPartitionTime=" << newPartitionTime << ", exerciseId = " << m_pluginProvider->exerciseId()
|
||||
<< ", workspaceId = " << m_pluginProvider->workspaceId() << ", this=" << this;
|
||||
|
||||
updateAllTrajectories();
|
||||
updateAllChargeEffects();
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START ";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setPickable(true);
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
const int partyId = getPartyIdFromOriginator(ddsData.originatorId(), ddsData.originatorTypeId().underlying());
|
||||
mapObj->setPartyId(partyId);
|
||||
|
||||
|
||||
|
||||
|
||||
const bool bIsSmoke = m_pluginProvider->pdmDtc()->isSmoke(ddsData.chargeTypeId(), ddsData.igniterTypeId(), ddsData.igniterFunctionId());
|
||||
if (bIsSmoke)
|
||||
mapObj->forcePartyColor(Qt::darkYellow);
|
||||
|
||||
|
||||
const Core::GeoPosition &impactGeoPos = ddsData.position();
|
||||
const Point3D origin = LtsUtils::QPoint3D(impactGeoPos.lon(), impactGeoPos.lat(), impactGeoPos.z());
|
||||
double impactRadius = m_pluginProvider->pdmDtc()->impactRadius(ddsData.chargeTypeId(), ddsData.igniterTypeId(), ddsData.igniterFunctionId());
|
||||
if (impactRadius <= 5)
|
||||
impactRadius = 5;
|
||||
|
||||
const auto polygon = form2PosCont(AreaEffectSimulation::Polygons::circle(origin.toPointF(), impactRadius));
|
||||
mapObj->setPositions(polygon);
|
||||
|
||||
const AreaEffectSimulation::AesEffectState effectState = ddsData.state().underlying();
|
||||
mapObj->setAesState(effectState2aesState(effectState.underlying()));
|
||||
|
||||
|
||||
updateVisibility(mapObj, ddsData);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END ";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::isElapsed(const DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
Q_UNUSED(data)
|
||||
|
||||
bool bIsElapsed = false;
|
||||
return bIsElapsed;
|
||||
}
|
||||
|
||||
int32_t ChargeEffectToMap::getSimId(const DDS_T &ddsData) const { return ddsData.id(); }
|
||||
|
||||
bool ChargeEffectToMap::removeElement(const int32_t simId) { return BaseClass::removeElement(simId); }
|
||||
|
||||
bool ChargeEffectToMap::iterateAesData(const std::function<bool(const AreaEffectSimulation::ChargeEffect &)> &cb) const
|
||||
{
|
||||
if (!m_pluginProvider)
|
||||
return false;
|
||||
|
||||
return m_pluginProvider->aesDtc()->chargeEffects(cb);
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part)
|
||||
{
|
||||
if ((part != FilterManagement::SymbolAppearanceSettings::Part::All) && (part != FilterManagement::SymbolAppearanceSettings::Part::Symbol))
|
||||
return;
|
||||
|
||||
|
||||
const bool relevant = symbolAppearanceSettingsChangesAreRelevant(m_symbolAppearanceSettings->settings());
|
||||
|
||||
m_currentSymbolSettings = m_symbolAppearanceSettings->settings();
|
||||
|
||||
if (!relevant)
|
||||
return;
|
||||
|
||||
updateAllChargeEffects();
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "[symbolAppearanceSettingsChangesAreRelevant] : currSas.symScale: " << m_currentSymbolSettings.symbolSettings.symbolScale
|
||||
<< " newSas.symScale: " << newSas.symbolSettings.symbolScale;
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale)
|
||||
|| (m_currentSymbolSettings.symbolSettings.symbolPartyAppearance != newSas.symbolSettings.symbolPartyAppearance);
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
|
||||
const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId());
|
||||
const auto &data = m_pluginProvider->aesDtc()->chargeEffect(simId);
|
||||
if (data.id() <= 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "[handleSymbolAppearanceSettings] data id is invalid! mapObjUniqueId: " << mapObj->uniqueMapId();
|
||||
return;
|
||||
}
|
||||
|
||||
this->updateVisibility(mapObj, data);
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::updateAllChargeEffects()
|
||||
{
|
||||
const auto cb = [this](const Sim2SituationMap::DDS_T &data) -> bool
|
||||
{
|
||||
|
||||
|
||||
if (isElapsed(data))
|
||||
return false;
|
||||
|
||||
const UniqueMapId uniqueMapId = this->m_simId2UniqueMapId.value(data.id(), INVALID_MAP_ID);
|
||||
if (uniqueMapId == INVALID_MAP_ID)
|
||||
{
|
||||
WARNING_LOG(m_logger) << " [updateAllChargeEffects] !!! Found a ChargeEffect which is in internal map but has no map object...: data.id: " << data.id();
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
WARNING_LOG(m_logger) << " [updateAllChargeEffects] !!! invalid map object...: data.id: " << data.id();
|
||||
return false;
|
||||
}
|
||||
this->updateVisibility(mapObj, data);
|
||||
return false;
|
||||
};
|
||||
iterateAesData(cb);
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::updateVisibility(RefPointer<MAP_T> &mapObj, const Sim2SituationMap::DDS_T &data)
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
const bool isVisi = isVisible(data);
|
||||
INFO_LOG(m_logger) << " [updateVisibility]: >> data.id: " << data.id() << " is visible? " << isVisi;
|
||||
|
||||
if (isVisi)
|
||||
{
|
||||
updateGunToTargetLine_SimpleOnSurface(mapObj, data);
|
||||
|
||||
|
||||
updateAllTrajectories();
|
||||
|
||||
updateImpacts2D3D(mapObj, data);
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
updateDetonation3D(mapObj, data, isVisi);
|
||||
}
|
||||
|
||||
mapObj->setScale(filterSettings.symbolSettings.symbolScale);
|
||||
mapObj->setVisibility(isVisi);
|
||||
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChargeEffectToMap::updateGunToTargetLine_SimpleOnSurface(RefPointer<MAP_T> &mapObj, const DDS_T &data)
|
||||
{
|
||||
const Core::GeoPosition2D &impactPos2D = data.position();
|
||||
const Point3D origin = LtsUtils::QPoint3D(impactPos2D.lon(), impactPos2D.lat(), .0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool bDisplayFilterShowGTL = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowGTL = m_displayFilter->showExplosionClusterGunToTargetLine();
|
||||
|
||||
if (bDisplayFilterShowGTL)
|
||||
{
|
||||
|
||||
Point3D originatorPos;
|
||||
Point3D targetPos;
|
||||
if (data.originatorTypeId() == ProjectDataManagement::StateChangeOriginator::Participant)
|
||||
{
|
||||
const auto &ppPos = m_pluginProvider->ppmDtc()->participantPosition(data.originatorId());
|
||||
originatorPos = Point3D(ppPos.pos().lon(), ppPos.pos().lat(), ppPos.pos().z());
|
||||
targetPos = origin;
|
||||
}
|
||||
mapObj->setGunToTargetLineSurface(originatorPos, targetPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapObj->setGunToTargetLineSurface(Point3D(), Point3D());
|
||||
}
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::updateSingleTrajectory(const AreaEffectSimulation::TrajectoryTimeAware &traj, bool considerTime)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
if (traj.originatorTypeId() != ProjectDataManagement::StateChangeOriginator::ChargeEffect)
|
||||
return false;
|
||||
|
||||
const int32_t simId = traj.originatorId();
|
||||
if (!m_simId2UniqueMapId.contains(simId))
|
||||
return false;
|
||||
|
||||
|
||||
bool bDisplayFilterShowTRJ = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowTRJ = m_displayFilter->showExplosionClusterTrajectory();
|
||||
|
||||
|
||||
const qint64 partitionTimeMsec = m_pluginProvider->partitionTime();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START "
|
||||
<< ", simId=" << simId << ", traj=" << traj << ", considerTime=" << considerTime
|
||||
<< ", partitionTimeMsec - traj.trajectoryStartTime() = " << partitionTimeMsec - traj.trajectoryStartTime();
|
||||
|
||||
if (traj.trajectoryStartTime() > partitionTimeMsec)
|
||||
return false;
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " getMapObjectOfSimId failed"
|
||||
<< " simId=" << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bHasChanged = false;
|
||||
|
||||
const bool moIsVisibleByFilter = true;
|
||||
const int index = 0;
|
||||
|
||||
if (bDisplayFilterShowTRJ && moIsVisibleByFilter)
|
||||
{
|
||||
|
||||
|
||||
const std::vector<Core::GeoPositionRelativeTime> &geometry = traj.geometry();
|
||||
const PositionCont &curPath = mapObj->trajectory(index);
|
||||
if (geometry.size() > static_cast<size_t>(curPath.size()))
|
||||
{
|
||||
|
||||
PositionCont posCont;
|
||||
posCont.reserve(geometry.size());
|
||||
for (const Core::GeoPositionRelativeTime &posTime : qAsConst(geometry))
|
||||
{
|
||||
if (considerTime && ((traj.trajectoryStartTime() + posTime.relativeTime()) > partitionTimeMsec))
|
||||
break;
|
||||
posCont.append(Point3D(posTime.lon(), posTime.lat(), posTime.z()));
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "update trajectory, simId=" << simId << ", index=" << index << ", posCont.size() " << posCont.size();
|
||||
|
||||
if (posCont.size() == 1)
|
||||
posCont.clear();
|
||||
bHasChanged = mapObj->setTrajectory(index, posCont);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bHasChanged = mapObj->setTrajectory(index, {});
|
||||
}
|
||||
|
||||
if (bHasChanged)
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::updateAllTrajectories()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef BENCHMARK_ALL_TRAC
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " trajectoryTimeAwares took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_uniqueMapIdsToUpdate.size() << ", size "
|
||||
<< m_aesDtc->trajectoryTimeAwares().size()
|
||||
#endif
|
||||
|
||||
|
||||
auto cb
|
||||
= [this](const AreaEffectSimulation::TrajectoryTimeAware &traj) { updateSingleTrajectory(traj); };
|
||||
m_pluginProvider->aesDtc()->trajectoryTimeAwares(cb);
|
||||
|
||||
#ifdef BENCHMARK_ALL_TRAC
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " All took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_uniqueMapIdsToUpdate.size() << ", size "
|
||||
<< m_aesDtc->trajectoryTimeAwares().size()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
TRACE_LOG(m_logger)
|
||||
<< LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::updateImpacts2D3D(RefPointer<MAP_T> &mapObj, const DDS_T &data)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
static QVector<AreaEffectSimulation::AesEffectState_def::type> relevantEffectStates
|
||||
= {AreaEffectSimulation::AesEffectState_def::EsActivated, AreaEffectSimulation::AesEffectState_def::EsFired};
|
||||
|
||||
|
||||
const bool bDisplayDueToEffectState = relevantEffectStates.contains(data.state().underlying());
|
||||
|
||||
if (bDisplayDueToEffectState)
|
||||
{
|
||||
|
||||
const Core::GeoPosition &impactGeoPos = data.position();
|
||||
const Point3D &origin = LtsUtils::QPoint3D(impactGeoPos.lon(), impactGeoPos.lat(), impactGeoPos.z());
|
||||
|
||||
const Core::ZReference zReference = data.zReference();
|
||||
switch (zReference.underlying())
|
||||
{
|
||||
case Core::ZReference_def::ZrDrapedOnGround:
|
||||
mapObj->setImpacts({origin});
|
||||
break;
|
||||
case Core::ZReference_def::ZrUndefined:
|
||||
case Core::ZReference_def::ZrAbsolute:
|
||||
mapObj->setImpactsAbsoluteHeight({origin});
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " ZReference not supported";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::updateDetonation3D(RefPointer<MAP_T> &mapObj, const DDS_T &data, bool isChargeEffectVisible)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START ";
|
||||
|
||||
const int32_t simId = data.id();
|
||||
const AreaEffectSimulation::AesEffectState effectState = data.state();
|
||||
|
||||
bool bHasChanged = false;
|
||||
|
||||
|
||||
|
||||
bool bDisplay = isChargeEffectVisible;
|
||||
const qint64 partitionTimeMsec = m_pluginProvider->partitionTime();
|
||||
|
||||
|
||||
if (bDisplay && m_displayFilter)
|
||||
bDisplay = m_displayFilter->showExplosionClusterDetonationSphere();
|
||||
|
||||
|
||||
|
||||
|
||||
static QVector<AreaEffectSimulation::AesEffectState_def::type> relevantEffectStates
|
||||
= {AreaEffectSimulation::AesEffectState_def::EsActivated, AreaEffectSimulation::AesEffectState_def::EsFired, AreaEffectSimulation::AesEffectState_def::EsExpired};
|
||||
|
||||
bDisplay = bDisplay && relevantEffectStates.contains(effectState.underlying());
|
||||
|
||||
const qint64 age = partitionTimeMsec - data.effectStart() + data.effectDuration();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId << ", bDisplay=" << bDisplay<<" effectState: "<<data.state()<<" age[msec]: "<<age;
|
||||
|
||||
if (bDisplay && age <= s_effect3dMaxDisplayDuration)
|
||||
{
|
||||
double impactRadius = m_pluginProvider->pdmDtc()->impactRadius(data.chargeTypeId(), data.igniterTypeId(), data.igniterFunctionId());
|
||||
if (impactRadius <= 5)
|
||||
impactRadius = 5;
|
||||
|
||||
const Core::GeoPosition &effectGeoPos = data.position();
|
||||
const Point3D &origin = Point3D(effectGeoPos.lon(), effectGeoPos.lat(), effectGeoPos.z());
|
||||
const Core::ZReference &zRef = data.zReference();
|
||||
|
||||
switch (zRef.underlying())
|
||||
{
|
||||
case Core::ZReference_def::ZrDrapedOnGround:
|
||||
if (mapObj->setDetonationsDraped({origin}, std::round(impactRadius)))
|
||||
bHasChanged = true;
|
||||
break;
|
||||
case Core::ZReference_def::ZrUndefined:
|
||||
case Core::ZReference_def::ZrAbsolute:
|
||||
if (mapObj->setDetonationsAbsolute({origin}, std::round(impactRadius)))
|
||||
bHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " ZReference not supported";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mapObj->setDetonationsDraped({}, 1))
|
||||
bHasChanged = true;
|
||||
if (mapObj->setDetonationsAbsolute({}, 1))
|
||||
bHasChanged = true;
|
||||
}
|
||||
|
||||
|
||||
if (bHasChanged)
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END ";
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::isVisible(const DDS_T &data) const
|
||||
{
|
||||
bool isVisible = visibleBySymbolPartyAppearance(data) && visibleByAesFilter(data);
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::visibleBySymbolPartyAppearance(const DDS_T &data) const
|
||||
{
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
const int partyId = getPartyIdFromOriginator(data.originatorId(), data.originatorTypeId().underlying());
|
||||
const auto spa = filterSettings.symbolSettings.symbolPartyAppearance.value(partyId);
|
||||
return spa.isVisible;
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::visibleByAesFilter(const DDS_T &data) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
switch (data.state().underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesEffectState_def::EsError:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsUnknown:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsRemoved:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsReceived:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsFired:
|
||||
DEBUG_LOG(m_logger) << "[visibleByAesFilter] set unvisible id: " << data.id() << ", state:" << data.state();
|
||||
return false;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsCreated:
|
||||
DEBUG_LOG(m_logger) << "[visibleByAesFilter][EsCreated] created visible: " << m_effectStateStruct.displayCreated;
|
||||
return m_effectStateStruct.displayCreated;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsPrepared:
|
||||
DEBUG_LOG(m_logger) << "[visibleByAesFilter][EsPrepared] prepared visible? " << m_effectStateStruct.displayPrepared;
|
||||
return m_effectStateStruct.displayPrepared;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsActivated:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsPaused:
|
||||
DEBUG_LOG(m_logger) << "[visibleByAesFilter] [active/paused] visible? " << m_effectStateStruct.displayActivated;
|
||||
return m_effectStateStruct.displayActivated;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsExpired:
|
||||
{
|
||||
auto timeTriggered = data.sampleTime();
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionClusterSingleExplosions);
|
||||
const auto afterGlow = m_effectStateStruct.expiredAfterglowDurationMSec;
|
||||
DEBUG_LOG(m_logger) << "[visibleByAesFilter] [EsExpired] >>> partitionTime: " << m_pluginProvider->partitionTime() << " timeTriggered: " << timeTriggered
|
||||
<< " afterGlow: " << afterGlow << " timeTriggered + afterGlow: " << timeTriggered + afterGlow;
|
||||
|
||||
return (m_pluginProvider->partitionTime() < timeTriggered + afterGlow);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "[ChargeEffectToMap] onAesDisplayFilterChanged aes Type: " << aesType;
|
||||
if (!m_displayFilter
|
||||
|| ((AreaEffectSimulation::AesType_def::AtExplosionCluster != aesType.underlying())
|
||||
&& (AreaEffectSimulation::AesType_def::AtExplosionArea != aesType.underlying())))
|
||||
return;
|
||||
|
||||
m_effectStateStruct = m_displayFilter->effectStateFilter(AreaEffectSimulation::AesType_def::AtExplosionArea);
|
||||
|
||||
|
||||
updateAllChargeEffects();
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::onChargeEffectChanged(const DDS_T &data, DataModification modType)
|
||||
{
|
||||
INFO_LOG(m_logger) << "[onChargeEffectChanged] >>> " << data.id() << " name: " << data.name() << " originId: " << data.originatorId()
|
||||
<< " originTypeId: " << data.originatorTypeId().underlying() << " chargeTypeId: " << data.chargeTypeId() << " state: " << data.state();
|
||||
this->handleChanged(data, modType);
|
||||
}
|
||||
|
||||
bool ChargeEffectToMap::onTracjectoryChanged(const AreaEffectSimulation::TrajectoryTimeAware &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, modType=" << modType;
|
||||
|
||||
Q_UNUSED(modType);
|
||||
|
||||
updateSingleTrajectory(data);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, modType=" << modType;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::updateAllNotifiedItems()
|
||||
{
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
std::string localLoggerName = m_logger.getLoggerName() + ".update";
|
||||
LOGGER_T logger = m_logger.getNGLLogger(localLoggerName);
|
||||
|
||||
INFO_LOG(logger) << LOGFUNCTION << " m_uniqueMapIdsToUpdate.size() = " << m_uniqueMapIdsToUpdate.size();
|
||||
|
||||
for (int uniqueMapId : qAsConst(m_uniqueMapIdsToUpdate))
|
||||
{
|
||||
|
||||
if (!m_uniqueMapId2SimId.contains(uniqueMapId))
|
||||
continue;
|
||||
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed for " << mapObj->debugInfo();
|
||||
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_uniqueMapIdsToUpdate.size()=" << m_uniqueMapIdsToUpdate.size();
|
||||
|
||||
#ifdef BENCHMARK_ALL_NOTIFIED
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_uniqueMapIdsToUpdate.size();
|
||||
#endif
|
||||
|
||||
m_uniqueMapIdsToUpdate.clear();
|
||||
}
|
||||
|
||||
void ChargeEffectToMap::addUniqueMapIdToNotifiy(int uniqueMapId, const char *file, int lineNo)
|
||||
{
|
||||
std::string localLoggerName = m_logger.getLoggerName() + ".update";
|
||||
LOGGER_T logger = m_logger.getNGLLogger(localLoggerName);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
const int simId = m_uniqueMapId2SimId.value(uniqueMapId, -1);
|
||||
DEBUG_LOG(logger) << "START ******* addUniqueMapIdToNotifiy: uniqueMapId = " << uniqueMapId << " (simId=" << simId << "), caller= " << file << ":" << lineNo;
|
||||
}
|
||||
|
||||
if (uniqueMapId > 0)
|
||||
m_uniqueMapIdsToUpdate.insert(uniqueMapId);
|
||||
if (!m_notifyTimer->isActive())
|
||||
m_notifyTimer->start();
|
||||
}
|
||||
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_data_plugin_aes_display_filter.h>
|
||||
#include <MapObjects/area_fire.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PdmHandler;
|
||||
|
||||
|
||||
|
||||
class ChargeEffectToMap final : public Sim2SituationMap<AreaEffectSimulation::ChargeEffect, SituationMap::AreaFire>
|
||||
, protected FilterManagement::AesDisplayFilter::FilterChangedCallback
|
||||
, protected DdsFilterHandling<SituationMap::AreaFire>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<AreaEffectSimulation::ChargeEffect, SituationMap::AreaFire>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::AreaFire>;
|
||||
|
||||
public:
|
||||
|
||||
explicit ChargeEffectToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
~ChargeEffectToMap();
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
int getPartyIdFromOriginator(const int originatorId, const int originatorType) const;
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer<MAP_T> mapObj) override;
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool removeElement(const int32_t simId) override;
|
||||
bool iterateAesData(const std::function<bool (const AreaEffectSimulation::ChargeEffect &)> &cb) const;
|
||||
|
||||
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) override;
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
void updateAllChargeEffects();
|
||||
void updateVisibility(RefPointer<MAP_T> &mapObj, const DDS_T &data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void updateGunToTargetLine_SimpleOnSurface(RefPointer<MAP_T> &mapObj, const DDS_T &data);
|
||||
bool updateSingleTrajectory(const AreaEffectSimulation::TrajectoryTimeAware &traj, bool considerTime = true);
|
||||
void updateAllTrajectories();
|
||||
void updateImpacts2D3D(RefPointer<MAP_T> &mapObj, const DDS_T &data);
|
||||
void updateDetonation3D(RefPointer<MAP_T> &mapObj, const DDS_T &data, bool isChargeEffectVisible = true);
|
||||
|
||||
bool isVisible(const Sim2SituationMap::DDS_T &data) const;
|
||||
bool visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &data) const;
|
||||
bool visibleByAesFilter(const Sim2SituationMap::DDS_T &data) const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
void onChargeEffectChanged(const DDS_T &data, DataModification modType);
|
||||
bool onTracjectoryChanged(const AreaEffectSimulation::TrajectoryTimeAware &data, DataModification modType);
|
||||
|
||||
void updateAllNotifiedItems();
|
||||
void addUniqueMapIdToNotifiy(int uniqueMapId, const char *file, int lineNo);
|
||||
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
|
||||
|
||||
protected:
|
||||
PluginProvider *m_pluginProvider;
|
||||
std::shared_ptr<FilterManagement::AesDisplayFilter> m_displayFilter;
|
||||
FilterManagement::AesDisplayFilter::EffectStateStruct m_effectStateStruct;
|
||||
|
||||
QTimer *m_notifyTimer{nullptr};
|
||||
QSet<int> m_uniqueMapIdsToUpdate;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
|
||||
#include "danger_area_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool DangerArea2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::dangerAreaChanged,
|
||||
this, &DangerArea2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->dangerAreas([this](const AreaEffectSimulation::DangerArea & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool DangerArea2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtDangerArea, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtDangerArea) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/danger_area.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class DangerArea2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<DangerArea2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::DangerArea;
|
||||
using MAP_TYPE = SituationMap::DangerArea;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtDangerArea;
|
||||
};
|
||||
|
||||
class DangerArea2SituationMap final : public Aes2SituationMap<DangerArea2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<DangerArea2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::DangerArea &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->dangerAreas(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
|
||||
|
||||
|
||||
#include "dus_single_mine_to_map.h"
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <AreaEffectSimulation/Utils/ddsdbconvert.h>
|
||||
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
#include <SituationMap/Symbology/sidc_codec.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool DusSingleMine2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::dusSingleMineChanged,
|
||||
this, &DusSingleMine2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->dusSingleMines([this](const AreaEffectSimulation::DusSingleMine & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool DusSingleMine2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
auto sp = m_aesInfoIfc.lock();
|
||||
if (!sp)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = this->uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
sp->showInfoWindow(simIds, Aes2SituationMapTraits<DusSingleMine2SituationMap>::aesType);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DusSingleMine2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
umodOut = UnifiedMapObjectData();
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_symDataToRender = mapObj->symbolDataToRender();
|
||||
|
||||
const std::function<bool(const AreaEffectSimulation::DusSingleMine &data)> cb = [simIdOut, &umodOut](const AreaEffectSimulation::DusSingleMine & data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
|
||||
umodOut.m_description2 = QString::number(data.mineId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return m_aesDtc->dusSingleMines(cb);
|
||||
}
|
||||
|
||||
bool DusSingleMine2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SymbolData symData;
|
||||
symData.sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapObj->symbologyType(), "10011500002103000000");
|
||||
|
||||
symData.color = Qt::yellow;
|
||||
symData.size = 1.0;
|
||||
mapObj->setSymbol(symData);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setOrigin(Point3D(ddsData.position().lon(), ddsData.position().lat(), .0));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setTextModifier(Participant::TextModifier::M_HigherFormation, QString::number(ddsData.mineId()));
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DusSingleMine2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.symbolTransparency != newSas.symbolSettings.symbolTransparency)
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
void DusSingleMine2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setUserSymbolOpacity(1.0f - m_currentSymbolSettings.symbolSettings.symbolTransparency);
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/participant.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class DusSingleMine2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<DusSingleMine2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::DusSingleMine;
|
||||
using MAP_TYPE = SituationMap::Participant;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtDusSingleMine;
|
||||
};
|
||||
|
||||
class DusSingleMine2SituationMap final : public Aes2SituationMap<DusSingleMine2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<DusSingleMine2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const DDS_TYPE &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->dusSingleMines(cb);
|
||||
}
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool updateSingleMines(const int simId,
|
||||
RefPointer<MAP_T> mapObj);
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+592
@@ -0,0 +1,592 @@
|
||||
|
||||
|
||||
|
||||
#include "effect_cluster_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <Map/map.h>
|
||||
|
||||
#define ADD_UNIQUE_MAP_ID_TO_NOTIFIY(uniqueMapId) addUniqueMapIdToNotifiy(uniqueMapId, __FILE__, __LINE__)
|
||||
|
||||
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# define BENCHMARK_SETUP_AND_START() QElapsedTimer elapsedTimer; elapsedTimer.start();
|
||||
|
||||
# define BENCHMARK_RUN
|
||||
|
||||
|
||||
# define BENCHMARK_ALL_NOTIFIED
|
||||
|
||||
#else
|
||||
# define BENCHMARK_SETUP_AND_START()
|
||||
#endif
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
EffectCluster2SituationMap::EffectCluster2SituationMap(PdmHandler *pdmHandler, ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, m_notifyTimer(new QTimer(this))
|
||||
, m_pdmHandler(pdmHandler)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->setInterval(100);
|
||||
m_notifyTimer->setSingleShot(true);
|
||||
connect(m_notifyTimer, &QTimer::timeout,
|
||||
this, &EffectCluster2SituationMap::updateAllNotifiedItems);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
EffectCluster2SituationMap::~EffectCluster2SituationMap()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->stop();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::run()
|
||||
{
|
||||
|
||||
QTimer::singleShot(1000, this, &EffectCluster2SituationMap::runDelayed);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::runDelayed()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::effectClusterChanged,
|
||||
this, &EffectCluster2SituationMap::onEffectClusterChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &EffectCluster2SituationMap::onAesItemViewChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->effectClusters([this](const AreaEffectSimulation::EffectCluster &data)
|
||||
{
|
||||
onEffectClusterChanged(data, DataModification::eAdded);
|
||||
});
|
||||
#ifdef BENCHMARK_RUN
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " EffectClusters took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK_RUN
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " trajectoryTimeAwares took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK_RUN
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " all took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
|
||||
void EffectCluster2SituationMap::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->stop();
|
||||
if (m_aesDtc)
|
||||
m_aesDtc->disconnect(this);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::updateVisibility(const Aes2SituationMap::DDS_TYPE &ddsData, RefPointer<Aes2SituationMap::MAP_TYPE> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << getSimId(ddsData);
|
||||
if (!BaseClass::updateVisibility(ddsData, mapObj))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " BaseClass::updateVisibility failed, simId=" << getSimId(ddsData);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
const AreaEffectSimulation::AesEffectState effectState = ddsData.effectStateId().underlying();
|
||||
|
||||
bool bIsMode3D = false;
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
bIsMode3D = true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool bDisplayFilterShowGTL = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowGTL = m_displayFilter->showExplosionClusterGunToTargetLine();
|
||||
const bool bDisplayFilterShowGFK = bDisplayFilterShowGTL && bIsMode3D
|
||||
;
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemViewGunToTargetLine;
|
||||
const std::vector<Core::GeoPosition>& form = itemViewGunToTargetLine.form();
|
||||
if (bDisplayFilterShowGTL || bDisplayFilterShowGFK)
|
||||
m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtEffectClusterGunToTargetLine, itemViewGunToTargetLine);
|
||||
|
||||
|
||||
if (bDisplayFilterShowGTL && (form.size() >= 2))
|
||||
mapObj->setGunToTargetLineSurface(Point3D(form.front().lon(), form.front().lat(), 0.0),
|
||||
Point3D(form.back().lon() , form.back().lat() , 0.0));
|
||||
else
|
||||
mapObj->setGunToTargetLineSurface(Point3D(), Point3D());
|
||||
|
||||
|
||||
if (bIsMode3D)
|
||||
{
|
||||
if (bDisplayFilterShowGFK)
|
||||
{
|
||||
|
||||
PositionCont gunToTargetPath;
|
||||
gunToTargetPath.reserve(static_cast<int>(form.size()));
|
||||
for (const Core::GeoPosition& item : qAsConst(form))
|
||||
gunToTargetPath.append(Point3D(item.lon(), item.lat(), item.z()));
|
||||
|
||||
mapObj->setGunToTargetTrajectory3D(gunToTargetPath);
|
||||
} else {
|
||||
mapObj->setGunToTargetTrajectory3D({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
bool bDisplayFilterShowMHP = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowMHP = m_displayFilter->showExplosionClusterMeanHitPoint();
|
||||
|
||||
PositionCont mhps;
|
||||
mhps.reserve(static_cast<int>(ddsData.effectors().size()));
|
||||
for (const auto &effector : qAsConst(ddsData.effectors()))
|
||||
{
|
||||
const Core::GeoPosition &mhpPos = effector.mhpPosition();
|
||||
mhps.append(Point3D(mhpPos.lon(), mhpPos.lat(), mhpPos.z()));
|
||||
}
|
||||
if (bDisplayFilterShowMHP)
|
||||
{
|
||||
|
||||
|
||||
|
||||
QColor impactsColor;
|
||||
const auto &chargeStruct = ddsData.chargeStruct();
|
||||
const bool bIsSmoke = m_pluginProvider->pdmDtc()->isSmoke(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId());
|
||||
if (bIsSmoke)
|
||||
impactsColor = Qt::darkYellow;
|
||||
mapObj->setScheduledImpacts(mhps, impactsColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapObj->setScheduledImpacts({});
|
||||
}
|
||||
}
|
||||
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
const AreaEffectSimulation::AesEffectState effectState = ddsData.effectStateId().underlying();
|
||||
mapObj->setAesState(effectState2aesState(effectState));
|
||||
|
||||
|
||||
|
||||
LineStyle ls = mapObj->lineStyle();
|
||||
ls.setLinePattern(LinePattern::Solid);
|
||||
mapObj->setLineStyle(ls);
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " part1 took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtEffectCluster, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtEffectCluster) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " aesItemViewFromEntityId took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " updateAllTracjectories took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " all took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::updateGeometry(const AreaEffectSimulation::AesItemView &aesItemView, RefPointer<AreaFire> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
|
||||
const int simId = aesItemView.aesItemId();
|
||||
auto it = m_ddsDataContainer.find(simId);
|
||||
if (it != m_ddsDataContainer.end())
|
||||
updateNonLethalArea(mapObj, *it, aesItemView);
|
||||
|
||||
return BaseClass::updateGeometry(aesItemView, mapObj);
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::removeElement(const int32_t simId)
|
||||
{
|
||||
return BaseClass::removeElement(simId);
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &aesItemView, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int simId = aesItemView.aesItemId();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (aesItemView.aesTypeId() == AreaEffectSimulation::AesType::AtEffectClusterGunToTargetLine)
|
||||
{
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (mapObj.valid())
|
||||
updateVisibility(m_ddsDataContainer.value(simId), mapObj);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool EffectCluster2SituationMap::updateGunToTargetLineAndTrajectory(const AreaEffectSimulation::AesItemView &itemView,
|
||||
RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
const std::vector<Core::GeoPosition>& formRef = itemView.form();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, form.size = " << formRef.size();
|
||||
|
||||
if (formRef.size() >= 2)
|
||||
{
|
||||
mapObj->setGunToTargetLineSurface(Point3D(formRef.front().lon(), formRef.front().lat(), 0.0),
|
||||
Point3D(formRef.back().lon() , formRef.back().lat() , 0.0));
|
||||
} else {
|
||||
|
||||
mapObj->setGunToTargetLineSurface(Point3D(), Point3D());
|
||||
}
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
{
|
||||
|
||||
PositionCont gunToTargetPath;
|
||||
gunToTargetPath.reserve(static_cast<int>(formRef.size()));
|
||||
for (const Core::GeoPosition& item : qAsConst(formRef))
|
||||
gunToTargetPath.append(Point3D(item.lon(), item.lat(), item.z()));
|
||||
|
||||
mapObj->setGunToTargetTrajectory3D(gunToTargetPath);
|
||||
}
|
||||
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
PositionCont circleE(const QPointF ¢er_geo, qreal radius, int steps= 72)
|
||||
{
|
||||
const LtsCoordTrans::UtmCoordinate ¢erUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(center_geo);
|
||||
PositionCont poly;
|
||||
if (steps < 6)
|
||||
steps = 6;
|
||||
poly.reserve(steps);
|
||||
for (int i = 0; i < 360; i += (360 / steps))
|
||||
{
|
||||
double angle = double(i) * LtsCoordTrans::deg2rad();
|
||||
const QPointF &pointGeo = centerUtm.geographic(QPointF(cos(angle) * radius, sin(angle) * radius));
|
||||
poly.push_back(Point3D(pointGeo.x(), pointGeo.y(), 0.0));
|
||||
}
|
||||
return poly;
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj,
|
||||
const AreaEffectSimulation::EffectCluster &EffectCluster,
|
||||
const AreaEffectSimulation::AesItemView &aesItemView)
|
||||
{
|
||||
if (!m_pdmHandler)
|
||||
return false;
|
||||
|
||||
if (EffectCluster.id() != aesItemView.aesItemId())
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int chargeTypeId = EffectCluster.chargeStruct().chargeTypeId();
|
||||
const ProjectDataManagement::GearClass &gc = m_pdmHandler->gearClassFromChargeTypeId(chargeTypeId);
|
||||
if (gc.underlying() == ProjectDataManagement::GearClass_def::AirSupport)
|
||||
{
|
||||
const QVector<ProjectDataManagement::CasEffect> &casEffectsVec = m_pdmHandler->casEffects(EffectCluster.chargeStruct());
|
||||
|
||||
|
||||
|
||||
if (casEffectsVec.size() >= 2)
|
||||
{
|
||||
const ProjectDataManagement::CasEffect &ce = casEffectsVec[1];
|
||||
|
||||
|
||||
const double impactRadius = ce.impactRadius();
|
||||
|
||||
const AreaEffectSimulation::Area &areaRef = EffectCluster.area();
|
||||
|
||||
const Core::GeoPosition2D &blGeo = aesItemView.boundingBoxBottomLeft();
|
||||
const QPointF ¢erGeo = AreaEffectSimulation::Polygons::bottomLeft2CenterPoint(QPointF(blGeo.lon(), blGeo.lat()),
|
||||
areaRef.width(), areaRef.height(), areaRef.rotation());
|
||||
|
||||
updateNonLethalArea(mapObj, centerGeo, impactRadius);
|
||||
}
|
||||
} else {
|
||||
updateNonLethalArea(mapObj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EffectCluster2SituationMap::updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj, const QPointF ¢erGeo, double radius)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, radius = " << radius;
|
||||
|
||||
if (!mapObj)
|
||||
return false;
|
||||
|
||||
if (radius <= 0)
|
||||
{
|
||||
mapObj->setNonLethalArea({});
|
||||
} else {
|
||||
const PositionCont &nonLethalAreaPolygon = circleE(centerGeo, radius);
|
||||
mapObj->setNonLethalArea(nonLethalAreaPolygon);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void EffectCluster2SituationMap::updateAllNotifiedItems()
|
||||
{
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
std::string localLoggerName = m_logger.getLoggerName() + ".update";
|
||||
LOGGER_T logger = m_logger.getNGLLogger(localLoggerName);
|
||||
|
||||
INFO_LOG(logger) << LOGFUNCTION << " m_uniqueMapIdsToUpdate.size() = " << m_uniqueMapIdsToUpdate.size();
|
||||
|
||||
for (int uniqueMapId : qAsConst(m_uniqueMapIdsToUpdate))
|
||||
{
|
||||
|
||||
if (!m_uniqueMapId2SimId.contains(uniqueMapId))
|
||||
continue;
|
||||
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed for "<< mapObj->debugInfo();
|
||||
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_uniqueMapIdsToUpdate.size()=" << m_uniqueMapIdsToUpdate.size();
|
||||
|
||||
#ifdef BENCHMARK_ALL_NOTIFIED
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " took " << elapsedTimer.elapsed() << " [ms]" << ", size " << m_uniqueMapIdsToUpdate.size();
|
||||
#endif
|
||||
|
||||
m_uniqueMapIdsToUpdate.clear();
|
||||
}
|
||||
|
||||
|
||||
void EffectCluster2SituationMap::addUniqueMapIdToNotifiy(int uniqueMapId, const char *file, int lineNo)
|
||||
{
|
||||
std::string localLoggerName = m_logger.getLoggerName() + ".update";
|
||||
LOGGER_T logger = m_logger.getNGLLogger(localLoggerName);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
const int simId = m_uniqueMapId2SimId.value(uniqueMapId, -1);
|
||||
DEBUG_LOG(logger) << "START ******* addUniqueMapIdToNotifiy: uniqueMapId = " << uniqueMapId << " (simId=" << simId << "), caller= " << file << ":" << lineNo;
|
||||
}
|
||||
|
||||
if (uniqueMapId > 0)
|
||||
m_uniqueMapIdsToUpdate.insert(uniqueMapId);
|
||||
if (!m_notifyTimer->isActive())
|
||||
m_notifyTimer->start();
|
||||
}
|
||||
|
||||
AreaEffectSimulation::AesType EffectCluster2SituationMap::aesTypeFromGearClassChargeType(const DDS_TYPE &data)const
|
||||
{
|
||||
static QMap<int, AreaEffectSimulation::AesType> s_aesTypeMap;
|
||||
|
||||
if (s_aesTypeMap.contains(data.chargeStruct().chargeTypeId()))
|
||||
return s_aesTypeMap[data.chargeStruct().chargeTypeId()];
|
||||
|
||||
const ProjectDataManagement::GearClass &gc = m_pdmHandler->gearClassFromChargeTypeId(data.chargeStruct().chargeTypeId());
|
||||
switch (gc.underlying())
|
||||
{
|
||||
case ProjectDataManagement::GearClass::AirSupport:
|
||||
s_aesTypeMap[data.chargeStruct().chargeTypeId()] = AreaEffectSimulation::AesType::AtAirSupportImpact;
|
||||
break;
|
||||
case ProjectDataManagement::GearClass::Artillery:
|
||||
case ProjectDataManagement::GearClass::Mortar:
|
||||
case ProjectDataManagement::GearClass::Rocket:
|
||||
s_aesTypeMap[data.chargeStruct().chargeTypeId()] = AreaEffectSimulation::AesType::AtExplosionArea;
|
||||
break;
|
||||
default:
|
||||
return AreaEffectSimulation::AesType::AtUnknown;
|
||||
}
|
||||
return s_aesTypeMap[data.chargeStruct().chargeTypeId()];
|
||||
}
|
||||
|
||||
void EffectCluster2SituationMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << " onAesDisplayFilterChanged, aesType =" << aesType
|
||||
<< ", this " << this;
|
||||
|
||||
if ((AreaEffectSimulation::AesType_def::AtEffectCluster != aesType.underlying()) &&
|
||||
(AreaEffectSimulation::AesType_def::AtExplosionArea != aesType.underlying()) &&
|
||||
(AreaEffectSimulation::AesType_def::AtAirSupportImpact != aesType.underlying()))
|
||||
return;
|
||||
|
||||
const auto cb = [this](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (isElapsed(data))
|
||||
return false;
|
||||
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
iterateAesData(cb);
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::isVisibleByFilter(const Aes2SituationMap::DDS_TYPE &data) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
const auto es = data.effectStart().is_set() ? data.effectStart().get() : 0;
|
||||
const auto partyId = data.partyId().is_set() ? data.partyId().get() : -1;
|
||||
bool isVisibleByFilter = partyId > 0 ? FilterClass::m_currentSymbolSettings.symbolSettings.symbolPartyAppearance.value(partyId).isVisible : true;
|
||||
if (isVisibleByFilter)
|
||||
{
|
||||
AreaEffectSimulation::AesType aestype = aesTypeFromGearClassChargeType(data);
|
||||
if (aestype == AreaEffectSimulation::AesType::AtUnknown)
|
||||
{
|
||||
WARNING_LOG(m_logger) << " Only AES TYPE explosion Cluster, AirSupportImpact, Explosion area will be displayed";
|
||||
aestype = AreaEffectSimulation::AesType::AtExplosionArea;
|
||||
}
|
||||
|
||||
isVisibleByFilter = m_displayFilter->isVisible(aestype,
|
||||
data.effectStateId(),
|
||||
data.chargeStruct().chargeTypeId(),
|
||||
partyId,
|
||||
data.isCentral(),
|
||||
es,
|
||||
data.effectDuration(),
|
||||
m_pluginProvider->partitionTime());
|
||||
}
|
||||
|
||||
return isVisibleByFilter;
|
||||
}
|
||||
|
||||
bool EffectCluster2SituationMap::onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &EffectCluster, DataModification modType)
|
||||
{
|
||||
updateDdsDataContainer(EffectCluster, modType);
|
||||
return BaseClass::handleChanged(EffectCluster, modType);
|
||||
}
|
||||
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/area_fire.h>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PdmHandler;
|
||||
|
||||
class EffectCluster2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<EffectCluster2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::EffectCluster;
|
||||
using MAP_TYPE = SituationMap::AreaFire;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtEffectCluster;
|
||||
};
|
||||
|
||||
class EffectCluster2SituationMap final : public Aes2SituationMap<EffectCluster2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<EffectCluster2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
|
||||
explicit EffectCluster2SituationMap(PdmHandler *pdmHandler,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
virtual ~EffectCluster2SituationMap();
|
||||
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::EffectCluster &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->effectClusters(cb);
|
||||
}
|
||||
|
||||
using BaseClass::updateVisibility;
|
||||
bool updateVisibility(const DDS_TYPE &ddsData, RefPointer<MAP_TYPE> mapObj) override;
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool updateGeometry(const AreaEffectSimulation::AesItemView &aesItemView,
|
||||
RefPointer<SituationMap::AreaFire> mapObj) override;
|
||||
|
||||
|
||||
bool removeElement(const int32_t simId) override;
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
bool isVisibleByFilter(const DDS_TYPE &data) const override;
|
||||
AreaEffectSimulation::AesType aesTypeFromGearClassChargeType(const Aes2SituationMap::DDS_TYPE &data) const;
|
||||
|
||||
|
||||
protected Q_SLOTS:
|
||||
bool runDelayed();
|
||||
bool onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &EffectCluster, DataModification modType);
|
||||
bool onAesItemViewChanged(const AreaEffectSimulation::AesItemView &aesItemView, DataModification modType);
|
||||
bool updateGunToTargetLineAndTrajectory(const AreaEffectSimulation::AesItemView &itemView, RefPointer<Sim2SituationMap::MAP_T> mapObj);
|
||||
|
||||
bool updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj,
|
||||
const AreaEffectSimulation::EffectCluster &EffectCluster,
|
||||
const AreaEffectSimulation::AesItemView &aesItemView);
|
||||
bool updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj, const QPointF ¢erGeo = QPointF(), double radius = 0);
|
||||
|
||||
void updateAllNotifiedItems();
|
||||
|
||||
void addUniqueMapIdToNotifiy(int uniqueMapId, const char *file, int lineNo);
|
||||
|
||||
protected:
|
||||
QTimer *m_notifyTimer{nullptr};
|
||||
QSet<int> m_uniqueMapIdsToUpdate;
|
||||
|
||||
PdmHandler *m_pdmHandler{nullptr};
|
||||
};
|
||||
|
||||
}
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "emergency_call_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/map.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Common/LtsAppDescriptor/lts_app_descriptor.h>
|
||||
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace SituationMap;
|
||||
|
||||
|
||||
static QImage renderEmergencySymbol(bool bExpired)
|
||||
{
|
||||
int size = 200;
|
||||
QImage image(size, size, QImage::Format_ARGB32);
|
||||
image.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QPen pen(Qt::white);
|
||||
pen.setWidth(10);
|
||||
painter.setPen(pen);
|
||||
|
||||
if (bExpired)
|
||||
painter.setBrush(QBrush(Qt::gray));
|
||||
else
|
||||
painter.setBrush(QBrush(Qt::red));
|
||||
|
||||
painter.drawEllipse(QPointF(image.rect().center()),
|
||||
image.rect().width() * 0.45,
|
||||
image.rect().height() * 0.45);
|
||||
|
||||
painter.setPen(QPen(Qt::white));
|
||||
|
||||
QFont font = painter.font();
|
||||
font.setBold(true);
|
||||
font.setPixelSize(75);
|
||||
painter.setFont(font);
|
||||
|
||||
QPointF pos(image.width() * 0.125,
|
||||
image.height() * 0.625);
|
||||
|
||||
painter.drawText(pos, QLatin1String("SOS"));
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool EmergencyCallToMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!pluginProvider)
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
m_almDtc = m_pluginProvider->almDtc();
|
||||
m_almInfoIfc = m_pluginProvider->almInfoIfc();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
|
||||
const bool bIsReplay = m_pluginProvider->isReplayPartition();
|
||||
const bool bIsSnapshot = m_pluginProvider->appId() == LtsAppDescriptor::App::Snapshot;
|
||||
|
||||
if (bIsReplay && !bIsSnapshot)
|
||||
{
|
||||
|
||||
|
||||
bool success = false;
|
||||
if (m_objFac.map())
|
||||
success = m_objFac.map()->layerFactory().switchEmergencyCallLayerOff();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", switchEmergencyCallLayerOff _OFF_ ; success = " << success;
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmergencyCallToMap::run()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " Starting to run";
|
||||
|
||||
this->stop();
|
||||
|
||||
if (m_almDtc)
|
||||
{
|
||||
connect(m_almDtc.get(), &AlarmManagement::Interface::Dtc::almEmergencyCallChanged,
|
||||
this, &EmergencyCallToMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_almDtc->almEmergencyCalls([this](const AlarmManagement::AlmEmergencyCall & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmergencyCallToMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " Stopping";
|
||||
if (m_almDtc)
|
||||
m_almDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool EmergencyCallToMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_almInfoIfc)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
m_almInfoIfc->showEmergencyCallInfoWindows(simIds);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmergencyCallToMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_almDtc)
|
||||
return false;
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [ simIdOut, &umodOut](const AlarmManagement::AlmEmergencyCall & data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_equipmentNumber = data.issi();
|
||||
QString desc = QStringLiteral("id: %1\ntime: %2");
|
||||
umodOut.m_description1 = desc.arg(data.id()).arg(QDateTime::fromMSecsSinceEpoch(data.sampleTime()).toString());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const AlarmManagement::AlmEmergencyCall &data)> cb1 = cb;
|
||||
return m_almDtc->almEmergencyCalls(cb1);
|
||||
|
||||
}
|
||||
|
||||
void EmergencyCallToMap::showExpired(bool showExpired)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, showExpired=" << showExpired;
|
||||
|
||||
bool change = m_showExpired != showExpired;
|
||||
|
||||
if (change)
|
||||
{
|
||||
m_showExpired = showExpired;
|
||||
run();
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, showExpired=" << showExpired;
|
||||
}
|
||||
|
||||
bool EmergencyCallToMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
bool bIsValid = m_showExpired || !data.expired();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< ", id: "<< data.id()
|
||||
<< ", issi: "<< data.issi()
|
||||
<< ", data.expired: " << data.expired()
|
||||
<< ", m_showExpired: " << m_showExpired
|
||||
<< " -> bIsValid=" << bIsValid;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, bIsValid=" << bIsValid;
|
||||
return !bIsValid;
|
||||
}
|
||||
|
||||
int32_t EmergencyCallToMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool EmergencyCallToMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", id " << ddsData.id();
|
||||
|
||||
mapObj->setPickable(true);
|
||||
mapObj->setDrawOrder(1);
|
||||
|
||||
|
||||
mapObj->setIdentifier(QStringLiteral("SOS_%1").arg(ddsData.issi()));
|
||||
|
||||
TextStyle textStyle;
|
||||
textStyle.setSize(20);
|
||||
if (ddsData.expired())
|
||||
textStyle.setTextColor(Qt::gray);
|
||||
else
|
||||
textStyle.setTextColor(Qt::red);
|
||||
textStyle.setTextOutlineColor(Qt::white);
|
||||
textStyle.setTextOutlineWidth(5);
|
||||
mapObj->setTextStyle(textStyle);
|
||||
|
||||
|
||||
const Core::GeoPosition2D &geoPos = ddsData.position();
|
||||
mapObj->setOrigin(Point3D(geoPos.lon(), geoPos.lat(), 0.0));
|
||||
|
||||
|
||||
mapObj->setProxyImage(renderEmergencySymbol(ddsData.expired()), QSize(50, 50));
|
||||
|
||||
|
||||
mapObj->setPinEnabled(true);
|
||||
|
||||
forceEmergencyCallLayerVisibility();
|
||||
|
||||
emit emergencyCallUpdated(mapObj->identifier(), Point3D(geoPos.lon(), geoPos.lat(), 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmergencyCallToMap::forceEmergencyCallLayerVisibility()
|
||||
{
|
||||
if (!m_pluginProvider)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " EmergencyCallLayer: failed due to missing pluginProvider!!!";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const bool bIsLive = !m_pluginProvider->isReplayPartition();
|
||||
|
||||
|
||||
if (bIsLive)
|
||||
{
|
||||
|
||||
bool success = false;
|
||||
if (m_objFac.map())
|
||||
success = m_objFac.map()->layerFactory().switchEmergencyCallLayerOn();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", switchEmergencyCallLayerOn _ON_ ; success = " << success;
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AlarmManagement/alm_data_plugin_interface.h>
|
||||
#include <Plugins/AlarmManagement/alm_info_gui_plugin_interface.h>
|
||||
#include <MapObjects/geo_image.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
class EmergencyCallToMap final : public Sim2SituationMap<AlarmManagement::AlmEmergencyCall, SituationMap::GeoImage>
|
||||
, protected DdsFilterHandling<SituationMap::GeoImage>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<AlarmManagement::AlmEmergencyCall, SituationMap::GeoImage>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::GeoImage>;
|
||||
|
||||
public:
|
||||
EmergencyCallToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
void showExpired(bool showExpired);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
void forceEmergencyCallLayerVisibility();
|
||||
|
||||
signals:
|
||||
void emergencyCallUpdated(const QString &name, const SituationMap::Point3D &geoPosition);
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider;
|
||||
bool m_showExpired{false};
|
||||
std::shared_ptr<AlarmManagement::Interface::Dtc> m_almDtc;
|
||||
std::shared_ptr<AlarmManagement::ForeignInfoGuiInterface> m_almInfoIfc;
|
||||
|
||||
};
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
|
||||
#include "explosion_area_to_map.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool ExplosionArea2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionAreaChanged,
|
||||
this, &ExplosionArea2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::triggeredImpactsChanged,
|
||||
this, &ExplosionArea2SituationMap::onTriggeredImpactsChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->explosionAreas([this](const AreaEffectSimulation::ExplosionArea &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
m_aesDtc->triggeredImpactss([this](const AreaEffectSimulation::TriggeredImpacts &data)
|
||||
{
|
||||
onTriggeredImpactsChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool ExplosionArea2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
|
||||
const AreaEffectSimulation::AesEffectState effectState = ddsData.effectStateId().underlying();
|
||||
mapObj->setAesState(effectState2aesState(effectState));
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionArea, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtExplosionArea) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionArea2SituationMap::onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType::AtExplosionAreaSingleExplosions)
|
||||
return false;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const int32_t simId = data.aesItemId();
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId=" << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionAreaSingleExplosions, itemView))
|
||||
{
|
||||
const PositionCont &posCont = form2PosCont(itemView.form());
|
||||
const auto &bitField = data.bitfield();
|
||||
|
||||
|
||||
int32_t impactCount = data.impactCount();
|
||||
if (impactCount != posCont.size())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " size mismatch"
|
||||
<< " impactCount=" << impactCount
|
||||
<< " posCont.size()=" << posCont.size() ;
|
||||
mapObj->setImpacts(posCont);
|
||||
}
|
||||
else
|
||||
{
|
||||
PositionCont posContImpacts;
|
||||
posContImpacts.reserve(posCont.size());
|
||||
for (int i = 0; i < posCont.size(); ++i)
|
||||
{
|
||||
if (!LtsUtils::BitArray::testBit(bitField, i))
|
||||
posContImpacts.append(posCont.at(i));
|
||||
}
|
||||
|
||||
mapObj->setImpacts(posContImpacts);
|
||||
}
|
||||
|
||||
if (!mapObj->updateView())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " updateView failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView(AtExplosionAreaSingleExplosions) found"
|
||||
<< " simId=" << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/area_fire.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class ExplosionArea2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<ExplosionArea2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::ExplosionArea;
|
||||
using MAP_TYPE = SituationMap::AreaFire;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtExplosionArea;
|
||||
};
|
||||
|
||||
class ExplosionArea2SituationMap final : public Aes2SituationMap<ExplosionArea2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<ExplosionArea2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::ExplosionArea &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->explosionAreas(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
bool onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+996
@@ -0,0 +1,996 @@
|
||||
|
||||
|
||||
|
||||
#include "explosion_cluster_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <Map/map.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#define ADD_UNIQUE_MAP_ID_TO_NOTIFIY(uniqueMapId) addUniqueMapIdToNotifiy(uniqueMapId, __FILE__, __LINE__)
|
||||
|
||||
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# define BENCHMARK_SETUP_AND_START() QElapsedTimer elapsedTimer; elapsedTimer.start();
|
||||
|
||||
# define BENCHMARK_RUN
|
||||
|
||||
|
||||
# define BENCHMARK_ALL_NOTIFIED
|
||||
|
||||
#else
|
||||
# define BENCHMARK_SETUP_AND_START()
|
||||
#endif
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
static int s_effect3dMaxDisplayDuration = 5000;
|
||||
|
||||
ExplosionCluster2SituationMap::ExplosionCluster2SituationMap(PdmHandler *pdmHandler, ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, m_notifyTimer(new QTimer(this))
|
||||
, m_pdmHandler(pdmHandler)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->setInterval(100);
|
||||
m_notifyTimer->setSingleShot(true);
|
||||
connect(m_notifyTimer, &QTimer::timeout,
|
||||
this, &ExplosionCluster2SituationMap::updateAllNotifiedItems);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
ExplosionCluster2SituationMap::~ExplosionCluster2SituationMap()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->stop();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::run()
|
||||
{
|
||||
|
||||
QTimer::singleShot(1000, this, &ExplosionCluster2SituationMap::runDelayed);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::runDelayed()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionClusterChanged,
|
||||
this, &ExplosionCluster2SituationMap::onExplosionClusterChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
|
||||
m_aesDtc->enableEffects();
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::effectsChanged,
|
||||
this, &ExplosionCluster2SituationMap::onEffectssChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::trajectoryTimeAwareChanged,
|
||||
this, &ExplosionCluster2SituationMap::onTracjectoryChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &ExplosionCluster2SituationMap::onAesItemViewChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_aesDtc->explosionClusters([this](const AreaEffectSimulation::ExplosionCluster &data)
|
||||
{
|
||||
onExplosionClusterChanged(data, DataModification::eAdded);
|
||||
});
|
||||
#ifdef BENCHMARK_RUN
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " explosionClusters took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
m_aesDtc->trajectoryTimeAwares([this](const AreaEffectSimulation::TrajectoryTimeAware &data)
|
||||
{
|
||||
onTracjectoryChanged(data, DataModification::eAdded);
|
||||
});
|
||||
#ifdef BENCHMARK_RUN
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " trajectoryTimeAwares took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &ExplosionCluster2SituationMap::onPartitionTimeChanged, Qt::UniqueConnection);
|
||||
|
||||
#ifdef BENCHMARK_RUN
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " all took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
|
||||
void ExplosionCluster2SituationMap::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_notifyTimer->stop();
|
||||
if (m_aesDtc)
|
||||
m_aesDtc->disconnect(this);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateVisibility(const Aes2SituationMap::DDS_TYPE &ddsData, RefPointer<Aes2SituationMap::MAP_TYPE> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << getSimId(ddsData);
|
||||
if (!BaseClass::updateVisibility(ddsData, mapObj))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " BaseClass::updateVisibility failed, simId=" << getSimId(ddsData);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
const AreaEffectSimulation::AesEffectState effectState = ddsData.effectStateId().underlying();
|
||||
|
||||
bool bIsMode3D = false;
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
bIsMode3D = true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool bDisplayFilterShowGTL = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowGTL = m_displayFilter->showExplosionClusterGunToTargetLine();
|
||||
const bool bDisplayFilterShowGFK = bDisplayFilterShowGTL && bIsMode3D &&
|
||||
((effectState.underlying() != AreaEffectSimulation::AesEffectState_def::EsActivated) &&
|
||||
(effectState.underlying() != AreaEffectSimulation::AesEffectState_def::EsExpired));
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemViewGunToTargetLine;
|
||||
const std::vector<Core::GeoPosition>& form = itemViewGunToTargetLine.form();
|
||||
if (bDisplayFilterShowGTL || bDisplayFilterShowGFK)
|
||||
m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionClusterGunToTargetLine, itemViewGunToTargetLine);
|
||||
|
||||
|
||||
if (bDisplayFilterShowGTL && (form.size() >= 2))
|
||||
mapObj->setGunToTargetLineSurface(Point3D(form.front().lon(), form.front().lat(), 0.0),
|
||||
Point3D(form.back().lon() , form.back().lat() , 0.0));
|
||||
else
|
||||
mapObj->setGunToTargetLineSurface(Point3D(), Point3D());
|
||||
|
||||
|
||||
if (bIsMode3D)
|
||||
{
|
||||
if (bDisplayFilterShowGFK)
|
||||
{
|
||||
|
||||
PositionCont gunToTargetPath;
|
||||
gunToTargetPath.reserve(form.size());
|
||||
for (const Core::GeoPosition& item : qAsConst(form))
|
||||
gunToTargetPath.append(Point3D(item.lon(), item.lat(), item.z()));
|
||||
|
||||
mapObj->setGunToTargetTrajectory3D(gunToTargetPath);
|
||||
} else {
|
||||
mapObj->setGunToTargetTrajectory3D({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateAllTracjectories(simId);
|
||||
|
||||
|
||||
{
|
||||
bool bDisplayFilterShowMHP = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowMHP = m_displayFilter->showExplosionClusterMeanHitPoint();
|
||||
|
||||
if (bDisplayFilterShowMHP)
|
||||
mapObj->setScheduledImpacts(form2PosCont(ddsData.mhPoints()));
|
||||
else
|
||||
mapObj->setScheduledImpacts({});
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (bIsMode3D)
|
||||
updateEffects3DAllItems(simId);
|
||||
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
|
||||
const AreaEffectSimulation::AesEffectState effectState = ddsData.effectStateId().underlying();
|
||||
mapObj->setAesState(effectState2aesState(effectState));
|
||||
|
||||
|
||||
|
||||
LineStyle ls = mapObj->lineStyle();
|
||||
if (ddsData.annotationString().empty())
|
||||
ls.setLinePattern(LinePattern::Solid);
|
||||
else
|
||||
ls.setLinePattern(LinePattern::Dash);
|
||||
mapObj->setLineStyle(ls);
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " part1 took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionCluster, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtExplosionCluster) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " aesItemViewFromEntityId took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
{
|
||||
|
||||
|
||||
|
||||
mapObj->setExtrusionHeight(20);
|
||||
}
|
||||
|
||||
|
||||
updateAllTracjectories(simId);
|
||||
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::Effects effectsOut;
|
||||
m_aesDtc->effectsFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionClusterSingleExplosions, effectsOut);
|
||||
onEffectssChanged(effectsOut, DataModification::eAdded);
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " updateAllTracjectories took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
#ifdef BENCHMARK_UPDATE_ELEMENT
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " all took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_simId2UniqueMapId.size();
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateGeometry(const AreaEffectSimulation::AesItemView &aesItemView, RefPointer<AreaFire> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
|
||||
const int simId = aesItemView.aesItemId();
|
||||
auto it = m_ddsDataContainer.find(simId);
|
||||
if (it != m_ddsDataContainer.end())
|
||||
updateNonLethalArea(mapObj, *it, aesItemView);
|
||||
|
||||
|
||||
return BaseClass::updateGeometry(aesItemView, mapObj);
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::removeElement(const int32_t simId)
|
||||
{
|
||||
return BaseClass::removeElement(simId);
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &aesItemView, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int simId = aesItemView.aesItemId();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (aesItemView.aesTypeId() == AreaEffectSimulation::AesType::AtExplosionClusterGunToTargetLine)
|
||||
{
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (mapObj.valid())
|
||||
updateVisibility(m_ddsDataContainer.value(simId), mapObj);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::onEffectssChanged(const AreaEffectSimulation::Effects &effects, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", effects = " << effects
|
||||
<< ", modType = " << modType;
|
||||
|
||||
|
||||
if (effects.aesTypeId() != AreaEffectSimulation::AesType::AtExplosionClusterSingleExplosions)
|
||||
return false;
|
||||
|
||||
const int aesItemId = effects.aesItemId();
|
||||
const int simId = aesItemId;
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId=" << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<AreaEffectSimulation::SingleEffect> &singleEffectsRef = effects.singleEffects();
|
||||
|
||||
PositionCont posContImpactsDraped, posContImpactsAbsolute;
|
||||
posContImpactsDraped.reserve(singleEffectsRef.size());
|
||||
posContImpactsAbsolute.reserve(singleEffectsRef.size());
|
||||
|
||||
|
||||
for (const AreaEffectSimulation::SingleEffect &se : qAsConst(singleEffectsRef))
|
||||
{
|
||||
if (se.singleEffectState().underlying() != AreaEffectSimulation::AesSingleEffectState_def::SesTriggered)
|
||||
continue;
|
||||
|
||||
switch (se.zPlacement().underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesZPlacement_def::ZpDraped:
|
||||
posContImpactsDraped.append({se.position().lon(), se.position().lat(), se.position().z()});
|
||||
break;
|
||||
case AreaEffectSimulation::AesZPlacement_def::ZpAbsolute:
|
||||
posContImpactsAbsolute.append({se.position().lon(), se.position().lat(), se.position().z()});
|
||||
break;
|
||||
case AreaEffectSimulation::AesZPlacement_def::ZpRelative:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mapObj->setImpacts(posContImpactsDraped);
|
||||
mapObj->setImpactsAbsoluteHeight(posContImpactsAbsolute);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
updateEffects3DSingleItem(effects);
|
||||
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< ", impacts = " << effects
|
||||
<< ", modType = " << modType;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateGunToTargetLineAndTrajectory(const AreaEffectSimulation::AesItemView &itemView,
|
||||
RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
const std::vector<Core::GeoPosition>& formRef = itemView.form();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, form.size = " << formRef.size();
|
||||
|
||||
if (formRef.size() >= 2)
|
||||
{
|
||||
mapObj->setGunToTargetLineSurface(Point3D(formRef.front().lon(), formRef.front().lat(), 0.0),
|
||||
Point3D(formRef.back().lon() , formRef.back().lat() , 0.0));
|
||||
} else {
|
||||
|
||||
mapObj->setGunToTargetLineSurface(Point3D(), Point3D());
|
||||
}
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
{
|
||||
|
||||
PositionCont gunToTargetPath;
|
||||
gunToTargetPath.reserve(formRef.size());
|
||||
for (const Core::GeoPosition& item : qAsConst(formRef))
|
||||
gunToTargetPath.append(Point3D(item.lon(), item.lat(), item.z()));
|
||||
|
||||
mapObj->setGunToTargetTrajectory3D(gunToTargetPath);
|
||||
}
|
||||
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::onTracjectoryChanged(const AreaEffectSimulation::TrajectoryTimeAware &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, modType=" << modType;
|
||||
|
||||
Q_UNUSED(modType);
|
||||
|
||||
updateSingleTracjectory(data);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, modType=" << modType;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PositionCont circle(const QPointF ¢er_geo, qreal radius, int steps= 72)
|
||||
{
|
||||
const LtsCoordTrans::UtmCoordinate ¢erUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(center_geo);
|
||||
PositionCont poly;
|
||||
if (steps < 6)
|
||||
steps = 6;
|
||||
poly.reserve(steps);
|
||||
for (int i = 0; i < 360; i += (360 / steps))
|
||||
{
|
||||
double angle = double(i) * LtsCoordTrans::deg2rad();
|
||||
const QPointF &pointGeo = centerUtm.geographic(QPointF(cos(angle) * radius, sin(angle) * radius));
|
||||
poly.push_back(Point3D(pointGeo.x(), pointGeo.y(), 0.0));
|
||||
}
|
||||
return poly;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj,
|
||||
const AreaEffectSimulation::ExplosionCluster &explosionCluster,
|
||||
const AreaEffectSimulation::AesItemView &aesItemView)
|
||||
{
|
||||
if (!m_pdmHandler)
|
||||
return false;
|
||||
|
||||
if (explosionCluster.id() != aesItemView.aesItemId())
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int chargeTypeId = explosionCluster.chargeStruct().chargeTypeId();
|
||||
const ProjectDataManagement::GearClass &gc = m_pdmHandler->gearClassFromChargeTypeId(chargeTypeId);
|
||||
if (gc.underlying() == ProjectDataManagement::GearClass_def::AirSupport)
|
||||
{
|
||||
const QVector<ProjectDataManagement::CasEffect> &casEffectsVec = m_pdmHandler->casEffects(explosionCluster.chargeStruct());
|
||||
|
||||
|
||||
|
||||
if (casEffectsVec.size() >= 2)
|
||||
{
|
||||
const ProjectDataManagement::CasEffect &ce = casEffectsVec[1];
|
||||
|
||||
|
||||
const double impactRadius = ce.impactRadius();
|
||||
|
||||
const AreaEffectSimulation::Area &areaRef = explosionCluster.area();
|
||||
|
||||
const Core::GeoPosition2D &blGeo = aesItemView.boundingBoxBottomLeft();
|
||||
const QPointF ¢erGeo = AreaEffectSimulation::Polygons::bottomLeft2CenterPoint(QPointF(blGeo.lon(), blGeo.lat()),
|
||||
areaRef.width(), areaRef.height(), areaRef.rotation());
|
||||
|
||||
updateNonLethalArea(mapObj, centerGeo, impactRadius);
|
||||
}
|
||||
} else {
|
||||
updateNonLethalArea(mapObj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj, const QPointF ¢erGeo, double radius)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, radius = " << radius;
|
||||
|
||||
if (!mapObj)
|
||||
return false;
|
||||
|
||||
if (radius <= 0)
|
||||
{
|
||||
mapObj->setNonLethalArea({});
|
||||
} else {
|
||||
const PositionCont &nonLethalAreaPolygon = circle(centerGeo, radius);
|
||||
mapObj->setNonLethalArea(nonLethalAreaPolygon);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateSingleTracjectory(const AreaEffectSimulation::TrajectoryTimeAware &traj, bool considerTime)
|
||||
{
|
||||
|
||||
|
||||
if (traj.originatorTypeId() != ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation)
|
||||
return false;
|
||||
|
||||
const int32_t simId = traj.originatorId();
|
||||
if (!m_simId2UniqueMapId.contains(simId))
|
||||
return false;
|
||||
|
||||
|
||||
bool bDisplayFilterShowTRJ = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowTRJ = m_displayFilter->showExplosionClusterTrajectory();
|
||||
|
||||
const int32_t index = traj.index();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, traj=" << traj
|
||||
<< ", simId=" << simId
|
||||
<< ", index=" << index
|
||||
<< ", considerTime=" << considerTime;
|
||||
|
||||
DEBUG_LOG(m_logger) << "START"
|
||||
<< ", simId=" << simId
|
||||
<< ", index=" << index
|
||||
<< ", considerTime=" << considerTime;
|
||||
|
||||
|
||||
const qint64 partitionTimeMsec = m_pluginProvider->partitionTime();
|
||||
if (traj.trajectoryStartTime() > partitionTimeMsec)
|
||||
return false;
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId=" << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bHasChanged = false;
|
||||
|
||||
const bool moIsVisibleByFilter = isVisibleByFilter(m_ddsDataContainer.value(simId));
|
||||
if (bDisplayFilterShowTRJ && moIsVisibleByFilter)
|
||||
{
|
||||
|
||||
|
||||
const std::vector<Core::GeoPositionRelativeTime>& geometry = traj.geometry();
|
||||
const PositionCont &curPath = mapObj->trajectory(index);
|
||||
if (geometry.size() > static_cast<size_t>(curPath.size()))
|
||||
{
|
||||
|
||||
PositionCont posCont;
|
||||
posCont.reserve(geometry.size());
|
||||
for (const Core::GeoPositionRelativeTime& posTime : qAsConst(geometry))
|
||||
{
|
||||
if (considerTime && ((traj.trajectoryStartTime() + posTime.relativeTime()) > partitionTimeMsec) )
|
||||
break;
|
||||
posCont.append(Point3D(posTime.lon(), posTime.lat(), posTime.z()));
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "update trajectory, simId=" << simId
|
||||
<< ", index=" << index
|
||||
<< ", posCont.size() " << posCont.size();
|
||||
|
||||
if (posCont.size() == 1)
|
||||
posCont.clear();
|
||||
bHasChanged = mapObj->setTrajectory(index, posCont);
|
||||
}
|
||||
} else {
|
||||
bHasChanged = mapObj->setTrajectory(index, {});
|
||||
}
|
||||
|
||||
if (bHasChanged)
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateAllTracjectories(int simToRestrict)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef BENCHMARK_ALL_TRAC
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " trajectoryTimeAwares took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_uniqueMapIdsToUpdate.size()
|
||||
<< ", size " << m_aesDtc->trajectoryTimeAwares().size()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
auto cb = [this, simToRestrict](const AreaEffectSimulation::TrajectoryTimeAware &traj)
|
||||
{
|
||||
|
||||
if (traj.originatorTypeId() != ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation)
|
||||
return;
|
||||
const int aesItemId = traj.originatorId();
|
||||
if ((simToRestrict < 0) || (simToRestrict == aesItemId))
|
||||
updateSingleTracjectory(traj);
|
||||
};
|
||||
m_aesDtc->trajectoryTimeAwares(cb);
|
||||
|
||||
|
||||
#ifdef BENCHMARK_ALL_TRAC
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " All took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", size " << m_uniqueMapIdsToUpdate.size()
|
||||
<< ", size " << m_aesDtc->trajectoryTimeAwares().size()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateEffects3DSingleItem(const AreaEffectSimulation::Effects &effects)
|
||||
{
|
||||
|
||||
if (effects.aesTypeId() != AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions)
|
||||
return false;
|
||||
|
||||
const int32_t simId = effects.aesItemId();
|
||||
if (!m_simId2UniqueMapId.contains(simId))
|
||||
return false;
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId=" << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bHasChanged = false;
|
||||
|
||||
const qint64 partitionTimeMsec = m_pluginProvider->partitionTime();
|
||||
|
||||
|
||||
bool bDisplayFilterShowDetoSphere = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowDetoSphere = m_displayFilter->showExplosionClusterDetonationSphere();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId
|
||||
<< ", bDisplayFilterShowDetoSphere=" << bDisplayFilterShowDetoSphere
|
||||
<< ", partitionTimeMsec=" << partitionTimeMsec;
|
||||
|
||||
if (bDisplayFilterShowDetoSphere)
|
||||
{
|
||||
const std::vector<AreaEffectSimulation::SingleEffect> &singleEffectsRef = effects.singleEffects();
|
||||
|
||||
PositionCont posContImpactsDraped, posContImpactsAbsolute;
|
||||
posContImpactsDraped.reserve(singleEffectsRef.size());
|
||||
posContImpactsAbsolute.reserve(singleEffectsRef.size());
|
||||
|
||||
int i = 0;
|
||||
for (const AreaEffectSimulation::SingleEffect &se : qAsConst(singleEffectsRef))
|
||||
{
|
||||
++i;
|
||||
|
||||
if (se.singleEffectState().underlying() != AreaEffectSimulation::AesSingleEffectState_def::SesTriggered)
|
||||
continue;
|
||||
|
||||
const qint64 age = partitionTimeMsec - se.singleEffectTime();
|
||||
const Core::GeoPosition &singleEffectPosGeo = se.position();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId=" << simId << ", SingleEffect, i = " << i
|
||||
<< ", age = " << age << ", s_effect3dMaxDisplayDuration = " << s_effect3dMaxDisplayDuration
|
||||
<< ", singleEffectPosGeo = " << singleEffectPosGeo;
|
||||
|
||||
if (age > s_effect3dMaxDisplayDuration)
|
||||
continue;
|
||||
|
||||
switch (se.zPlacement().underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesZPlacement_def::ZpDraped:
|
||||
posContImpactsDraped.append({singleEffectPosGeo.lon(), singleEffectPosGeo.lat(), singleEffectPosGeo.z()});
|
||||
break;
|
||||
case AreaEffectSimulation::AesZPlacement_def::ZpAbsolute:
|
||||
posContImpactsAbsolute.append({singleEffectPosGeo.lon(), singleEffectPosGeo.lat(), singleEffectPosGeo.z()});
|
||||
break;
|
||||
case AreaEffectSimulation::AesZPlacement_def::ZpRelative:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId=" << simId << ", posContImpactsDraped : " << posContImpactsDraped.size() << " von " << singleEffectsRef.size();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId=" << simId << ", posContImpactsAbsolute: " << posContImpactsAbsolute.size() << " von " << singleEffectsRef.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double impactRadius = 5;
|
||||
auto it = m_ddsDataContainer.find(simId);
|
||||
if (it != m_ddsDataContainer.end())
|
||||
impactRadius = m_pdmHandler->impactRadius(it->chargeStruct(), 5);
|
||||
|
||||
if (mapObj->setDetonationsDraped(posContImpactsDraped, impactRadius))
|
||||
bHasChanged = true;
|
||||
if (mapObj->setDetonationsAbsolute(posContImpactsAbsolute, impactRadius))
|
||||
bHasChanged = true;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId=" << simId
|
||||
<< " impactRadius = " << impactRadius
|
||||
<< ", bHasChanged = " << bHasChanged;
|
||||
|
||||
} else {
|
||||
if (mapObj->setDetonationsDraped({}, 1))
|
||||
bHasChanged = true;
|
||||
if (mapObj->setDetonationsAbsolute({}, 1))
|
||||
bHasChanged = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (bHasChanged)
|
||||
ADD_UNIQUE_MAP_ID_TO_NOTIFIY(mapObj->uniqueMapId());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::updateEffects3DAllItems(int simToRestrict)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
auto cb = [this, simToRestrict](const AreaEffectSimulation::Effects &effect)
|
||||
{
|
||||
if ((simToRestrict < 0) || (simToRestrict == effect.aesItemId()))
|
||||
updateEffects3DSingleItem(effect);
|
||||
};
|
||||
m_aesDtc->effectss(cb);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ExplosionCluster2SituationMap::updateAllNotifiedItems()
|
||||
{
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
std::string localLoggerName = m_logger.getLoggerName() + ".update";
|
||||
LOGGER_T logger = m_logger.getNGLLogger(localLoggerName);
|
||||
|
||||
INFO_LOG(logger) << LOGFUNCTION << " m_uniqueMapIdsToUpdate.size() = " << m_uniqueMapIdsToUpdate.size();
|
||||
|
||||
for (int uniqueMapId : qAsConst(m_uniqueMapIdsToUpdate))
|
||||
{
|
||||
|
||||
if (!m_uniqueMapId2SimId.contains(uniqueMapId))
|
||||
continue;
|
||||
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed for "<< mapObj->debugInfo();
|
||||
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_uniqueMapIdsToUpdate.size()=" << m_uniqueMapIdsToUpdate.size();
|
||||
|
||||
#ifdef BENCHMARK_ALL_NOTIFIED
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " took " << elapsedTimer.elapsed() << " [ms]" << ", size " << m_uniqueMapIdsToUpdate.size();
|
||||
#endif
|
||||
|
||||
m_uniqueMapIdsToUpdate.clear();
|
||||
}
|
||||
|
||||
|
||||
void ExplosionCluster2SituationMap::addUniqueMapIdToNotifiy(int uniqueMapId, const char *file, int lineNo)
|
||||
{
|
||||
std::string localLoggerName = m_logger.getLoggerName() + ".update";
|
||||
LOGGER_T logger = m_logger.getNGLLogger(localLoggerName);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
const int simId = m_uniqueMapId2SimId.value(uniqueMapId, -1);
|
||||
DEBUG_LOG(logger) << "START ******* addUniqueMapIdToNotifiy: uniqueMapId = " << uniqueMapId << " (simId=" << simId << "), caller= " << file << ":" << lineNo;
|
||||
}
|
||||
|
||||
if (uniqueMapId > 0)
|
||||
m_uniqueMapIdsToUpdate.insert(uniqueMapId);
|
||||
if (!m_notifyTimer->isActive())
|
||||
m_notifyTimer->start();
|
||||
}
|
||||
|
||||
void ExplosionCluster2SituationMap::onPartitionTimeChanged(qint64 newPartitionTime)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, newPartitionTime=" << newPartitionTime
|
||||
<< ", exerciseId = " << m_pluginProvider->exerciseId()
|
||||
<< ", workspaceId = " << m_pluginProvider->workspaceId()
|
||||
<< ", this=" << this;
|
||||
|
||||
updateAllTracjectories();
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
updateEffects3DAllItems();
|
||||
}
|
||||
|
||||
AreaEffectSimulation::AesType ExplosionCluster2SituationMap::aesTypeFromGearClassChargeType(const DDS_TYPE &data)const
|
||||
{
|
||||
static QMap<int, AreaEffectSimulation::AesType> s_aesTypeMap;
|
||||
|
||||
if (s_aesTypeMap.contains(data.chargeStruct().chargeTypeId()))
|
||||
return s_aesTypeMap[data.chargeStruct().chargeTypeId()];
|
||||
|
||||
const ProjectDataManagement::GearClass &gc = m_pdmHandler->gearClassFromChargeTypeId(data.chargeStruct().chargeTypeId());
|
||||
switch (gc.underlying())
|
||||
{
|
||||
case ProjectDataManagement::GearClass::AirSupport:
|
||||
s_aesTypeMap[data.chargeStruct().chargeTypeId()] = AreaEffectSimulation::AesType::AtAirSupportImpact;
|
||||
break;
|
||||
case ProjectDataManagement::GearClass::Artillery:
|
||||
case ProjectDataManagement::GearClass::Mortar:
|
||||
case ProjectDataManagement::GearClass::Rocket:
|
||||
s_aesTypeMap[data.chargeStruct().chargeTypeId()] = AreaEffectSimulation::AesType::AtExplosionArea;
|
||||
break;
|
||||
default:
|
||||
return AreaEffectSimulation::AesType::AtUnknown;
|
||||
}
|
||||
return s_aesTypeMap[data.chargeStruct().chargeTypeId()];
|
||||
}
|
||||
|
||||
void ExplosionCluster2SituationMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << "START onAesDisplayFilterChanged, aesType =" << aesType
|
||||
<< ", this " << this;
|
||||
|
||||
if ((AreaEffectSimulation::AesType_def::AtExplosionCluster != aesType.underlying()) &&
|
||||
(AreaEffectSimulation::AesType_def::AtExplosionArea != aesType.underlying()) &&
|
||||
(AreaEffectSimulation::AesType_def::AtAirSupportImpact != aesType.underlying()))
|
||||
return;
|
||||
|
||||
const auto cb = [this](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (isElapsed(data))
|
||||
return false;
|
||||
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
iterateAesData(cb);
|
||||
TRACE_LOG(m_logger) << "END onAesDisplayFilterChanged, aesType =" << aesType
|
||||
<< ", this " << this;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::isVisibleByFilter(const Aes2SituationMap::DDS_TYPE &data) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
const auto es = data.effectStart().is_set() ? data.effectStart().get() : 0;
|
||||
const auto partyId = data.partyId().is_set() ? data.partyId().get() : -1;
|
||||
bool isVisibleByFilter = partyId > 0 ? FilterClass::m_currentSymbolSettings.symbolSettings.symbolPartyAppearance.value(partyId).isVisible : true;
|
||||
if (isVisibleByFilter)
|
||||
{
|
||||
AreaEffectSimulation::AesType aestype = aesTypeFromGearClassChargeType(data);
|
||||
if (aestype == AreaEffectSimulation::AesType::AtUnknown)
|
||||
{
|
||||
WARNING_LOG(m_logger) << " Only AES TYPE explosion Cluster, AirSupportImpact, Explosion area will be displayed";
|
||||
aestype = AreaEffectSimulation::AesType::AtExplosionArea;
|
||||
}
|
||||
|
||||
isVisibleByFilter = m_displayFilter->isVisible(aestype,
|
||||
data.effectStateId(),
|
||||
data.chargeStruct().chargeTypeId(),
|
||||
partyId,
|
||||
data.isCentral(),
|
||||
es,
|
||||
data.effectDuration(),
|
||||
m_pluginProvider->partitionTime());
|
||||
}
|
||||
|
||||
return isVisibleByFilter;
|
||||
}
|
||||
|
||||
bool ExplosionCluster2SituationMap::onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &explosionCluster, DataModification modType)
|
||||
{
|
||||
updateDdsDataContainer(explosionCluster, modType);
|
||||
return BaseClass::handleChanged(explosionCluster, modType);
|
||||
}
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/area_fire.h>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PdmHandler;
|
||||
|
||||
class ExplosionCluster2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<ExplosionCluster2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::ExplosionCluster;
|
||||
using MAP_TYPE = SituationMap::AreaFire;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtExplosionCluster;
|
||||
};
|
||||
|
||||
class ExplosionCluster2SituationMap final : public Aes2SituationMap<ExplosionCluster2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<ExplosionCluster2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
|
||||
explicit ExplosionCluster2SituationMap(PdmHandler *pdmHandler,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
virtual ~ExplosionCluster2SituationMap();
|
||||
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::ExplosionCluster &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->explosionClusters(cb);
|
||||
}
|
||||
|
||||
using BaseClass::updateVisibility;
|
||||
bool updateVisibility(const DDS_TYPE &ddsData, RefPointer<MAP_TYPE> mapObj) override;
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool updateGeometry(const AreaEffectSimulation::AesItemView &aesItemView,
|
||||
RefPointer<SituationMap::AreaFire> mapObj) override;
|
||||
|
||||
|
||||
bool removeElement(const int32_t simId) override;
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
bool isVisibleByFilter(const DDS_TYPE &data) const override;
|
||||
AreaEffectSimulation::AesType aesTypeFromGearClassChargeType(const Aes2SituationMap::DDS_TYPE &data) const;
|
||||
|
||||
|
||||
protected Q_SLOTS:
|
||||
bool runDelayed();
|
||||
bool onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &explosionCluster, DataModification modType);
|
||||
bool onAesItemViewChanged(const AreaEffectSimulation::AesItemView &aesItemView, DataModification modType);
|
||||
bool onEffectssChanged(const AreaEffectSimulation::Effects &effects, DataModification modType);
|
||||
bool updateGunToTargetLineAndTrajectory(const AreaEffectSimulation::AesItemView &itemView, RefPointer<Sim2SituationMap::MAP_T> mapObj);
|
||||
bool onTracjectoryChanged(const AreaEffectSimulation::TrajectoryTimeAware &data, DataModification modType);
|
||||
|
||||
bool updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj,
|
||||
const AreaEffectSimulation::ExplosionCluster &explosionCluster,
|
||||
const AreaEffectSimulation::AesItemView &aesItemView);
|
||||
bool updateNonLethalArea(RefPointer<Sim2SituationMap::MAP_T> mapObj, const QPointF ¢erGeo = QPointF(), double radius = 0);
|
||||
|
||||
bool updateSingleTracjectory(const AreaEffectSimulation::TrajectoryTimeAware &traj, bool considerTime = true);
|
||||
bool updateAllTracjectories(int simToRestrict = -1);
|
||||
|
||||
bool updateEffects3DSingleItem(const AreaEffectSimulation::Effects& effects);
|
||||
bool updateEffects3DAllItems(int simToRestrict = -1);
|
||||
|
||||
void updateAllNotifiedItems();
|
||||
|
||||
void addUniqueMapIdToNotifiy(int uniqueMapId, const char *file, int lineNo);
|
||||
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
|
||||
|
||||
protected:
|
||||
QTimer *m_notifyTimer{nullptr};
|
||||
QSet<int> m_uniqueMapIdsToUpdate;
|
||||
|
||||
PdmHandler *m_pdmHandler{nullptr};
|
||||
};
|
||||
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
|
||||
#include "explosion_single_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <Map/bounding_box.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
ExplosionSingle2SituationMap::ExplosionSingle2SituationMap(PdmHandler *pdmHandler, ObjectFactory &objFac, const QString &layername, const char *loggerName)
|
||||
: BaseClass(objFac, layername, loggerName)
|
||||
, m_pdmHandler(pdmHandler)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExplosionSingle2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (! m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged,
|
||||
this, &ExplosionSingle2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->explosionSingles([this](const AreaEffectSimulation::ExplosionSingle &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool ExplosionSingle2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtExplosionSingle, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtExplosionSingle) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
const Core::GeoPosition2D& impactPos2D = ddsData.impactPosition();
|
||||
mapObj->setImpactOrigin(Point3D(impactPos2D.lon(), impactPos2D.lat(), 0.0));
|
||||
|
||||
|
||||
if (m_pdmHandler && m_pdmHandler->isSmart(ddsData.chargeStruct()))
|
||||
mapObj->setImpactType(SingleFire::ImpactType::doubleImpact);
|
||||
else
|
||||
mapObj->setImpactType(SingleFire::ImpactType::normalImpact);
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/single_fire.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PdmHandler;
|
||||
|
||||
class ExplosionSingle2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<ExplosionSingle2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::ExplosionSingle;
|
||||
using MAP_TYPE = SituationMap::SingleFire;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtExplosionSingle;
|
||||
};
|
||||
|
||||
class ExplosionSingle2SituationMap final : public Aes2SituationMap<ExplosionSingle2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<ExplosionSingle2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
ExplosionSingle2SituationMap(PdmHandler *pdmHandler,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
const char *loggerName);
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::ExplosionSingle &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->explosionSingles(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
PdmHandler *m_pdmHandler = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
|
||||
|
||||
|
||||
#include "functional_area_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/bounding_box.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool FunctionalArea2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::functionalAreaChanged,
|
||||
this, &FunctionalArea2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->functionalAreas([this](const AreaEffectSimulation::FunctionalArea &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool FunctionalArea2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtFunctionalArea, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtFunctionalArea) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (ddsData.pointSymbol().is_set())
|
||||
{
|
||||
const QString pointSymbolSidc = QString::fromStdString(ddsData.pointSymbol().get());
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " pointSymbolSidc ='" << pointSymbolSidc << "'"
|
||||
<< " simId=" << simId ;
|
||||
mapObj->setPointSymbolSidc(pointSymbolSidc);
|
||||
|
||||
SituationMap::BoundingBox bbox;
|
||||
mapObj->boundingBox(bbox);
|
||||
Point3D center;
|
||||
if (bbox.isValid())
|
||||
{
|
||||
center = bbox.center();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " center ='" << center << "'"
|
||||
<< " simId=" << simId ;
|
||||
}
|
||||
mapObj->setPointSymbolOrigin(center);
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/functional_area.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class FunctionalArea2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<FunctionalArea2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::FunctionalArea;
|
||||
using MAP_TYPE = SituationMap::FunctionalArea;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtFunctionalArea;
|
||||
};
|
||||
|
||||
class FunctionalArea2SituationMap final : public Aes2SituationMap<FunctionalArea2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<FunctionalArea2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::FunctionalArea &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->functionalAreas(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
|
||||
#include "gas_pipe_to_map.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool GasPipe2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::gasPipeChanged,
|
||||
this, &GasPipe2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->gasPipes([this](const AreaEffectSimulation::GasPipe &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool GasPipe2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtGasPipe, itemView))
|
||||
{
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtGasPipe) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/polygon.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class GasPipe2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<GasPipe2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::GasPipe;
|
||||
using MAP_TYPE = SituationMap::Polygon;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtGasPipe;
|
||||
};
|
||||
|
||||
class GasPipe2SituationMap final : public Aes2SituationMap<GasPipe2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<GasPipe2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::GasPipe &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->gasPipes(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+471
@@ -0,0 +1,471 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "guez_ied_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <MathUtils/simple_helper.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Symbology/sidc_codec.h>
|
||||
#include <Symbology/sidc_builder_base.h>
|
||||
|
||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
GuezIed2SituationMap::GuezIed2SituationMap(ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
GuezIed2SituationMap::~GuezIed2SituationMap()
|
||||
{
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->removeChangedCallback(this);
|
||||
}
|
||||
|
||||
int32_t GuezIed2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider)
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
m_guezIedDtc = pluginProvider->gimDtc();
|
||||
if (!m_guezIedDtc)
|
||||
return false;
|
||||
|
||||
m_guezIedGuiIfc = pluginProvider->gimIfc();
|
||||
|
||||
|
||||
m_guezIedDtc->enableIed(true);
|
||||
m_guezIedDtc->enableIedPosition(true);
|
||||
m_guezIedDtc->waitForHistoricalDataIed(1000);
|
||||
m_guezIedDtc->waitForHistoricalDataIedPosition(1000);
|
||||
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
auto fltAesIfc = pluginProvider->fltAesIfc();
|
||||
if (fltAesIfc)
|
||||
{
|
||||
m_displayFilter = fltAesIfc->aesFilterForOperator(pluginProvider->operatorId(), pluginProvider->workspaceId());
|
||||
if (m_displayFilter)
|
||||
m_displayFilter->addChangedCallback(this);
|
||||
}
|
||||
|
||||
onAesDisplayFilterChanged(AreaEffectSimulation::AesType_def::AtMineAreaSingleMines);
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &GuezIed2SituationMap::partitionTimeChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_guezIedDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_guezIedDtc.get(), &GuezIedManagement::Interface::Dtc::iedChanged,
|
||||
this, &GuezIed2SituationMap::onIedChanged);
|
||||
connect(m_guezIedDtc.get(), &GuezIedManagement::Interface::Dtc::iedPositionChanged,
|
||||
this, &GuezIed2SituationMap::onIedPositionChanged);
|
||||
|
||||
|
||||
m_guezIedDtc->ieds([this](const GuezIedManagement::Ied & data)
|
||||
{
|
||||
onIedChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
|
||||
m_guezIedDtc->iedPositions([this](const GuezIedManagement::IedPosition & data)
|
||||
{
|
||||
onIedPositionChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
onAesDisplayFilterChanged(AreaEffectSimulation::AesType_def::AtMineAreaSingleMines);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
if (!m_guezIedGuiIfc)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
m_guezIedGuiIfc->showInfoWindow(simIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_guezIedDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [simIdOut, &umodOut](const GuezIedManagement::Ied & data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_equipmentNumber = data.equipmentNumber();
|
||||
umodOut.m_partyId = data.partyId();
|
||||
umodOut.m_description1 = QString::fromStdString(data.name());
|
||||
umodOut.m_description2 = QString::number(data.explosiveForce());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const GuezIedManagement::Ied &data)> cb1 = cb;
|
||||
return m_guezIedDtc->ieds(cb1);
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::onIedChanged(const GuezIedManagement::Ied &data,
|
||||
DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "onIedChanged: " << data;
|
||||
|
||||
updateDdsDataContainer(data, modType);
|
||||
handleChanged(data, modType);
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::onIedPositionChanged(const GuezIedManagement::IedPosition &data, DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "onIedPositionChanged: " << data;
|
||||
|
||||
const int32_t simId = data.id();
|
||||
const Core::GeoPosition &geoPos = data.position();
|
||||
|
||||
|
||||
auto it = m_simId2UniqueMapId.constFind(simId);
|
||||
if (it == m_simId2UniqueMapId.constEnd())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " GUEZ Ied not found simId = " << simId;
|
||||
return;
|
||||
}
|
||||
|
||||
const UniqueMapId uniqueMapId = it.value();
|
||||
RefPointer<Sim2SituationMap::MAP_T> mapObj = m_objFac.get<Sim2SituationMap::MAP_T>(uniqueMapId);
|
||||
if (mapObj)
|
||||
{
|
||||
|
||||
mapObj->setOrigin(Point3D(geoPos.lon(), geoPos.lat(), geoPos.z()));
|
||||
if (!mapObj->updateView())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " GUEZ Ied updateView failed"
|
||||
<< " simId = " << simId
|
||||
<< " uniqueMapId = " << uniqueMapId ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " GUEZ Ied not found in objFac"
|
||||
<< " simId = " << simId
|
||||
<< " uniqueMapId = " << uniqueMapId ;
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return;
|
||||
}
|
||||
|
||||
Injury guezIedStateToInjury(const GuezIedManagement::IedTacticalState &iedState)
|
||||
{
|
||||
switch (iedState.underlying())
|
||||
{
|
||||
case GuezIedManagement::IedTacticalState::Active:
|
||||
return AdvancedSymbology::Injury::NoInjury;
|
||||
break;
|
||||
default:
|
||||
return AdvancedSymbology::Injury::TotalKill;
|
||||
}
|
||||
}
|
||||
|
||||
void updateIedPyro(const GuezIedManagement::IedTacticalState &iedStateIn,
|
||||
AdvancedSymbology::Injury &injuryInOut,
|
||||
QString &symbolInOut)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (injuryInOut != AdvancedSymbology::Injury::TotalKill)
|
||||
return;
|
||||
|
||||
switch (iedStateIn.underlying())
|
||||
{
|
||||
case GuezIedManagement::IedTacticalState::Unknown:
|
||||
case GuezIedManagement::IedTacticalState::NotActive:
|
||||
case GuezIedManagement::IedTacticalState::Active:
|
||||
|
||||
break;
|
||||
case GuezIedManagement::IedTacticalState::TriggeredBySwitch:
|
||||
case GuezIedManagement::IedTacticalState::TriggeredByRemote:
|
||||
case GuezIedManagement::IedTacticalState::TriggeredByLightBarrier:
|
||||
case GuezIedManagement::IedTacticalState::TriggeredByTautWire:
|
||||
case GuezIedManagement::IedTacticalState::TriggeredByControlDevice:
|
||||
{
|
||||
|
||||
|
||||
const QString &bsc = AdvancedSymbology::SidcBuilderBase::concreteSidcToBaseSymbolCode(symbolInOut);
|
||||
|
||||
if ((bsc.compare(QStringLiteral("AP6D|BASE|40110300")) == 0 ||
|
||||
bsc.compare(QStringLiteral("M25D|BASE|40110300")) == 0)
|
||||
)
|
||||
{
|
||||
symbolInOut = QStringLiteral("AP6D|CMPL|10014000001103010000");
|
||||
injuryInOut = AdvancedSymbology::Injury::NoInjury;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GuezIedManagement::IedTacticalState::Defused:
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " id=" << ddsData.id()
|
||||
<< " name=" << ddsData.name();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SymbolData symData = mapObj->symbol();
|
||||
symData.sidc = QString::fromStdString(ddsData.symbol());
|
||||
|
||||
|
||||
mapObj->setTextModifier(Participant::TextModifier::T_UniqueDesignation, QString::fromStdString(ddsData.name()));
|
||||
mapObj->setTextModifier(Participant::TextModifier::M_HigherFormation, QString::number(ddsData.explosiveForce()));
|
||||
|
||||
|
||||
mapObj->setPartyId(ddsData.partyId());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AdvancedSymbology::Injury injury = guezIedStateToInjury(ddsData.tacticalState());
|
||||
if ((ddsData.type() == GuezIedManagement::IedType_def::IedSmallPyro) ||
|
||||
(ddsData.type() == GuezIedManagement::IedType_def::IedBigPyro))
|
||||
{
|
||||
updateIedPyro(ddsData.tacticalState(), injury, symData.sidc);
|
||||
}
|
||||
|
||||
int32_t injuryPartyId = -1;
|
||||
mapObj->setInjury(injury, injuryPartyId);
|
||||
|
||||
mapObj->setSymbol(symData);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_symbolAppearanceSettings)
|
||||
handleSymbolAppearanceSettings(mapObj, ddsData);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "GuezIed2SituationMap";
|
||||
|
||||
if (!m_displayFilter || aesType != AreaEffectSimulation::AesType_def::AtMineAreaSingleMines)
|
||||
return;
|
||||
|
||||
m_effectStateStruct = m_displayFilter->effectStateFilter(AreaEffectSimulation::AesType_def::AtMineAreaSingleMines);
|
||||
|
||||
|
||||
handleSymbolAppearanceSettings();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part)
|
||||
{
|
||||
if ((part != FilterManagement::SymbolAppearanceSettings::Part::All) &&
|
||||
(part != FilterManagement::SymbolAppearanceSettings::Part::Symbol))
|
||||
return;
|
||||
|
||||
|
||||
const bool relevant = symbolAppearanceSettingsChangesAreRelevant(m_symbolAppearanceSettings->settings());
|
||||
|
||||
m_currentSymbolSettings = m_symbolAppearanceSettings->settings();
|
||||
|
||||
if (!relevant)
|
||||
return;
|
||||
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.symbolTransparency != newSas.symbolSettings.symbolTransparency) ||
|
||||
(m_currentSymbolSettings.symbolSettings.symbolPartyAppearance != newSas.symbolSettings.symbolPartyAppearance);
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::handleSymbolAppearanceSettings()
|
||||
{
|
||||
for (const GuezIedManagement::Ied &ied : qAsConst(m_ddsDataContainer))
|
||||
{
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(ied.id(), INVALID_MAP_ID);
|
||||
if (uniqueMapId == INVALID_MAP_ID)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << "Found a ied which is in internal map but has no map object...: " << ied.id();
|
||||
continue;
|
||||
}
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj, ied);
|
||||
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj, const Sim2SituationMap::DDS_T &ddsData)
|
||||
{
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
|
||||
mapObj->setScale(filterSettings.symbolSettings.symbolScale);
|
||||
mapObj->setUserSymbolOpacity(1.0f - filterSettings.symbolSettings.symbolTransparency);
|
||||
|
||||
const auto spa = filterSettings.symbolSettings.symbolPartyAppearance.value(ddsData.partyId());
|
||||
mapObj->setTextModifierVisibility(Participant::TextModifier::T_UniqueDesignation, spa.showDesignator);
|
||||
mapObj->setTextModifierVisibility(Participant::TextModifier::M_HigherFormation, spa.showTacticalIdentifier);
|
||||
|
||||
const bool isVisi = isVisible(ddsData);
|
||||
mapObj->setVisibility(isVisi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GuezIed2SituationMap::isVisible(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
bool isVisi = visibleBySymbolPartyAppearance(ddsData) &&
|
||||
visibleByAesFilter(ddsData);
|
||||
|
||||
return isVisi;
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
const auto spa = filterSettings.symbolSettings.symbolPartyAppearance.value(ddsData.partyId());
|
||||
return spa.isVisible;
|
||||
}
|
||||
|
||||
bool GuezIed2SituationMap::visibleByAesFilter(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
switch (ddsData.tacticalState().underlying())
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case GuezIedManagement::IedTacticalState_def::NotActive:
|
||||
return m_effectStateStruct.displayPrepared;
|
||||
case GuezIedManagement::IedTacticalState_def::Active:
|
||||
return m_effectStateStruct.displayActivated;
|
||||
case GuezIedManagement::IedTacticalState_def::Unknown:
|
||||
return false;
|
||||
|
||||
case GuezIedManagement::IedTacticalState_def::Defused:
|
||||
case GuezIedManagement::IedTacticalState_def::TriggeredByControlDevice:
|
||||
case GuezIedManagement::IedTacticalState_def::TriggeredByLightBarrier:
|
||||
case GuezIedManagement::IedTacticalState_def::TriggeredByRemote:
|
||||
case GuezIedManagement::IedTacticalState_def::TriggeredBySwitch:
|
||||
case GuezIedManagement::IedTacticalState_def::TriggeredByTautWire:
|
||||
auto timeTriggered = ddsData.sampleTime();
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineAreaSingleMines);
|
||||
const auto afterGlow = m_effectStateStruct.expiredAfterglowDurationMSec;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " partitionTime=" << m_pluginProvider->partitionTime()
|
||||
<< " timeTriggered" << timeTriggered
|
||||
<< " afterGlow" << afterGlow
|
||||
<< " timeTriggered + afterGlow=" << timeTriggered + afterGlow;
|
||||
return (m_pluginProvider->partitionTime() < timeTriggered + afterGlow);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuezIed2SituationMap::partitionTimeChanged()
|
||||
{
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <GuezIedManagement/gim_data_plugin_interface.h>
|
||||
#include <GuezIedManagement/gim_info_gui_plugin_interface.h>
|
||||
#include <FilterManagement/flt_data_plugin_aes_display_filter.h>
|
||||
#include <AreaEffectSimulation/aes_enums.hpp>
|
||||
#include <MapObjects/participant.h>
|
||||
|
||||
namespace Buildings
|
||||
{
|
||||
class ForeignInfoGuiInterface;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class GuezIed2SituationMap final : public Sim2SituationMap<GuezIedManagement::Ied, SituationMap::Participant>
|
||||
, protected FilterManagement::AesDisplayFilter::FilterChangedCallback
|
||||
, protected DdsFilterHandling<SituationMap::Participant>
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = SituationMap::Sim2SituationMap<GuezIedManagement::Ied, SituationMap::Participant>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::Participant>;
|
||||
|
||||
public:
|
||||
GuezIed2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
~GuezIed2SituationMap();
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override
|
||||
{
|
||||
if (m_guezIedDtc)
|
||||
m_guezIedDtc->disconnect(this);
|
||||
if (m_pluginProvider)
|
||||
disconnect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &GuezIed2SituationMap::partitionTimeChanged);
|
||||
}
|
||||
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onIedChanged(const GuezIedManagement::Ied &data, DataModification modType = DataModification::eAdded);
|
||||
void onIedPositionChanged(const GuezIedManagement::IedPosition &data, DataModification modType = DataModification::eAdded);
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
|
||||
protected:
|
||||
void partitionTimeChanged();
|
||||
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) override;
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId());
|
||||
handleSymbolAppearanceSettings(mapObj, m_ddsDataContainer.value(simId));
|
||||
}
|
||||
|
||||
void handleSymbolAppearanceSettings();
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj, const Sim2SituationMap::DDS_T &ddsData);
|
||||
|
||||
|
||||
|
||||
|
||||
bool isVisible(const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
bool visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
bool visibleByAesFilter(const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<GuezIedManagement::Interface::Dtc> m_guezIedDtc;
|
||||
std::shared_ptr<GuezIedManagement::ForeignGuiInterface> m_guezIedGuiIfc;
|
||||
PluginProvider *m_pluginProvider;
|
||||
|
||||
std::shared_ptr<FilterManagement::AesDisplayFilter> m_displayFilter;
|
||||
FilterManagement::AesDisplayFilter::EffectStateStruct m_effectStateStruct;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "guez_nasat_9liner.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <MathUtils/simple_helper.h>
|
||||
#include <Common/PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
|
||||
#include <QPolygonF>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
int32_t GuezNasat9Liner2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
GuezNasat9Liner2SituationMap::GuezNasat9Liner2SituationMap(ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
, m_notifyTimer(new QTimer(this))
|
||||
{
|
||||
m_notifyTimer->setInterval(500);
|
||||
m_notifyTimer->setSingleShot(true);
|
||||
connect(m_notifyTimer, &QTimer::timeout,
|
||||
this, &GuezNasat9Liner2SituationMap::updateAllItems);
|
||||
}
|
||||
|
||||
GuezNasat9Liner2SituationMap::~GuezNasat9Liner2SituationMap()
|
||||
{
|
||||
m_notifyTimer->stop();
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no pluginProvider";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
m_gnaDtc = pluginProvider->gnaDtc();
|
||||
if (!m_gnaDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_gnaDtc";
|
||||
return false;
|
||||
}
|
||||
m_gnaDtc->enableNasat9Liner();
|
||||
|
||||
|
||||
m_ppmDtc = pluginProvider->ppmDtc();
|
||||
if (!m_ppmDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_ppmDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &GuezNasat9Liner2SituationMap::onPartitionTimeChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_gnaDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
|
||||
this, &GuezNasat9Liner2SituationMap::onParticipantChanged, Qt::UniqueConnection);
|
||||
|
||||
m_ppmDtc->participants([this](const ParticipantManagement::Participant &data)
|
||||
{
|
||||
onParticipantChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
connect(m_gnaDtc.get(), &GuezNasat::Interface::Dtc::nasat9LinerChanged,
|
||||
this, &GuezNasat9Liner2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_gnaDtc->nasat9Liners([this](const GuezNasat::Nasat9Liner & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::isElapsed(const GuezNasat::Nasat9Liner &ddsData) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData;
|
||||
|
||||
if (BaseClass::isElapsed(ddsData))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData << " HIDE";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData << " SHOW";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
|
||||
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_gnaDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
umodOut.m_description1 = QString::fromStdString(m_gnaDtc->nasat9Liner(simIdOut).name());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void GuezNasat9Liner2SituationMap::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " pId=" << data.id()
|
||||
<< " parytIdOld=" << m_participantToPartyId.value(data.id(), -1)
|
||||
<< " parytId=" << data.partyId()
|
||||
<< ", m_participantToPartyId.size()=" << m_participantToPartyId.size();
|
||||
const int simId = data.id();
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
m_participantToPartyId[simId] = data.partyId();
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
m_ddsDataContainer.remove(simId);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_notifyTimer->start();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_participantToPartyId.size()=" << m_participantToPartyId.size();
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::handleChanged(const Sim2SituationMap::DDS_T &ddsData, DataModification modType)
|
||||
{
|
||||
m_notifyTimer->start();
|
||||
updateDdsDataContainer(ddsData, modType);
|
||||
return BaseClass::handleChanged(ddsData, modType);
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " id=" << ddsData.id()
|
||||
<< " name=" << ddsData.name()
|
||||
<< " isCurrent=" << ddsData.isCurrent()
|
||||
<< " initialPoint=" << ddsData.initialPoint()
|
||||
<< " targetPosition=" << ddsData.targetPosition()
|
||||
<< " participantId=" << ddsData.participantId()
|
||||
<< " m_participantToPartyId.size()=" << m_participantToPartyId.size()
|
||||
<< " partyId.size()=" << m_participantToPartyId.value(ddsData.participantId(), -1);
|
||||
|
||||
mapObj->setPickable(false);
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
|
||||
|
||||
mapObj->setPartyId(m_participantToPartyId.value(ddsData.participantId(), -1));
|
||||
|
||||
TextStyle ts = mapObj->textStyle();
|
||||
ts.setHorizontalAlignment(HorizontalAlignment::Center);
|
||||
mapObj->setTextStyle(ts);
|
||||
|
||||
MAP_T::NineLinerData data;
|
||||
data.initialPoint = Point3D(ddsData.initialPoint().lon(), ddsData.initialPoint().lat(), .0);
|
||||
data.targetPosition = Point3D(ddsData.targetPosition().lon(), ddsData.targetPosition().lat(), .0);
|
||||
data.fah = ddsData.finalAttackHeading();
|
||||
data.fahLow = ddsData.finalAttackHeadingLow();
|
||||
data.fahHigh = ddsData.finalAttackHeadingHigh();
|
||||
data.friendliesBearing = ddsData.friendliesBearing();
|
||||
data.friendliesDistance = ddsData.friendliesDistance();
|
||||
|
||||
mapObj->setNineLinerData(data);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec != newSas.symbolSettings.nasatNineLinerDisplayLengthMSec);
|
||||
}
|
||||
|
||||
void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
|
||||
|
||||
for (const GuezNasat::Nasat9Liner &nineLiner : qAsConst(m_ddsDataContainer))
|
||||
{
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(nineLiner.id());
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj, nineLiner);
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
|
||||
}
|
||||
|
||||
void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId());
|
||||
handleSymbolAppearanceSettings(mapObj, m_ddsDataContainer.value(simId));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings(RefPointer<Sim2SituationMap::MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData)
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
|
||||
const bool isVisi = visibleByDisplayLength(m_pluginProvider->partitionTime(), ddsData.sampleTime());
|
||||
|
||||
if (mapObj->visibility() != isVisi)
|
||||
{
|
||||
mapObj->setVisibility(isVisi);
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
}
|
||||
}
|
||||
|
||||
bool GuezNasat9Liner2SituationMap::visibleByDisplayLength(const qint64 newPartitionTime, const qint64 stateTime) const
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " newPartitionTime = " << newPartitionTime
|
||||
<< " stateTime = " << stateTime
|
||||
<< " age = " << (newPartitionTime - stateTime)
|
||||
<< " nasatNineLinerDisplayLengthMSec = " << m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec;
|
||||
|
||||
if (m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec < 0)
|
||||
return true;
|
||||
return (newPartitionTime - stateTime) <= m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec;
|
||||
|
||||
}
|
||||
|
||||
void GuezNasat9Liner2SituationMap::onPartitionTimeChanged()
|
||||
{
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
void GuezNasat9Liner2SituationMap::updateAllItems()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
|
||||
for (const DDS_T &ddsData : qAsConst(m_ddsDataContainer))
|
||||
{
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(ddsData.id());
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
updateElementImpl(ddsData, mapObj);
|
||||
handleSymbolAppearanceSettings(mapObj);
|
||||
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed for "<< mapObj->debugInfo();
|
||||
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/GuezNasat/gna_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <MapObjects/polyline.h>
|
||||
#include <MapObjects/nine_liner.h>
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace Buildings
|
||||
{
|
||||
class ForeignInfoGuiInterface;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class GuezNasat9Liner2SituationMap final : public Sim2SituationMap<GuezNasat::Nasat9Liner, SituationMap::NineLiner>
|
||||
, protected DdsFilterHandling<SituationMap::NineLiner>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<GuezNasat::Nasat9Liner, SituationMap::NineLiner>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::NineLiner>;
|
||||
|
||||
public:
|
||||
explicit GuezNasat9Liner2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
~GuezNasat9Liner2SituationMap();
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override
|
||||
{
|
||||
|
||||
|
||||
if (m_gnaDtc)
|
||||
m_gnaDtc->disconnect(this);
|
||||
if (m_ppmDtc)
|
||||
m_ppmDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool isElapsed(const GuezNasat::Nasat9Liner &ddsData) const override;
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType);
|
||||
void updateAllItems();
|
||||
|
||||
protected:
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool handleChanged(const DDS_T &ddsData, DataModification modType);
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings();
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData);
|
||||
bool visibleByDisplayLength(const qint64 newPartitionTime, const qint64 stateTime) const;
|
||||
void onPartitionTimeChanged();
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider{nullptr};
|
||||
std::shared_ptr<GuezNasat::Interface::Dtc> m_gnaDtc;
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
QHash<int, int> m_participantToPartyId;
|
||||
|
||||
QTimer *m_notifyTimer{nullptr};
|
||||
|
||||
QMap<int, qint64> m_lastSampleTimePerParticipant;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+541
@@ -0,0 +1,541 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "hitlineinfo_to_map.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/map.h>
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <LtsUtilsCore/outdated_position.h>
|
||||
#include <MathUtils/simple_helper.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
HitlineInfo2SituationMap::HitlineInfo2SituationMap(PdmHandler *pdmHandler,
|
||||
Participant2SituationMap *participant2SituationMap,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pdmHandler(pdmHandler)
|
||||
, m_participant2SituationMap(participant2SituationMap)
|
||||
, m_pBuildingHitlineCleanupTimer(new QTimer(this))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_pBuildingHitlineCleanupTimer->setInterval(1000 * 60 * 5);
|
||||
connect(m_pBuildingHitlineCleanupTimer, &QTimer::timeout, this, &HitlineInfo2SituationMap::onCleanupBuildingHitlines);
|
||||
m_pBuildingHitlineCleanupTimer->start();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
HitlineInfo2SituationMap::~HitlineInfo2SituationMap()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
int32_t HitlineInfo2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->ppmDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
m_ppmDtc = pluginProvider->ppmDtc();
|
||||
|
||||
if (!m_ppmDtc)
|
||||
return false;
|
||||
|
||||
auto bldDtc = m_pluginProvider->bldDtc();
|
||||
if (bldDtc)
|
||||
{
|
||||
connect(bldDtc.get(), &Buildings::Interface::Dtc::buildingHitLineInfoChanged,
|
||||
this, &HitlineInfo2SituationMap::onBuildingHitlineInfoChanged);
|
||||
bldDtc->buildingHitLineInfos([this](const Buildings::BuildingHitLineInfo & data)
|
||||
{
|
||||
onBuildingHitlineInfoChanged(data, DataModification::eAdded);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &HitlineInfo2SituationMap::onPartitionTimeChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_ppmDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::hitLineInfoChanged,
|
||||
this, &HitlineInfo2SituationMap::onHitLineInfoChanged);
|
||||
|
||||
|
||||
m_ppmDtc->hitLineInfos([this](const Sim2SituationMap::DDS_T & ddsData)
|
||||
{
|
||||
onHitLineInfoChanged(ddsData, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void HitlineInfo2SituationMap::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_ppmDtc)
|
||||
m_ppmDtc->disconnect(this);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::isElapsed(const ParticipantManagement::HitLineInfo &ddsData) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const Core::GeoPosition &startGeoPos = ddsData.originatorPos();
|
||||
const Core::GeoPosition &endGeoPos = ddsData.injuryPos();
|
||||
{
|
||||
Point3D dummy(startGeoPos.lon(), startGeoPos.lat(), startGeoPos.z());
|
||||
if (dummy.isNull())
|
||||
return true;
|
||||
}
|
||||
{
|
||||
Point3D dummy(endGeoPos.lon(), endGeoPos.lat(), endGeoPos.z());
|
||||
if (dummy.isNull())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
{
|
||||
if (startGeoPos.z() < 0)
|
||||
return true;
|
||||
if (endGeoPos.z() < 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
auto ppmParticipantInfoIfc = m_pluginProvider->ppmParticipantInfoIfc();
|
||||
if (!ppmParticipantInfoIfc)
|
||||
return false;
|
||||
|
||||
const QVector<qint32> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
ppmParticipantInfoIfc->showHitLineInfoWindow(simIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString HitlineInfo2SituationMap::chargeTypeIdentifier(const int32_t originatorChargeTypeId) const
|
||||
{
|
||||
if (!m_pdmHandler)
|
||||
return QStringLiteral("ctId_%1").arg(originatorChargeTypeId);
|
||||
|
||||
QString chargeTypeString = m_pdmHandler->trChargeTypeShortName(originatorChargeTypeId);
|
||||
if (chargeTypeString.isEmpty())
|
||||
return QStringLiteral("ctId_%1").arg(originatorChargeTypeId);
|
||||
return chargeTypeString;
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_ppmDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [this, simIdOut, &umodOut](const Sim2SituationMap::DDS_T & ddsData) -> bool
|
||||
{
|
||||
if (ddsData.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_partyId = ddsData.originatorPartyId();
|
||||
const int32_t originatorChargeTypeId = ddsData.chargeTypeId();
|
||||
umodOut.m_description1 = chargeTypeIdentifier(originatorChargeTypeId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const Sim2SituationMap::DDS_T &ddsData)> cb1 = cb;
|
||||
return m_ppmDtc->hitLineInfos(cb1);
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::onHitLineInfoChanged(const Sim2SituationMap::DDS_T &ddsData,
|
||||
DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", ddsData.id()=" << ddsData.id()
|
||||
<< ", ddsData.injuryBuildingId()=" << ddsData.injuryBuildingId()
|
||||
<< ", modType=" << modType
|
||||
<< ", m_buildingHits.size()=" << m_buildingHits.size();
|
||||
|
||||
|
||||
if (((modType==DataModification::eAdded) || (modType==DataModification::eModified)) &&
|
||||
(!visibleByBldgHitlines(ddsData))
|
||||
)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Not showing participant hitline " << ddsData <<
|
||||
" since there is already a hitline on the building";
|
||||
return true;
|
||||
}
|
||||
|
||||
updateDdsDataContainer(ddsData, modType);
|
||||
return handleChanged(ddsData, modType);
|
||||
}
|
||||
|
||||
|
||||
void HitlineInfo2SituationMap::onBuildingHitlineInfoChanged(const Buildings::BuildingHitLineInfo &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", data.id()=" << data.id()
|
||||
<< ", data.originatorParticipantId()=" << data.originatorParticipantId()
|
||||
<< ", data.buildingId()=" << data.buildingId()
|
||||
<< ", modType=" << modType
|
||||
<< ", m_buildingHits.size()=" << m_buildingHits.size();
|
||||
|
||||
if (modType != DataModification::eAdded && modType != DataModification::eModified)
|
||||
return;
|
||||
|
||||
BuildingHit bh;
|
||||
bh.sampleTime = data.sampleTime();
|
||||
bh.originatorParticipantId = data.originatorParticipantId();
|
||||
bh.chargeTypeId = data.chargeTypeId();
|
||||
m_buildingHits[data.buildingId()].push_back(bh);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< ", data.id()=" << data.id()
|
||||
<< ", data.originatorParticipantId()=" << data.originatorParticipantId()
|
||||
<< ", data.buildingId()=" << data.buildingId()
|
||||
<< ", modType=" << modType
|
||||
<< ", m_buildingHits.size()=" << m_buildingHits.size();
|
||||
}
|
||||
|
||||
void HitlineInfo2SituationMap::onCleanupBuildingHitlines()
|
||||
{
|
||||
const qint64 tNow = QDateTime::currentMSecsSinceEpoch();
|
||||
const auto isOutdated = [tNow](const BuildingHit &bh)
|
||||
{
|
||||
return LtsUtils::isPositionTimeOutdated(tNow, bh.sampleTime);
|
||||
};
|
||||
for (auto &hitLines : m_buildingHits)
|
||||
hitLines.erase(std::remove_if(hitLines.begin(), hitLines.end(), isOutdated), hitLines.end());
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::createElement(const DDS_T &ddsData)
|
||||
{
|
||||
const int32_t simId = getSimId(ddsData);
|
||||
if (!m_simId2UniqueMapId.contains(simId))
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " new Hitline !!!!" << " simId = " << simId;
|
||||
|
||||
const SpecialChargeType specialChargeTypeId = m_pdmHandler->isSpecialChargeType(ddsData.chargeTypeId());
|
||||
if (PdmHandler::isChargeTypeLtdOrLrf(specialChargeTypeId))
|
||||
m_participant2SituationMap->onParticipantFakeGearEventChanged(ddsData.originatorParticipantId(), ddsData.sampleTime(), specialChargeTypeId);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return BaseClass::createElement(ddsData);
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
const qint32 hitlineId = ddsData.id();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " id=" << hitlineId;
|
||||
|
||||
|
||||
mapObj->setVisibility(SituationMap::ObjectAppearance::Tactical, false);
|
||||
mapObj->rLineStyle().setLineWidth(3);
|
||||
|
||||
|
||||
LineStyle ls = mapObj->lineStyle();
|
||||
|
||||
const SpecialChargeType sct = m_pdmHandler->isSpecialChargeType(ddsData.chargeTypeId());
|
||||
switch (sct)
|
||||
{
|
||||
case SpecialChargeType::LRF:
|
||||
ls.setLinePattern(LinePattern::Dot);
|
||||
break;
|
||||
case SpecialChargeType::LTD:
|
||||
ls.setLinePattern(LinePattern::Solid);
|
||||
break;
|
||||
case SpecialChargeType::NoneSpecial:
|
||||
default:
|
||||
ls.setLinePattern(LinePattern::Dash);
|
||||
}
|
||||
|
||||
mapObj->setLineStyle(ls);
|
||||
|
||||
|
||||
mapObj->setPartyId(ddsData.originatorPartyId());
|
||||
|
||||
|
||||
const int32_t originatorChargeTypeId = ddsData.chargeTypeId();
|
||||
mapObj->setIdentifier(chargeTypeIdentifier(originatorChargeTypeId));
|
||||
|
||||
|
||||
|
||||
const Core::GeoPosition &startGeoPos = ddsData.originatorPos();
|
||||
const Core::GeoPosition &endGeoPos = ddsData.injuryPos();
|
||||
mapObj->setStartAndEndPoint(Point3D(startGeoPos.lon(), startGeoPos.lat(), startGeoPos.z()),
|
||||
Point3D(endGeoPos.lon(), endGeoPos.lat(), endGeoPos.z()));
|
||||
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj, ddsData);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " id=" << hitlineId;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HitlineInfo2SituationMap::onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part)
|
||||
{
|
||||
if ((part != FilterManagement::SymbolAppearanceSettings::Part::All) &&
|
||||
(part != FilterManagement::SymbolAppearanceSettings::Part::Symbol))
|
||||
return;
|
||||
|
||||
|
||||
const bool relevant = symbolAppearanceSettingsChangesAreRelevant(m_symbolAppearanceSettings->settings());
|
||||
|
||||
m_currentSymbolSettings = m_symbolAppearanceSettings->settings();
|
||||
|
||||
if (!relevant)
|
||||
return;
|
||||
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return qFuzzyCompare(m_currentSymbolSettings.symbolSettings.symbolScale, newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.symbolPartyAppearance != newSas.symbolSettings.symbolPartyAppearance) ||
|
||||
(m_currentSymbolSettings.symbolSettings.hitLineDisplayLengthMSec != newSas.symbolSettings.hitLineDisplayLengthMSec||
|
||||
(m_currentSymbolSettings.symbolSettings.lrfLineDisplayLengthMSec != newSas.symbolSettings.lrfLineDisplayLengthMSec)||
|
||||
(m_currentSymbolSettings.symbolSettings.ltdLineDisplayLengthMSec != newSas.symbolSettings.ltdLineDisplayLengthMSec));
|
||||
}
|
||||
|
||||
void HitlineInfo2SituationMap::handleSymbolAppearanceSettings()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
|
||||
|
||||
for (const ParticipantManagement::HitLineInfo &hitline : qAsConst(m_ddsDataContainer))
|
||||
{
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(hitline.id());
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj, hitline);
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size();
|
||||
}
|
||||
|
||||
void HitlineInfo2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " ddsData.id()=" << ddsData.id()
|
||||
<< ", mapObj = " << mapObj->debugInfo();
|
||||
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
mapObj->setScale(filterSettings.symbolSettings.symbolScale);
|
||||
|
||||
bool bUncertain = false;
|
||||
const bool isVisi = isVisible(ddsData, &bUncertain);
|
||||
if (bUncertain)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
QTimer::singleShot(200, this, [this, ddsData]()
|
||||
{
|
||||
RefPointer<MAP_T> mapObj = getMapObjectOfSimId(ddsData.id());
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
handleSymbolAppearanceSettings(mapObj, ddsData);
|
||||
});
|
||||
}
|
||||
if (mapObj->visibility() != isVisi)
|
||||
{
|
||||
mapObj->setVisibility(isVisi);
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " ddsData.id()=" << ddsData.id()
|
||||
<< ", mapObj = " << mapObj->debugInfo();
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::isVisible(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const
|
||||
{
|
||||
return
|
||||
visibleByBldgHitlines(ddsData) &&
|
||||
visibleBySymbolPartyAppearance(ddsData) &&
|
||||
visibleByHitLineDisplayLength(m_pluginProvider->partitionTime(), ddsData) &&
|
||||
visibleByParticipants(ddsData, bUncertain);
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
const FilterManagement::SymbolAppearanceSettings::Settings &filterSettings = m_symbolAppearanceSettings->settings();
|
||||
const auto spa = filterSettings.symbolSettings.symbolPartyAppearance.value(ddsData.originatorPartyId());
|
||||
return spa.isVisible;
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::visibleByParticipants(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (!m_participant2SituationMap)
|
||||
return true;
|
||||
|
||||
bool bParticipant1Exists = true;
|
||||
bool bParticipant2Exists = true;
|
||||
bool visi =
|
||||
m_participant2SituationMap->isParticipantVisible(ddsData.originatorParticipantId(), &bParticipant1Exists) &&
|
||||
m_participant2SituationMap->isParticipantVisible(ddsData.injuryParticipantId(), &bParticipant2Exists);
|
||||
|
||||
if ((!bParticipant1Exists || !bParticipant2Exists) && bUncertain)
|
||||
*bUncertain = true;
|
||||
return visi;
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::visibleByBldgHitlines(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
auto itBuildingHit = m_buildingHits.constFind(ddsData.injuryBuildingId());
|
||||
if (itBuildingHit != m_buildingHits.constEnd())
|
||||
{
|
||||
const QVector<BuildingHit> &bHits = itBuildingHit.value();
|
||||
|
||||
|
||||
qint64 displayLength = m_currentSymbolSettings.symbolSettings.hitLineDisplayLengthMSec;
|
||||
const SpecialChargeType sct = m_pdmHandler->isSpecialChargeType(ddsData.chargeTypeId());
|
||||
switch (sct)
|
||||
{
|
||||
case SpecialChargeType::LRF:
|
||||
displayLength = m_currentSymbolSettings.symbolSettings.lrfLineDisplayLengthMSec;
|
||||
break;
|
||||
case SpecialChargeType::LTD:
|
||||
displayLength = m_currentSymbolSettings.symbolSettings.ltdLineDisplayLengthMSec;
|
||||
break;
|
||||
case SpecialChargeType::NoneSpecial:
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (const BuildingHit &bh : bHits)
|
||||
{
|
||||
if (bh.chargeTypeId == ddsData.chargeTypeId() &&
|
||||
bh.originatorParticipantId == ddsData.originatorParticipantId() &&
|
||||
ddsData.sampleTime() - displayLength < bh.sampleTime)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Not showing participant hitline " << ddsData << " since there is already a hitline on the building";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HitlineInfo2SituationMap::visibleByHitLineDisplayLength(const qint64 newPartitionTime, const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
const qint64 stateTime = ddsData.sampleTime();
|
||||
qint64 displayLength = m_currentSymbolSettings.symbolSettings.hitLineDisplayLengthMSec;
|
||||
|
||||
const SpecialChargeType sct = m_pdmHandler->isSpecialChargeType(ddsData.chargeTypeId());
|
||||
switch (sct)
|
||||
{
|
||||
case SpecialChargeType::LRF:
|
||||
displayLength = m_currentSymbolSettings.symbolSettings.lrfLineDisplayLengthMSec;
|
||||
break;
|
||||
case SpecialChargeType::LTD:
|
||||
displayLength = m_currentSymbolSettings.symbolSettings.ltdLineDisplayLengthMSec;
|
||||
break;
|
||||
case SpecialChargeType::NoneSpecial:
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " newPartitionTime = " << newPartitionTime
|
||||
<< " stateTime = " << stateTime
|
||||
<< " age = " << (newPartitionTime - stateTime)
|
||||
<< " SpecialChargeType = " << sct
|
||||
<< " displayLengthMSec = " << displayLength;
|
||||
|
||||
if (displayLength <= 0)
|
||||
return false;
|
||||
|
||||
return (newPartitionTime - stateTime) <= displayLength;
|
||||
}
|
||||
|
||||
|
||||
void HitlineInfo2SituationMap::onPartitionTimeChanged()
|
||||
{
|
||||
handleSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include "participant_to_map.h"
|
||||
#include <MapObjects/hit_line.h>
|
||||
|
||||
#include <Buildings/bld_dtc.h>
|
||||
#include <FilterManagement/flt_dtc.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_participant_info_gui_plugin_interface.h>
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
class PdmHandler;
|
||||
|
||||
|
||||
class HitlineInfo2SituationMap final : public Sim2SituationMap<ParticipantManagement::HitLineInfo, SituationMap::HitLine>
|
||||
, protected DdsFilterHandling<SituationMap::HitLine>
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = SituationMap::Sim2SituationMap<ParticipantManagement::HitLineInfo, SituationMap::HitLine>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::HitLine>;
|
||||
|
||||
public:
|
||||
HitlineInfo2SituationMap(PdmHandler *pdmHandler,
|
||||
Participant2SituationMap *participant2SituationMap,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName);
|
||||
~HitlineInfo2SituationMap();
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
bool isElapsed(const ParticipantManagement::HitLineInfo &ddsData) const override;
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
QString chargeTypeIdentifier(const int32_t originatorChargeTypeId) const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
bool onHitLineInfoChanged(const Sim2SituationMap::DDS_T &ddsData, DataModification modType = DataModification::eAdded);
|
||||
void onBuildingHitlineInfoChanged(const Buildings::BuildingHitLineInfo &data, DataModification modType);
|
||||
void onCleanupBuildingHitlines();
|
||||
|
||||
protected:
|
||||
bool isVisible(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const;
|
||||
bool visibleBySymbolPartyAppearance(const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
bool visibleByParticipants(const Sim2SituationMap::DDS_T &ddsData, bool *bUncertain) const;
|
||||
bool visibleByBldgHitlines(const Sim2SituationMap::DDS_T &ddsData) const;
|
||||
|
||||
bool visibleByHitLineDisplayLength(const qint64 newPartitionTime, const DDS_T &ddsData) const;
|
||||
void onPartitionTimeChanged();
|
||||
|
||||
bool createElement(const DDS_T &ddsData) override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) override;
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId());
|
||||
handleSymbolAppearanceSettings(mapObj, m_ddsDataContainer.value(simId));
|
||||
}
|
||||
|
||||
void handleSymbolAppearanceSettings();
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> mapObj, const Sim2SituationMap::DDS_T &ddsData);
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider = nullptr;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
|
||||
PdmHandler *m_pdmHandler = nullptr;
|
||||
|
||||
QPointer<Participant2SituationMap> m_participant2SituationMap;
|
||||
|
||||
struct BuildingHit
|
||||
{
|
||||
int64_t sampleTime = 0;
|
||||
int originatorParticipantId = 0;
|
||||
int chargeTypeId = 0;
|
||||
};
|
||||
QHash<int, QVector<BuildingHit>> m_buildingHits;
|
||||
QTimer *m_pBuildingHitlineCleanupTimer = nullptr;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
enum class MapObjectType {
|
||||
MOT_Undefined,
|
||||
MOT_Participant,
|
||||
MOT_Aes,
|
||||
MOT_Building,
|
||||
MOT_Bridge,
|
||||
MOT_MountingPoint,
|
||||
MOT_GuezIed,
|
||||
MOT_TrainingArea,
|
||||
MOT_SpecialArea,
|
||||
MOT_ShootbackArea
|
||||
};
|
||||
|
||||
}
|
||||
+440
@@ -0,0 +1,440 @@
|
||||
|
||||
|
||||
|
||||
#include "mine_area_null_to_map.h"
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <AreaEffectSimulation/Utils/ddsdbconvert.h>
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
#include <SituationMap/Symbology/sidc_codec.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
DusMineStateProxy::DusMineStateProxy(QObject *parent)
|
||||
: BaseClass(parent)
|
||||
, m_lastDusMineState()
|
||||
, m_lastItemView()
|
||||
, m_logger(getLogger("DusMineStateProxy"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DusMineStateProxy::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider)
|
||||
return false;
|
||||
|
||||
m_aesDtc = pluginProvider->aesDtc();
|
||||
|
||||
return m_aesDtc != nullptr;
|
||||
}
|
||||
|
||||
bool DusMineStateProxy::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::dusMineStateChanged,
|
||||
this, static_cast<bool (DusMineStateProxy::*)(const AreaEffectSimulation::DusMineState&, DataModification)>(&DusMineStateProxy::handleChanged), Qt::UniqueConnection);
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, static_cast<bool (DusMineStateProxy::*)(const AreaEffectSimulation::AesItemView&, DataModification)>(&DusMineStateProxy::handleChanged), Qt::UniqueConnection);
|
||||
|
||||
const std::function<bool(const AreaEffectSimulation::DusMineState &)> cbDusMineState = [this] (const AreaEffectSimulation::DusMineState &data) -> bool
|
||||
{ return handleChanged(data, DataModification::eAdded); };
|
||||
m_aesDtc->dusMineStates(cbDusMineState);
|
||||
|
||||
const std::function<bool(const AreaEffectSimulation::AesItemView &)> cbAesItemView = [this] (const AreaEffectSimulation::AesItemView &data) -> bool
|
||||
{ return handleChanged(data, DataModification::eAdded); };
|
||||
m_aesDtc->aesItemViews(cbAesItemView);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DusMineStateProxy::stop()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
this->disconnect();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool DusMineStateProxy::dusMineStateAndPositionDatas(const std::function<void (const DusMineStateAndPositionData &)> &cb)
|
||||
{
|
||||
if (m_map.isEmpty())
|
||||
return false;
|
||||
|
||||
for (auto it = m_map.constBegin(); it != m_map.constEnd(); ++it)
|
||||
cb(it.value());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DusMineStateProxy::dusMineStateAndPositionDatas(const std::function<bool (const DusMineStateAndPositionData &)> &cb)
|
||||
{
|
||||
if (m_map.isEmpty())
|
||||
return false;
|
||||
|
||||
for (auto it = m_map.constBegin(); it != m_map.constEnd(); ++it)
|
||||
if (cb(it.value()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool DusMineStateProxy::handleChanged(const AreaEffectSimulation::DusMineState &ddsData, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
|
||||
if (ddsData.id() != 0)
|
||||
return false;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, ddsData.id()=" << ddsData.id()
|
||||
<< " ddsData.mines().size() = " << ddsData.mines().size();
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
m_lastDusMineState = AreaEffectSimulation::DusMineState();
|
||||
else
|
||||
m_lastDusMineState = ddsData;
|
||||
|
||||
return publishNewMap();
|
||||
}
|
||||
|
||||
bool DusMineStateProxy::handleChanged(const AreaEffectSimulation::AesItemView &ddsData, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
|
||||
if (ddsData.id() != AreaEffectSimulation::AesType::AtMineAreaSingleMines)
|
||||
return false;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, ddsData.id()=" << ddsData.id()
|
||||
<< " ddsData.form().size() = " << ddsData.form().size();
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
m_lastItemView = AreaEffectSimulation::AesItemView();
|
||||
else
|
||||
m_lastItemView = ddsData;
|
||||
|
||||
return publishNewMap();
|
||||
}
|
||||
|
||||
bool DusMineStateProxy::publishNewMap()
|
||||
{
|
||||
if (m_lastItemView.setId() != m_lastDusMineState.setId())
|
||||
return false;
|
||||
|
||||
const QMap<int32_t, DusMineStateAndPositionData> &mapContVeryNew = getFromDds();
|
||||
|
||||
QMapIterator<int32_t, DusMineStateAndPositionData> mapItRetrieved(mapContVeryNew);
|
||||
|
||||
|
||||
while (mapItRetrieved.hasNext())
|
||||
{
|
||||
mapItRetrieved.next();
|
||||
|
||||
if (m_map.contains(mapItRetrieved.key()))
|
||||
emit dusMineStateChanged(mapItRetrieved.value(), DataModification::eModified);
|
||||
else
|
||||
emit dusMineStateChanged(mapItRetrieved.value(), DataModification::eAdded);
|
||||
}
|
||||
|
||||
|
||||
QMapIterator<int32_t, DusMineStateAndPositionData> mapItRemoved(m_map);
|
||||
|
||||
|
||||
while (mapItRemoved.hasNext())
|
||||
{
|
||||
mapItRemoved.next();
|
||||
|
||||
if (! mapContVeryNew.contains(mapItRemoved.key()))
|
||||
emit dusMineStateChanged(mapItRemoved.value(), DataModification::eRemoved);
|
||||
}
|
||||
|
||||
|
||||
m_map = mapContVeryNew;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Publishing new dus-mine map to situationMap adapter";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const QMap<int32_t, DusMineStateAndPositionData> DusMineStateProxy::getFromDds()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, ddsData.id()=" << m_lastDusMineState.id()
|
||||
<< " ddsData.mines().size() = " << m_lastDusMineState.mines().size();
|
||||
|
||||
QMap<int32_t, DusMineStateAndPositionData> mapCont;
|
||||
|
||||
const auto size = m_lastDusMineState.mines().size();
|
||||
|
||||
const auto &mines = m_lastDusMineState.mines();
|
||||
if (m_logger.isDebugEnabled())
|
||||
{
|
||||
int idx = 0;
|
||||
for (const AreaEffectSimulation::DusMine &mine : mines)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " idx=" << idx++
|
||||
<< ", eqId=" << mine.eqId()
|
||||
<< ", chargeTypeId=" << mine.chargeTypeId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (size != m_lastItemView.form().size())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " ddsData.id()=" << m_lastDusMineState.id()
|
||||
<< " size does not match"
|
||||
<< " ddsData.mines().size() = " << mines.size()
|
||||
<< " itemView.form().size() = " << m_lastItemView.form().size();
|
||||
return mapCont;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " ddsData.id()=" << m_lastDusMineState.id()
|
||||
<< " size ::"
|
||||
<< " ddsData.mines().size() = " << mines.size()
|
||||
<< " itemView.form().size() = " << m_lastItemView.form().size();
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
const AreaEffectSimulation::DusMine &dusMine = mines[i];
|
||||
const Core::GeoPosition2D &pos = m_lastItemView.form().at(i);
|
||||
|
||||
DusMineStateAndPositionData dmsDdsData(dusMine.eqId(),
|
||||
{dusMine.chargeTypeId(),0,0},
|
||||
dusMine.triggered(),
|
||||
pos
|
||||
);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " i=" << i << ", id/eqId=" << dusMine.eqId() << ", pos=" << pos;
|
||||
|
||||
mapCont.insert(dusMine.eqId(), dmsDdsData);
|
||||
}
|
||||
|
||||
return mapCont;
|
||||
}
|
||||
|
||||
|
||||
bool DusMineStateProxy::getItemView(AreaEffectSimulation::AesItemView &itemView)
|
||||
{
|
||||
|
||||
int aesType = static_cast<int>(AreaEffectSimulation::AesType::inner_enum::AtMineAreaSingleMines);
|
||||
|
||||
const AreaEffectSimulation::AesItemView &localItemView = m_aesDtc->aesItemView(aesType);
|
||||
|
||||
if (localItemView.id() != aesType)
|
||||
return false;
|
||||
itemView = localItemView;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool MineAreaNull2SituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!BaseClass::init(pluginProvider))
|
||||
return false;
|
||||
|
||||
if (!m_dusMineStateProxy)
|
||||
{
|
||||
m_dusMineStateProxy = new DusMineStateProxy(this);
|
||||
if (!m_dusMineStateProxy->init(pluginProvider))
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed for DusMineStateProxy";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MineAreaNull2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!m_dusMineStateProxy)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no DusMineStateProxy";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dusMineStateProxy->run();
|
||||
|
||||
connect(m_dusMineStateProxy, &DusMineStateProxy::dusMineStateChanged,
|
||||
this, &MineAreaNull2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_dusMineStateProxy->dusMineStateAndPositionDatas([this](const DusMineStateAndPositionData & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void MineAreaNull2SituationMap::stop()
|
||||
{
|
||||
if (m_dusMineStateProxy)
|
||||
m_dusMineStateProxy->stop();
|
||||
}
|
||||
|
||||
bool MineAreaNull2SituationMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
auto sp = m_aesInfoIfc.lock();
|
||||
if (!sp)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = this->uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
sp->showInfoWindow(simIds, AreaEffectSimulation::AesType_def::AtMineAreaSingleMines);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MineAreaNull2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_dusMineStateProxy)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_symDataToRender = mapObj->symbolDataToRender();
|
||||
|
||||
const auto cb = [simIdOut, &umodOut](const DusMineStateAndPositionData &data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_description1 = QString::number(data.id());
|
||||
umodOut.m_description2 = data.triggered() ? tr("disarmed") : tr("armed");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const DusMineStateAndPositionData &data)> cb1 = cb;
|
||||
return m_dusMineStateProxy->dusMineStateAndPositionDatas(cb1);
|
||||
}
|
||||
|
||||
bool MineAreaNull2SituationMap::updateVisibility(const Aes2SituationMap::DDS_TYPE &ddsData, RefPointer<Aes2SituationMap::MAP_TYPE> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << getSimId(ddsData);
|
||||
if (!BaseClass::updateVisibility(ddsData, mapObj))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " BaseClass::updateVisibility failed, simId=" << getSimId(ddsData);
|
||||
return false;
|
||||
}
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
|
||||
bool bUpdateView = false;
|
||||
if (m_displayFilter )
|
||||
{
|
||||
|
||||
mapObj->setVisibility(m_displayFilter->showNotTriggeredCDMine()
|
||||
&& this->isVisibleByFilter(ddsData));
|
||||
bUpdateView = true;
|
||||
|
||||
}
|
||||
|
||||
if (bUpdateView && !mapObj->updateView())
|
||||
ERROR_LOG(m_logger)<< LOGFUNCTION << " simId = " << getSimId(ddsData) << " XXXX updateView failed";
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void MineAreaNull2SituationMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
|
||||
|
||||
if (AreaEffectSimulation::AesType_def::AtMineArea != aesType.underlying())
|
||||
return;
|
||||
|
||||
const auto cb = [this](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (data.isDeleted())
|
||||
return false;
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
iterateAesData(cb);
|
||||
|
||||
}
|
||||
|
||||
bool MineAreaNull2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
|
||||
const int32_t simId_eqId = ddsData.id();
|
||||
|
||||
|
||||
SymbolData symData;
|
||||
symData.sidc = AdvancedSymbology::SidcCodec::encodeComplete( mapObj->symbologyType(), "10011500002101000000" );
|
||||
|
||||
symData.color = Qt::yellow;
|
||||
symData.size = 1.0;
|
||||
mapObj->setSymbol(symData);
|
||||
|
||||
|
||||
SituationMap::Injury injury = SituationMap::Injury::NoInjury;
|
||||
if (ddsData.triggered())
|
||||
injury = SituationMap::Injury::TotalKill;
|
||||
mapObj->setInjury(injury, QColor(Qt::black));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setVisibility(true);
|
||||
|
||||
|
||||
mapObj->setOrigin(Point3D(ddsData.position().lon(), ddsData.position().lat(), .0));
|
||||
|
||||
|
||||
mapObj->setTextModifier(Participant::TextModifier::M_HigherFormation, QString::number(simId_eqId));
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MineAreaNull2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.symbolTransparency != newSas.symbolSettings.symbolTransparency)
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
void MineAreaNull2SituationMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setUserSymbolOpacity(1.0f - m_currentSymbolSettings.symbolSettings.symbolTransparency);
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/participant.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class AesItemProxy
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
class EffectStart final
|
||||
{
|
||||
public:
|
||||
static bool is_set() { return false; }
|
||||
static qint64 get() { return 0; }
|
||||
};
|
||||
|
||||
|
||||
class PartyId final
|
||||
{
|
||||
public:
|
||||
static bool is_set() { return false; }
|
||||
static qint64 get() { return -1; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
explicit AesItemProxy(int32_t id = 0,
|
||||
const AreaEffectSimulation::ChargeStruct &chargeStruct = {-1,0,0},
|
||||
const Core::GeoPosition2D &form = Core::GeoPosition2D())
|
||||
: m_id_param(id),
|
||||
m_chargeStruct(chargeStruct),
|
||||
m_form_param(form)
|
||||
{}
|
||||
|
||||
virtual ~AesItemProxy() = default;
|
||||
|
||||
|
||||
int32_t id() const { return m_id_param; }
|
||||
void setId(const int32_t &value) { m_id_param = value; }
|
||||
|
||||
static std::string name() { return std::string(); }
|
||||
|
||||
static bool isDeleted() { return false; }
|
||||
|
||||
static EffectStart effectStart() { return {}; }
|
||||
static PartyId partyId() { return {}; }
|
||||
static bool isCentral() { return false;}
|
||||
|
||||
static AreaEffectSimulation::AesEffectState effectStateId() { return AreaEffectSimulation::AesEffectState_def::EsCreated;}
|
||||
AreaEffectSimulation::ChargeStruct chargeStruct() const { return m_chargeStruct; }
|
||||
|
||||
int chargeTypeId() const { return m_chargeStruct.chargeTypeId(); }
|
||||
static qint64 effectDuration() { return -1; }
|
||||
|
||||
Core::GeoPosition2D position() const { return m_form_param; }
|
||||
|
||||
private:
|
||||
int32_t m_id_param;
|
||||
AreaEffectSimulation::ChargeStruct m_chargeStruct;
|
||||
Core::GeoPosition2D m_form_param;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class DusMineStateAndPositionData : public AesItemProxy
|
||||
{
|
||||
public:
|
||||
using BaseClass = AesItemProxy;
|
||||
|
||||
|
||||
explicit DusMineStateAndPositionData(int32_t id = 0,
|
||||
const AreaEffectSimulation::ChargeStruct &chargeStruct = {-1,0,0},
|
||||
bool triggered = false,
|
||||
const Core::GeoPosition2D &form = Core::GeoPosition2D()
|
||||
)
|
||||
: BaseClass(id, chargeStruct, form),
|
||||
m_triggered(triggered)
|
||||
{}
|
||||
|
||||
virtual ~DusMineStateAndPositionData() = default;
|
||||
|
||||
bool triggered() const { return m_triggered; }
|
||||
void setTriggered(bool onOff) { m_triggered = onOff; }
|
||||
|
||||
private:
|
||||
bool m_triggered;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class MineAreaNull2SituationMap;
|
||||
|
||||
class DusMineStateProxy final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = QObject;
|
||||
|
||||
explicit DusMineStateProxy(QObject *parent = nullptr);
|
||||
~DusMineStateProxy() = default;
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run();
|
||||
void stop();
|
||||
|
||||
|
||||
virtual bool dusMineStateAndPositionDatas(const std::function<void(const DusMineStateAndPositionData &data)> &cb);
|
||||
virtual bool dusMineStateAndPositionDatas(const std::function<bool(const DusMineStateAndPositionData &data)> &cb);
|
||||
|
||||
Q_SIGNALS:
|
||||
void dusMineStateChanged(const DusMineStateAndPositionData &dusMineStateAndPositionData, DataModification modType);
|
||||
|
||||
protected:
|
||||
bool handleChanged(const AreaEffectSimulation::DusMineState &ddsData, DataModification modType);
|
||||
bool handleChanged(const AreaEffectSimulation::AesItemView &ddsData, DataModification modType);
|
||||
bool publishNewMap();
|
||||
|
||||
const QMap<int32_t, DusMineStateAndPositionData> getFromDds();
|
||||
|
||||
|
||||
bool getItemView(AreaEffectSimulation::AesItemView &itemView);
|
||||
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
|
||||
|
||||
AreaEffectSimulation::DusMineState m_lastDusMineState;
|
||||
AreaEffectSimulation::AesItemView m_lastItemView;
|
||||
QMap<int32_t, DusMineStateAndPositionData> m_map;
|
||||
|
||||
QSharedPointer<MineAreaNull2SituationMap> m_mineAreaNull2SituationMap;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class MineAreaNull2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<MineAreaNull2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = DusMineStateAndPositionData;
|
||||
using MAP_TYPE = SituationMap::Participant;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtMineArea;
|
||||
};
|
||||
|
||||
class MineAreaNull2SituationMap final : public Aes2SituationMap<MineAreaNull2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<MineAreaNull2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool init(PluginProvider *pluginProvider) override;
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
bool iterateAesData(const std::function<bool(const DDS_TYPE &data)> &cb) const
|
||||
{
|
||||
|
||||
|
||||
if (!m_dusMineStateProxy)
|
||||
return false;
|
||||
return m_dusMineStateProxy->dusMineStateAndPositionDatas(cb);
|
||||
}
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
using BaseClass::updateVisibility;
|
||||
bool updateVisibility(const DDS_TYPE &ddsData, RefPointer<MAP_TYPE> mapObj) override;
|
||||
|
||||
|
||||
protected:
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool updateSingleMines(const int simId,
|
||||
RefPointer<MAP_T> mapObj);
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
private:
|
||||
DusMineStateProxy *m_dusMineStateProxy = nullptr;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+451
@@ -0,0 +1,451 @@
|
||||
|
||||
|
||||
|
||||
#include "mine_area_to_map.h"
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <AreaEffectSimulation/Utils/ddsdbconvert.h>
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool MineArea2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_triggeredImpacts.clear();
|
||||
m_aesItemViewForImpacts.clear();
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::mineAreaChanged,
|
||||
this, &MineArea2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::triggeredImpactsChanged,
|
||||
this, &MineArea2SituationMap::onTriggeredImpactsChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &MineArea2SituationMap::onAesItemViewChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->mineAreas([this](const AreaEffectSimulation::MineArea &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
m_aesDtc->triggeredImpactss([this](const AreaEffectSimulation::TriggeredImpacts &data)
|
||||
{
|
||||
onTriggeredImpactsChanged(data, DataModification::eAdded);
|
||||
});
|
||||
m_aesDtc->aesItemViews([this](const AreaEffectSimulation::AesItemView &data)
|
||||
{
|
||||
onAesItemViewChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool MineArea2SituationMap::updateVisibility(const DDS_TYPE &data, RefPointer<MAP_TYPE> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << getSimId(data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!BaseClass::updateVisibility(data, mapObj))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " BaseClass::updateVisibility failed, simId=" << getSimId(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool bDisplayFilterShowDetails = true;
|
||||
if (m_displayFilter)
|
||||
bDisplayFilterShowDetails = m_displayFilter->showDetails(AreaEffectSimulation::AesType_def::AtMineArea);
|
||||
|
||||
const bool bShowDetails = mapObj->visibility() && bDisplayFilterShowDetails;
|
||||
bool bUpdateView = false;
|
||||
if (bShowDetails != mapObj->mineVisibility(MineField::MineState::Activated))
|
||||
{
|
||||
mapObj->setMineVisibility(MineField::MineState::Activated, bShowDetails);
|
||||
bUpdateView = true;
|
||||
}
|
||||
if (bShowDetails != mapObj->mineVisibility(MineField::MineState::DeActivated))
|
||||
{
|
||||
mapObj->setMineVisibility(MineField::MineState::DeActivated, bShowDetails);
|
||||
bUpdateView = true;
|
||||
}
|
||||
|
||||
if (bUpdateView)
|
||||
if (!mapObj->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " simId = " << getSimId(data) << " XXXX updateView failed";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MineArea2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
|
||||
{
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtMineArea, itemView))
|
||||
{
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtMineArea) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
const QVector<AreaEffectSimulation::Database::AesMineAreaSegment> segments(AreaEffectSimulation::DdsDbConvert::mineAreaSegments(ddsData));
|
||||
const QVector<QPolygonF> singleSegments(AreaEffectSimulation::Polygons::mineAreaSingleSegments(segments, ddsData.width(), ddsData.isCenterLine()));
|
||||
|
||||
QList<int> keysInUse = mapObj->keysInUse();
|
||||
|
||||
int segmentIdx = -1;
|
||||
PositionCont posCont;
|
||||
for(const QPolygonF &singleSegment : singleSegments)
|
||||
{
|
||||
++segmentIdx;
|
||||
posCont.clear();
|
||||
posCont.reserve(singleSegment.size());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for (auto item : singleSegment)
|
||||
posCont.append(Point3D(item.x(), item.y(), .0));
|
||||
|
||||
mapObj->setSegment(segmentIdx, posCont);
|
||||
|
||||
keysInUse.removeAll(segmentIdx);
|
||||
}
|
||||
|
||||
for (auto item : qAsConst(keysInUse))
|
||||
if (item >= 0)
|
||||
mapObj->removeSegment(item);
|
||||
}
|
||||
|
||||
|
||||
auto itTi = m_triggeredImpacts.constFind(simId);
|
||||
if (itTi != m_triggeredImpacts.cend())
|
||||
onTriggeredImpactsChanged(itTi.value(), DataModification::eAdded);
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MineArea2SituationMap::updateGeometry(const AreaEffectSimulation::AesItemView &data,
|
||||
RefPointer<SituationMap::MineField> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const PositionCont &posCont = form2PosCont(data.form());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setSegment(-1, posCont);
|
||||
|
||||
mapObj->setPositions(posCont);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, posCont.size() = " << posCont.size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MineArea2SituationMap::onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int32_t simId = data.aesItemId();
|
||||
if (simId < 0)
|
||||
return;
|
||||
|
||||
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType::AtMineAreaSingleMines)
|
||||
return;
|
||||
|
||||
|
||||
if (simId == 0)
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
m_triggeredImpacts.remove(simId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_triggeredImpacts[simId] = data;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId
|
||||
<< " m_triggeredImpacts updated";
|
||||
|
||||
|
||||
updateMines(simId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " simId = " << simId;
|
||||
}
|
||||
|
||||
void MineArea2SituationMap::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " data.aesTypeId()=" << data.aesTypeId() << " modType=" << modType;
|
||||
|
||||
const int32_t simId = data.aesItemId();
|
||||
if (simId < 0)
|
||||
return;
|
||||
|
||||
|
||||
{
|
||||
if (data.aesTypeId() == AreaEffectSimulation::AesType::AtMineArea)
|
||||
{
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< ", simId = " << simId
|
||||
<< ", modType=" << modType;
|
||||
return;
|
||||
}
|
||||
updateGeometry(data, mapObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType::AtMineAreaSingleMines)
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
m_aesItemViewForImpacts.remove(simId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_aesItemViewForImpacts[simId] = data;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId
|
||||
<< " m_aesItemViewForImpacts updated";
|
||||
|
||||
|
||||
updateMines(simId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " simId = " << simId;
|
||||
}
|
||||
|
||||
bool MineArea2SituationMap::completeMissingData(int32_t simId,
|
||||
AreaEffectSimulation::TriggeredImpacts &dataTriggeredImpacts,
|
||||
AreaEffectSimulation::AesItemView &dataAesItemView) const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " simId = " << simId;
|
||||
|
||||
if (simId < 0)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
auto itAIV = m_aesItemViewForImpacts.find(simId);
|
||||
if (itAIV == m_aesItemViewForImpacts.constEnd())
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " simId = " << simId
|
||||
<< " no AesItemViewForImpacts found.";
|
||||
return false;
|
||||
}
|
||||
dataAesItemView = itAIV.value();
|
||||
|
||||
|
||||
|
||||
|
||||
auto itTI = m_triggeredImpacts.find(simId);
|
||||
|
||||
if (itTI == m_triggeredImpacts.constEnd())
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " simId = " << simId
|
||||
<< " no TriggeredImpacts found.";
|
||||
return false;
|
||||
}
|
||||
dataTriggeredImpacts = itTI.value();
|
||||
|
||||
|
||||
|
||||
const int32_t impactCount = dataTriggeredImpacts.impactCount();
|
||||
const int32_t formSize = dataAesItemView.form().size();
|
||||
|
||||
if (impactCount != formSize)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< " simId = " << simId
|
||||
<< " size mismatch"
|
||||
<< " impactCount=" << impactCount
|
||||
<< " formSize.size()=" << formSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " simId = " << simId;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MineArea2SituationMap::updateMines(const int32_t simId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " simId = " << simId;
|
||||
if (simId < 0)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId = " << simId << " (maybe expired)";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AreaEffectSimulation::TriggeredImpacts dataTriggeredImpacts;
|
||||
AreaEffectSimulation::AesItemView dataAesItemView;
|
||||
bool bothTopicsMatch = completeMissingData(simId, dataTriggeredImpacts, dataAesItemView);
|
||||
const PositionCont &posCont = form2PosCont(dataAesItemView.form());
|
||||
|
||||
|
||||
|
||||
|
||||
if (bothTopicsMatch)
|
||||
{
|
||||
PositionCont posContActivated;
|
||||
PositionCont posContDeActivated;
|
||||
posContActivated.reserve(posCont.size());
|
||||
posContDeActivated.reserve(posCont.size());
|
||||
|
||||
const auto &bitField = dataTriggeredImpacts.bitfield();
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < posCont.size(); ++i)
|
||||
{
|
||||
const Point3D &point = posCont.at(i);
|
||||
if (LtsUtils::BitArray::testBit(bitField, i))
|
||||
posContActivated.append(point);
|
||||
else
|
||||
posContDeActivated.append(point);
|
||||
}
|
||||
|
||||
mapObj->setPositionsMine(MineField::MineState::Activated, posContActivated);
|
||||
|
||||
mapObj->setPositionsMine(MineField::MineState::DeActivated, posContDeActivated);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " size match -> posContActivated " << posContActivated.size();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " size match -> posContDeActivated " << posContDeActivated.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " simId = " << simId
|
||||
<< " bothTopicsMatch = " << bothTopicsMatch
|
||||
<< " on initial, there is no TriggeredImpacts published. In that case interpret all positions as active..";
|
||||
mapObj->setPositionsMine(MineField::MineState::Activated, posCont);
|
||||
|
||||
mapObj->setPositionsMine(MineField::MineState::DeActivated, PositionCont());
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " size mismatch -> all active";
|
||||
}
|
||||
|
||||
if (!mapObj->updateView())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " simId = " << simId
|
||||
<< " updateView failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " simId = " << simId;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/mine_field.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MineArea2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<MineArea2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::MineArea;
|
||||
using MAP_TYPE = SituationMap::MineField;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtMineArea;
|
||||
};
|
||||
|
||||
class MineArea2SituationMap final : public Aes2SituationMap<MineArea2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<MineArea2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::MineArea &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->mineAreas(cb);
|
||||
}
|
||||
|
||||
bool updateVisibility(const DDS_TYPE &data, RefPointer<MAP_TYPE> mapObj) override;
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool updateGeometry(const AreaEffectSimulation::AesItemView &data,
|
||||
RefPointer<SituationMap::MineField> mapObj) override;
|
||||
bool updateSingleMines(const int simId,
|
||||
RefPointer<MAP_T> mapObj);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
|
||||
void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType);
|
||||
protected:
|
||||
bool completeMissingData(int32_t simId,
|
||||
AreaEffectSimulation::TriggeredImpacts &dataTriggeredImpacts,
|
||||
AreaEffectSimulation::AesItemView &dataAesItemView) const;
|
||||
bool updateMines(const int32_t simId);
|
||||
|
||||
private:
|
||||
QMap<int32_t, AreaEffectSimulation::TriggeredImpacts> m_triggeredImpacts;
|
||||
|
||||
QMap<int32_t, AreaEffectSimulation::AesItemView> m_aesItemViewForImpacts;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
|
||||
#include "mine_corridor_to_map.h"
|
||||
#include <AreaEffectSimulation/Utils/polygons.h>
|
||||
#include <AreaEffectSimulation/Utils/ddsdbconvert.h>
|
||||
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool MineCorridor2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::mineCorridorChanged,
|
||||
this, &MineCorridor2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->mineCorridors([this](const AreaEffectSimulation::MineCorridor &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool MineCorridor2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
|
||||
QColor color(Qt::gray);
|
||||
color.setAlpha(175);
|
||||
mapObj->rLineStyle().setLineColor(color);
|
||||
mapObj->rFillStyle().setFillColor(color);
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtMineCorridor, itemView))
|
||||
{
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtMineCorridor) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/polygon.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MineCorridor2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<MineCorridor2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::MineCorridor;
|
||||
using MAP_TYPE = SituationMap::Polygon;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtMineCorridor;
|
||||
};
|
||||
|
||||
class MineCorridor2SituationMap final : public Aes2SituationMap<MineCorridor2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<MineCorridor2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::MineCorridor &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->mineCorridors(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+905
@@ -0,0 +1,905 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "mounting_point_to_map.h"
|
||||
#include <Map/map.h>
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/layer_factory.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonArray>
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
QString toString(ResourceManagerMode rmm)
|
||||
{
|
||||
switch (rmm) {
|
||||
case ResourceManagerMode::Undefined:
|
||||
return QStringLiteral("RMM_Undefined");
|
||||
break;
|
||||
case ResourceManagerMode::RMM_PlanActivityView:
|
||||
return QStringLiteral("RMM_PlanActivityView");
|
||||
break;
|
||||
case ResourceManagerMode::RMM_PlanDefinitionView:
|
||||
return QStringLiteral("RMM_PlanDefinitionView");
|
||||
break;
|
||||
case ResourceManagerMode::RMM_ComponentMonitor:
|
||||
return QStringLiteral("RMM_ComponentMonitor");
|
||||
break;
|
||||
}
|
||||
return QStringLiteral("RMM_UNKNOWN");
|
||||
}
|
||||
|
||||
bool MountingPointToMap::init(PluginProvider *pluginProvider, bool resourceMode)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->ismDtc() ||
|
||||
!pluginProvider->ismDataIfc())
|
||||
return false;
|
||||
|
||||
m_resourceMode = resourceMode;
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " m_resourceMode=" << m_resourceMode
|
||||
<< " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
m_ismDtc = m_pluginProvider->ismDtc();
|
||||
m_ismDataIfc = m_pluginProvider->ismDataIfc();
|
||||
m_ismGuiIfc = m_pluginProvider->ismGuiIfc();
|
||||
m_cmoDtc = m_pluginProvider->cmoDtc();
|
||||
|
||||
InfrastructureManagement::MountingPoint::init();
|
||||
|
||||
m_handleAllMountingPointsTimer = new QTimer(this);
|
||||
m_handleAllMountingPointsTimer->setInterval(1500);
|
||||
m_handleAllMountingPointsTimer->setSingleShot(true);
|
||||
connect(m_handleAllMountingPointsTimer, &QTimer::timeout,
|
||||
this, &MountingPointToMap::onHandleAllMountingPoints);
|
||||
|
||||
|
||||
#ifdef SUPPORT_SELECTION_APPROACH
|
||||
m_selectionFilterTimer = new QTimer(this);
|
||||
m_selectionFilterTimer->setInterval(2000);
|
||||
connect(m_selectionFilterTimer, &QTimer::timeout,
|
||||
this, &MountingPointToMap::onHandleSelectionFilterTimeout);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (m_cmoDtc)
|
||||
{
|
||||
m_cmoDtc->enableComponentStatus(true);
|
||||
m_cmoDtc->waitForHistoricalDataComponentStatus(1000);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " m_resourceMode=" << m_resourceMode
|
||||
<< " exerciseId=" << m_pluginProvider->exerciseId()
|
||||
<< " DONE";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MountingPointToMap::initRenderer()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", to rmm = " << toString(m_resourceManagerMode)
|
||||
<< ", m_uniqueValueRendererAssigned=" << m_uniqueValueRendererAssigned;
|
||||
|
||||
|
||||
if (m_uniqueValueRendererAssigned)
|
||||
return true;
|
||||
|
||||
QElapsedTimer elapsedTimer;
|
||||
if (m_logger.isInfoEnabled())
|
||||
elapsedTimer.start();
|
||||
|
||||
m_uniqueValueRendererAssigned = initRendererInternal();
|
||||
|
||||
if (m_logger.isInfoEnabled())
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END, initRendererXY to rmm = " << toString(m_resourceManagerMode) << " took " << elapsedTimer.elapsed() << " [ms]";
|
||||
|
||||
return m_uniqueValueRendererAssigned;
|
||||
}
|
||||
|
||||
bool MountingPointToMap::initRendererInternal()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START, rmm=" << toString(m_resourceManagerMode);
|
||||
|
||||
const QString &layername = m_layername;
|
||||
|
||||
QVector<SituationMap::LayerFactory::UniqueValueData> uvCont;
|
||||
SituationMap::LayerFactory::UniqueValueData uvd;
|
||||
|
||||
|
||||
QMap<InfrastructureManagement::MountingPointType_def::type, InfrastructureManagement::MountingPoint::MpNameImageData> &imageCont =
|
||||
InfrastructureManagement::MountingPoint::getImageTable();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uvCont.reserve(imageCont.size() * 5);
|
||||
|
||||
for (const InfrastructureManagement::MountingPoint::MpNameImageData &mnid : qAsConst(imageCont) )
|
||||
{
|
||||
{
|
||||
const InfrastructureManagement::MountingPoint::NameImagePair &nipRef = mnid.nipBlue;
|
||||
uvd.label = nipRef.m_name;
|
||||
uvd.img = nipRef.m_img.scaled(QSize(25,25), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
uvd.value = nipRef.m_name;
|
||||
uvCont.append(uvd);
|
||||
}
|
||||
{
|
||||
const InfrastructureManagement::MountingPoint::NameImagePair &nipRef = mnid.nipGray;
|
||||
uvd.label = nipRef.m_name;
|
||||
uvd.img = nipRef.m_img.scaled(QSize(25,25), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
uvd.value = nipRef.m_name;
|
||||
uvCont.append(uvd);
|
||||
}
|
||||
{
|
||||
const InfrastructureManagement::MountingPoint::NameImagePair &nipRef = mnid.nipGreen;
|
||||
uvd.label = nipRef.m_name;
|
||||
uvd.img = nipRef.m_img.scaled(QSize(25,25), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
uvd.value = nipRef.m_name;
|
||||
uvCont.append(uvd);
|
||||
}
|
||||
{
|
||||
const InfrastructureManagement::MountingPoint::NameImagePair &nipRef = mnid.nipRed;
|
||||
uvd.label = nipRef.m_name;
|
||||
uvd.img = nipRef.m_img.scaled(QSize(25,25), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
uvd.value = nipRef.m_name;
|
||||
uvCont.append(uvd);
|
||||
}
|
||||
{
|
||||
const InfrastructureManagement::MountingPoint::NameImagePair &nipRef = mnid.nipOrange;
|
||||
uvd.label = nipRef.m_name;
|
||||
uvd.img = nipRef.m_img.scaled(QSize(25,25), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
uvd.value = nipRef.m_name;
|
||||
uvCont.append(uvd);
|
||||
}
|
||||
}
|
||||
|
||||
bool success = m_objFac.map()->layerFactory().assignUniqueValueRenderer(layername,
|
||||
QStringLiteral("MountingPointFieldName"),
|
||||
uvCont);
|
||||
if (!success)
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRenderer ... on layer= " << layername << " failed";
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END, rmm=" << toString(m_resourceManagerMode);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
ResourceManagerMode MountingPointToMap::resourceManagerMode() const
|
||||
{
|
||||
return m_resourceManagerMode;
|
||||
}
|
||||
bool MountingPointToMap::setResourceManagerMode(ResourceManagerMode rmm)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", current rmm = " << toString(m_resourceManagerMode) << " - desired rmm = " << toString(rmm);
|
||||
|
||||
QElapsedTimer elapsedTimer;
|
||||
if (m_logger.isInfoEnabled())
|
||||
elapsedTimer.start();
|
||||
|
||||
if (rmm == ResourceManagerMode::Undefined)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " ERROR, ResourceManagerMode::Undefined required "
|
||||
<< ", stay at current rmm = " << toString(m_resourceManagerMode);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool change = m_resourceManagerMode != rmm;
|
||||
m_resourceManagerMode = rmm;
|
||||
|
||||
if (change)
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
if (change && m_logger.isInfoEnabled())
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END, switching to current rmm = " << toString(m_resourceManagerMode) << " took " << elapsedTimer.elapsed() << " [ms]";
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END" << ", desired rmm = " << toString(rmm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MountingPointToMap::run()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " Starting to run";
|
||||
|
||||
this->stop();
|
||||
|
||||
if (!m_ismDataIfc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << "Could not run. ForeignDataInterface not set.";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
connect(m_ismDataIfc.get(), &InfrastructureManagement::ForeignDataInterface::buildingsInCurrentExerciseChanged,
|
||||
this, &MountingPointToMap::onBuildingsInCurrentExerciseChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_ismDataIfc.get(), &InfrastructureManagement::ForeignDataInterface::mountingPointChanged,
|
||||
this, &MountingPointToMap::onMountingPointChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
initRenderer();
|
||||
|
||||
|
||||
|
||||
onHandleAllMountingPoints();
|
||||
|
||||
#ifdef SUPPORT_SELECTION_APPROACH
|
||||
setVisibility();
|
||||
m_selectionFilterTimer->start();
|
||||
#endif
|
||||
|
||||
|
||||
if (m_cmoDtc)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect(m_cmoDtc.get(), &ComponentMonitor::Interface::Dtc::componentStatusChanged,
|
||||
this, &MountingPointToMap::onComponentStatusChanged, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MountingPointToMap::onHandleAllMountingPoints()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", m_pluginProvider->exerciseId() = " << m_pluginProvider->exerciseId()
|
||||
<< ", m_resourceMode = " << m_resourceMode;
|
||||
|
||||
|
||||
if (m_pluginProvider->exerciseId() != 0 || m_resourceMode)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " mountingPoints().size() = " << m_ismDataIfc->mountingPoints().size();
|
||||
|
||||
m_ismDataIfc->mountingPoints([this](const InfrastructureManagement::MountingPoint& data)
|
||||
{
|
||||
onMountingPointChanged(data, DataModification::eAdded);
|
||||
});
|
||||
}
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void MountingPointToMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping...";
|
||||
|
||||
if (m_handleAllMountingPointsTimer)
|
||||
m_handleAllMountingPointsTimer->stop();
|
||||
|
||||
#ifdef SUPPORT_SELECTION_APPROACH
|
||||
if (m_selectionFilterTimer)
|
||||
m_selectionFilterTimer->stop();
|
||||
#endif
|
||||
|
||||
if (m_ismDtc)
|
||||
m_ismDtc->disconnect(this);
|
||||
|
||||
if (m_ismDataIfc)
|
||||
m_ismDataIfc->disconnect(this);
|
||||
|
||||
if (m_cmoDtc)
|
||||
m_cmoDtc->disconnect(this);
|
||||
|
||||
m_mountingPoints.clear();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping...done";
|
||||
}
|
||||
|
||||
|
||||
bool MountingPointToMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
|
||||
if (!m_ismGuiIfc)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
if (m_ismGuiIfc->isInSelectionMode())
|
||||
m_ismGuiIfc->addToSelection(simIds);
|
||||
else
|
||||
m_ismGuiIfc->showMountingPointInfoWindows(simIds);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MountingPointToMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_ismDataIfc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
|
||||
|
||||
|
||||
|
||||
const auto cb = [this, simIdOut, &umodOut](const InfrastructureManagement::MountingPoint &data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_description1 = data.name();
|
||||
umodOut.m_participantData.m_typeName = InfrastructureManagement::toString(data.type());
|
||||
|
||||
|
||||
QString attribValueUnused;
|
||||
bool suc = false;
|
||||
|
||||
switch (m_resourceManagerMode) {
|
||||
case ResourceManagerMode::RMM_PlanActivityView:
|
||||
suc = InfrastructureManagement::MountingPoint::getImageAttributePlanActivity(data, umodOut.m_image, attribValueUnused);
|
||||
if (!suc)
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< "getImageAttributePlanActivity failed m_resourceMode=" << m_resourceMode
|
||||
<< " m_resourceManagerMode=" << toString(m_resourceManagerMode);
|
||||
break;
|
||||
case ResourceManagerMode::RMM_PlanDefinitionView:
|
||||
suc = InfrastructureManagement::MountingPoint::getImageAttributePlanDefinition(data, umodOut.m_image, attribValueUnused);
|
||||
if (!suc)
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< "getImageAttributePlanDefinition failed m_resourceMode=" << m_resourceMode
|
||||
<< " m_resourceManagerMode=" << toString(m_resourceManagerMode);
|
||||
break;
|
||||
case ResourceManagerMode::RMM_ComponentMonitor:
|
||||
{
|
||||
InfrastructureManagement::MountingPoint::MpColor col = InfrastructureManagement::MountingPoint::MpColor::GRAY;
|
||||
suc = InfrastructureManagement::MountingPoint::getImageAttribute(data, col, umodOut.m_image, attribValueUnused);
|
||||
if (!suc)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< "getImageAttribute failed m_resourceMode=" << m_resourceMode
|
||||
<< " m_resourceManagerMode=" << toString(m_resourceManagerMode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const InfrastructureManagement::MountingPoint &data)> cb1 = cb;
|
||||
return m_ismDataIfc->mountingPoints(cb1);
|
||||
}
|
||||
|
||||
bool MountingPointToMap::onMountingPointChanged(const InfrastructureManagement::MountingPoint &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " m_resourceMode=" << m_resourceMode
|
||||
<< " onMountingPointChanged"
|
||||
<< " id=" << data.id()
|
||||
<< " name=" << data.name()
|
||||
<< " buildingId=" << data.buildingId()
|
||||
<< " associatedAssetId=" << data.associatedAssetId()
|
||||
<< " hasAssociatedAsset=" << data.hasAssociatedAsset()
|
||||
<< " MountingPointType=" << data.type()
|
||||
<< " aimState=" << data.aimState()
|
||||
<< " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
if (m_pluginProvider->exerciseId() == 0 && !m_resourceMode)
|
||||
return true;
|
||||
if (!isElapsed(data))
|
||||
{
|
||||
m_mountingPoints.insert(data.id(), data);
|
||||
|
||||
|
||||
const std::string &hostname = mountingPointHostname(data);
|
||||
if (!hostname.empty())
|
||||
{
|
||||
m_associatedAssetHostnameToMountingPointId[hostname] = data.id();
|
||||
DEBUG_LOG(m_logger) << " m_resourceMode=" << m_resourceMode
|
||||
<< " INSERT hostname '" << hostname << "'"
|
||||
<< " id " << data.id();
|
||||
|
||||
}
|
||||
}
|
||||
return handleChanged(data, modType);
|
||||
}
|
||||
|
||||
bool MountingPointToMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << " isElapsed"
|
||||
<< ", m_resourceManagerMode=" << (int)m_resourceManagerMode;
|
||||
|
||||
if (BaseClass::isElapsed(data))
|
||||
return true;
|
||||
|
||||
const InfrastructureManagement::MountingPointType mpType = data.type();
|
||||
|
||||
|
||||
if (mpType.underlying() == InfrastructureManagement::MountingPointType::BuildingNetworkSwitch)
|
||||
return true;
|
||||
|
||||
|
||||
if (m_resourceMode)
|
||||
{
|
||||
|
||||
switch (m_resourceManagerMode) {
|
||||
case ResourceManagerMode::RMM_PlanActivityView:
|
||||
|
||||
return ( (mpType.underlying() == InfrastructureManagement::MountingPointType_def::BuildingControlUnit) ||
|
||||
(data.aimState().underlying() == InfrastructureManagement::MountingPointState_def::Idle)
|
||||
);
|
||||
break;
|
||||
case ResourceManagerMode::RMM_PlanDefinitionView:
|
||||
|
||||
return (mpType.underlying() == InfrastructureManagement::MountingPointType_def::BuildingControlUnit);
|
||||
break;
|
||||
case ResourceManagerMode::RMM_ComponentMonitor:
|
||||
|
||||
return
|
||||
! (data.hasAssociatedAsset() &&
|
||||
(
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::OutdoorIPS) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::IndoorIPS) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::OutdoorCamera) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::IndoorCamera) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::OutdoorCamera) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::EffectGenerationControlUnit) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::BuildingSensorModule)
|
||||
)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const int bldgId = data.buildingId();
|
||||
if (!m_ismDataIfc->isBuildingsInCurrentExercise(bldgId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "isElapsed: buildingId=" << bldgId;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if ((mpType.underlying() == InfrastructureManagement::MountingPointType::OutdoorCamera) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType::AnnouncementUnit))
|
||||
return data.hasAssociatedAsset() == false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int32_t MountingPointToMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool MountingPointToMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " m_resourceMode=" << m_resourceMode
|
||||
<< " m_resourceManagerMode=" << (int)m_resourceManagerMode
|
||||
<< " id " << ddsData.id()
|
||||
<< " type " << ddsData.type()
|
||||
<< " name = " << ddsData.name()
|
||||
<< " has associatedAssetId = " << ddsData.associatedAssetId()
|
||||
<< " aimState = " << ddsData.aimState()
|
||||
<< ", goeCoord = " << ddsData.geoPosition();
|
||||
|
||||
|
||||
|
||||
const Core::GeoPosition &geoPos = ddsData.geoPosition();
|
||||
mapObj->setOrigin(Point3D(geoPos.lon(), geoPos.lat(), geoPos.z()));
|
||||
|
||||
|
||||
QString attribValue;
|
||||
QImage imgUnused;
|
||||
|
||||
switch (m_resourceManagerMode) {
|
||||
case ResourceManagerMode::RMM_PlanActivityView:
|
||||
{
|
||||
bool suc = InfrastructureManagement::MountingPoint::getImageAttributePlanActivity(ddsData, imgUnused, attribValue);
|
||||
if (!suc)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< "getImageAttributePlanActivity failed m_resourceMode=" << m_resourceMode
|
||||
<< " m_resourceManagerMode=" << (int)m_resourceManagerMode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ResourceManagerMode::RMM_PlanDefinitionView:
|
||||
{
|
||||
bool suc = InfrastructureManagement::MountingPoint::getImageAttributePlanDefinition(ddsData, imgUnused, attribValue);
|
||||
if (!suc)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< "getImageAttributePlanDefinition failed m_resourceMode=" << m_resourceMode
|
||||
<< " m_resourceManagerMode=" << (int)m_resourceManagerMode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ResourceManagerMode::RMM_ComponentMonitor:
|
||||
{
|
||||
InfrastructureManagement::MountingPoint::MpColor col = InfrastructureManagement::MountingPoint::MpColor::GRAY;
|
||||
|
||||
const InfrastructureManagement::MountingPointType mpType = ddsData.type();
|
||||
if ( (mpType.underlying() == InfrastructureManagement::MountingPointType_def::OutdoorIPS) ||
|
||||
(mpType.underlying() == InfrastructureManagement::MountingPointType_def::IndoorIPS) )
|
||||
{
|
||||
col = InfrastructureManagement::MountingPoint::MpColor::GRAY;
|
||||
} else {
|
||||
const std::string &hostname = mountingPointHostname(ddsData);
|
||||
if (!hostname.empty())
|
||||
{
|
||||
ComponentMonitor::ComponentState stateOut;
|
||||
if (componentStateOfHostname(hostname, stateOut))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " componentStateOfHostname: '" << hostname << "' -> " << stateOut;
|
||||
|
||||
switch (stateOut.underlying()) {
|
||||
case ComponentMonitor::ComponentState_def::Undefined:
|
||||
if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
|
||||
col = InfrastructureManagement::MountingPoint::MpColor::ORANGE;
|
||||
else
|
||||
col = InfrastructureManagement::MountingPoint::MpColor::RED;
|
||||
break;
|
||||
case ComponentMonitor::ComponentState_def::Reachable:
|
||||
col = InfrastructureManagement::MountingPoint::MpColor::GREEN;
|
||||
break;
|
||||
case ComponentMonitor::ComponentState_def::Unreachable:
|
||||
col = InfrastructureManagement::MountingPoint::MpColor::RED;
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " componentStateOfHostname: host '" << hostname << "' not found. Maybe topic removed ";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool suc = InfrastructureManagement::MountingPoint::getImageAttribute(ddsData, col, imgUnused, attribValue);
|
||||
if (!suc)
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION
|
||||
<< ", getImageAttribute failed m_resourceMode=" << m_resourceMode
|
||||
<< ", m_resourceManagerMode=" << (int)m_resourceManagerMode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QVariantMap attribMap;
|
||||
attribMap.insert(QStringLiteral("MountingPointFieldName"), attribValue);
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION
|
||||
<< " id " << ddsData.id()
|
||||
<< " type " << ddsData.type()
|
||||
<< " name = " << ddsData.name()
|
||||
<< " attribValue = >>>" << attribValue << "<<<";
|
||||
mapObj->setAttributes(attribMap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BLDCOMPONENT_FILTER_APPROACH
|
||||
void MountingPointToMap::handleBuildingComponentSettings(RefPointer<Sim2SituationMap::MAP_T> &mapObj)
|
||||
{
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
|
||||
const UniqueMapId uniqueMapId = mapObj->uniqueMapId();
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return;
|
||||
|
||||
const InfrastructureManagement::MountingPoint &ddsDataMP = m_mountingPoints[simIdOut];
|
||||
Q_ASSERT(ddsDataMP.id() == simIdOut);
|
||||
|
||||
handleBuildingComponentSettingsMP(mapObj, ddsDataMP);
|
||||
}
|
||||
void MountingPointToMap::handleBuildingComponentSettingsMP(RefPointer<Sim2SituationMap::MAP_T> &mapObj,
|
||||
const InfrastructureManagement::MountingPoint &mountingPoint)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_resourceMode=" << m_resourceMode
|
||||
<< ", debugInfo='" << mapObj->debugInfo();
|
||||
if (!mapObj.valid())
|
||||
return;
|
||||
|
||||
const InfrastructureManagement::MountingPointType_def::type type = mountingPoint.type().underlying();
|
||||
bool newVisi = showMountingPointType(type);
|
||||
if (newVisi)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
const QSet<int> hiddenFloorIdsRef = m_currentBuildingComponentSettings.buildingSettings.hiddenFloorIds;
|
||||
newVisi = !hiddenFloorIdsRef.contains(mountingPoint.floor());
|
||||
}
|
||||
|
||||
bool oldVisibility = mapObj->visibility();
|
||||
if (oldVisibility != newVisi)
|
||||
{
|
||||
mapObj->setVisibility(newVisi);
|
||||
if (!mapObj->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << mapObj->debugInfo() << "'" << " updateView failed";
|
||||
}
|
||||
}
|
||||
|
||||
bool MountingPointToMap::showMountingPointType(InfrastructureManagement::MountingPointType_def::type mpType) const
|
||||
{
|
||||
const FilterManagement::BuildingComponentSettings::BldCmpSettings::ComponentSettings &cs =
|
||||
m_currentBuildingComponentSettings.componentSettings;
|
||||
|
||||
switch (mpType) {
|
||||
case InfrastructureManagement::MountingPointType_def::AnnouncementUnit:
|
||||
#ifdef GUEZ_MODE
|
||||
return false;
|
||||
#else
|
||||
return cs.showAnnouncementUnit;
|
||||
#endif
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::BuildingControlUnit:
|
||||
return cs.showBuildingControlUnit;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::BuildingNetworkSwitch:
|
||||
#ifdef GUEZ_MODE
|
||||
return false;
|
||||
#else
|
||||
return cs.showBuildingNetworkSwitch;
|
||||
#endif
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::BuildingSensorModule:
|
||||
return cs.showBuildingSensorModule;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::EffectGenerationControlUnit:
|
||||
return cs.showEffectGenerationControlUnit;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::IndoorCamera:
|
||||
return cs.showIndoorCamera;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::IndoorIPS:
|
||||
return cs.showIndoorIPS;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::MeteoDataUnit:
|
||||
return cs.showMeteoDataUnit;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::OutdoorCamera:
|
||||
return cs.showOutdoorCamera;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::OutdoorControlUnit:
|
||||
#ifdef GUEZ_MODE
|
||||
return false;
|
||||
#else
|
||||
return cs.showOutdoorControlUnit;
|
||||
#endif
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::OutdoorIPS:
|
||||
return cs.showOutdoorIPS;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::VirtualIPS:
|
||||
return cs.showVirtualIPS;
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType_def::Unknown:
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " visibility of MountingPointType_def::Unknown - unwanted, most likelky an error...";
|
||||
#ifdef LTS_DEBUG
|
||||
Q_ASSERT(false);
|
||||
#endif
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_SELECTION_APPROACH
|
||||
void MountingPointToMap::onHandleSelectionFilterTimeout()
|
||||
{
|
||||
if (!m_ismGuiIfc)
|
||||
return;
|
||||
m_ismGuiIfc->getCurrentFilters(m_selectionFilter.m_floorIds, m_selectionFilter.m_mountingPointTypes);
|
||||
setVisibility();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string MountingPointToMap::mountingPointHostname(const InfrastructureManagement::MountingPoint &mountingPoint)
|
||||
{
|
||||
|
||||
if (!mountingPoint.hasAssociatedAsset())
|
||||
return {};
|
||||
|
||||
const int assAssetId = mountingPoint.associatedAssetId();
|
||||
const InfrastructureManagement::InstrumentationAsset &iAsset = m_ismDtc->instrumentationAsset(assAssetId);
|
||||
if (iAsset.id() == assAssetId)
|
||||
{
|
||||
const std::string &hostname = iAsset.hostname();
|
||||
if (!hostname.empty())
|
||||
return hostname;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool MountingPointToMap::componentStateOfHostname(const std::string &hostname, ComponentMonitor::ComponentState &stateOut)
|
||||
{
|
||||
stateOut = ComponentMonitor::ComponentState(ComponentMonitor::ComponentState_def::Undefined);
|
||||
if (!m_cmoDtc)
|
||||
return false;
|
||||
|
||||
const auto cb = [hostname, &stateOut](const ComponentMonitor::ComponentStatus &ddsData) -> bool
|
||||
{
|
||||
if (ddsData.hostname().compare(hostname) == 0)
|
||||
{
|
||||
stateOut = ddsData.state();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const ComponentMonitor::ComponentStatus &data)> cb1 = cb;
|
||||
return m_cmoDtc->componentStatuss(cb1);
|
||||
}
|
||||
|
||||
void MountingPointToMap::onBuildingsInCurrentExerciseChanged()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", m_resourceManagerMode = " << toString(m_resourceManagerMode);
|
||||
|
||||
|
||||
m_handleAllMountingPointsTimer->start();
|
||||
}
|
||||
|
||||
bool MountingPointToMap::onComponentStatusChanged(const ComponentMonitor::ComponentStatus &data, DataModification modType)
|
||||
{
|
||||
|
||||
if (m_resourceManagerMode != ResourceManagerMode::RMM_ComponentMonitor)
|
||||
return false;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", data =" << data
|
||||
<< ", modType = " << modType
|
||||
<< ", m_resourceManagerMode = " << toString(m_resourceManagerMode);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const std::string &hostname = data.hostname();
|
||||
if (hostname.empty())
|
||||
return false;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", data =" << data
|
||||
<< ", modType = " << modType
|
||||
<< ", m_resourceManagerMode = " << toString(m_resourceManagerMode);
|
||||
|
||||
const auto it = m_associatedAssetHostnameToMountingPointId.find(hostname);
|
||||
if (it == m_associatedAssetHostnameToMountingPointId.end())
|
||||
return false;
|
||||
const int mountingPointId = *it;
|
||||
|
||||
|
||||
const InfrastructureManagement::MountingPoint &mountingPoint = m_mountingPoints[mountingPointId];
|
||||
|
||||
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(mountingPointId, INVALID_MAP_ID);
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << "Found a mountingPoint which is in internal map but has no map object...: " << mountingPointId;
|
||||
return false;
|
||||
}
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
return false;
|
||||
|
||||
|
||||
updateElementImpl(mountingPoint, mapObj);
|
||||
|
||||
if (!mapObj->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << mapObj->debugInfo() << "'" << " updateView failed";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#define BLDCOMPONENT_FILTER_APPROACH
|
||||
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include "resource_manager_mode.h"
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
#include <Plugins/ComponentMonitor/cmo_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <MapObjects/geo_image.h>
|
||||
#include <MapObjects/map_object_attributes.h>
|
||||
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class MountingPointToMap final : public Sim2SituationMap<InfrastructureManagement::MountingPoint, SituationMap::MapObjectAttributes>
|
||||
, protected DdsFilterHandling<SituationMap::MapObjectAttributes>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<InfrastructureManagement::MountingPoint, SituationMap::MapObjectAttributes>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::MapObjectAttributes>;
|
||||
|
||||
public:
|
||||
MountingPointToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider, bool resourceMode);
|
||||
bool initRenderer();
|
||||
bool initRendererInternal();
|
||||
|
||||
|
||||
|
||||
ResourceManagerMode resourceManagerMode() const;
|
||||
bool setResourceManagerMode(ResourceManagerMode rmm);
|
||||
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onHandleAllMountingPoints();
|
||||
|
||||
#ifdef SUPPORT_SELECTION_APPROACH
|
||||
void onHandleSelectionFilterTimeout();
|
||||
#endif
|
||||
|
||||
bool onMountingPointChanged(const InfrastructureManagement::MountingPoint &data, DataModification modType);
|
||||
void onBuildingsInCurrentExerciseChanged();
|
||||
|
||||
bool onComponentStatusChanged(const ComponentMonitor::ComponentStatus &data, DataModification modType);
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj) override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
Q_UNUSED(mapObj);
|
||||
}
|
||||
|
||||
#ifdef BLDCOMPONENT_FILTER_APPROACH
|
||||
bool buildingComponentSettingsChangesAreRelevant(const FilterManagement::BuildingComponentSettings::BldCmpSettings&) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void handleBuildingComponentSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
void handleBuildingComponentSettingsMP(RefPointer<MAP_T> &mapObj,
|
||||
const InfrastructureManagement::MountingPoint &mountingPoint);
|
||||
bool showMountingPointType(InfrastructureManagement::MountingPointType_def::type mpType) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::string mountingPointHostname(const InfrastructureManagement::MountingPoint &mountingPoint);
|
||||
bool componentStateOfHostname(const std::string &hostname, ComponentMonitor::ComponentState &stateOut);
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider{nullptr};
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_ismDataIfc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignResourceManagementGuiInterface> m_ismGuiIfc;
|
||||
std::shared_ptr<ComponentMonitor::Interface::Dtc> m_cmoDtc;
|
||||
|
||||
bool m_uniqueValueRendererAssigned{false};
|
||||
bool m_resourceMode{false};
|
||||
ResourceManagerMode m_resourceManagerMode{ResourceManagerMode::RMM_PlanActivityView};
|
||||
QTimer *m_handleAllMountingPointsTimer{nullptr};
|
||||
QMap<int, InfrastructureManagement::MountingPoint> m_mountingPoints;
|
||||
QMap<std::string, int> m_associatedAssetHostnameToMountingPointId;
|
||||
|
||||
#ifdef SUPPORT_SELECTION_APPROACH
|
||||
struct SelectionFilter
|
||||
{
|
||||
QVector<int> m_floorIds;
|
||||
QVector<InfrastructureManagement::MountingPointType> m_mountingPointTypes;
|
||||
} m_selectionFilter;
|
||||
QTimer *m_selectionFilterTimer{nullptr};
|
||||
#endif
|
||||
|
||||
};
|
||||
}
|
||||
+353
@@ -0,0 +1,353 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "mse_bridge_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <MathUtils/simple_helper.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/Buildings/bld_info_gui_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <SituationMap/Symbology/sidc_codec.h>
|
||||
|
||||
#include <Common/resource_path.h>
|
||||
|
||||
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
int32_t MSEBridgeToMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool MSEBridgeToMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->ismDtc())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no pluginProvider";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
m_ismDtc = pluginProvider->ismDtc();
|
||||
|
||||
m_bldInfoIfc = pluginProvider->bldInfoIfc();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MSEBridgeToMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_ismDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mseIdWithoutValidFootprint.clear();
|
||||
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainFootprintChanged,
|
||||
this, &MSEBridgeToMap::onMainFootprintChanged);
|
||||
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
|
||||
this, &MSEBridgeToMap::onMainStructureElementChanged);
|
||||
|
||||
|
||||
m_ismDtc->mainStructureElements([this](const InfrastructureManagement::MainStructureElement & data)
|
||||
{
|
||||
onMainStructureElementChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MSEBridgeToMap::isElapsed(const InfrastructureManagement::MainStructureElement &ddsData) const
|
||||
{
|
||||
if (BaseClass::isElapsed(ddsData))
|
||||
return true;
|
||||
|
||||
if (ddsData.structureElementTypeId() != InfrastructureManagement::StructureElementType::Bridge)
|
||||
return true;
|
||||
|
||||
const qint32 mseId = ddsData.id();
|
||||
const InfrastructureManagement::MainFootprint &mainFootprint = m_ismDtc->mainFootprint(mseId);
|
||||
if (mainFootprint.elements().size() < 4)
|
||||
{
|
||||
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 MSEBridgeToMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
if (!m_bldInfoIfc)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
m_bldInfoIfc->showBridgeInfoWindow(simIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MSEBridgeToMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_ismDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [this, simIdOut, &umodOut](const InfrastructureManagement::MainStructureElement & data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_description1 = m_ismDtc->getBuildingDisplayName(data);
|
||||
umodOut.m_participantData.m_typeName = InfrastructureManagement::toString(data.structureElementTypeId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const InfrastructureManagement::MainStructureElement &data)> cb1 = cb;
|
||||
return m_ismDtc->mainStructureElements(cb1);
|
||||
}
|
||||
|
||||
|
||||
void MSEBridgeToMap::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data,
|
||||
DataModification modType)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
handleChanged(data, modType);
|
||||
}
|
||||
|
||||
void MSEBridgeToMap::onMainFootprintChanged(const InfrastructureManagement::MainFootprint &data, DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
if (data.elements().size() < 4)
|
||||
return;
|
||||
|
||||
const int32_t mseId = data.id();
|
||||
if (m_mseIdWithoutValidFootprint.contains(mseId))
|
||||
{
|
||||
|
||||
const InfrastructureManagement::MainStructureElement &mseData= m_ismDtc->mainStructureElement(mseId);
|
||||
if (mseData.id() == mseId)
|
||||
{
|
||||
m_mseIdWithoutValidFootprint.removeAll(mseId);
|
||||
onMainStructureElementChanged(mseData, DataModification::eAdded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MSEBridgeToMap::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();
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
|
||||
mapObj->setIdentifier(m_ismDtc->getBuildingDisplayName(ddsData));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const qint32 bridgeId = getSimId(ddsData);
|
||||
|
||||
|
||||
|
||||
|
||||
QList<QPointF> relPositions2D;
|
||||
{
|
||||
const InfrastructureManagement::MainFootprint &mainFootprint = m_ismDtc->mainFootprint(bridgeId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " id=" << ddsData.id()
|
||||
<< " name=" << ddsData.name()
|
||||
<< " mainFootprint.elements().size()=" << mainFootprint.elements().size();
|
||||
|
||||
relPositions2D.reserve(mainFootprint.elements().size());
|
||||
|
||||
for (const InfrastructureManagement::FootprintElement &element : mainFootprint.elements())
|
||||
{
|
||||
const auto &relPos = element.relPosition();
|
||||
relPositions2D += QPointF(relPos.offsetX(), relPos.offsetY());
|
||||
}
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "footprint = " << relPositions2D;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PositionCont absPositionsGeo;
|
||||
|
||||
const Core::GeoPosition &geoPosition = ddsData.geoPosition();
|
||||
const double angleRad = ddsData.angle() * LtsCoordTrans::deg2rad();
|
||||
const QPointF referencePointGeo(geoPosition.lon(), geoPosition.lat());
|
||||
const LtsCoordTrans::UtmCoordinate referencePointUTM = LtsCoordTrans::UtmCoordinate::fromGeographic(referencePointGeo);
|
||||
|
||||
|
||||
const QPointF center;
|
||||
absPositionsGeo.reserve(relPositions2D.size());
|
||||
for (const auto &relPosition : qAsConst(relPositions2D))
|
||||
{
|
||||
const QPointF relPositionRotate = MathUtils::rotate(relPosition, center, angleRad);
|
||||
const QPointF pGeo = referencePointUTM.geographic(relPositionRotate);
|
||||
absPositionsGeo.append(Point3D::fromQPointF(pGeo));
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "absPositionsGeo = " << absPositionsGeo;
|
||||
|
||||
mapObj->setPositions(absPositionsGeo);
|
||||
|
||||
|
||||
mapObj->setMarker(Point3D::fromQPointF(referencePointGeo));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static QString resourcePath = SituationMap::getResourcePath() + QDir::separator() + QStringLiteral("3Dmodels") + QDir::separator();
|
||||
|
||||
BuildingOutline::ModelSceneSymbolData mssd;
|
||||
|
||||
mssd.url = QUrl(resourcePath + QString(QStringLiteral("SPD/buildings/Bruecke_20m/Bruecke_20m.dae")));
|
||||
|
||||
mssd.scale = 1.0;
|
||||
QColor color = Qt::darkGray;
|
||||
LinePattern linePattern = LinePattern::Dash;
|
||||
FillPattern fillPattern = FillPattern::Solid;
|
||||
|
||||
|
||||
|
||||
switch(m_ismDtc->getBridgeStatus(ddsData.id()).underlying())
|
||||
{
|
||||
case InfrastructureManagement::BridgeStatus::Broken:
|
||||
{
|
||||
|
||||
QFileInfo fi(resourcePath + QString(QStringLiteral("SPD/buildings/Bruecke_20m/Bruecke_20m_defekt.dae")));
|
||||
if (fi.exists())
|
||||
mssd.url = QUrl(fi.absoluteFilePath());
|
||||
else
|
||||
mssd.scale = 0.25;
|
||||
|
||||
|
||||
linePattern = LinePattern::Dot;
|
||||
fillPattern = FillPattern::DiagonalCross;
|
||||
}
|
||||
break;
|
||||
case InfrastructureManagement::BridgeStatus::Intact:
|
||||
mssd.scale = 1.2;
|
||||
color.setAlphaF(0.5);
|
||||
break;
|
||||
default:
|
||||
color = Qt::yellow;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
TextStyle ts = mapObj->textStyle();
|
||||
ts.setHorizontalAlignment(HorizontalAlignment::Center);
|
||||
|
||||
|
||||
LineStyle ls = mapObj->lineStyle();
|
||||
ls.setLinePattern(linePattern);
|
||||
|
||||
FillStyle fs = mapObj->fillStyle();
|
||||
fs.setFillColor(color);
|
||||
fs.setFillPattern(fillPattern);
|
||||
|
||||
mapObj->setTextStyle(ts);
|
||||
mapObj->setLineStyle(ls);
|
||||
mapObj->setFillStyle(fs);
|
||||
|
||||
mssd.heading = (ddsData.angle()*-1)+90;
|
||||
mapObj->setModelSceneSymbolData(mssd);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MSEBridgeToMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.showBuildingIdentifier != newSas.symbolSettings.showBuildingIdentifier);
|
||||
}
|
||||
|
||||
void MSEBridgeToMap::handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
mapObj->setIdentifierVisible(m_currentSymbolSettings.symbolSettings.showBuildingIdentifier);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Buildings/bld_dtc.h>
|
||||
#include <MapObjects/building_outline.h>
|
||||
|
||||
namespace Buildings
|
||||
{
|
||||
class ForeignInfoGuiInterface;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class MSEBridgeToMap final : public Sim2SituationMap<InfrastructureManagement::MainStructureElement, SituationMap::BuildingOutline>
|
||||
, protected DdsFilterHandling<SituationMap::BuildingOutline>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<InfrastructureManagement::MainStructureElement, SituationMap::BuildingOutline>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::BuildingOutline>;
|
||||
|
||||
public:
|
||||
explicit MSEBridgeToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override
|
||||
{
|
||||
if (m_ismDtc)
|
||||
m_ismDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool isElapsed(const InfrastructureManagement::MainStructureElement &ddsData) const override;
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data,
|
||||
DataModification modType = DataModification::eAdded);
|
||||
void onMainFootprintChanged(const InfrastructureManagement::MainFootprint &data,
|
||||
DataModification modType = DataModification::eAdded);
|
||||
|
||||
protected:
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider = nullptr;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<Buildings::ForeignInfoGuiInterface> m_bldInfoIfc;
|
||||
mutable QVector<int> m_mseIdWithoutValidFootprint;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "mse_point_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <Plugins/Buildings/bld_info_gui_plugin_interface.h>
|
||||
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace SituationMap;
|
||||
|
||||
|
||||
QImage renderApproachingPoint(const QColor &color)
|
||||
{
|
||||
int size = 100;
|
||||
QImage image(size, size, QImage::Format_ARGB32);
|
||||
image.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
|
||||
painter.setPen(QPen(Qt::NoPen));
|
||||
painter.setBrush(QBrush(color, Qt::Dense5Pattern));
|
||||
painter.drawRect(image.rect());
|
||||
|
||||
|
||||
|
||||
QPen pen(color);
|
||||
pen.setWidth(5);
|
||||
painter.setPen(pen);
|
||||
|
||||
const int sizeHalf = size / 2.0;
|
||||
|
||||
QPointF center(sizeHalf, sizeHalf);
|
||||
|
||||
|
||||
painter.setBrush(color);
|
||||
painter.drawEllipse(center, sizeHalf * 0.1, sizeHalf * 0.1);
|
||||
|
||||
|
||||
QLine newLine(sizeHalf, 0, sizeHalf, sizeHalf * 0.6);
|
||||
painter.drawLine(newLine);
|
||||
|
||||
QTransform trans;
|
||||
trans.translate(sizeHalf, sizeHalf);
|
||||
trans.rotate(90);
|
||||
trans.translate(-sizeHalf, -sizeHalf);
|
||||
|
||||
newLine = trans.map(newLine);
|
||||
painter.drawLine(newLine);
|
||||
|
||||
newLine = trans.map(newLine);
|
||||
painter.drawLine(newLine);
|
||||
|
||||
newLine = trans.map(newLine);
|
||||
painter.drawLine(newLine);
|
||||
|
||||
painter.end();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool MSEPointToMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->ismDtc() ||
|
||||
!pluginProvider->ismDataIfc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
m_ismDtc = m_pluginProvider->ismDtc();
|
||||
|
||||
m_bldInfoIfc = pluginProvider->bldInfoIfc();
|
||||
|
||||
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MSEPointToMap::run()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Starting to run";
|
||||
|
||||
this->stop();
|
||||
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
|
||||
this, &MSEPointToMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_ismDtc->mainStructureElements([this](const InfrastructureManagement::MainStructureElement & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MSEPointToMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " Stopping";
|
||||
if (m_ismDtc)
|
||||
m_ismDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool MSEPointToMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_ismDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [simIdOut, &umodOut](const InfrastructureManagement::MainStructureElement & data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
|
||||
umodOut.m_description1 = QString::fromStdString(data.name());
|
||||
umodOut.m_participantData.m_typeName = InfrastructureManagement::toString(data.structureElementTypeId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const InfrastructureManagement::MainStructureElement &data)> cb1 = cb;
|
||||
return m_ismDtc->mainStructureElements(cb1);
|
||||
}
|
||||
|
||||
bool MSEPointToMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << " isElapsed";
|
||||
|
||||
if (BaseClass::isElapsed(data))
|
||||
return true;
|
||||
|
||||
if (data.isDeleted())
|
||||
return true;
|
||||
|
||||
if (data.structureElementTypeId() != InfrastructureManagement::StructureElementType::ApproachingPoint)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t MSEPointToMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool MSEPointToMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION
|
||||
<< ", id " << ddsData.id()
|
||||
<< ", name = " << ddsData.name();
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
TextStyle textStyle;
|
||||
textStyle.setSize(10);
|
||||
|
||||
|
||||
if (ddsData.structureElementTypeId() == InfrastructureManagement::StructureElementType::ApproachingPoint)
|
||||
{
|
||||
textStyle.setTextColor(Qt::yellow);
|
||||
mapObj->setProxyImage(renderApproachingPoint(Qt::yellow), QSize(50, 50));
|
||||
}
|
||||
|
||||
mapObj->setTextStyle(textStyle);
|
||||
|
||||
|
||||
const Core::GeoPosition &geoPos = ddsData.geoPosition();
|
||||
mapObj->setOrigin(Point3D(geoPos.lon(), geoPos.lat(), geoPos.z()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MSEPointToMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
if (!m_bldInfoIfc)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <MapObjects/geo_image.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MSEPointToMap final : public Sim2SituationMap<InfrastructureManagement::MainStructureElement, SituationMap::GeoImage>
|
||||
, protected DdsFilterHandling<SituationMap::GeoImage>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<InfrastructureManagement::MainStructureElement, SituationMap::GeoImage>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::GeoImage>;
|
||||
|
||||
public:
|
||||
MSEPointToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<Buildings::ForeignInfoGuiInterface> m_bldInfoIfc;
|
||||
|
||||
};
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
|
||||
|
||||
|
||||
#include "ncontamination_to_map.h"
|
||||
#include <Map/map.h>
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool NContamination2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::nContaminationChanged,
|
||||
this, &NContamination2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->nContaminations([this](const AreaEffectSimulation::NContamination &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &NContamination2SituationMap::onPartitionTimeChanged, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
void NContamination2SituationMap::onPartitionTimeChanged(qint64 newPartitionTime)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
updateAllSpheres3D(newPartitionTime);
|
||||
}
|
||||
|
||||
|
||||
void NContamination2SituationMap::updateAllSpheres3D(qint64 newPartitionTime)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", m_simId2UniqueMapId.size = " << m_simId2UniqueMapId.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QMapIterator<int32_t, UniqueMapId> it(m_simId2UniqueMapId);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const UniqueMapId uniqueMapId = it.value();
|
||||
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
const int simId = it.key();
|
||||
const AreaEffectSimulation::NContamination &nCont = m_aesDtc->nContamination(simId);
|
||||
if (nCont.id() != simId)
|
||||
continue;
|
||||
|
||||
if (updateSphere3D(mapObj, nCont, newPartitionTime))
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " updateView failed";
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool NContamination2SituationMap::updateSphere3D(RefPointer<Sim2SituationMap::MAP_T> mapObj, const AreaEffectSimulation::NContamination &data, qint64 newPartitionTime)
|
||||
{
|
||||
const int32_t simId = data.id();
|
||||
|
||||
if (!mapObj)
|
||||
return false;
|
||||
|
||||
bool bUpdateRequired = false;
|
||||
|
||||
const bool bDesiredNewState = (data.effectStateId().underlying() == AreaEffectSimulation::AesEffectState_def::EsActivated) &&
|
||||
((newPartitionTime - data.sampleTime() < 5000));
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", START" << " simId = " << simId
|
||||
<< ", sampleTime " << data.sampleTime()
|
||||
<< ", bDesiredNewState " << bDesiredNewState;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (mapObj->hasDetonation() && !bDesiredNewState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", START REMOVE " << " simId = " << simId;
|
||||
mapObj->resetDetonation();
|
||||
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
else if (!mapObj->hasDetonation() && bDesiredNewState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", START ADD " << " simId = " << simId;
|
||||
|
||||
const Core::GeoPosition2D &geoPos = data.impactPosition();
|
||||
Point3D markerOrigin(geoPos.lon(), geoPos.lat(), 0);
|
||||
mapObj->setDetonation(markerOrigin, data.impactRadius());
|
||||
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", END" << " simId = " << simId;
|
||||
return bUpdateRequired;
|
||||
}
|
||||
|
||||
bool NContamination2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
updateSphere3D(mapObj, ddsData, m_pluginProvider->partitionTime());
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtNContamination, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtNContamination) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
const Core::GeoPosition2D& impactPos2D = ddsData.impactPosition();
|
||||
mapObj->setImpactOrigin(Point3D(impactPos2D.lon(), impactPos2D.lat(), 0.0));
|
||||
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/nuclear_agent.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class NContamination2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<NContamination2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::NContamination;
|
||||
using MAP_TYPE = SituationMap::NuclearAgent;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtNContamination;
|
||||
};
|
||||
|
||||
class NContamination2SituationMap final : public Aes2SituationMap<NContamination2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<NContamination2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::NContamination &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->nContaminations(cb);
|
||||
}
|
||||
protected Q_SLOTS:
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
protected:
|
||||
void updateAllSpheres3D(qint64 newPartitionTime);
|
||||
bool updateSphere3D(RefPointer<MAP_T> mapObj, const AreaEffectSimulation::NContamination &data, qint64 newPartitionTime);
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+371
@@ -0,0 +1,371 @@
|
||||
|
||||
|
||||
|
||||
#include "off_route_to_map.h"
|
||||
#include <Map/map.h>
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/layer_factory.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
static int s_offRouteMine2 = 254;
|
||||
|
||||
|
||||
|
||||
bool OffRoute2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
return false;
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::offRouteMineChanged,
|
||||
this, &OffRoute2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
|
||||
this, &OffRoute2SituationMap::onAesItemViewChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->offRouteMines([this](const AreaEffectSimulation::OffRouteMine &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
connect(m_pluginProvider, &PluginProvider::partitionTimeChanged,
|
||||
this, &OffRoute2SituationMap::onPartitionTimeChanged, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
void OffRoute2SituationMap::onPartitionTimeChanged(qint64 newPartitionTime)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
updateAllDetonationSpheres(newPartitionTime);
|
||||
}
|
||||
|
||||
void OffRoute2SituationMap::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, " << " data.aesTypeId()=" << data.aesTypeId() << " modType=" << modType;
|
||||
|
||||
|
||||
|
||||
if (data.aesTypeId() != AreaEffectSimulation::AesType::AtOffRouteMineSecondary)
|
||||
return;
|
||||
|
||||
const int32_t simId = data.aesItemId();
|
||||
if (simId < 0)
|
||||
return;
|
||||
|
||||
|
||||
updateSecondary(simId);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " data.aesTypeId()=" << data.aesTypeId() << " modType=" << modType;
|
||||
}
|
||||
|
||||
void OffRoute2SituationMap::updateAllDetonationSpheres(qint64 newPartitionTime)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", m_simId2UniqueMapId.size = " << m_simId2UniqueMapId.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QMapIterator<int32_t, UniqueMapId> it(m_simId2UniqueMapId);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const UniqueMapId uniqueMapId = it.value();
|
||||
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
|
||||
const int simId = it.key();
|
||||
const AreaEffectSimulation::OffRouteMine &offRouteMine = m_aesDtc->offRouteMine(simId);
|
||||
if (offRouteMine.id() != simId)
|
||||
continue;
|
||||
|
||||
if (updateDetonationSphere3D(mapObj, offRouteMine, newPartitionTime))
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " updateView failed";
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool OffRoute2SituationMap::updateDetonationSphere3D(RefPointer<Sim2SituationMap::MAP_T> mapObj, const AreaEffectSimulation::OffRouteMine &trap, qint64 newPartitionTime)
|
||||
{
|
||||
const int32_t simId = trap.id();
|
||||
|
||||
if (!mapObj)
|
||||
return false;
|
||||
|
||||
bool bUpdateRequired = false;
|
||||
|
||||
const bool bDesiredNewState = trap.triggered() && ((newPartitionTime - trap.sampleTime() < 5000));
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", START" << " simId = " << simId
|
||||
<< ", sampleTime " << trap.sampleTime()
|
||||
<< ", bDesiredNewState " << bDesiredNewState;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef RENDERER_APPROACH
|
||||
|
||||
if (mapObj->has3DMarkerRenderer() && !bDesiredNewState)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << ", START REMOVE " << " simId = " << simId;
|
||||
mapObj->set3DMarkerRenderer(Point3D(), QVariantMap());
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
else if (!mapObj->has3DMarkerRenderer() && bDesiredNewState)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << ", START ADD " << " simId = " << simId;
|
||||
|
||||
const Core::GeoPosition2D &geoPos = trap.area().cornerBottomLeft();
|
||||
Point3D markerOrigin(geoPos.lon(), geoPos.lat(), 0);
|
||||
|
||||
QVariantMap attribMap;
|
||||
QString attribValue;
|
||||
|
||||
const QColor &majorColor = mapObj->majorColor();
|
||||
attribValue = QString(QStringLiteral("Impact_Color_%1")).arg(majorColor.name());
|
||||
attribMap.insert(QStringLiteral("IMPACT_COLOR"), attribValue);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const double radius = 10;
|
||||
|
||||
attribValue = QString(QStringLiteral("Impact_Radius_%1")).arg(radius);
|
||||
attribMap.insert(QStringLiteral("IMPACT_RADIUS"), attribValue);
|
||||
|
||||
LayerFactory::UniqueValueDataAesCentral::TYPE type{LayerFactory::UniqueValueDataAesCentral::TYPE::SPHERE};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
attribValue = QString(QStringLiteral("Impact_Type_%1")).arg(LayerFactory::toString(type));
|
||||
attribMap.insert(QStringLiteral("IMPACT_TYPE"), attribValue);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
attribMap.insert(QStringLiteral("HEADING"), 0);
|
||||
attribMap.insert(QStringLiteral("PITCH") , 0);
|
||||
attribMap.insert(QStringLiteral("ROLL") , 90);
|
||||
|
||||
|
||||
|
||||
mapObj->set3DMarkerRenderer(markerOrigin, attribMap);
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (mapObj->has3DMarkerSceneSymbol() && !bDesiredNewState)
|
||||
{
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << ", START REMOVE " << " simId = " << simId;
|
||||
mapObj->set3DMarkerSceneSymbol(Point3D(), {});
|
||||
bUpdateRequired = true;
|
||||
}
|
||||
else if (!mapObj->has3DMarkerSceneSymbol() && bDesiredNewState)
|
||||
{
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << ", START ADD " << " simId = " << simId;
|
||||
|
||||
const Core::GeoPosition2D &geoPos = trap.area().cornerBottomLeft();
|
||||
Point3D markerOrigin(geoPos.lon(), geoPos.lat(), 0);
|
||||
|
||||
VirtualMine::SceneSymbolData ssData;
|
||||
|
||||
const QColor &majorColor = mapObj->majorColor();
|
||||
ssData.color = majorColor;
|
||||
|
||||
ssData.radius = std::max( (trap.impactRadius().is_set() ? trap.impactRadius().get() : 1) , 1.0);
|
||||
|
||||
|
||||
|
||||
|
||||
ssData.cone = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->set3DMarkerSceneSymbol(markerOrigin, ssData);
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", END" << " simId = " << simId;
|
||||
return bUpdateRequired;
|
||||
}
|
||||
|
||||
bool OffRoute2SituationMap::updateSecondary(int32_t simId, bool bUpdateJust3DPart)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " simId = " << simId
|
||||
<< ", bUpdateJust3DPart" << bUpdateJust3DPart;
|
||||
if (simId < 0)
|
||||
return false;
|
||||
|
||||
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfSimId(simId);
|
||||
if (!mapObj.valid())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " getMapObjectOfSimId failed"
|
||||
<< " simId = " << simId << " (maybe expired)";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const AreaEffectSimulation::OffRouteMine &trap = m_aesDtc->offRouteMine(simId);
|
||||
|
||||
if (trap.chargeStruct().chargeTypeId() == s_offRouteMine2)
|
||||
{
|
||||
AreaEffectSimulation::AesItemView dataAesItemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtOffRouteMineSecondary, dataAesItemView))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " AesItemViewForSecondary found :-) ";
|
||||
} else {
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " no AesItemViewForSecondary found. :-( ";
|
||||
}
|
||||
|
||||
|
||||
if ((dataAesItemView.aesItemId() == simId) &&
|
||||
(trap.id() == simId) &&
|
||||
trap.triggered())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " setSubsidiaryLine";
|
||||
VirtualMine::OptionalData optData;
|
||||
optData.closed = true;
|
||||
mapObj->setSubsidiaryLine(0,
|
||||
form2PosCont(dataAesItemView.form()), optData);
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " removeSubsidiaryLine";
|
||||
mapObj->removeSubsidiaryLine(0);
|
||||
}
|
||||
|
||||
if (!mapObj->updateView()){
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " simId = " << simId << " updateView failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << ", END" << " simId = " << simId
|
||||
<< " trap.triggered(" << trap.triggered();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OffRoute2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtOffRouteMine, itemView))
|
||||
{
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
|
||||
if (m_objFac.map() && (m_objFac.map()->mode() == Mode::Mode_3D))
|
||||
updateDetonationSphere3D(mapObj, ddsData, m_pluginProvider->partitionTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtOffRouteMine) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
|
||||
updateSecondary(simId);
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OffRoute2SituationMap::isVisibleByFilter(const Aes2SituationMap::DDS_TYPE &data) const
|
||||
{
|
||||
if (!m_displayFilter)
|
||||
return true;
|
||||
|
||||
const auto es = data.effectStart().is_set() ? data.effectStart().get() : 0;
|
||||
const auto partyId = data.partyId().is_set() ? data.partyId().get() : -1;
|
||||
bool isVisibleByFilter = partyId > 0 ? FilterClass::m_currentSymbolSettings.symbolSettings.symbolPartyAppearance.value(partyId).isVisible : true;
|
||||
if (isVisibleByFilter)
|
||||
isVisibleByFilter = m_displayFilter->isVisible(AreaEffectSimulation::AesType_def::AtMineArea,
|
||||
data.effectStateId(),
|
||||
data.chargeStruct().chargeTypeId(),
|
||||
partyId,
|
||||
data.isCentral(),
|
||||
es,
|
||||
data.effectDuration(),
|
||||
m_pluginProvider->partitionTime());
|
||||
|
||||
return isVisibleByFilter;
|
||||
}
|
||||
|
||||
void OffRoute2SituationMap::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
if ((AreaEffectSimulation::AesType_def::AtOffRouteMine != aesType.underlying()) &&
|
||||
(AreaEffectSimulation::AesType_def::AtMineArea != aesType.underlying()))
|
||||
return;
|
||||
|
||||
const auto cb = [this](const DDS_TYPE &data) -> bool
|
||||
{
|
||||
|
||||
if (data.isDeleted())
|
||||
return false;
|
||||
this->updateVisibility(data);
|
||||
return false;
|
||||
};
|
||||
iterateAesData(cb);
|
||||
}
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/virtual_mine.h>
|
||||
#include <QObject>
|
||||
|
||||
#define OFFROUTEMINE_HAS_SECONDARY_VIEW
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class OffRoute2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<OffRoute2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::OffRouteMine;
|
||||
using MAP_TYPE = SituationMap::VirtualMine;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtOffRouteMine;
|
||||
};
|
||||
|
||||
class OffRoute2SituationMap final : public Aes2SituationMap<OffRoute2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<OffRoute2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::OffRouteMine &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->offRouteMines(cb);
|
||||
}
|
||||
protected Q_SLOTS:
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
protected:
|
||||
void updateAllDetonationSpheres(qint64 newPartitionTime);
|
||||
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType);
|
||||
protected:
|
||||
bool updateDetonationSphere3D(RefPointer<MAP_T> mapObj, const AreaEffectSimulation::OffRouteMine &trap, qint64 newPartitionTime);
|
||||
bool updateSecondary(int32_t simId, bool bUpdateJust3DPart = false);
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
bool isVisibleByFilter(const DDS_TYPE &data) const override;
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
};
|
||||
|
||||
}
|
||||
+1887
File diff suppressed because it is too large.
Load diff
+228
@@ -0,0 +1,228 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include "pdm_handler.h"
|
||||
|
||||
#include <Utils/movement_track_manager.h>
|
||||
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_participant_info_gui_plugin_interface.h>
|
||||
#include <Plugins/OcSituationClient/osc_participant_info_gui_plugin_interface.h>
|
||||
#include <Plugins/GuezIedManagement/gim_data_plugin_interface.h>
|
||||
|
||||
#include <MapObjects/participant.h>
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
struct HitlineInfo
|
||||
{
|
||||
qint32 participantId = -1;
|
||||
ParticipantManagement::ParticipantPosition participantPosition;
|
||||
|
||||
ParticipantManagement::StateInformation participantState;
|
||||
|
||||
ParticipantManagement::ParticipantPosition originatorPosition;
|
||||
qint32 injuryPartyId = -1;
|
||||
};
|
||||
|
||||
|
||||
class LayerFactory;
|
||||
class PdmHandler;
|
||||
|
||||
|
||||
class Participant2SituationMap final : public Sim2SituationMap<ParticipantManagement::Participant, SituationMap::Participant>
|
||||
, protected DdsFilterHandling<SituationMap::Participant>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<ParticipantManagement::Participant, SituationMap::Participant>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::Participant>;
|
||||
|
||||
struct InternalPosition final : public ParticipantManagement::UnitPosition
|
||||
{
|
||||
Core::PositionReportingSource reportingSource;
|
||||
bool isUnit = true;
|
||||
bool bShowCenter = false;
|
||||
|
||||
bool bIsMountedOn = false;
|
||||
bool bHasMountedParticipants = false;
|
||||
|
||||
inline const Core::GeoPosition &position() const OMG_NOEXCEPT
|
||||
{
|
||||
return (isUnit && bShowCenter) ? positionCenter() : positionLeader();
|
||||
}
|
||||
inline rti::core::int64 sampleTime() const OMG_NOEXCEPT
|
||||
{
|
||||
return (isUnit && bShowCenter) ? sampleTimeCenter() : sampleTimeLeader();
|
||||
}
|
||||
|
||||
InternalPosition() = default;
|
||||
explicit InternalPosition(const ParticipantManagement::UnitPosition &unitPos_param, bool bCenter)
|
||||
: ParticipantManagement::UnitPosition(unitPos_param)
|
||||
, bShowCenter(bCenter)
|
||||
{}
|
||||
};
|
||||
public:
|
||||
Participant2SituationMap(PdmHandler *pdmHandler,
|
||||
ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
const char *loggerName);
|
||||
~Participant2SituationMap();
|
||||
|
||||
|
||||
|
||||
bool init(LayerFactory *layerFactory,
|
||||
PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
void setMovementTrackManager(const QPointer<MovementTrackManager> &mtMgr) { m_movementTrackManager = mtMgr; }
|
||||
|
||||
bool enableFireEventFlashing(bool enable);
|
||||
bool isFireEventFlashingEnabled() const;
|
||||
|
||||
|
||||
bool isParticipantVisible(const int32_t participantId, bool *bParticipantExists) const;
|
||||
Q_SIGNALS:
|
||||
void hitlineOccured(const HitlineInfo &hitlineInfo);
|
||||
void participantPositionChanged(const int32_t participantId, const Point3D &newPos);
|
||||
void participantOwnPositionChanged(const Point3D &newPos, int64_t sampleTime);
|
||||
|
||||
public Q_SLOTS:
|
||||
void onParticipantFakeGearEventChanged(int participantId, qint64 sampleTime, SpecialChargeType specialChargeType);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onPartitionTimeChanged(qint64 newPartitionTime);
|
||||
|
||||
void onFireEventFlashTimer();
|
||||
|
||||
void onTypesChanged(const ParticipantManagement::Type &data,
|
||||
DataModification modType);
|
||||
|
||||
void onParticipantChanged(const ParticipantManagement::Participant &data,
|
||||
DataModification modType);
|
||||
|
||||
void onPositionChanged(const ParticipantManagement::ParticipantPosition &data,
|
||||
DataModification modType);
|
||||
|
||||
void onUnitPositionChanged(const ParticipantManagement::UnitPosition &data,
|
||||
DataModification modType);
|
||||
|
||||
void updateParticipantPosition(int participantId, bool bHandleSymbolAppearanceSettingsParticipant = true);
|
||||
void updateParticipantPosition(const InternalPosition &pos, bool bHandleSymbolAppearanceSettingsParticipant = true);
|
||||
|
||||
|
||||
void onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data,
|
||||
DataModification modType);
|
||||
|
||||
void onBiteChanged(const ParticipantManagement::Bite &data,
|
||||
DataModification modType);
|
||||
|
||||
void onParticipantGearEventChanged(const ParticipantManagement::ParticipantGearEvent &data, DataModification modType);
|
||||
|
||||
void onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType);
|
||||
|
||||
void onDusMineStateChanged(const AreaEffectSimulation::DusMineState &data, DataModification modType);
|
||||
|
||||
void onMovementTrackActivityChanged(int trackId, bool active);
|
||||
void onMovementTrackRemoved(int trackId);
|
||||
|
||||
void addToUpdateNotify(const RefPointer<MAP_T> &mapObj);
|
||||
void notifyMapAboutModifedObjects();
|
||||
|
||||
protected:
|
||||
void updateHierarchyLevels();
|
||||
int participantHierachyLevel(const ParticipantManagement::Participant &data) const;
|
||||
QString layernameWithHierachy(qint32 hierachyLevel) const;
|
||||
QString layernameWithHierachy(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
|
||||
bool isElapsed(const ParticipantManagement::Participant &data) const override;
|
||||
|
||||
|
||||
void checkForUnknownOriginatorsParticipant(int possibleOriginatorParticipantId);
|
||||
void checkForUnknownOriginatorsAes(int possibleOriginatorEffectSimId);
|
||||
bool updateDynamicParticipantData(RefPointer<Sim2SituationMap::MAP_T> mapObj, const ParticipantManagement::DynamicParticipantData &data);
|
||||
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const ParticipantManagement::Participant &ddsData,
|
||||
RefPointer<Participant> mapObj) override;
|
||||
|
||||
bool removeElement(const int32_t simId) override;
|
||||
|
||||
void updateGearEvents(bool doUpdateView = false);
|
||||
void updateGearEventInternal(bool doUpdateView,
|
||||
qint64 curPartitionTimeMSec,
|
||||
qint64 fireEventFlashingDurationMSec,
|
||||
const QSet<int> &particpantIdsWithGearEvents);
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings & ) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override;
|
||||
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) override;
|
||||
bool hasBitError(const ParticipantManagement::DynamicParticipantData &dpd) const;
|
||||
bool isOutOfDate(const InternalPosition &pos) const;
|
||||
bool isSimulatedPosition(const InternalPosition &pos) const;
|
||||
void handleSymbolAppearanceSettingsParticipant(int participantId);
|
||||
void handleSymbolAppearanceSettingsParticipant(RefPointer<MAP_T> &mapObj,
|
||||
const ParticipantManagement::Participant &participant);
|
||||
void handleSymbolAppearanceSettingsParticipant(RefPointer<MAP_T> &mapObj,
|
||||
const ParticipantManagement::Participant &participant,
|
||||
const InternalPosition &pPos,
|
||||
const ParticipantManagement::DynamicParticipantData &dpd);
|
||||
|
||||
private:
|
||||
LayerFactory *m_layerFactory = nullptr;
|
||||
PluginProvider *m_pluginProvider = nullptr;
|
||||
QTimer *m_notifiyTimer = nullptr;
|
||||
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> m_ppmParticipantInfoIfc;
|
||||
std::shared_ptr<OcSituationClient::ForeignParticipantInfoGuiInterface> m_ocParticipantInfoIfc;
|
||||
|
||||
|
||||
|
||||
QHash<qint32, ParticipantManagement::Type> m_types;
|
||||
QHash<int, ParticipantManagement::Participant> m_participants;
|
||||
QHash<int, InternalPosition> m_participantPositions;
|
||||
QHash<int, ParticipantManagement::DynamicParticipantData> m_participantDynamicData;
|
||||
QHash<int, qint64> m_participantGearEvents;
|
||||
QHash<int, qint64> m_lrfParticipantFakeGearEvents;
|
||||
QHash<int, qint64> m_ltdParticipantFakeGearEvents;
|
||||
|
||||
QHash<int, bool> m_participantsWithProperties;
|
||||
QVector<QPair<int, int>> m_unknownOriginatorsParticipant;
|
||||
QVector<QPair<int, int>> m_unknownOriginatorsAes;
|
||||
QSet<int> m_participantWithMaybeMissingPartyId;
|
||||
QHash<int, int> m_aesItemView2PartyId;
|
||||
QVector<RefPointer<MAP_T>> m_objectsToUpdate;
|
||||
|
||||
QSet<int> m_hasBiteError;
|
||||
PdmHandler *m_pdmHandler;
|
||||
bool m_bShowCenterPositions = false;
|
||||
|
||||
QTimer *m_fireEventFlashTimer = nullptr;
|
||||
int m_fireEventFlashTriState = 0;
|
||||
bool m_fireEventFlashEnable = true;
|
||||
|
||||
QPointer<SituationMap::MovementTrackManager> m_movementTrackManager;
|
||||
};
|
||||
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
|
||||
|
||||
|
||||
#include "pdm_handler.h"
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
QString toString(SpecialChargeType value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SpecialChargeType::NoneSpecial:
|
||||
return QStringLiteral("SpecialChargeType:NoneSpecial");
|
||||
case SpecialChargeType::LRF:
|
||||
return QStringLiteral("SpecialChargeType:LRF");
|
||||
case SpecialChargeType::LTD:
|
||||
return QStringLiteral("SpecialChargeType:LTD");
|
||||
}
|
||||
Q_ASSERT(false);
|
||||
return QStringLiteral("SpecialChargeTypeERROR");
|
||||
}
|
||||
|
||||
PdmHandler::PdmHandler(const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &dtcPdm)
|
||||
: m_dtcPdm(dtcPdm)
|
||||
, m_logger(getLogger("PdmHandler"))
|
||||
{}
|
||||
|
||||
|
||||
void PdmHandler::initializePdm()
|
||||
{
|
||||
if (m_dtcPdm == nullptr)
|
||||
return;
|
||||
|
||||
if (m_bPdmInitialized)
|
||||
return;
|
||||
m_bPdmInitialized = true;
|
||||
|
||||
connect(m_dtcPdm.get(), &ProjectDataManagement::Interface::Dtc::chargeTypeChanged,
|
||||
this, &PdmHandler::onChargeTypeChanged);
|
||||
connect(m_dtcPdm.get(), &ProjectDataManagement::Interface::Dtc::gearTypeChargeTypeChanged,
|
||||
this, &PdmHandler::onGearTypeChargeTypeChanged);
|
||||
|
||||
m_chargeTypes = m_dtcPdm->chargeTypes();
|
||||
m_gearTypeChargeTypes = m_dtcPdm->gearTypeChargeTypes();
|
||||
}
|
||||
|
||||
void PdmHandler::onChargeTypeChanged(const ProjectDataManagement::ChargeType &data, DataModification mod)
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
m_chargeTypes[data.id()] = data;
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PdmHandler::onGearTypeChargeTypeChanged(const ProjectDataManagement::GearTypeChargeType &data, DataModification mod)
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
m_gearTypeChargeTypes[data.id()] = data;
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ProjectDataManagement::ChargeType PdmHandler::chargeTypeFromId(int chargeTypeId)
|
||||
{
|
||||
if (chargeTypeId <= 0)
|
||||
return ProjectDataManagement::ChargeType();
|
||||
|
||||
initializePdm();
|
||||
|
||||
auto it = m_chargeTypes.constFind(chargeTypeId);
|
||||
if (it == m_chargeTypes.cend())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not find charge type with id " << chargeTypeId;
|
||||
return ProjectDataManagement::ChargeType();
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
int PdmHandler::maxRangeFromGearTypeIdAndChargeTypeId(int gearTypeId, int chargeTypeId)
|
||||
{
|
||||
if (gearTypeId < 0)
|
||||
return -1;
|
||||
if (chargeTypeId < 0)
|
||||
return -1;
|
||||
|
||||
initializePdm();
|
||||
|
||||
|
||||
for (const auto &entry : qAsConst(m_gearTypeChargeTypes))
|
||||
if ((entry.gearTypeId() == gearTypeId) &&
|
||||
(entry.chargeTypeId() == chargeTypeId))
|
||||
return entry.maxRange();
|
||||
|
||||
|
||||
for (const auto &entry : qAsConst(m_gearTypeChargeTypes))
|
||||
if ((entry.gearTypeId() == 1000) &&
|
||||
(entry.chargeTypeId() == chargeTypeId))
|
||||
return entry.maxRange();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
double PdmHandler::impactRadius(const AreaEffectSimulation::ChargeStruct &chargeStruct, double defaultValue)
|
||||
{
|
||||
if (chargeStruct.chargeTypeId() < 0)
|
||||
return defaultValue;
|
||||
|
||||
initializePdm();
|
||||
if (!m_dtcPdm)
|
||||
return defaultValue;
|
||||
|
||||
return m_dtcPdm->impactRadius(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId());
|
||||
}
|
||||
|
||||
bool PdmHandler::isSmart(const AreaEffectSimulation::ChargeStruct &chargeStruct)
|
||||
{
|
||||
if (chargeStruct.chargeTypeId() < 0)
|
||||
return false;
|
||||
|
||||
initializePdm();
|
||||
if (!m_dtcPdm)
|
||||
return false;
|
||||
|
||||
return m_dtcPdm->isSmart(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId());
|
||||
}
|
||||
|
||||
QString PdmHandler::trChargeTypeShortName(int chargeTypeId)
|
||||
{
|
||||
if (!m_dtcPdm)
|
||||
return QString();
|
||||
|
||||
return m_dtcPdm->trChargeTypeShortName(chargeTypeId);
|
||||
}
|
||||
|
||||
bool PdmHandler::isLRFChargeType(int chargeTypeId)
|
||||
{
|
||||
return isSpecialChargeType(chargeTypeId) == SpecialChargeType::LRF;
|
||||
}
|
||||
|
||||
bool PdmHandler::isLTDChargeType(int chargeTypeId)
|
||||
{
|
||||
return isSpecialChargeType(chargeTypeId) == SpecialChargeType::LTD;
|
||||
}
|
||||
|
||||
bool PdmHandler::isChargeTypeLtdOrLrf(SpecialChargeType sct)
|
||||
{
|
||||
return ((sct == SpecialChargeType::LRF) || (sct == SpecialChargeType::LTD));
|
||||
}
|
||||
|
||||
ProjectDataManagement::GearClass PdmHandler::gearClassFromChargeTypeId(int chargeTypeId)
|
||||
{
|
||||
if (!m_dtcPdm)
|
||||
return ProjectDataManagement::GearClass_def::Unknown;
|
||||
return m_dtcPdm->gearClassFromChargeTypeId(chargeTypeId);
|
||||
}
|
||||
|
||||
QVector<ProjectDataManagement::CasEffect> PdmHandler::casEffects(const AreaEffectSimulation::ChargeStruct &chargeStruct)
|
||||
{
|
||||
if (!m_dtcPdm)
|
||||
return {};
|
||||
return m_dtcPdm->casEffects(chargeStruct.chargeTypeId(), chargeStruct.igniterTypeId(), chargeStruct.igniterFunctionId());
|
||||
}
|
||||
|
||||
bool PdmHandler::isChargeTypeLtdOrLrf(int chargeTypeId)
|
||||
{
|
||||
const SpecialChargeType specialChargeTypeId = isSpecialChargeType(chargeTypeId);
|
||||
return isChargeTypeLtdOrLrf(specialChargeTypeId);
|
||||
}
|
||||
|
||||
|
||||
SpecialChargeType PdmHandler::isSpecialChargeType(int chargeTypeId)
|
||||
{
|
||||
|
||||
ProjectDataManagement::ChargeTypeProperty ret = m_dtcPdm->getChargeTypeSpecialProperty(chargeTypeId, 0,0);
|
||||
|
||||
if (ret == ProjectDataManagement::ChargeTypeProperty::LRF)
|
||||
return SpecialChargeType::LRF;
|
||||
if (ret == ProjectDataManagement::ChargeTypeProperty::LTD)
|
||||
return SpecialChargeType::LTD;
|
||||
|
||||
|
||||
return SpecialChargeType::NoneSpecial;
|
||||
}
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <Common/situation_map_logging.h>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <ProjectDataManagement/pdm_dtc.h>
|
||||
#include <AreaEffectSimulation/aes_dtc.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
enum class SpecialChargeType
|
||||
{
|
||||
NoneSpecial,
|
||||
LRF,
|
||||
LTD
|
||||
};
|
||||
|
||||
QString toString(SpecialChargeType value);
|
||||
|
||||
static inline std::ostream &operator<< (std::ostream &stream,
|
||||
const SpecialChargeType value)
|
||||
{
|
||||
stream << "SpecialChargeType " << toString(value);
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PdmHandler(const std::shared_ptr<ProjectDataManagement::Interface::Dtc> &dtcPdm);
|
||||
|
||||
ProjectDataManagement::ChargeType chargeTypeFromId(int chargeTypeId);
|
||||
int maxRangeFromGearTypeIdAndChargeTypeId(int gearTypeId, int chargeTypeId);
|
||||
double impactRadius(const AreaEffectSimulation::ChargeStruct &chargeStruct, double defaultValue = 10.0);
|
||||
bool isSmart(const AreaEffectSimulation::ChargeStruct &chargeStruct);
|
||||
QString trChargeTypeShortName(int chargeTypeId);
|
||||
|
||||
SpecialChargeType isSpecialChargeType(int chargeTypeId);
|
||||
bool isLRFChargeType(int chargeTypeId);
|
||||
bool isLTDChargeType(int chargeTypeId);
|
||||
bool isChargeTypeLtdOrLrf(int chargeTypeId);
|
||||
static bool isChargeTypeLtdOrLrf(SpecialChargeType sct);
|
||||
|
||||
ProjectDataManagement::GearClass gearClassFromChargeTypeId(int chargeTypeId);
|
||||
QVector<ProjectDataManagement::CasEffect> casEffects(const AreaEffectSimulation::ChargeStruct &chargeStruct);
|
||||
|
||||
private:
|
||||
void initializePdm();
|
||||
void onChargeTypeChanged(const ProjectDataManagement::ChargeType &data, DataModification mod);
|
||||
void onGearTypeChargeTypeChanged(const ProjectDataManagement::GearTypeChargeType &data, DataModification mod);
|
||||
|
||||
private:
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_dtcPdm;
|
||||
QMap<int, ProjectDataManagement::ChargeType> m_chargeTypes;
|
||||
QMap<int, ProjectDataManagement::GearTypeChargeType> m_gearTypeChargeTypes;
|
||||
bool m_bPdmInitialized{false};
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
#include <SituationMap/sitmapdds_export.h>
|
||||
|
||||
namespace LtsAppDescriptor
|
||||
{
|
||||
enum class App;
|
||||
}
|
||||
namespace AlarmManagement
|
||||
{
|
||||
class ForeignInfoGuiInterface;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AssetManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
class ForeignInfoGuiInterface;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Buildings
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
class ForeignInfoGuiInterface;
|
||||
}
|
||||
|
||||
namespace CentralEffectSimulation
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class ForeignFltParticipantGuiInterface;
|
||||
class ForeignAesGuiInterface;
|
||||
class ForeignFltBuildingComponentGuiInterface;
|
||||
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace GuezIedManagement
|
||||
{
|
||||
class ForeignGuiInterface;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace GuezNasat
|
||||
{
|
||||
class ForeignGuiInterface;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ForeignDataInterface;
|
||||
class ForeignResourceManagementGuiInterface;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
class ForeignParticipantInfoGuiInterface;
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ProjectDataManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace OcSituationClient
|
||||
{
|
||||
class ForeignParticipantInfoGuiInterface;
|
||||
}
|
||||
|
||||
namespace ServiceMonitor
|
||||
{
|
||||
class ForeignGuiInterface;
|
||||
}
|
||||
|
||||
namespace TargetManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class SITMAPDDS_EXPORT PluginProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QObject::QObject;
|
||||
|
||||
virtual QString toString() const = 0;
|
||||
|
||||
|
||||
virtual int exerciseId() const = 0;
|
||||
virtual bool isSessionValid() const = 0;
|
||||
virtual qint64 partitionTime() const = 0;
|
||||
virtual int partitionId() const = 0;
|
||||
virtual int operatorId() const = 0;
|
||||
virtual LtsAppDescriptor::App appId() const = 0;
|
||||
virtual bool isVisibleParty(int partyId) const = 0;
|
||||
virtual QString workspaceId() const = 0;
|
||||
virtual bool isReplayPartition() const = 0;
|
||||
|
||||
virtual std::shared_ptr<AreaEffectSimulation::Interface::Dtc> aesDtc() const = 0;
|
||||
virtual std::shared_ptr<AreaEffectSimulation::ForeignInfoGuiInterface> aesInfoIfc() const = 0;
|
||||
virtual std::shared_ptr<AlarmManagement::Interface::Dtc> almDtc() const = 0;
|
||||
virtual std::shared_ptr<AlarmManagement::Interface::Ftc> almFtc() const = 0;
|
||||
virtual std::shared_ptr<AlarmManagement::ForeignInfoGuiInterface> almInfoIfc() const = 0;
|
||||
virtual std::shared_ptr<AssetManagement::Interface::Dtc> asmDtc() const = 0;
|
||||
virtual std::shared_ptr<AssetManagement::Interface::Ftc> asmFtc() const = 0;
|
||||
virtual std::shared_ptr<Buildings::Interface::Dtc> bldDtc() const = 0;
|
||||
virtual std::shared_ptr<Buildings::Interface::Ftc> bldFtc() const = 0;
|
||||
virtual std::shared_ptr<Buildings::ForeignInfoGuiInterface> bldInfoIfc() const = 0;
|
||||
virtual std::shared_ptr<CentralEffectSimulation::Interface::Dtc> cesDtc() const = 0;
|
||||
virtual std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc() const = 0;
|
||||
virtual std::shared_ptr<ExerciseManagement::Interface::Ftc> exmFtc() const = 0;
|
||||
virtual std::shared_ptr<FilterManagement::Interface::Dtc> fltDtc() const = 0;
|
||||
virtual std::shared_ptr<FilterManagement::Interface::Ftc> fltFtc() const = 0;
|
||||
virtual std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> fltParticipantIfc() const = 0;
|
||||
virtual std::shared_ptr<FilterManagement::ForeignAesGuiInterface> fltAesIfc() const = 0;
|
||||
virtual std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> fltBuildingComponentIfc() const = 0;
|
||||
virtual std::shared_ptr<GuezIedManagement::Interface::Dtc> gimDtc() const = 0;
|
||||
virtual std::shared_ptr<GuezIedManagement::ForeignGuiInterface> gimIfc() const = 0;
|
||||
virtual std::shared_ptr<GuezNasat::Interface::Dtc> gnaDtc() const = 0;
|
||||
virtual std::shared_ptr<GuezNasat::ForeignGuiInterface> gnaIfc() const = 0;
|
||||
virtual std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc() const = 0;
|
||||
virtual std::shared_ptr<InfrastructureManagement::ForeignDataInterface> ismDataIfc() const = 0;
|
||||
virtual std::shared_ptr<InfrastructureManagement::ForeignResourceManagementGuiInterface> ismGuiIfc() const = 0;
|
||||
virtual std::shared_ptr<OperatorManagement::Interface::Dtc> opmDtc() const = 0;
|
||||
virtual std::shared_ptr<OperatorManagement::Interface::Ftc> opmFtc() const = 0;
|
||||
virtual std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc() const = 0;
|
||||
virtual std::shared_ptr<SituationReplay::Interface::Dtc> srpDtc() const = 0;
|
||||
virtual std::shared_ptr<ParticipantManagement::Interface::Ftc> ppmFtc() const = 0;
|
||||
virtual std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> ppmParticipantInfoIfc() const = 0;
|
||||
virtual std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc() const = 0;
|
||||
virtual std::shared_ptr<OcSituationClient::ForeignParticipantInfoGuiInterface> ocParticipantInfoIfc() const = 0;
|
||||
virtual std::shared_ptr<ServiceMonitor::ForeignGuiInterface> smoServiceMonitorIfc() const = 0;
|
||||
virtual std::shared_ptr<TargetManagement::Interface::Dtc> tgtDtc() const = 0;
|
||||
virtual std::shared_ptr<ComponentMonitor::Interface::Dtc> cmoDtc() const = 0;
|
||||
|
||||
signals:
|
||||
void partitionTimeChanged(qint64 partitionTime);
|
||||
void workspaceIdChanged(const QString &newWorkspaceId);
|
||||
};
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
|
||||
#include "recon_area_to_map.h"
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool ReconArea2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::reconAreaChanged,
|
||||
this, &ReconArea2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->reconAreas([this](const AreaEffectSimulation::ReconArea &data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool ReconArea2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
mapObj->setVisibility(ObjectAppearance::Tactical, false);
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
if (ddsData.partyId().is_set())
|
||||
mapObj->setPartyId(ddsData.partyId().get());
|
||||
else
|
||||
{
|
||||
mapObj->rLineStyle().setLineColor(Qt::black);
|
||||
mapObj->rFillStyle().setFillColor(Qt::black);
|
||||
}
|
||||
|
||||
mapObj->setAesState(effectState2aesState(ddsData.effectStateId().underlying()));
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, Aes2SituationMapTraits<ReconArea2SituationMap>::aesType, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtReconArea) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/biological_agent.h>
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class ReconArea2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<ReconArea2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::ReconArea;
|
||||
using MAP_TYPE = SituationMap::BiologicalAgent;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtReconArea;
|
||||
};
|
||||
|
||||
class ReconArea2SituationMap final : public Aes2SituationMap<ReconArea2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<ReconArea2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::ReconArea &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->reconAreas(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
enum class ResourceManagerMode
|
||||
{
|
||||
Undefined,
|
||||
RMM_PlanActivityView,
|
||||
RMM_PlanDefinitionView,
|
||||
RMM_ComponentMonitor
|
||||
};
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
|
||||
|
||||
|
||||
#include "shootback_area_to_map.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
bool ShootbackAreaToSituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->asmDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
m_tgtDtc = m_pluginProvider->tgtDtc();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShootbackAreaToSituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_tgtDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
this->stop();
|
||||
|
||||
connect(m_tgtDtc.get(), &TargetManagement::Interface::Dtc::shootbackAreaChanged,
|
||||
this, &ShootbackAreaToSituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_tgtDtc->shootbackAreas([this](const TargetManagement::ShootbackArea & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShootbackAreaToSituationMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping";
|
||||
if (m_tgtDtc)
|
||||
m_tgtDtc->disconnect(this);
|
||||
}
|
||||
|
||||
int32_t ShootbackAreaToSituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool ShootbackAreaToSituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setLineStyle(LineStyle(Qt::black, 2, LinePattern::Solid));
|
||||
|
||||
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
const Core::GeoPosition2D ¢er = ddsData.position();
|
||||
const LtsCoordTrans::UtmCoordinate referencePointUTM = LtsCoordTrans::UtmCoordinate::fromGeographic(center.lon(), center.lat());
|
||||
|
||||
const QPointF size(ddsData.width() / 2.0, ddsData.height() / 2.0);
|
||||
|
||||
PositionCont posCont;
|
||||
posCont.reserve(4);
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(size.x() * -1, size.y() * -1)));
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(size.x() * -1, size.y() * +1)));
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(size.x() * +1, size.y() * +1)));
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(size.x() * +1, size.y() * -1)));
|
||||
|
||||
mapObj->setPositions(posCont);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/TargetManagement/tgt_data_plugin_interface.h>
|
||||
#include <MapObjects/polygon.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class ShootbackAreaToSituationMap final : public Sim2SituationMap<TargetManagement::ShootbackArea, SituationMap::Polygon>
|
||||
, protected DdsFilterHandling<SituationMap::Polygon>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<TargetManagement::ShootbackArea, SituationMap::Polygon>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::Polygon>;
|
||||
|
||||
public:
|
||||
ShootbackAreaToSituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
protected:
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
}
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider;
|
||||
std::shared_ptr<TargetManagement::Interface::Dtc> m_tgtDtc;
|
||||
};
|
||||
|
||||
}
|
||||
+680
@@ -0,0 +1,680 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include "unified_map_object_data.h"
|
||||
#include "plugin_provider.h"
|
||||
#include <Map/object_factory.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
|
||||
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
||||
|
||||
|
||||
|
||||
#include <FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
||||
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
const char SimIdProperty[] = "SimId";
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
class Sim2SituationMapBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
Sim2SituationMapBase(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass()
|
||||
, m_objFac(objFac)
|
||||
, m_assignDrawOrder(true)
|
||||
, m_drawOrder(drawOrder)
|
||||
, m_layername(layername)
|
||||
, m_loggerName(QString::fromLatin1(loggerName))
|
||||
, m_logger(getLogger(loggerName))
|
||||
{}
|
||||
|
||||
virtual ~Sim2SituationMapBase() = default;
|
||||
|
||||
bool assignDrawOrder() const
|
||||
{
|
||||
return m_assignDrawOrder;
|
||||
}
|
||||
void setAssignDrawOrder(bool assignDrawOrder)
|
||||
{
|
||||
m_assignDrawOrder = assignDrawOrder;
|
||||
}
|
||||
|
||||
virtual bool run() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
virtual void clearObjects() = 0;
|
||||
|
||||
|
||||
virtual bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
Q_UNUSED(uniqueMapIds);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool unifiedMapObjectData(UniqueMapId , UnifiedMapObjectData &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
long mapObjectCount() const
|
||||
{
|
||||
return m_simId2UniqueMapId.size();
|
||||
}
|
||||
|
||||
UniqueMapId simId2UniqueMapId(int32_t simId) const
|
||||
{
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(simId, SituationMap::INVALID_MAP_ID);
|
||||
return uniqueMapId;
|
||||
}
|
||||
|
||||
bool uniqueMapId2SimId(UniqueMapId uniqueMapId, int32_t &simId) const
|
||||
{
|
||||
if (!SituationMap::isUniqueMapIdValid(uniqueMapId))
|
||||
return false;
|
||||
|
||||
simId = m_uniqueMapId2SimId.value(uniqueMapId, -1);
|
||||
return (simId != -1);
|
||||
}
|
||||
|
||||
const QVector<int32_t> uniqueMapIds2SimIds(const QVector<UniqueMapId> &uniqueMapIds) const
|
||||
{
|
||||
QVector<int32_t> simIds;
|
||||
simIds.reserve(uniqueMapIds.size());
|
||||
|
||||
int32_t simId_entityId = -1;
|
||||
for(const UniqueMapId uniqueMapId : qAsConst(uniqueMapIds))
|
||||
{
|
||||
if (this->uniqueMapId2SimId(uniqueMapId, simId_entityId))
|
||||
simIds.append(simId_entityId);
|
||||
}
|
||||
return simIds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual qint64 startTime(UniqueMapId uniqueMapId) const
|
||||
{
|
||||
Q_UNUSED(uniqueMapId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const QString &layername() const
|
||||
{
|
||||
return m_layername;
|
||||
}
|
||||
|
||||
template <typename MAP_T>
|
||||
void iterateObjects(const std::function<void( RefPointer<MAP_T> &mapObj)> &f)
|
||||
{
|
||||
for (const UniqueMapId &uniqueMapId : qAsConst(m_simId2UniqueMapId))
|
||||
{
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
f(mapObj);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void reRenderObjects()
|
||||
{
|
||||
for (const UniqueMapId &uniqueMapId : qAsConst(m_simId2UniqueMapId))
|
||||
{
|
||||
RefPointer<AbstractMapObject> mapObj = m_objFac.get(uniqueMapId);
|
||||
if (!mapObj.valid())
|
||||
continue;
|
||||
mapObj->reRenderSymbol();
|
||||
mapObj->updateView();
|
||||
|
||||
if (!mapObj->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " updateElement failed, "
|
||||
<< " uniqueMapId = " << uniqueMapId
|
||||
<< " debugInfo='" << mapObj->debugInfo() << "'";
|
||||
}
|
||||
}
|
||||
|
||||
void emit_visibilityHasChangedSignal()
|
||||
{
|
||||
emit visibilityHasChangedSignal();
|
||||
}
|
||||
|
||||
virtual void symbolAppearanceSettingsChangedPostOperation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void mapObjectChanged(UniqueMapId uniqueMapId);
|
||||
void mapObjectRemoved(UniqueMapId uniqueMapId);
|
||||
|
||||
void visibilityHasChangedSignal();
|
||||
|
||||
protected:
|
||||
ObjectFactory &m_objFac;
|
||||
bool m_assignDrawOrder;
|
||||
int m_drawOrder;
|
||||
const QString m_layername;
|
||||
|
||||
QMap<int32_t, UniqueMapId> m_simId2UniqueMapId;
|
||||
QMap<UniqueMapId, int32_t> m_uniqueMapId2SimId;
|
||||
|
||||
QString m_loggerName;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename DDS_TYPE, typename MAP_TYPE>
|
||||
class Sim2SituationMap : public Sim2SituationMapBase
|
||||
{
|
||||
public:
|
||||
|
||||
using DDS_T = DDS_TYPE;
|
||||
using MAP_T = MAP_TYPE;
|
||||
|
||||
Sim2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
const char *loggerName)
|
||||
: Sim2SituationMapBase(objFac, layername, 0, loggerName)
|
||||
{}
|
||||
|
||||
Sim2SituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: Sim2SituationMapBase(objFac, layername, drawOrder, loggerName)
|
||||
{}
|
||||
|
||||
~Sim2SituationMap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual int32_t getSimId(const DDS_TYPE &ddsData) const = 0;
|
||||
virtual bool isElapsed(const DDS_TYPE &ddsData) const
|
||||
{
|
||||
Q_UNUSED(ddsData)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
RefPointer<MAP_T> getMapObjectOfUniqueMapId(const UniqueMapId uniqueMapId) const
|
||||
{
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
return {};
|
||||
return m_objFac.get<MAP_T>(uniqueMapId);
|
||||
}
|
||||
|
||||
RefPointer<MAP_T> getMapObjectOfSimId(const int32_t simId) const
|
||||
{
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(simId, INVALID_MAP_ID);
|
||||
return getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
void addProperties(RefPointer<MAP_T> mapObj, int32_t simId)
|
||||
{
|
||||
if (mapObj)
|
||||
mapObj->setProperty(SimIdProperty, simId);
|
||||
}
|
||||
|
||||
virtual QString layernameWithHierachy(const DDS_T &ddsData) const
|
||||
{
|
||||
Q_UNUSED(ddsData);
|
||||
return m_layername;
|
||||
}
|
||||
|
||||
|
||||
virtual bool createElement(const DDS_T &ddsData)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " simId = " << getSimId(ddsData);
|
||||
|
||||
const int32_t simId = getSimId(ddsData);
|
||||
|
||||
|
||||
if (m_simId2UniqueMapId.contains(simId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " mapObject already exists"
|
||||
<< " simId = " << simId;
|
||||
return true;
|
||||
}
|
||||
|
||||
const QString &debugInfo = QStringLiteral("%1_%2").arg(m_loggerName).arg(simId);
|
||||
const QString &layername = this->layernameWithHierachy(ddsData);
|
||||
RefPointer<MAP_T> mapObj = m_objFac.create<MAP_T>(layername, debugInfo);
|
||||
if (!mapObj)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " creation failed"
|
||||
<< " simId = " << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_assignDrawOrder)
|
||||
mapObj->setDrawOrder(m_drawOrder);
|
||||
|
||||
addProperties(mapObj, simId);
|
||||
|
||||
|
||||
const UniqueMapId uniqueMapId = mapObj->uniqueMapId();
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " uniqueMapId invalid"
|
||||
<< " simId = " << simId;
|
||||
return false;
|
||||
}
|
||||
m_simId2UniqueMapId[simId] = uniqueMapId;
|
||||
m_uniqueMapId2SimId[uniqueMapId] = simId;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj) = 0;
|
||||
|
||||
bool updateElement(const DDS_T &ddsData)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " simId = " << getSimId(ddsData);
|
||||
const int32_t simId = getSimId(ddsData);
|
||||
|
||||
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(simId, INVALID_MAP_ID);
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " not found" << " simId = " << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (!mapObj)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " not found in objFac"
|
||||
<< " simId = " << simId
|
||||
<< " uniqueMapId = " << uniqueMapId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = updateElementImpl(ddsData, mapObj);
|
||||
if (!success)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " updateElementImpl failed, "
|
||||
<< " simId = " << getSimId(ddsData);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
handleSymbolAppearanceSettings(mapObj);
|
||||
handleBuildingComponentSettings(mapObj);
|
||||
|
||||
if (!mapObj->updateView())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " updateElement failed, "
|
||||
<< " simId = " << getSimId(ddsData);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
emit mapObjectChanged(uniqueMapId);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool removeElement(const DDS_T &ddsData)
|
||||
{
|
||||
const int32_t simId = getSimId(ddsData);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START" << " simId = " << simId;
|
||||
return removeElement(simId);
|
||||
}
|
||||
|
||||
virtual bool removeElement(const int32_t simId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START" << " simId = " << simId;
|
||||
|
||||
|
||||
const UniqueMapId uniqueMapId = m_simId2UniqueMapId.value(simId, INVALID_MAP_ID);
|
||||
if (!isUniqueMapIdValid(uniqueMapId))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " not found"
|
||||
<< ", simId = " << simId;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPointer<MAP_T> mapObj = m_objFac.get<MAP_T>(uniqueMapId);
|
||||
if (mapObj)
|
||||
{
|
||||
mapObj->removeMySelf();
|
||||
m_simId2UniqueMapId.remove(simId);
|
||||
m_uniqueMapId2SimId.remove(uniqueMapId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " not found in objFac"
|
||||
<< " simId = " << simId
|
||||
<< " uniqueMapId = " << uniqueMapId;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
|
||||
|
||||
emit mapObjectRemoved(uniqueMapId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) = 0;
|
||||
virtual void handleBuildingComponentSettings(RefPointer<MAP_T> &)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void clearObjects() override
|
||||
{
|
||||
const QList<int32_t> &simIds = m_simId2UniqueMapId.keys();
|
||||
for(int32_t simId : simIds)
|
||||
this->removeElement(simId);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool handleChanged(const DDS_T &ddsData, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " modType = " << modType
|
||||
<< " simId = " << getSimId(ddsData);
|
||||
|
||||
const bool bIsElapsed = isElapsed(ddsData);
|
||||
if (bIsElapsed && (modType == DataModification::eAdded))
|
||||
modType = DataModification::eRemoved;
|
||||
|
||||
if (bIsElapsed && modType == DataModification::eModified)
|
||||
modType = DataModification::eRemoved;
|
||||
|
||||
bool success = false;
|
||||
switch (modType)
|
||||
{
|
||||
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
success = this->createElement(ddsData) && this->updateElement(ddsData);
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
success = this->removeElement(ddsData);
|
||||
break;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QHash<int, DDS_T> m_ddsDataContainer;
|
||||
void updateDdsDataContainer(const DDS_T &data, DataModification modType)
|
||||
{
|
||||
int simId = getSimId(data);
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
m_ddsDataContainer[simId] = data;
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
m_ddsDataContainer.remove(simId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename MAP_T>
|
||||
class DdsFilterHandling :
|
||||
protected FilterManagement::SymbolAppearanceSettings::SettingsChangedCallback,
|
||||
protected FilterManagement::BuildingComponentSettings::SettingsChangedCallback
|
||||
{
|
||||
public:
|
||||
DdsFilterHandling(const char *loggerName, Sim2SituationMapBase *smBase)
|
||||
: m_smBase(smBase)
|
||||
, my_logger(getLogger(loggerName))
|
||||
{}
|
||||
virtual ~DdsFilterHandling()
|
||||
{
|
||||
removeSymbolAppearanceCallback();
|
||||
removeBuildingComponentCallback();
|
||||
}
|
||||
|
||||
protected:
|
||||
void init(PluginProvider *pluginProvider)
|
||||
{
|
||||
m_pluginProvider = pluginProvider;
|
||||
onWorkspaceIdChanged(m_pluginProvider->workspaceId());
|
||||
QObject::connect(pluginProvider, &PluginProvider::workspaceIdChanged, m_smBase,
|
||||
[this](const QString &newWorkspaceId) { onWorkspaceIdChanged(newWorkspaceId); });
|
||||
}
|
||||
|
||||
virtual void onWorkspaceIdChanged(const QString &newWorkspaceId)
|
||||
{
|
||||
DEBUG_LOG(my_logger) << LOGFUNCTION << ": onWorkspaceIdChanged: " << newWorkspaceId
|
||||
<< ", m_pluginProvider->toString: " << m_pluginProvider->toString();
|
||||
|
||||
removeSymbolAppearanceCallback();
|
||||
removeBuildingComponentCallback();
|
||||
|
||||
const auto fltParticipantIfc = m_pluginProvider->fltParticipantIfc();
|
||||
if (fltParticipantIfc)
|
||||
{
|
||||
m_symbolAppearanceSettings = fltParticipantIfc->symbolAppearanceForOperator(m_pluginProvider->operatorId(),
|
||||
m_pluginProvider->workspaceId());
|
||||
if (m_symbolAppearanceSettings)
|
||||
m_symbolAppearanceSettings->addChangedCallback(this);
|
||||
else
|
||||
{
|
||||
ERROR_LOG(my_logger) << LOGFUNCTION << " addChangedCallback SymAppearance failed";
|
||||
#ifdef LTS_DEBUG
|
||||
Q_ASSERT(false);
|
||||
#endif
|
||||
}
|
||||
onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part::All);
|
||||
}
|
||||
else
|
||||
ERROR_LOG(my_logger) << LOGFUNCTION << " no FilterManagement flm";
|
||||
|
||||
if (m_symbolAppearanceSettings && !m_symbolAppearanceSettings->isChangedCallbackRegistered(this))
|
||||
for (int i=0; i<20;++i)
|
||||
ERROR_LOG(my_logger) << LOGFUNCTION << " isChangedCallbackRegistered SymApp failure!!!";
|
||||
|
||||
const auto buildingComponentIfc = m_pluginProvider->fltBuildingComponentIfc();
|
||||
if (buildingComponentIfc)
|
||||
{
|
||||
m_buildingComponentSettings = buildingComponentIfc->buildingComponentSettingsForOperator(m_pluginProvider->operatorId(),
|
||||
m_pluginProvider->workspaceId());
|
||||
|
||||
if (m_buildingComponentSettings)
|
||||
m_buildingComponentSettings->addChangedCallback(this);
|
||||
else
|
||||
{
|
||||
ERROR_LOG(my_logger) << LOGFUNCTION << " addChangedCallback BldgCmpnt failed";
|
||||
#ifdef LTS_DEBUG
|
||||
Q_ASSERT(false);
|
||||
#endif
|
||||
}
|
||||
onBuildingComponentSettingsChanged();
|
||||
}
|
||||
else if (m_pluginProvider->appId() == LtsAppDescriptor::App::ResourceManager)
|
||||
ERROR_LOG(my_logger) << LOGFUNCTION << " no FilterManagement flm (fltBuildingComponentIfc)";
|
||||
|
||||
if (m_buildingComponentSettings && !m_buildingComponentSettings->isChangedCallbackRegistered(this))
|
||||
for (int i=0; i<20;++i)
|
||||
ERROR_LOG(my_logger) << LOGFUNCTION << " isChangedCallbackRegistered BldgCmpnt failure!!!";
|
||||
}
|
||||
|
||||
private:
|
||||
void removeSymbolAppearanceCallback()
|
||||
{
|
||||
if (m_symbolAppearanceSettings)
|
||||
m_symbolAppearanceSettings->removeChangedCallback(this);
|
||||
m_symbolAppearanceSettings = nullptr;
|
||||
}
|
||||
|
||||
void removeBuildingComponentCallback()
|
||||
{
|
||||
if (m_buildingComponentSettings)
|
||||
m_buildingComponentSettings->removeChangedCallback(this);
|
||||
m_buildingComponentSettings = nullptr;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings & ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool buildingComponentSettingsChangesAreRelevant(const FilterManagement::BuildingComponentSettings::BldCmpSettings& ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(FilterManagement::SymbolAppearanceSettings::Part part) override
|
||||
{
|
||||
Q_UNUSED(part);
|
||||
|
||||
QElapsedTimer elapsedTimer;
|
||||
if (my_logger.isInfoEnabled())
|
||||
elapsedTimer.start();
|
||||
|
||||
|
||||
const bool relevant = symbolAppearanceSettingsChangesAreRelevant(m_symbolAppearanceSettings->settings());
|
||||
|
||||
|
||||
m_currentSymbolSettings = m_symbolAppearanceSettings->settings();
|
||||
|
||||
if (!relevant)
|
||||
return;
|
||||
|
||||
|
||||
auto cb = [this](RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
handleSymbolAppearanceSettings(mapObj);
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(my_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
};
|
||||
m_smBase->iterateObjects<MAP_T>(cb);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_smBase->symbolAppearanceSettingsChangedPostOperation();
|
||||
|
||||
if (my_logger.isInfoEnabled())
|
||||
{
|
||||
|
||||
|
||||
|
||||
std::string className;
|
||||
if (m_smBase)
|
||||
{
|
||||
auto &tempRef = *m_smBase;
|
||||
className = typeid(tempRef).name();
|
||||
}
|
||||
INFO_LOG(my_logger) << className << " with PostOperation took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< ", mapObjectCount " << m_smBase->mapObjectCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void onBuildingComponentSettingsChanged() override
|
||||
{
|
||||
|
||||
const bool relevant = buildingComponentSettingsChangesAreRelevant(m_buildingComponentSettings->bldCmpSettings());
|
||||
|
||||
|
||||
m_currentBuildingComponentSettings = m_buildingComponentSettings->bldCmpSettings();
|
||||
|
||||
if (!relevant)
|
||||
return;
|
||||
|
||||
|
||||
auto cb = [this](RefPointer<MAP_T> &mapObj)
|
||||
{
|
||||
handleBuildingComponentSettings(mapObj);
|
||||
if (!mapObj->updateView())
|
||||
WARNING_LOG(my_logger) << LOGFUNCTION << " updateView failed,"
|
||||
<< " mapObj = " << mapObj->debugInfo();
|
||||
};
|
||||
m_smBase->iterateObjects<MAP_T>(cb);
|
||||
}
|
||||
|
||||
virtual void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) = 0;
|
||||
virtual void handleBuildingComponentSettings(RefPointer<MAP_T> &)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
std::shared_ptr<FilterManagement::SymbolAppearanceSettings> m_symbolAppearanceSettings;
|
||||
FilterManagement::SymbolAppearanceSettings::Settings m_currentSymbolSettings;
|
||||
|
||||
std::shared_ptr<FilterManagement::BuildingComponentSettings> m_buildingComponentSettings;
|
||||
FilterManagement::BuildingComponentSettings::BldCmpSettings m_currentBuildingComponentSettings;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider{nullptr};
|
||||
Sim2SituationMapBase *m_smBase{nullptr};
|
||||
NGL::INGLLogger &my_logger;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+355
@@ -0,0 +1,355 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "sound_area_to_map.h"
|
||||
#include <Map/object_factory.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace SituationMap;
|
||||
|
||||
|
||||
inline PositionCont form2PosCont2D(const std::vector<Core::GeoPosition2D> &form)
|
||||
{
|
||||
PositionCont ret;
|
||||
ret.reserve(form.size());
|
||||
for (const auto &pos : form)
|
||||
ret.push_back({pos.lon(), pos.lat(), 0.0});
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool SoundAreaToMap::init(PluginProvider *pluginProvider, bool resourceMode)
|
||||
{
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->ismDtc() ||
|
||||
!pluginProvider->ismDataIfc())
|
||||
return false;
|
||||
m_resourceMode = resourceMode;
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_resourceMode=" << m_resourceMode
|
||||
<< " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
m_ismDtc = m_pluginProvider->ismDtc();
|
||||
m_ismDataIfc = m_pluginProvider->ismDataIfc();
|
||||
m_ismGuiIfc = m_pluginProvider->ismGuiIfc();
|
||||
|
||||
InfrastructureManagement::MountingPoint::init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SoundAreaToMap::run()
|
||||
{
|
||||
this->stop();
|
||||
|
||||
if (!m_ismDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << "Could not run. Dtc not set.";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::effectAreaChanged,
|
||||
this, &SoundAreaToMap::onEffectAreaChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
if (m_pluginProvider->exerciseId() != 0 || m_resourceMode)
|
||||
{
|
||||
m_ismDtc->effectAreas([this](const InfrastructureManagement::EffectArea& data)
|
||||
{
|
||||
onEffectAreaChanged(data, DataModification::eAdded);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SoundAreaToMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping";
|
||||
|
||||
if (m_ismDtc)
|
||||
m_ismDtc->disconnect(this);
|
||||
|
||||
m_bldgsInExcersise.clear();
|
||||
m_mountingPoints.clear();
|
||||
}
|
||||
|
||||
bool SoundAreaToMap::mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
|
||||
return true;
|
||||
|
||||
if (!m_ismGuiIfc)
|
||||
return false;
|
||||
|
||||
const QVector<int32_t> &simIds = uniqueMapIds2SimIds(uniqueMapIds);
|
||||
if (simIds.isEmpty())
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SoundAreaToMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const
|
||||
{
|
||||
if (!m_ismDtc)
|
||||
return false;
|
||||
|
||||
int32_t simIdOut = -1;
|
||||
if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut))
|
||||
return false;
|
||||
|
||||
umodOut = UnifiedMapObjectData();
|
||||
RefPointer<MAP_T> mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId);
|
||||
if (mapObj.valid())
|
||||
umodOut.m_image = mapObj->previewImage();
|
||||
|
||||
const auto cb = [simIdOut, &umodOut](const InfrastructureManagement::EffectArea &data) -> bool
|
||||
{
|
||||
if (data.id() == simIdOut)
|
||||
{
|
||||
umodOut.m_description1 = QString::fromStdString(data.name());
|
||||
umodOut.m_description2 = tr("Sound Area") + QString(QStringLiteral(" (%1)")).arg(data.id());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const InfrastructureManagement::EffectArea &data)> cb1 = cb;
|
||||
return m_ismDtc->effectAreas(cb1);
|
||||
}
|
||||
|
||||
bool SoundAreaToMap::onEffectAreaChanged(const InfrastructureManagement::EffectArea &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " onEffectAreaChanged"
|
||||
<< " id=" << data.id()
|
||||
<< " name='" << data.name() << "'"
|
||||
<< " areaEgcuId=" << data.areaEgcuId()
|
||||
<< " ata.geometry().size()=" << data.geometry().size()
|
||||
<< " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return handleChanged(data, modType);
|
||||
}
|
||||
|
||||
bool SoundAreaToMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << " isElapsed?";
|
||||
|
||||
if (BaseClass::isElapsed(data))
|
||||
return true;
|
||||
|
||||
if (data.geometry().size() < 3)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t SoundAreaToMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
SituationMap::PositionCont soundGeometryToPositions(const QJsonDocument &jdoc)
|
||||
{
|
||||
QJsonObject jObj = jdoc.object();
|
||||
if (jObj.isEmpty())
|
||||
return {};
|
||||
|
||||
const QJsonArray &jArray = jObj[QLatin1String("soundGeometry")].toArray();
|
||||
if (jArray.isEmpty())
|
||||
return {};
|
||||
|
||||
SituationMap::PositionCont posCont;
|
||||
posCont.reserve(jArray.size());
|
||||
for (const auto &val : qAsConst(jArray))
|
||||
{
|
||||
const QJsonObject &objTemp = val.toObject();
|
||||
posCont.append(Point3D::fromQPointF({objTemp[QLatin1String("lon")].toDouble(),
|
||||
objTemp[QLatin1String("lat")].toDouble()}
|
||||
));
|
||||
}
|
||||
return posCont;
|
||||
}
|
||||
|
||||
InfrastructureManagement::MountingPoint SoundAreaToMap::mountingPointWithAssociatedId(int associatedId)
|
||||
{
|
||||
if (!m_ismDataIfc)
|
||||
return InfrastructureManagement::MountingPoint();
|
||||
|
||||
InfrastructureManagement::MountingPoint mp;
|
||||
|
||||
const auto cb = [&mp, associatedId](const InfrastructureManagement::MountingPoint &data) -> bool
|
||||
{
|
||||
if (data.associatedAssetId() == associatedId)
|
||||
{
|
||||
mp = data;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool(const InfrastructureManagement::MountingPoint &data)> cb1 = cb;
|
||||
m_ismDataIfc->mountingPoints(cb1);
|
||||
|
||||
return mp;
|
||||
}
|
||||
|
||||
|
||||
bool SoundAreaToMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer<Sim2SituationMap::MAP_T> mapObj)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " id " << ddsData.id()
|
||||
<< ", name = " << ddsData.name();
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
mapObj->setPickable(true);
|
||||
|
||||
|
||||
|
||||
|
||||
QColor col(Qt::red);
|
||||
mapObj->setLineStyle(LineStyle(col, 1, LinePattern::DashDotDot));
|
||||
mapObj->setFillStyle(FillStyle(col, FillPattern::BackwardDiagonal));
|
||||
|
||||
const SituationMap::PositionCont &posCont = form2PosCont2D(ddsData.geometry());
|
||||
mapObj->setPositions(posCont);
|
||||
|
||||
|
||||
|
||||
|
||||
const InfrastructureManagement::MountingPoint &associatedMountingPoint = mountingPointWithAssociatedId(ddsData.areaEgcuId());
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " id " << ddsData.id()
|
||||
<< ", name = " << ddsData.name()
|
||||
<< " MP: buildingId" << associatedMountingPoint.buildingId()
|
||||
<< " MP: geoPosition" << associatedMountingPoint.geoPosition();
|
||||
|
||||
if (associatedMountingPoint.id() > 0)
|
||||
{
|
||||
mapObj->setMarkerData(MarkerData(associatedMountingPoint.toImage(), QSize(25,25)));
|
||||
const Core::GeoPosition &geoPos = associatedMountingPoint.geoPosition();
|
||||
mapObj->setMarkerOrigin(Point3D(geoPos.lon(), geoPos.lat(), geoPos.z()));
|
||||
} else {
|
||||
mapObj->setMarkerData(MarkerData());
|
||||
mapObj->setMarkerOrigin(Point3D());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool SoundAreaToMap::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data,
|
||||
DataModification modType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << "SoundAreaToMap::onMainStructureElementChanged data.id=" << data.id();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " vorher " << m_bldgsInExcersise.values();
|
||||
|
||||
m_bldgsInExcersise.remove(data.id());
|
||||
|
||||
if (modType == DataModification::eAdded || modType == DataModification::eModified)
|
||||
{
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(data.properties()), &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Could not parse JSON props of building with ID "
|
||||
<< data.id()
|
||||
<< ". Reason: "
|
||||
<< parseError.errorString()
|
||||
<< "; JSON: "
|
||||
<< doc.toJson(QJsonDocument::Compact);
|
||||
return true;
|
||||
}
|
||||
|
||||
const int32_t actualExerciseId = m_pluginProvider->exerciseId();
|
||||
const QJsonArray &arr = doc.object().value(QLatin1String("available_in_exercise")).toArray();
|
||||
for (const QJsonValue &value : qAsConst(arr))
|
||||
{
|
||||
if (!value.isDouble())
|
||||
continue;
|
||||
|
||||
const int tmp = value.toInt();
|
||||
DEBUG_LOG(m_logger) << "actualExerciseId=" << actualExerciseId
|
||||
<< " available_in_exercise=" << tmp;
|
||||
if (tmp == actualExerciseId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_bldgsInExcersise.append:" << data.id();
|
||||
m_bldgsInExcersise.insert(data.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " nachher " << m_bldgsInExcersise.values();
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <MapObjects/sound_area.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class SoundAreaToMap final : public Sim2SituationMap<InfrastructureManagement::EffectArea, SituationMap::SoundArea>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<InfrastructureManagement::EffectArea, SituationMap::SoundArea>;
|
||||
|
||||
public:
|
||||
SoundAreaToMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider, bool resourceMode);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
|
||||
bool mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds) override;
|
||||
|
||||
bool unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
bool onEffectAreaChanged(const InfrastructureManagement::EffectArea &data, DataModification modType);
|
||||
bool onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data,
|
||||
DataModification modType = DataModification::eAdded);
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const DDS_T &ddsData, RefPointer<MAP_T> mapObj) override;
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
Q_UNUSED(mapObj);
|
||||
}
|
||||
|
||||
private:
|
||||
InfrastructureManagement::MountingPoint mountingPointWithAssociatedId(int associatedId);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider{nullptr};
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_ismDataIfc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignResourceManagementGuiInterface> m_ismGuiIfc;
|
||||
bool m_resourceMode{false};
|
||||
QSet<int> m_bldgsInExcersise;
|
||||
QMap<int, InfrastructureManagement::MountingPoint> m_mountingPoints;
|
||||
|
||||
};
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
|
||||
#include "special_areas_to_map.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
bool SpecialAreaToSituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->ismDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
m_ismDtc = m_pluginProvider->ismDtc();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpecialAreaToSituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!m_ismDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
this->stop();
|
||||
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::specialAreaChanged,
|
||||
this, &SpecialAreaToSituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
m_ismDtc->specialAreas([this](const InfrastructureManagement::SpecialArea & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpecialAreaToSituationMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping";
|
||||
if (m_ismDtc)
|
||||
m_ismDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool SpecialAreaToSituationMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
Q_UNUSED(data)
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t SpecialAreaToSituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool SpecialAreaToSituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
mapObj->setPickable(false);
|
||||
|
||||
|
||||
mapObj->setLineStyle(LineStyle(Qt::green, 3, LinePattern::DashDot));
|
||||
mapObj->setFillStyle(FillStyle(FillPattern::Null));
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
const std::vector<Core::GeoPosition2D> &polygon = ddsData.polygon();
|
||||
|
||||
PositionCont posCont;
|
||||
posCont.reserve(polygon.size());
|
||||
for (const auto &p : qAsConst(polygon))
|
||||
posCont.push_back(Point3D(p.lon(), p.lat(), .0));
|
||||
|
||||
mapObj->setPositions(posCont);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <MapObjects/polygon.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class SpecialAreaToSituationMap final : public Sim2SituationMap<InfrastructureManagement::SpecialArea, SituationMap::Polygon>
|
||||
, protected DdsFilterHandling<SituationMap::Polygon>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<InfrastructureManagement::SpecialArea, SituationMap::Polygon>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::Polygon>;
|
||||
|
||||
public:
|
||||
SpecialAreaToSituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.showSpecialAreas != newSas.symbolSettings.showSpecialAreas);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
mapObj->setVisibility(m_currentSymbolSettings.symbolSettings.showSpecialAreas);
|
||||
}
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
};
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
|
||||
#include "technical_area_to_map.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
bool TechnicalArea2SituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_aesDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::technicalAreaChanged,
|
||||
this, &TechnicalArea2SituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_aesDtc->technicalAreas([this](const AreaEffectSimulation::TechnicalArea & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::run();
|
||||
}
|
||||
|
||||
bool TechnicalArea2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
const int32_t simId = ddsData.id();
|
||||
|
||||
mapObj->setPickable(false);
|
||||
|
||||
|
||||
mapObj->setLineStyle(LineStyle(Qt::black, 2, LinePattern::DashDotDot));
|
||||
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AreaEffectSimulation::AesItemView itemView;
|
||||
if (m_aesDtc->aesItemViewFromEntityId(simId, AreaEffectSimulation::AesType::AtTechnicalArea, itemView))
|
||||
this->updateGeometry(itemView, mapObj);
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " no AesItemView (AtTechnicalArea) found"
|
||||
<< ", simId = " << simId
|
||||
<< ", provide fallBackGeometry";
|
||||
|
||||
|
||||
mapObj->setPositions({{0.0, 0.0, .0},
|
||||
{0.0, 0.1, .0},
|
||||
{0.1, 0.1, .0},
|
||||
{0.1, 0.0, .0}});
|
||||
|
||||
}
|
||||
|
||||
updateVisibility(ddsData, mapObj);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "aes_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AreaEffectSimulation/aes_data_plugin_interface.h>
|
||||
#include <MapObjects/polygon.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class TechnicalArea2SituationMap;
|
||||
template <>
|
||||
struct Aes2SituationMapTraits<TechnicalArea2SituationMap>
|
||||
{
|
||||
using DDS_TYPE = AreaEffectSimulation::TechnicalArea;
|
||||
using MAP_TYPE = SituationMap::Polygon;
|
||||
static const AreaEffectSimulation::AesType_def::type aesType = AreaEffectSimulation::AesType_def::AtTechnicalArea;
|
||||
};
|
||||
|
||||
class TechnicalArea2SituationMap final : public Aes2SituationMap<TechnicalArea2SituationMap>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using BaseClass = SituationMap::Aes2SituationMap<TechnicalArea2SituationMap>;
|
||||
using BaseClass::BaseClass;
|
||||
|
||||
bool run() override;
|
||||
bool iterateAesData(const std::function<bool(const AreaEffectSimulation::TechnicalArea &data)> &cb) const
|
||||
{
|
||||
return m_aesDtc->technicalAreas(cb);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
};
|
||||
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
|
||||
#include "training_area_to_map.h"
|
||||
#include <LtsUtilsCore/dds_bitarray.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
bool TrainingAreaToSituationMap::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!pluginProvider ||
|
||||
!pluginProvider->asmDtc())
|
||||
return false;
|
||||
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " exerciseId=" << m_pluginProvider->exerciseId();
|
||||
|
||||
if (m_pluginProvider->exmDtc())
|
||||
{
|
||||
const int curExerciseId = m_pluginProvider->exerciseId();
|
||||
m_trainingAreaIdOfCurrentExercise = m_pluginProvider->exmDtc()->exercise(curExerciseId).trainingAreaId();
|
||||
}
|
||||
|
||||
m_asmDtc = m_pluginProvider->asmDtc();
|
||||
|
||||
|
||||
FilterClass::init(m_pluginProvider);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TrainingAreaToSituationMap::run()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_asmDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
this->stop();
|
||||
|
||||
connect(m_asmDtc.get(), &AssetManagement::Interface::Dtc::trainingAreaChanged,
|
||||
this, &TrainingAreaToSituationMap::handleChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
m_asmDtc->trainingAreas([this](const AssetManagement::TrainingArea & data)
|
||||
{
|
||||
handleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void TrainingAreaToSituationMap::stop()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "Stopping";
|
||||
if (m_asmDtc)
|
||||
m_asmDtc->disconnect(this);
|
||||
}
|
||||
|
||||
bool TrainingAreaToSituationMap::isElapsed(const Sim2SituationMap::DDS_T &data) const
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (m_trainingAreaIdOfCurrentExercise <= 0)
|
||||
return false;
|
||||
|
||||
return (m_trainingAreaIdOfCurrentExercise != data.id());
|
||||
}
|
||||
|
||||
int32_t TrainingAreaToSituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const
|
||||
{
|
||||
return ddsData.id();
|
||||
}
|
||||
|
||||
bool TrainingAreaToSituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
|
||||
|
||||
mapObj->setPickable(false);
|
||||
|
||||
|
||||
mapObj->setLineStyle(LineStyle(Qt::black, 2, LinePattern::Dot));
|
||||
mapObj->setFillStyle(FillStyle(FillPattern::Null));
|
||||
|
||||
|
||||
mapObj->setIdentifier(QString::fromStdString(ddsData.name()));
|
||||
|
||||
const Core::GeoPosition2D &bottomLeft = ddsData.bottomLeft();
|
||||
const LtsCoordTrans::UtmCoordinate referencePointUTM = LtsCoordTrans::UtmCoordinate::fromGeographic(bottomLeft.lon(), bottomLeft.lat());
|
||||
|
||||
const QPointF size(ddsData.width(), ddsData.height());
|
||||
|
||||
PositionCont posCont;
|
||||
posCont.reserve(4);
|
||||
posCont.push_back(Point3D(bottomLeft.lon(), bottomLeft.lat(), .0));
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(0 , size.y())));
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(size.x(), size.y())));
|
||||
posCont.push_back(Point3D::fromQPointF(referencePointUTM.geographic(size.x(), 0)));
|
||||
|
||||
mapObj->setPositions(posCont);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sim_to_situation_map_tmpl.h"
|
||||
#include <Plugins/AssetManagement/asm_data_plugin_interface.h>
|
||||
#include <MapObjects/polygon.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class TrainingAreaToSituationMap final : public Sim2SituationMap<AssetManagement::TrainingArea, SituationMap::Polygon>
|
||||
, protected DdsFilterHandling<SituationMap::Polygon>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = SituationMap::Sim2SituationMap<AssetManagement::TrainingArea, SituationMap::Polygon>;
|
||||
using FilterClass = DdsFilterHandling<SituationMap::Polygon>;
|
||||
|
||||
public:
|
||||
TrainingAreaToSituationMap(ObjectFactory &objFac,
|
||||
const QString &layername,
|
||||
int drawOrder,
|
||||
const char *loggerName)
|
||||
: BaseClass(objFac, layername, drawOrder, loggerName)
|
||||
, FilterClass(loggerName, this)
|
||||
, m_pluginProvider(nullptr)
|
||||
{}
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
bool run() override;
|
||||
void stop() override;
|
||||
|
||||
protected:
|
||||
bool isElapsed(const Sim2SituationMap::DDS_T &data) const override;
|
||||
int32_t getSimId(const Sim2SituationMap::DDS_T &ddsData) const override;
|
||||
bool updateElementImpl(const Sim2SituationMap::DDS_T &ddsData,
|
||||
RefPointer<MAP_T> mapObj) override;
|
||||
|
||||
bool symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const override
|
||||
{
|
||||
return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) ||
|
||||
(m_currentSymbolSettings.symbolSettings.showTrainingAreaBorder != newSas.symbolSettings.showTrainingAreaBorder);
|
||||
}
|
||||
void handleSymbolAppearanceSettings(RefPointer<MAP_T> &mapObj) override
|
||||
{
|
||||
mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale);
|
||||
mapObj->setVisibility(m_currentSymbolSettings.symbolSettings.showTrainingAreaBorder);
|
||||
}
|
||||
|
||||
private:
|
||||
PluginProvider *m_pluginProvider;
|
||||
int m_trainingAreaIdOfCurrentExercise = -1;
|
||||
std::shared_ptr<AssetManagement::Interface::Dtc> m_asmDtc;
|
||||
};
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#include <Map/situation_map_types.h>
|
||||
|
||||
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
struct UnifiedMapObjectData
|
||||
{
|
||||
|
||||
int m_equipmentNumber{-1};
|
||||
int m_partyId{-1};
|
||||
|
||||
struct participantData
|
||||
{
|
||||
int m_participantId{-1};
|
||||
int m_typeId{-1};
|
||||
int m_vulnerabilityState{-1};
|
||||
QString m_vulnerabilityString;
|
||||
QString m_typeName;
|
||||
};
|
||||
participantData m_participantData;
|
||||
|
||||
struct buildingData
|
||||
{
|
||||
int buildingId{-1};
|
||||
};
|
||||
buildingData m_buildingData;
|
||||
|
||||
|
||||
QString m_description1;
|
||||
QString m_description2;
|
||||
|
||||
|
||||
SymbolDataToRender m_symDataToRender;
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
Executable
+249
@@ -0,0 +1,249 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Mike Wille, SLSE, 2016-06-10
|
||||
#
|
||||
|
||||
IF(BUILD_RPM)
|
||||
IF(UNIX)
|
||||
OPTION(BUILD_USE_MAP_CACHE "Use MapCache (GUEZ_ONLY) via _pname" ON)
|
||||
ELSE()
|
||||
OPTION(BUILD_USE_MAP_CACHE "Use MapCache (GUEZ_ONLY) via _pname" OFF)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
# !BUILD_RPM entspricht LTS_DEBUG
|
||||
OPTION(BUILD_USE_MAP_CACHE "Use MapCache (GUEZ_ONLY) via LTS_debug)" ON)
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Enable MapCache: ${BUILD_USE_MAP_CACHE})")
|
||||
IF (BUILD_USE_MAP_CACHE)
|
||||
add_definitions(-DUSE_MAP_CACHE)
|
||||
ENDIF()
|
||||
|
||||
|
||||
SET(sitmap_dds_SRCS
|
||||
|
||||
situation_map_init.cpp
|
||||
situation_map_init.h
|
||||
situation_map_init_p.h
|
||||
|
||||
MapObjectSelection/map_object_model.cpp
|
||||
MapObjectSelection/map_object_model.h
|
||||
MapObjectSelection/map_object_selection_widget.cpp
|
||||
MapObjectSelection/map_object_selection_widget.h
|
||||
MapObjectSelection/map_object_custom_view.cpp
|
||||
MapObjectSelection/map_object_custom_view.h
|
||||
|
||||
AdapterDds/adapter_dds.cpp
|
||||
AdapterDds/adapter_dds.h
|
||||
AdapterDds/map_object_type.h
|
||||
AdapterDds/aes_to_situation_map_tmpl.h
|
||||
AdapterDds/air_support_impact_to_map.cpp
|
||||
AdapterDds/air_support_impact_to_map.h
|
||||
AdapterDds/emergency_call_to_map.cpp
|
||||
AdapterDds/emergency_call_to_map.h
|
||||
AdapterDds/bccontamination_to_map.cpp
|
||||
AdapterDds/bccontamination_to_map.h
|
||||
AdapterDds/borderline_to_map.cpp
|
||||
AdapterDds/borderline_to_map.h
|
||||
AdapterDds/buildings_to_map.cpp
|
||||
AdapterDds/buildings_to_map.h
|
||||
AdapterDds/buildinghitlineinfo_to_map.cpp
|
||||
AdapterDds/buildinghitlineinfo_to_map.h
|
||||
AdapterDds/building_contamination.cpp
|
||||
AdapterDds/building_contamination.h
|
||||
AdapterDds/building_ownership.cpp
|
||||
AdapterDds/building_ownership.h
|
||||
AdapterDds/booby_traps_to_map.cpp
|
||||
AdapterDds/booby_traps_to_map.h
|
||||
AdapterDds/special_areas_to_map.cpp
|
||||
AdapterDds/special_areas_to_map.h
|
||||
AdapterDds/danger_area_to_map.cpp
|
||||
AdapterDds/danger_area_to_map.h
|
||||
AdapterDds/dus_single_mine_to_map.cpp
|
||||
AdapterDds/dus_single_mine_to_map.h
|
||||
AdapterDds/explosion_area_to_map.cpp
|
||||
AdapterDds/explosion_area_to_map.h
|
||||
AdapterDds/explosion_cluster_to_map.cpp
|
||||
AdapterDds/explosion_cluster_to_map.h
|
||||
AdapterDds/effect_cluster_to_map.cpp
|
||||
AdapterDds/effect_cluster_to_map.h
|
||||
AdapterDds/explosion_single_to_map.cpp
|
||||
AdapterDds/explosion_single_to_map.h
|
||||
# AdapterDds/explosion_single_central_to_map.cpp
|
||||
# AdapterDds/explosion_single_central_to_map.h
|
||||
AdapterDds/functional_area_to_map.cpp
|
||||
AdapterDds/functional_area_to_map.h
|
||||
AdapterDds/gas_pipe_to_map.cpp
|
||||
AdapterDds/gas_pipe_to_map.h
|
||||
AdapterDds/guez_ied_to_map.cpp
|
||||
AdapterDds/guez_ied_to_map.h
|
||||
|
||||
AdapterDds/guez_nasat_9liner.cpp
|
||||
AdapterDds/guez_nasat_9liner.h
|
||||
|
||||
AdapterDds/hitlineinfo_to_map.cpp
|
||||
AdapterDds/hitlineinfo_to_map.h
|
||||
AdapterDds/mine_area_null_to_map.cpp
|
||||
AdapterDds/mine_area_null_to_map.h
|
||||
AdapterDds/mine_area_to_map.cpp
|
||||
AdapterDds/mine_area_to_map.h
|
||||
AdapterDds/mine_corridor_to_map.cpp
|
||||
AdapterDds/mine_corridor_to_map.h
|
||||
AdapterDds/mounting_point_to_map.cpp
|
||||
AdapterDds/mounting_point_to_map.h
|
||||
AdapterDds/sound_area_to_map.cpp
|
||||
AdapterDds/sound_area_to_map.h
|
||||
AdapterDds/mse_point_to_map.cpp
|
||||
AdapterDds/mse_point_to_map.h
|
||||
AdapterDds/mse_bridge_to_map.cpp
|
||||
AdapterDds/mse_bridge_to_map.h
|
||||
AdapterDds/ncontamination_to_map.cpp
|
||||
AdapterDds/ncontamination_to_map.h
|
||||
AdapterDds/off_route_to_map.cpp
|
||||
AdapterDds/off_route_to_map.h
|
||||
AdapterDds/participant_to_map.cpp
|
||||
AdapterDds/participant_to_map.h
|
||||
AdapterDds/pdm_handler.cpp
|
||||
AdapterDds/pdm_handler.h
|
||||
AdapterDds/shootback_area_to_map.cpp
|
||||
AdapterDds/shootback_area_to_map.h
|
||||
AdapterDds/recon_area_to_map.cpp
|
||||
AdapterDds/recon_area_to_map.h
|
||||
AdapterDds/technical_area_to_map.cpp
|
||||
AdapterDds/technical_area_to_map.h
|
||||
AdapterDds/training_area_to_map.cpp
|
||||
AdapterDds/training_area_to_map.h
|
||||
AdapterDds/plugin_provider.h
|
||||
AdapterDds/sim_to_situation_map_tmpl.h
|
||||
AdapterDds/unified_map_object_data.h
|
||||
AdapterDds/charge_effect_to_map.cpp
|
||||
AdapterDds/charge_effect_to_map.h
|
||||
)
|
||||
NGL_WRAP_UI(sitmap_dds_SRCS
|
||||
MapObjectSelection/map_object_selection_dialog.ui
|
||||
MapObjectSelection/map_object_custom_view.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS SitmapDds SHARED ${sitmap_dds_SRCS})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(SitmapDds
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(SitmapDds
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
situationMap
|
||||
LtsUtilsGuiDds # RequestHelper
|
||||
PRIVATE
|
||||
svcMapDummy
|
||||
situationMapFunctionDialog # remove me here plz
|
||||
LtsCoordTrans
|
||||
LtsDataView
|
||||
LtsSessionData
|
||||
situationMapObjects
|
||||
LtsUtilsSettings
|
||||
#needed through AdapterDds sources
|
||||
AlmDataPluginInterface
|
||||
AsmDataPluginInterface
|
||||
BldDataPluginInterface
|
||||
ExmDataPluginInterface
|
||||
FltDataPluginInterface
|
||||
IsmDataPluginInterface
|
||||
GnaDataPluginInterface
|
||||
CmoDataPluginInterface
|
||||
SmoCheckButtonHandler
|
||||
TgtDataPluginInterface
|
||||
IsmShared
|
||||
svcAesClient
|
||||
svcCesClient
|
||||
svcGimClient
|
||||
svcPpmClient
|
||||
svcSrpClient
|
||||
|
||||
)
|
||||
|
||||
#
|
||||
# SitmapGuiPlugin
|
||||
#
|
||||
SET(sitmap_edit_gui_SRCS
|
||||
sitmap_gui_plugin.cpp
|
||||
sitmap_gui_plugin.h
|
||||
sitmap_register_app_handler.cpp
|
||||
sitmap_register_app_handler.h
|
||||
|
||||
sitmap_widget_control.cpp
|
||||
sitmap_widget_control.h
|
||||
sitmap_layer_control.cpp
|
||||
sitmap_layer_control.h
|
||||
ConfigureUrl/sitmap_configure_url_model.cpp
|
||||
ConfigureUrl/sitmap_configure_url_model.h
|
||||
ConfigureUrl/sitmap_configure_url_widget.cpp
|
||||
ConfigureUrl/sitmap_configure_url_widget.h
|
||||
ConfigureUrl/sitmap_configure_urls.cpp
|
||||
ConfigureUrl/sitmap_configure_urls.h
|
||||
layers_model.cpp
|
||||
layers_model.h
|
||||
|
||||
terrain_profile_handler.cpp
|
||||
terrain_profile_handler.h
|
||||
|
||||
viewshed_dialog.h
|
||||
|
||||
plugin_provider_lts_session.h
|
||||
plugin_provider_lts_session.cpp
|
||||
|
||||
TopicEditor/topic_editor.h
|
||||
TopicEditor/topic_editor.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(sitmap_edit_gui_SRCS
|
||||
ConfigureUrl/sitmap_configure_url_widget.ui
|
||||
ConfigureUrl/sitmap_configure_single_url.ui
|
||||
ConfigureUrl/sitmap_configure_urls.ui
|
||||
sitmap_widget_control.ui
|
||||
sitmap_layer_control.ui
|
||||
|
||||
TopicEditor/topic_editor.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS SitmapGuiPlugin MODULE ${sitmap_edit_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(SitmapGuiPlugin
|
||||
SitmapDds
|
||||
|
||||
svcMapDummy
|
||||
situationMapCommon
|
||||
situationMap
|
||||
situationMapObjects
|
||||
NGLLogger
|
||||
LtsPrinting
|
||||
LtsSession
|
||||
SituationMapGuiPluginInterface
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsCoordTrans
|
||||
LtsAppDescriptor
|
||||
LtsAppManager
|
||||
LtsUtilsSettings
|
||||
TopicEditorBase
|
||||
FltFilterChange
|
||||
LtsNotification
|
||||
|
||||
# only to create a menu entry - should be done by the bdv gui plugin...
|
||||
BdvViewerGuiPluginInterface
|
||||
|
||||
AesDataPluginInterface
|
||||
AlmDataPluginInterface
|
||||
AsmDataPluginInterface
|
||||
BldDataPluginInterface
|
||||
CesDataPluginInterface
|
||||
FltDataPluginInterface
|
||||
GimDataPluginInterface
|
||||
GnaDataPluginInterface
|
||||
IsmDataPluginInterface
|
||||
OpmDataPluginInterface
|
||||
PpmDataPluginInterface
|
||||
TgtDataPluginInterface
|
||||
CmoDataPluginInterface
|
||||
)
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Configure_Single_Url</class>
|
||||
<widget class="QWidget" name="Configure_Single_Url">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1099</width>
|
||||
<height>134</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Layer Control</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Url:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="toolTip">
|
||||
<string>Min. zoom in limit</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="le_minScale">
|
||||
<property name="text">
|
||||
<string notr="true">-1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="toolTip">
|
||||
<string>Max. zoom in limit</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QLineEdit" name="le_maxScale">
|
||||
<property name="text">
|
||||
<string notr="true">-1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>17</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="3">
|
||||
<widget class="QLineEdit" name="le_name"/>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="3">
|
||||
<widget class="QLineEdit" name="le_url"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "sitmap_configure_url_model.h"
|
||||
|
||||
|
||||
#include <AssetManagement/asm_data_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
ConfigureMapUrlModel::ConfigureMapUrlModel(QObject *parent)
|
||||
: BaseClass( {tr("Name"), tr("Url"), tr("Map Type"), tr("Min Scale"), tr("Max Scale")}, parent)
|
||||
{
|
||||
}
|
||||
|
||||
ConfigureMapUrlModel::~ConfigureMapUrlModel()
|
||||
{
|
||||
}
|
||||
|
||||
void ConfigureMapUrlModel::addData(const DATA_T &entry)
|
||||
{
|
||||
for (const auto &r : qAsConst(m_vecData))
|
||||
{
|
||||
if (r == entry)
|
||||
return;
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), m_vecData.size(), m_vecData.size());
|
||||
m_vecData += entry;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
QModelIndex ConfigureMapUrlModel::moveRow(const QModelIndex &sourceIndex, int destinationRow)
|
||||
{
|
||||
if (destinationRow >= m_vecData.size() || destinationRow < 0)
|
||||
return sourceIndex;
|
||||
|
||||
std::swap(m_vecData[destinationRow], m_vecData[sourceIndex.row()]);
|
||||
|
||||
|
||||
QModelIndex idx = index(destinationRow, 0);
|
||||
emit dataChanged(index(sourceIndex.row(), 0), index(sourceIndex.row(), columnCount(QModelIndex()) - 1));
|
||||
emit dataChanged(idx, index(destinationRow, columnCount(QModelIndex()) - 1));
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
QVector<ConfigureMapUrlModel::DATA_T> ConfigureMapUrlModel::allData() const
|
||||
{
|
||||
return m_vecData;
|
||||
}
|
||||
|
||||
QVariant ConfigureMapUrlModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole &&
|
||||
role != Qt::EditRole &&
|
||||
role != Qt::UserRole) || !index.isValid() || index.row() >= m_vecData.size())
|
||||
return QVariant();
|
||||
|
||||
const DATA_T &md = m_vecData.at(index.row());
|
||||
switch (index.column())
|
||||
{
|
||||
case Columns::Url:
|
||||
return QString::fromStdString(md.url());
|
||||
case Columns::Name:
|
||||
return QString::fromStdString(md.name());
|
||||
case Columns::MapType:
|
||||
{
|
||||
switch (md.mapTypeId().underlying())
|
||||
{
|
||||
case AssetManagement::MapType_def::Aerial:
|
||||
return tr("Aerial");
|
||||
case AssetManagement::MapType_def::Topographic:
|
||||
return tr("Topographic");
|
||||
case AssetManagement::MapType_def::Unknown:
|
||||
case AssetManagement::MapType_def::Feature:
|
||||
case AssetManagement::MapType_def::Elevation:
|
||||
case AssetManagement::MapType_def::SceneObjects:
|
||||
break;
|
||||
|
||||
}
|
||||
return tr("Unknown");
|
||||
}
|
||||
case Columns::MinScale:
|
||||
return md.minScale();
|
||||
case Columns::MaxScale:
|
||||
return md.maxScale();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace AssetManagement
|
||||
{
|
||||
class MapDescription;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
class ConfigureMapUrlModel : public LtsWidgets::LtsAbstractTableModel<AssetManagement::MapDescription>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = LtsWidgets::LtsAbstractTableModel<AssetManagement::MapDescription>;
|
||||
using DATA_T = AssetManagement::MapDescription;
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
Name,
|
||||
Url,
|
||||
MapType,
|
||||
MinScale,
|
||||
MaxScale,
|
||||
};
|
||||
|
||||
explicit ConfigureMapUrlModel(QObject *parent = nullptr);
|
||||
~ConfigureMapUrlModel();
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
void addData(const DATA_T &entry);
|
||||
QModelIndex moveRow(const QModelIndex &sourceIndex, int destinationRow);
|
||||
QVector<ConfigureMapUrlModel::DATA_T> allData() const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "sitmap_configure_url_widget.h"
|
||||
#include "ui_sitmap_configure_url_widget.h"
|
||||
#include "ui_sitmap_configure_single_url.h"
|
||||
|
||||
#include "sitmap_configure_url_model.h"
|
||||
|
||||
|
||||
#include <AssetManagement/asm_data_plugin_interface.h>
|
||||
|
||||
|
||||
constexpr int MIN_SCALE = -1;
|
||||
constexpr int MAX_SCALE = 9999999;
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
ConfigureSingleMapUrl::ConfigureSingleMapUrl(QWidget *parent)
|
||||
: BaseClass(parent)
|
||||
, m_ui(new Ui::Configure_Single_Url)
|
||||
, m_buttonBox(new LtsWidgets::LtsDialogButtonBox(this))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
m_ui->setupUi(this);
|
||||
|
||||
layout()->addWidget(m_buttonBox);
|
||||
connect(m_buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &ConfigureSingleMapUrl::onOk);
|
||||
connect(m_buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &ConfigureSingleMapUrl::onClose);
|
||||
|
||||
m_ui->le_url->setPlaceholderText(QStringLiteral("http://HOSTNAME/arcgis/rest/services/XXXX/MapServer"));
|
||||
|
||||
m_ui->le_name->setPlaceholderText(tr("Displayname"));
|
||||
|
||||
|
||||
m_ui->le_minScale->setPlaceholderText(tr("limit zoom out, '-1' for invalid, '0' for infinite"));
|
||||
m_ui->le_minScale->setValidator(new QIntValidator(MIN_SCALE, MAX_SCALE, this));
|
||||
m_ui->le_minScale->setToolTip(m_ui->le_minScale->placeholderText());
|
||||
|
||||
|
||||
m_ui->le_maxScale->setPlaceholderText(tr("limit zoom in, '-1' for invalid"));
|
||||
m_ui->le_maxScale->setValidator(new QIntValidator(MIN_SCALE, MAX_SCALE, this));
|
||||
m_ui->le_maxScale->setToolTip(m_ui->le_maxScale->placeholderText());
|
||||
}
|
||||
|
||||
ConfigureSingleMapUrl::~ConfigureSingleMapUrl()
|
||||
{
|
||||
}
|
||||
|
||||
void ConfigureSingleMapUrl::setPlaceholderTextForFile()
|
||||
{
|
||||
m_ui->le_url->setPlaceholderText(QStringLiteral("file:filename.ext"));
|
||||
}
|
||||
|
||||
void ConfigureSingleMapUrl::setData(const ConfigureSingleMapUrl::DATA_T &data)
|
||||
{
|
||||
m_ui->le_url->setText(QString::fromStdString(data.url()));
|
||||
m_ui->le_name->setText(QString::fromStdString(data.name()));
|
||||
m_ui->le_minScale->setText(QString::number(data.minScale()));
|
||||
m_ui->le_maxScale->setText(QString::number(data.maxScale()));
|
||||
}
|
||||
|
||||
ConfigureSingleMapUrl::DATA_T ConfigureSingleMapUrl::data()
|
||||
{
|
||||
ConfigureSingleMapUrl::DATA_T data;
|
||||
data.url(m_ui->le_url->text().trimmed().toStdString());
|
||||
data.name(m_ui->le_name->text().trimmed().toStdString());
|
||||
data.minScale(m_ui->le_minScale->text().toDouble());
|
||||
data.maxScale(m_ui->le_maxScale->text().toDouble());
|
||||
return data;
|
||||
}
|
||||
|
||||
void ConfigureSingleMapUrl::onOk()
|
||||
{
|
||||
emit signalApply();
|
||||
this->close();
|
||||
}
|
||||
|
||||
void ConfigureSingleMapUrl::onClose()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureMapUrlsWidget::ConfigureMapUrlsWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::Configure_Urls_Widget)
|
||||
, m_logger(getLogger("ConfigureMapUrlsWidget"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbUp, &QPushButton::clicked, this, &ConfigureMapUrlsWidget::onUpClicked);
|
||||
connect(m_ui->pbDown, &QPushButton::clicked, this, &ConfigureMapUrlsWidget::onDownClicked);
|
||||
connect(m_ui->pbAdd, &QPushButton::clicked, this, &ConfigureMapUrlsWidget::onAddClicked);
|
||||
connect(m_ui->pbModify, &QPushButton::clicked, this, &ConfigureMapUrlsWidget::onModfiyClicked);
|
||||
connect(m_ui->pbRemove, &QPushButton::clicked, this, &ConfigureMapUrlsWidget::onRemoveClicked);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
ConfigureMapUrlsWidget::~ConfigureMapUrlsWidget()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
delete m_ui;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ConfigureMapUrlsWidget::setModel(ConfigureMapUrlModel *model)
|
||||
{
|
||||
if (!m_ui->tvLayer || !model)
|
||||
return;
|
||||
m_ui->tvLayer->setModel(model);
|
||||
|
||||
m_ui->tvLayer->hideColumn(ConfigureMapUrlModel::Columns::MapType);
|
||||
|
||||
m_configureMapUrlModel = model;
|
||||
}
|
||||
|
||||
ConfigureMapUrlModel *ConfigureMapUrlsWidget::model() const
|
||||
{
|
||||
return m_configureMapUrlModel;
|
||||
}
|
||||
|
||||
QTableView *ConfigureMapUrlsWidget::tableView()
|
||||
{
|
||||
return m_ui->tvLayer;
|
||||
}
|
||||
|
||||
void ConfigureMapUrlsWidget::onUpClicked()
|
||||
{
|
||||
if (!m_configureMapUrlModel)
|
||||
return;
|
||||
int currentRow = m_ui->tvLayer->currentIndex().row();
|
||||
|
||||
if (currentRow - 1 < 0)
|
||||
return;
|
||||
|
||||
QModelIndex idx = m_configureMapUrlModel->moveRow(m_ui->tvLayer->currentIndex(), currentRow - 1);
|
||||
m_ui->tvLayer->setCurrentIndex(idx);
|
||||
emit hasChanges();
|
||||
}
|
||||
|
||||
void ConfigureMapUrlsWidget::onDownClicked()
|
||||
{
|
||||
if (!m_configureMapUrlModel)
|
||||
return;
|
||||
int currentRow = m_ui->tvLayer->currentIndex().row();
|
||||
|
||||
QModelIndex idx = m_configureMapUrlModel->moveRow(m_ui->tvLayer->currentIndex(), currentRow + 1);
|
||||
m_ui->tvLayer->setCurrentIndex(idx);
|
||||
emit hasChanges();
|
||||
}
|
||||
|
||||
|
||||
void ConfigureMapUrlsWidget::onAddClicked()
|
||||
{
|
||||
delete m_currentConfigureSingleUrl;
|
||||
m_currentConfigureSingleUrl = new ConfigureSingleMapUrl(this);
|
||||
m_currentConfigureSingleUrl->setWindowTitle(tr("Add Url"));
|
||||
if (m_placeholderTextFile)
|
||||
m_currentConfigureSingleUrl->setPlaceholderTextForFile();
|
||||
|
||||
connect(m_currentConfigureSingleUrl.data(), &ConfigureSingleMapUrl::signalApply,
|
||||
this, &ConfigureMapUrlsWidget::addSingleUrl);
|
||||
|
||||
m_currentConfigureSingleUrl->show();
|
||||
}
|
||||
void ConfigureMapUrlsWidget::addSingleUrl()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!m_configureMapUrlModel)
|
||||
return;
|
||||
|
||||
const ConfigureSingleMapUrl::DATA_T &data = m_currentConfigureSingleUrl->data();
|
||||
|
||||
m_configureMapUrlModel->addData(data);
|
||||
emit hasChanges();
|
||||
}
|
||||
|
||||
void ConfigureMapUrlsWidget::onModfiyClicked()
|
||||
{
|
||||
delete m_currentConfigureSingleUrl;
|
||||
m_currentConfigureSingleUrl = new ConfigureSingleMapUrl(this);
|
||||
m_currentConfigureSingleUrl->setWindowTitle(tr("Modify Url"));
|
||||
if (m_placeholderTextFile)
|
||||
m_currentConfigureSingleUrl->setPlaceholderTextForFile();
|
||||
|
||||
connect(m_currentConfigureSingleUrl.data(), &ConfigureSingleMapUrl::signalApply,
|
||||
this, &ConfigureMapUrlsWidget::modifySingleUrl);
|
||||
|
||||
int currentRow = m_ui->tvLayer->currentIndex().row();
|
||||
m_currentConfigureSingleUrl->setData(m_configureMapUrlModel->getRowData(currentRow));
|
||||
|
||||
m_currentConfigureSingleUrl->show();
|
||||
}
|
||||
void ConfigureMapUrlsWidget::modifySingleUrl()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!m_configureMapUrlModel)
|
||||
return;
|
||||
|
||||
int currentRow = m_ui->tvLayer->currentIndex().row();
|
||||
const ConfigureSingleMapUrl::DATA_T &data = m_currentConfigureSingleUrl->data();
|
||||
|
||||
m_configureMapUrlModel->setRowData(currentRow, data);
|
||||
emit hasChanges();
|
||||
}
|
||||
|
||||
void ConfigureMapUrlsWidget::onRemoveClicked()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
int currentRow = m_ui->tvLayer->currentIndex().row();
|
||||
m_configureMapUrlModel->removeRow(currentRow);
|
||||
emit hasChanges();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
|
||||
|
||||
#include <QTableView>
|
||||
|
||||
class QToolButton;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class Configure_Urls_Widget;
|
||||
class Configure_Single_Url;
|
||||
}
|
||||
|
||||
|
||||
namespace AssetManagement
|
||||
{
|
||||
class MapDescription;
|
||||
}
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class ConfigureMapUrlModel;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ConfigureSingleMapUrl final : public LtsWidgets::LtsFramelessDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using BaseClass = LtsWidgets::LtsFramelessDialog;
|
||||
using DATA_T = AssetManagement::MapDescription;
|
||||
|
||||
explicit ConfigureSingleMapUrl(QWidget *parent = nullptr);
|
||||
~ConfigureSingleMapUrl();
|
||||
|
||||
void setPlaceholderTextForFile();
|
||||
|
||||
void setData(const DATA_T &data);
|
||||
DATA_T data();
|
||||
|
||||
Q_SIGNALS:
|
||||
void signalApply();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onOk();
|
||||
void onClose();
|
||||
|
||||
private:
|
||||
Ui::Configure_Single_Url *m_ui;
|
||||
LtsWidgets::LtsDialogButtonBox *m_buttonBox;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ConfigureMapUrlsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigureMapUrlsWidget(QWidget *parent = nullptr);
|
||||
~ConfigureMapUrlsWidget();
|
||||
|
||||
void setPlaceholderTextForFile() { m_placeholderTextFile = true; }
|
||||
|
||||
void setModel(ConfigureMapUrlModel *model);
|
||||
ConfigureMapUrlModel *model() const;
|
||||
|
||||
QTableView *tableView();
|
||||
|
||||
Q_SIGNALS:
|
||||
void hasChanges();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onUpClicked();
|
||||
void onDownClicked();
|
||||
void onAddClicked();
|
||||
void onModfiyClicked();
|
||||
void onRemoveClicked();
|
||||
|
||||
void addSingleUrl();
|
||||
void modifySingleUrl();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
QPointer<ConfigureSingleMapUrl> m_currentConfigureSingleUrl;
|
||||
|
||||
Ui::Configure_Urls_Widget *m_ui;
|
||||
ConfigureMapUrlModel *m_configureMapUrlModel = nullptr;
|
||||
bool m_placeholderTextFile = false;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Configure_Urls_Widget</class>
|
||||
<widget class="QWidget" name="Configure_Urls_Widget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>811</width>
|
||||
<height>441</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Layer Control</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableView" name="tvLayer">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::CurrentChanged|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbUp">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Z/src/nglwidgets/nglresources.qrc">
|
||||
<normaloff>:/icons/png/camera_arrow_up.png</normaloff>:/icons/png/camera_arrow_up.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbDown">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Z/src/nglwidgets/nglresources.qrc">
|
||||
<normaloff>:/icons/png/camera_arrow_down.png</normaloff>:/icons/png/camera_arrow_down.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbAdd">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Z/src/nglwidgets/nglresources.qrc">
|
||||
<normaloff>:/icons/png/add.png</normaloff>:/icons/png/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbModify">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Z/src/nglwidgets/nglresources.qrc">
|
||||
<normaloff>:/icons/png/edith_graphic_eass.png</normaloff>:/icons/png/edith_graphic_eass.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbRemove">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Z/src/nglwidgets/nglresources.qrc">
|
||||
<normaloff>:/icons/png/remove.png</normaloff>:/icons/png/remove.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../../../Z/src/nglwidgets/nglresources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
+377
@@ -0,0 +1,377 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "sitmap_configure_urls.h"
|
||||
#include "ui_sitmap_configure_urls.h"
|
||||
|
||||
#include "sitmap_configure_url_model.h"
|
||||
#include "sitmap_configure_url_widget.h"
|
||||
|
||||
#include <Map/map_initializer.h>
|
||||
|
||||
#include "AdapterDds/plugin_provider.h"
|
||||
#include <LtsUtils/LtsUtilsCore/dds_vector.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
ConfigureMapUrls::ConfigureMapUrls(QWidget *parent)
|
||||
: LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_pluginProvider(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_ui(new Ui::Configure_Urls)
|
||||
, m_logger(getLogger("ConfigureMapUrls"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
m_ui->setupUi(this);
|
||||
|
||||
ConfigureMapUrlsWidget *w;
|
||||
|
||||
|
||||
m_ui->tabWidget->removeTab(0);
|
||||
|
||||
w = new ConfigureMapUrlsWidget();
|
||||
w->setModel(new ConfigureMapUrlModel(this));
|
||||
m_ui->tabWidget->addTab(w, tr("Map"));
|
||||
connect(w, &ConfigureMapUrlsWidget::hasChanges, this, &ConfigureMapUrls::slotChangesMade);
|
||||
|
||||
w = new ConfigureMapUrlsWidget();
|
||||
w->setModel(new ConfigureMapUrlModel(this));
|
||||
m_ui->tabWidget->addTab(w, tr("Scene"));
|
||||
connect(w, &ConfigureMapUrlsWidget::hasChanges, this, &ConfigureMapUrls::slotChangesMade);
|
||||
|
||||
w = new ConfigureMapUrlsWidget();
|
||||
w->setModel(new ConfigureMapUrlModel(this));
|
||||
w->setPlaceholderTextForFile();
|
||||
m_ui->tabWidget->addTab(w, tr("Elevation"));
|
||||
connect(w, &ConfigureMapUrlsWidget::hasChanges, this, &ConfigureMapUrls::slotChangesMade);
|
||||
|
||||
w = new ConfigureMapUrlsWidget();
|
||||
w->setModel(new ConfigureMapUrlModel(this));
|
||||
w->setPlaceholderTextForFile();
|
||||
m_ui->tabWidget->addTab(w, tr("SceneObject"));
|
||||
connect(w, &ConfigureMapUrlsWidget::hasChanges, this, &ConfigureMapUrls::slotChangesMade);
|
||||
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Configuration_of_Modells_SLPKs"));
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
ConfigureMapUrls::~ConfigureMapUrls()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
delete m_ui;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ConfigureMapUrls::init(PluginProvider *pluginProvider)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_pluginProvider = pluginProvider;
|
||||
|
||||
if (!m_pluginProvider)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no pluginProvider";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bRet = true;
|
||||
m_asmDtc = m_pluginProvider->asmDtc();
|
||||
if (!m_asmDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " Can not retrieve AssetManagement::DTC";
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
m_asmFtc = m_pluginProvider->asmFtc();
|
||||
if (!m_asmFtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " Can not retrieve AssetManagement::FTC";
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
connect(m_ui->cbTrainingArea, &LtsWidgets::LtsComboBox::currentTextChanged,
|
||||
this, &ConfigureMapUrls::onSelectedTrainingAreaChanged);
|
||||
|
||||
m_ui->tabWidget->setCurrentIndex(0);
|
||||
|
||||
fillTrainingAreaCbx();
|
||||
syncTaToGui();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void ConfigureMapUrls::fillTrainingAreaCbx()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_asmDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
QSignalBlocker blocker(m_ui->cbTrainingArea);
|
||||
|
||||
|
||||
int curIdxTa = m_ui->cbTrainingArea->currentIndex();
|
||||
m_ui->cbTrainingArea->clear();
|
||||
auto cb = [this](const AssetManagement::TrainingArea & ta)
|
||||
{
|
||||
m_ui->cbTrainingArea->addItem(QString::fromStdString(ta.name()), QVariant(ta.id()));
|
||||
};
|
||||
m_asmDtc->trainingAreas(cb);
|
||||
m_ui->cbTrainingArea->model()->sort(0);
|
||||
|
||||
if (curIdxTa >= 0)
|
||||
m_ui->cbTrainingArea->setCurrentIndex(curIdxTa);
|
||||
}
|
||||
|
||||
if (m_ui->cbTrainingArea->model()->rowCount() > 0)
|
||||
{
|
||||
const int newTrainingAreaId = m_ui->cbTrainingArea->currentData().toInt();
|
||||
if (!retrieveTaOfService(newTrainingAreaId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " retrieveTrainingAreaOfService failed";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ConfigureMapUrls::onSelectedTrainingAreaChanged(const QString & )
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
const int newTrainingAreaId = m_ui->cbTrainingArea->currentData().toInt();
|
||||
if (m_trainingArea.id() == newTrainingAreaId)
|
||||
return;
|
||||
|
||||
if (hasUnsavedChanges())
|
||||
{
|
||||
switch (LtsWidgets::LtsMessageDialog::askApplyDiscardCancel(this))
|
||||
{
|
||||
case LtsWidgets::Button::Apply:
|
||||
apply();
|
||||
if (!retrieveTaOfService(newTrainingAreaId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " retrieveTrainingAreaOfService failed";
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case LtsWidgets::Button::Cancel:
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " set back to m_trainingArea.id() = " << m_trainingArea.id();
|
||||
m_ui->cbTrainingArea->setCurrentIndex(m_ui->cbTrainingArea->findData(QVariant(m_trainingArea.id()), Qt::UserRole));
|
||||
break;
|
||||
case LtsWidgets::Button::Discard:
|
||||
if (!retrieveTaOfService(newTrainingAreaId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " retrieveTrainingAreaOfService failed";
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " got unexpected!!!";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!retrieveTaOfService(newTrainingAreaId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " retrieveTrainingAreaOfService failed";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
syncTaToGui();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ConfigureMapUrls::retrieveTaOfService(int trainingAreaId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, trainingAreaId=" << trainingAreaId;
|
||||
|
||||
if (!m_asmDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_trainingArea = AssetManagement::TrainingArea();
|
||||
syncTaToGui();
|
||||
|
||||
|
||||
AssetManagement::TrainingArea ta = m_asmDtc->trainingArea(trainingAreaId);
|
||||
if (ta.id() != trainingAreaId)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " switch to m_trainingArea failed (taId=" << trainingAreaId << ")";
|
||||
return false;
|
||||
}
|
||||
m_trainingArea = ta;
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " switch to m_trainingArea " << m_trainingArea.id()
|
||||
<< ", ta" << ta;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline std::vector<AssetManagement::MapDescription> vecToVec(const QVector<AssetManagement::MapDescription> &vec)
|
||||
{
|
||||
return LtsUtils::convert<std::vector<AssetManagement::MapDescription>>(vec);
|
||||
}
|
||||
|
||||
static inline QVector<AssetManagement::MapDescription> vecToVec(const std::vector<AssetManagement::MapDescription> &vec)
|
||||
{
|
||||
return LtsUtils::convert<QVector<AssetManagement::MapDescription>>(vec);
|
||||
}
|
||||
|
||||
void basicConfig(ConfigureMapUrlsWidget *tv, bool showTypeMinMax = true)
|
||||
{
|
||||
if (!tv)
|
||||
return;
|
||||
tv->tableView()->resizeColumnsToContents();
|
||||
tv->tableView()->setColumnWidth(1, 100);
|
||||
tv->tableView()->setColumnWidth(2, 100);
|
||||
tv->tableView()->setColumnWidth(3, 100);
|
||||
tv->tableView()->setColumnWidth(4, 100);
|
||||
|
||||
if (!showTypeMinMax)
|
||||
{
|
||||
tv->tableView()->hideColumn(ConfigureMapUrlModel::Columns::MapType);
|
||||
tv->tableView()->hideColumn(ConfigureMapUrlModel::Columns::MinScale);
|
||||
tv->tableView()->hideColumn(ConfigureMapUrlModel::Columns::MaxScale);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureMapUrls::syncTaToGui()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
ConfigureMapUrlsWidget *w;
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(0));
|
||||
if (w && w->model())
|
||||
{
|
||||
w->model()->setData(vecToVec(m_trainingArea.map2D()));
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " model->rowCount()" << w->model()->rowCount();
|
||||
}
|
||||
basicConfig(w);
|
||||
|
||||
if (w && w->model())
|
||||
connect(w->model(), &ConfigureMapUrlModel::dataChanged, this, []()
|
||||
{
|
||||
qCritical() << " Changed!!!";
|
||||
});
|
||||
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(1));
|
||||
if (w && w->model())
|
||||
{
|
||||
w->model()->setData(vecToVec(m_trainingArea.scene3D()));
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " model->rowCount()" << w->model()->rowCount();
|
||||
}
|
||||
basicConfig(w);
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(2));
|
||||
if (w && w->model())
|
||||
w->model()->setData(vecToVec(m_trainingArea.elevation()));
|
||||
basicConfig(w, false);
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(3));
|
||||
if (w && w->model())
|
||||
w->model()->setData(vecToVec(m_trainingArea.sceneObjects()));
|
||||
basicConfig(w, false);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ConfigureMapUrls::syncGuiToTa()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
ConfigureMapUrlsWidget *w;
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(0));
|
||||
if (w && w->model())
|
||||
m_trainingArea.map2D(vecToVec(w->model()->allData()));
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(1));
|
||||
if (w && w->model())
|
||||
m_trainingArea.scene3D(vecToVec(w->model()->allData()));
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(2));
|
||||
if (w && w->model())
|
||||
m_trainingArea.elevation(vecToVec(w->model()->allData()));
|
||||
|
||||
w = static_cast<ConfigureMapUrlsWidget *>(m_ui->tabWidget->widget(3));
|
||||
if (w && w->model())
|
||||
m_trainingArea.sceneObjects(vecToVec(w->model()->allData()));
|
||||
|
||||
|
||||
|
||||
|
||||
for (auto &item : m_trainingArea.map2D())
|
||||
item.mapDescriptionTypeId(AssetManagement::MapDescriptionType_def::Map2D);
|
||||
for (auto &item : m_trainingArea.scene3D())
|
||||
item.mapDescriptionTypeId(AssetManagement::MapDescriptionType_def::Scene3D);
|
||||
for (auto &item : m_trainingArea.elevation())
|
||||
item.mapDescriptionTypeId(AssetManagement::MapDescriptionType_def::Elevation);
|
||||
for (auto &item : m_trainingArea.sceneObjects())
|
||||
item.mapDescriptionTypeId(AssetManagement::MapDescriptionType_def::SceneObj);
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void ConfigureMapUrls::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Configure Map Urls"));
|
||||
|
||||
}
|
||||
|
||||
bool ConfigureMapUrls::apply()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!m_asmFtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " Can not retrieve AssetManagement::FTC";
|
||||
return false;
|
||||
}
|
||||
|
||||
this->syncGuiToTa();
|
||||
|
||||
bool success = m_requestHelper->startSingleRequest([this]()
|
||||
{
|
||||
return m_asmFtc->trainingAreaModifyRequest(m_trainingArea, this);
|
||||
});
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, scucess=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
void ConfigureMapUrls::onTrainingAreaModifyReply(const Core::FunctionReplyObject &reply)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (reply.error())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << "Got onTrainingAreaModifyReply error: " << reply();
|
||||
return;
|
||||
}
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " Got onTrainingAreaModifyReply with id " << reply.id();
|
||||
|
||||
m_requestHelper->requestReply(reply);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
|
||||
|
||||
#include <AssetManagement/asm_data_plugin_interface.h>
|
||||
|
||||
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class Configure_Urls;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class PluginProvider;
|
||||
|
||||
|
||||
|
||||
|
||||
class ConfigureMapUrls : public LtsWidgets::LtsDialog
|
||||
, protected AssetManagement::Interface::Ftc::TrainingAreaModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigureMapUrls(QWidget *parent = nullptr);
|
||||
~ConfigureMapUrls();
|
||||
|
||||
bool init(PluginProvider *pluginProvider);
|
||||
|
||||
protected:
|
||||
void fillTrainingAreaCbx();
|
||||
bool retrieveTaOfService(int trainingAreaId);
|
||||
void syncTaToGui();
|
||||
void syncGuiToTa();
|
||||
|
||||
void onTrainingAreaModifyReply(const Core::FunctionReplyObject &reply) override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onSelectedTrainingAreaChanged(const QString &dummy = QString());
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
bool apply() override final;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
SituationMap::PluginProvider *m_pluginProvider;
|
||||
std::shared_ptr<AssetManagement::Interface::Dtc> m_asmDtc;
|
||||
std::shared_ptr<AssetManagement::Interface::Ftc> m_asmFtc;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
AssetManagement::TrainingArea m_trainingArea;
|
||||
|
||||
Ui::Configure_Urls *m_ui;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Configure_Urls</class>
|
||||
<widget class="QWidget" name="Configure_Urls">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>667</width>
|
||||
<height>368</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblTrainingArea">
|
||||
<property name="text">
|
||||
<string>Training Area:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbTrainingArea">
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="map">
|
||||
<attribute name="title">
|
||||
<string>Map</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "map_object_custom_view.h"
|
||||
#include "ui_map_object_custom_view.h"
|
||||
#include "map_object_model.h"
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <QDataWidgetMapper>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
MapObjectCustomView::MapObjectCustomView(QWidget *parent)
|
||||
: BaseClass(parent)
|
||||
, m_ui(new Ui::MapObjectCustomView)
|
||||
, m_mapper(new QDataWidgetMapper(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->isTablet())
|
||||
{
|
||||
constexpr auto scaleFactor = 1.4;
|
||||
resize(size() * scaleFactor);
|
||||
m_ui->lbIcon->setMinimumSize(m_ui->lbIcon->minimumSize() * scaleFactor);
|
||||
m_ui->lbIcon->setMaximumSize(m_ui->lbIcon->maximumSize() * scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
MapObjectCustomView::~MapObjectCustomView()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool MapObjectCustomView::init(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
if (idx.model() != m_mapper->model())
|
||||
{
|
||||
|
||||
m_mapper->setModel(const_cast<QAbstractItemModel *>(idx.model()));
|
||||
m_mapper->addMapping(m_ui->lbDescription, MapObjectModel::Columns::SINGLE_DESCRIPTION, "text");
|
||||
m_mapper->addMapping(m_ui->lbIcon, MapObjectModel::Columns::PICTURE, "pixmap");
|
||||
}
|
||||
|
||||
setRow(idx.row());
|
||||
return true;
|
||||
}
|
||||
|
||||
void MapObjectCustomView::setRow(int row)
|
||||
{
|
||||
m_mapper->setCurrentIndex(row);
|
||||
|
||||
|
||||
QAbstractItemModel *modelPtr = m_mapper->model();
|
||||
if (modelPtr)
|
||||
m_uniqueMapId = modelPtr->data(modelPtr->index(row, MapObjectModel::Columns::UNIQUE_MAP_ID)).toInt();
|
||||
else
|
||||
m_uniqueMapId = -1;
|
||||
}
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <Map/situation_map_types.h>
|
||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
||||
|
||||
|
||||
class QDataWidgetMapper;
|
||||
namespace Ui
|
||||
{
|
||||
class MapObjectCustomView;
|
||||
}
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MapObjectCustomView final : public LtsDataView::AbstractDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = AbstractDisplayWidget;
|
||||
|
||||
public:
|
||||
explicit MapObjectCustomView(QWidget *parent = nullptr);
|
||||
~MapObjectCustomView();
|
||||
bool init(const QModelIndex &idx) override;
|
||||
|
||||
private:
|
||||
void setRow(int row);
|
||||
private:
|
||||
Ui::MapObjectCustomView *m_ui;
|
||||
QDataWidgetMapper *m_mapper = nullptr;
|
||||
|
||||
UniqueMapId m_uniqueMapId = INVALID_MAP_ID;
|
||||
};
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MapObjectCustomView</class>
|
||||
<widget class="QWidget" name="MapObjectCustomView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>63</width>
|
||||
<height>88</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbIcon">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbDescription">
|
||||
<property name="text">
|
||||
<string notr="true"><Desc></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+539
@@ -0,0 +1,539 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "map_object_model.h"
|
||||
#include <Symbology/sidc_codec.h>
|
||||
|
||||
#include <SituationMap/Map/party_id_to_color_functor.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <QBuffer>
|
||||
#include <QPainter>
|
||||
#include <QGuiApplication>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
static constexpr int ICON_RESOLUTION_CUSTOM = 128;
|
||||
static constexpr int ICON_RESOLUTION_TABLE = 32;
|
||||
|
||||
|
||||
void updateMapObjectDataToEnsureGoodQuality(MapObjectData *mod)
|
||||
{
|
||||
mod->m_symDataToRender.sizeL = ICON_RESOLUTION_CUSTOM;
|
||||
}
|
||||
|
||||
MapObjectData::~MapObjectData()
|
||||
{
|
||||
delete m_symbolResultWatcher;
|
||||
}
|
||||
|
||||
void MapObjectData::onResultReady()
|
||||
{
|
||||
if (!m_symbolResultWatcher)
|
||||
return;
|
||||
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = m_symbolResultWatcher->symbolResult();
|
||||
if (!symResult)
|
||||
return;
|
||||
setImage(symResult->symbolImage().image());
|
||||
emit dataChanged(m_uniqueMapId);
|
||||
m_symbolResultWatcher->deleteLater();
|
||||
m_symbolResultWatcher = nullptr;
|
||||
}
|
||||
|
||||
void MapObjectData::requestImage(AdvancedSymbology::SymbolDictionary *dict)
|
||||
{
|
||||
if (!m_symbolResultWatcher)
|
||||
{
|
||||
m_symbolResultWatcher = new AdvancedSymbology::SymbolResultWatcher;
|
||||
connect(m_symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady,
|
||||
this, &MapObjectData::onResultReady);
|
||||
}
|
||||
updateMapObjectDataToEnsureGoodQuality(this);
|
||||
m_symbolResultWatcher->setSymbolResult(dict->findImage(m_symDataToRender));
|
||||
}
|
||||
|
||||
void MapObjectData::setImage(const QImage &img)
|
||||
{
|
||||
if (img.isNull())
|
||||
{
|
||||
m_pixIcon = QPixmap();
|
||||
m_pixPicture = QPixmap();
|
||||
return;
|
||||
}
|
||||
const auto dpr = qApp->devicePixelRatio();
|
||||
|
||||
m_pixIcon = QPixmap::fromImage(img.scaled(QSize(ICON_RESOLUTION_TABLE, ICON_RESOLUTION_TABLE) * dpr,
|
||||
Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||
m_pixPicture = QPixmap::fromImage(img.scaled(QSize(ICON_RESOLUTION_CUSTOM, ICON_RESOLUTION_CUSTOM) * dpr,
|
||||
Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||
m_pixIcon.setDevicePixelRatio(dpr);
|
||||
m_pixPicture.setDevicePixelRatio(dpr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MapObjectModel::MapObjectModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<QSharedPointer<MapObjectData>>(
|
||||
{
|
||||
tr("UniqueMapid"),
|
||||
tr("Sidc"),
|
||||
tr("Description"),
|
||||
tr("Icon"),
|
||||
tr("ParticipantId"),
|
||||
tr("Equipment number"),
|
||||
tr("Party"),
|
||||
tr("TypeId"),
|
||||
tr("Type"),
|
||||
tr("VulnerabilityStateId"),
|
||||
tr("VulnerabilityState"),
|
||||
tr("Designator"),
|
||||
tr("Tact. Identifier"),
|
||||
tr("Picture")
|
||||
},
|
||||
parent)
|
||||
, m_logger(getLogger("MapObjectModel"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
MapObjectModel::~MapObjectModel()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void MapObjectModel::initModel(Map *map)
|
||||
{
|
||||
m_map = map;
|
||||
m_dictionary = &(m_map->symbolDictionary());
|
||||
|
||||
|
||||
|
||||
|
||||
connect(m_dictionary, &AdvancedSymbology::SymbolDictionary::changedDelayed, this, &MapObjectModel::requestCivilIcons, Qt::UniqueConnection);
|
||||
|
||||
connect(this, &MapObjectModel::rowsInserted, this, &MapObjectModel::updateUsedPartyIds);
|
||||
connect(this, &MapObjectModel::rowsRemoved, this, &MapObjectModel::updateUsedPartyIds);
|
||||
connect(this, &MapObjectModel::modelReset, this, &MapObjectModel::updateUsedPartyIds);
|
||||
}
|
||||
|
||||
bool MapObjectModel::contains(UniqueMapId uniqueMapId) const
|
||||
{
|
||||
return findRowForUniqueMapId(uniqueMapId) >= 0;
|
||||
}
|
||||
|
||||
|
||||
void MapObjectModel::remove(UniqueMapId uniqueMapId)
|
||||
{
|
||||
const int row = findRowForUniqueMapId(uniqueMapId);
|
||||
removeRow(row);
|
||||
}
|
||||
|
||||
void MapObjectModel::setMapObjectData(const QVector<QSharedPointer<MapObjectData>> &mapObjectDataVec)
|
||||
{
|
||||
setData(mapObjectDataVec);
|
||||
|
||||
for (const QSharedPointer<MapObjectData> &mapObjectData : mapObjectDataVec)
|
||||
if (mapObjectData)
|
||||
{
|
||||
updateMapObjectDataToEnsureGoodQuality(mapObjectData.data());
|
||||
connect(mapObjectData.data(), &MapObjectData::dataChanged,
|
||||
this, &MapObjectModel::onDataChanged, Qt::UniqueConnection);
|
||||
}
|
||||
}
|
||||
|
||||
bool MapObjectModel::addMapObjectData(const QSharedPointer<MapObjectData> &mapObjectData)
|
||||
{
|
||||
const int row = findRowForUniqueMapId(mapObjectData->m_uniqueMapId);
|
||||
if (row >= 0)
|
||||
return false;
|
||||
|
||||
updateMapObjectDataToEnsureGoodQuality(mapObjectData.data());
|
||||
|
||||
|
||||
if (!insertRow(mapObjectData))
|
||||
return false;
|
||||
|
||||
connect(mapObjectData.data(), &MapObjectData::dataChanged,
|
||||
this, &MapObjectModel::onDataChanged, Qt::UniqueConnection);
|
||||
return true;
|
||||
}
|
||||
|
||||
QImage markImage(const QPixmap &orgPixmap)
|
||||
{
|
||||
QImage newImage(orgPixmap.size(), QImage::Format_ARGB32);
|
||||
static QColor fillColor = QColor(211, 211, 211, 120);
|
||||
newImage.fill(fillColor);
|
||||
|
||||
QPainter painter(&newImage);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
painter.drawPixmap(orgPixmap.rect(), orgPixmap);
|
||||
painter.end();
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
bool MapObjectModel::updateMapObjectData(const QSharedPointer<MapObjectData> &mapObjectData)
|
||||
{
|
||||
const int row = findRowForUniqueMapId(mapObjectData->m_uniqueMapId);
|
||||
if (row < 0)
|
||||
return false;
|
||||
|
||||
|
||||
if (!mapObjectData->m_symDataToRender.sidc.isEmpty())
|
||||
{
|
||||
updateMapObjectDataToEnsureGoodQuality(mapObjectData.data());
|
||||
|
||||
const auto &oldRowData = m_vecData.at(row);
|
||||
if (oldRowData->m_symDataToRender == mapObjectData->m_symDataToRender)
|
||||
return true;
|
||||
|
||||
|
||||
mapObjectData->setImage(markImage(oldRowData->m_pixPicture));
|
||||
|
||||
|
||||
requestIcon(mapObjectData);
|
||||
}
|
||||
|
||||
connect(mapObjectData.data(), &MapObjectData::dataChanged,
|
||||
this, &MapObjectModel::onDataChanged, Qt::UniqueConnection);
|
||||
|
||||
return setRowData(row, mapObjectData);
|
||||
}
|
||||
|
||||
void MapObjectModel::requestCivilIcons()
|
||||
{
|
||||
for (const DATA_T &moData : qAsConst(m_vecData))
|
||||
{
|
||||
if (!moData)
|
||||
continue;
|
||||
const QString &sidc = moData->m_symDataToRender.sidc;
|
||||
if (!AdvancedSymbology::SidcCodec::isEncoded(sidc))
|
||||
continue;
|
||||
if (!AdvancedSymbology::SidcCodec::isCivil(sidc))
|
||||
continue;
|
||||
requestIcon(moData);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant MapObjectModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole &&
|
||||
orientation == Qt::Horizontal)
|
||||
{
|
||||
if (section == PARTY)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
cfc.data.reserve(m_usedPartyIds.size());
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (const int partyId : m_usedPartyIds)
|
||||
{
|
||||
const PartyIdToColorFunctor::PartyData party = m_map->partyIdToColorFunctor().partyId(partyId);
|
||||
cfd.data = partyId;
|
||||
cfd.text = party.m_name;
|
||||
cfd.icon = party.m_icon;
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = false;
|
||||
return cfc.toVariant();
|
||||
}
|
||||
|
||||
if (section == TYPE_NAME)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
cfc.data.reserve(m_usedTypeName.size());
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (const QString &typeName : m_usedTypeName)
|
||||
{
|
||||
cfd.data = typeName;
|
||||
cfd.text = typeName;
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = true;
|
||||
return cfc.toVariant();
|
||||
}
|
||||
|
||||
if (section == VULNERABILITY_STATE)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
cfc.data.reserve(m_usedVulnerabilities.size());
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (auto it = m_usedVulnerabilities.begin(); it != m_usedVulnerabilities.end(); ++it)
|
||||
{
|
||||
cfd.data = it.key();
|
||||
cfd.text = it.value();
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = false;
|
||||
return cfc.toVariant();
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QVariant MapObjectModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return QVariant();
|
||||
if (role != Qt::DisplayRole &&
|
||||
role != Qt::ToolTipRole &&
|
||||
role != Qt::EditRole &&
|
||||
role != Qt::DecorationRole &&
|
||||
role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
return QVariant();
|
||||
|
||||
const DATA_T &moData = m_vecData.at(index.row());
|
||||
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case PARTY:
|
||||
return QStringLiteral("%1 (%2)").arg(moData->m_partyName).arg(moData->m_partyId);
|
||||
case UNIQUE_MAP_ID:
|
||||
case ICON:
|
||||
{
|
||||
QString tooltip(QStringLiteral("<html>"));
|
||||
|
||||
const QPixmap &img = moData->m_pixPicture;
|
||||
if (!img.isNull())
|
||||
{
|
||||
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
img.save(&buffer, "PNG", 100);
|
||||
tooltip.append(QStringLiteral("<center><img src='data:image/png;base64,%1'></center>").arg(QString::fromLatin1(data.toBase64())));
|
||||
}
|
||||
|
||||
if (!moData->m_typeName.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::TYPE_NAME , Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_typeName));
|
||||
}
|
||||
if (!moData->m_typeName.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::VULNERABILITY_STATE, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_vulnerabilityString));
|
||||
}
|
||||
if (!moData->m_description1.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::DESCRIPTION1, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_description1));
|
||||
}
|
||||
if (!moData->m_description2.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::DESCRIPTION2, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_description2));
|
||||
}
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
tooltip.append(QStringLiteral("<p>participantId: %2</p>").arg(moData->m_participantId));
|
||||
tooltip.append(QStringLiteral("<p>row: %2</p>").arg(index.row()));
|
||||
tooltip.append(QStringLiteral("<p>uniqueMapId: %2</p>").arg(moData->m_uniqueMapId));
|
||||
tooltip.append(QStringLiteral("<p>typeId: %2</p>").arg(moData->m_typeId));
|
||||
tooltip.append(QStringLiteral("<p>vulnerabilityStateId: %2</p>").arg(moData->m_vulnerabilityState));
|
||||
#endif
|
||||
|
||||
tooltip.append(QStringLiteral("</html>"));
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((role == Qt::DisplayRole) || (role == Qt::EditRole) || (role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole))
|
||||
{
|
||||
const UniqueMapId &uniqueMapId = moData->m_uniqueMapId;
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case UNIQUE_MAP_ID:
|
||||
return uniqueMapId;
|
||||
case SIDC:
|
||||
return moData->m_symDataToRender.sidc;
|
||||
case SINGLE_DESCRIPTION:
|
||||
if (moData->m_equipmentNumber >= 0)
|
||||
return moData->m_equipmentNumber;
|
||||
else
|
||||
return moData->m_description1;
|
||||
case ICON:
|
||||
{
|
||||
|
||||
if (moData->m_pixIcon.isNull())
|
||||
{
|
||||
moData->setImage(AdvancedSymbology::SymbolDictionary::temporaryImage());
|
||||
requestIcon(moData);
|
||||
}
|
||||
if (moData->m_pixIcon.isNull())
|
||||
return QVariant();
|
||||
return moData->m_pixIcon;
|
||||
}
|
||||
case PARTICIPANT_ID:
|
||||
return moData->m_participantId <= 0 ? QVariant() : QVariant(moData->m_participantId);
|
||||
case EQUIPMENT_NUMBER:
|
||||
return moData->m_equipmentNumber <= 0 ? QVariant() : QVariant(moData->m_equipmentNumber);
|
||||
case PARTY:
|
||||
return moData->m_partyName;
|
||||
case TYPE_ID:
|
||||
return moData->m_typeId <= 0 ? QVariant() : QVariant(moData->m_typeId);
|
||||
case TYPE_NAME:
|
||||
return moData->m_typeName;
|
||||
case VULNERABILITY_STATE:
|
||||
return moData->m_vulnerabilityString;
|
||||
case VULNERABILITY_STATE_ID:
|
||||
return moData->m_vulnerabilityState <= 0 ? QVariant() : QVariant(moData->m_vulnerabilityState);
|
||||
case DESCRIPTION1:
|
||||
return moData->m_description1;
|
||||
case DESCRIPTION2:
|
||||
return moData->m_description2;
|
||||
case PICTURE:
|
||||
{
|
||||
|
||||
if (moData->m_pixPicture.isNull())
|
||||
{
|
||||
moData->setImage(AdvancedSymbology::SymbolDictionary::temporaryImage());
|
||||
requestIcon(moData);
|
||||
}
|
||||
if (moData->m_pixPicture.isNull())
|
||||
return QVariant();
|
||||
return moData->m_pixPicture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
{
|
||||
if (index.column() == PARTY)
|
||||
return moData->m_partyId;
|
||||
|
||||
if (index.column() == TYPE_NAME)
|
||||
return moData->m_typeName;
|
||||
|
||||
if (index.column() == VULNERABILITY_STATE)
|
||||
return moData->m_vulnerabilityState;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
UniqueMapId MapObjectModel::uniqueMapIdOfIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return SituationMap::INVALID_MAP_ID;
|
||||
|
||||
const DATA_T &moData = m_vecData.at(index.row());
|
||||
if (!moData)
|
||||
return SituationMap::INVALID_MAP_ID;
|
||||
|
||||
return moData->m_uniqueMapId;
|
||||
}
|
||||
|
||||
void MapObjectModel::onDataChanged(UniqueMapId uniqueMapId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapId=" << uniqueMapId;
|
||||
|
||||
|
||||
int row = findRowForUniqueMapId(uniqueMapId);
|
||||
emit dataChanged(index(row, 0), index(row, LtsAbstractTableModel::columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
|
||||
int MapObjectModel::findRowForUniqueMapId(UniqueMapId uniqueMapId) const
|
||||
{
|
||||
for (int i = 0; i < m_vecData.size(); ++i)
|
||||
{
|
||||
if (m_vecData.at(i)->m_uniqueMapId == uniqueMapId)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MapObjectModel::requestIcon(const MapObjectModel::DATA_T &data) const
|
||||
{
|
||||
|
||||
data->requestImage(m_dictionary);
|
||||
}
|
||||
|
||||
void MapObjectModel::updateUsedPartyIds()
|
||||
{
|
||||
m_usedPartyIds.clear();
|
||||
m_usedTypeName.clear();
|
||||
m_usedVulnerabilities.clear();
|
||||
for (const QSharedPointer<MapObjectData> &item : qAsConst(m_vecData))
|
||||
{
|
||||
if (!item)
|
||||
continue;
|
||||
m_usedPartyIds[item->m_partyId] = item->m_partyId;
|
||||
m_usedTypeName.insert(item->m_typeName);
|
||||
m_usedVulnerabilities.insert(item->m_vulnerabilityState,
|
||||
item->m_vulnerabilityState < 0 ? QStringLiteral("-") : item->m_vulnerabilityString);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MapObjectProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<MapObjectModel*>(sourceModel);
|
||||
BaseClass::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
bool MapObjectProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
if (!m_sourceModel ||
|
||||
source_left.column() != source_right.column() ||
|
||||
source_left.row() < 0 || source_left.row() >= m_sourceModel->m_vecData.size() ||
|
||||
source_right.row() < 0 || source_right.row() >= m_sourceModel->m_vecData.size()
|
||||
)
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
|
||||
|
||||
const QSharedPointer<MapObjectData> &left = m_sourceModel->m_vecData.at(source_left.row());
|
||||
const QSharedPointer<MapObjectData>&right = m_sourceModel->m_vecData.at(source_right.row());
|
||||
switch (source_left.column())
|
||||
{
|
||||
case MapObjectModel::Columns::UNIQUE_MAP_ID:
|
||||
return left->m_uniqueMapId < right->m_uniqueMapId;
|
||||
case MapObjectModel::Columns::SIDC:
|
||||
return left->m_symDataToRender.sidc < right->m_symDataToRender.sidc;
|
||||
case MapObjectModel::Columns::SINGLE_DESCRIPTION:
|
||||
if (left->m_equipmentNumber && right->m_equipmentNumber)
|
||||
return left->m_equipmentNumber < right->m_equipmentNumber;
|
||||
if (left->m_equipmentNumber)
|
||||
return true;
|
||||
if (right->m_equipmentNumber)
|
||||
return true;
|
||||
return left->m_description1 < left->m_description1;
|
||||
case MapObjectModel::Columns::PARTICIPANT_ID:
|
||||
return left->m_participantId < right->m_participantId;
|
||||
case MapObjectModel::Columns::EQUIPMENT_NUMBER:
|
||||
return left->m_equipmentNumber < right->m_equipmentNumber;
|
||||
case MapObjectModel::Columns::PARTY:
|
||||
return left->m_partyId < right->m_partyId;
|
||||
case MapObjectModel::Columns::TYPE_ID:
|
||||
return left->m_typeId < right->m_typeId;
|
||||
case MapObjectModel::Columns::TYPE_NAME:
|
||||
return left->m_typeName < right->m_typeName;
|
||||
case MapObjectModel::Columns::DESCRIPTION1:
|
||||
return left->m_description1 < right->m_description1;
|
||||
case MapObjectModel::Columns::DESCRIPTION2:
|
||||
return left->m_description2 < right->m_description2;
|
||||
}
|
||||
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loaded 100 of 11247 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user