Files
qt5-legatus-legacy/Lts/Plugins/SituationMapPlugin/Gui/SituationMap/AdapterDds/adapter_dds.cpp
T
2026-08-13 18:33:10 +02:00

2023 lines
68 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "adapter_dds.h"
#include <Map/map.h>
#include <Map/layer_factory.h>
#include <Map/location_display.h>
#include <Map/party_id_to_color_functor.h>
#include <LtsUtilsSettings/settings.h>
// Participants:
#include "charge_effect_to_map.h"
#include "participant_to_map.h"
#include "hitlineinfo_to_map.h"
#include "buildinghitlineinfo_to_map.h"
// AES:
#include "air_support_impact_to_map.h"
#include "bccontamination_to_map.h"
#include "borderline_to_map.h"
#include "danger_area_to_map.h"
#include "explosion_area_to_map.h"
#include "explosion_single_to_map.h"
#include "explosion_cluster_to_map.h"
#include "effect_cluster_to_map.h"
#include "functional_area_to_map.h"
#include "gas_pipe_to_map.h"
#include "mine_area_to_map.h"
#include "mine_area_null_to_map.h"
#include "mine_corridor_to_map.h"
#include "ncontamination_to_map.h"
#include "recon_area_to_map.h"
#include "technical_area_to_map.h"
#include "booby_traps_to_map.h"
#include "off_route_to_map.h"
#include "dus_single_mine_to_map.h" // AHTC
// ALM:
#include "emergency_call_to_map.h"
// ASM:
#include "training_area_to_map.h"
// ISM:
#include "mounting_point_to_map.h"
#include "sound_area_to_map.h"
#include "buildings_to_map.h"
#include "mse_point_to_map.h"
#include "mse_bridge_to_map.h"
#include "special_areas_to_map.h"
// GIM
#include "guez_ied_to_map.h"
// GNA
#include "guez_nasat_9liner.h"
// CES
#include "building_ownership.h"
#include "building_contamination.h"
// PDM
#include "pdm_handler.h"
// TGT
#include "shootback_area_to_map.h"
// Qt:
#include <limits>
#include <QTimer>
#include <QDateTime>
#include <functional>
namespace SituationMap
{
AdapterDds::AdapterDds(QObject *parent)
: QObject(parent)
, m_logger(getLogger("AdapterDds"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START DDDDDDDD" ;
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
}
AdapterDds::~AdapterDds()
{
// no logging here, NGLLogger lib may already be unloaded!
qDebug() << LOGFUNCTION << " START";
stop();
qDeleteAll(m_aes2MapCont);
// handle particpants explicit:
m_particpants.clear(); // If this was the last reference, then the pointer itself will be deleted.
// handle buildingOwnership explicit:
m_buildingOwnership.clear(); // If this was the last reference, then the pointer itself will be deleted.
m_buildingContamination.clear();
m_trainingAreas.clear();
m_shootbackAreas.clear();
m_specialAreas.clear();
// handle hitline2SituationMap explicit:
m_hitlineInfo2SituationMap.clear(); // If this was the last reference, then the pointer itself will be deleted.
m_bldHitlineInfo2SituationMap.clear();
delete m_pdmHandler;
qDebug() << LOGFUNCTION << " END";
}
bool AdapterDds::init(Map *map, PluginProvider *pluginProvider, QPointer<MovementTrackManager> &movementTrackMgr, bool resourceMode)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" ;
if (!map || !pluginProvider)
return false;
m_map = map;
m_pluginProvider = pluginProvider;
m_movementTrackManager = movementTrackMgr;
// pdmHandler
m_pdmHandler = new PdmHandler(m_pluginProvider->pdmDtc());
// Participants & Hitlines:
{
// Participants
const QString participantLayername = m_map->layerFactory().participantLayername(); // == 'Participants'
m_particpants = QSharedPointer<Participant2SituationMap>(new Participant2SituationMap(m_pdmHandler,
m_map->objectFactory(),
participantLayername,
"Participant2SituationMap"));
if (!m_particpants->init(&m_map->layerFactory(), m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// connect signals:
connect(m_particpants.data(), &Participant2SituationMap::participantPositionChanged,
this, &AdapterDds::participantPositionChanged, Qt::UniqueConnection);
if(strcmp(PROJECTBUILD, "commaster") == 0 || strcmp(PROJECTBUILD, "demotablet") == 0)
{
connect(m_particpants.data(), &Participant2SituationMap::participantOwnPositionChanged,
this, &AdapterDds::onParticipantOwnPositionChanged, Qt::UniqueConnection);
}
m_particpants->setMovementTrackManager(m_movementTrackManager);
// HitlineInfo:
{
// ensure that the hitlines are on top:
const int drawOrder = std::numeric_limits<int>::max()/10;
m_hitlineInfo2SituationMap = QSharedPointer<HitlineInfo2SituationMap>(new HitlineInfo2SituationMap(m_pdmHandler,
m_particpants.data(),
m_map->objectFactory(),
participantLayername,
drawOrder,
"HitlineInfo2SituationMap"));
if (!m_hitlineInfo2SituationMap->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
// ensure that the hitlines are on top:
const int drawOrder = std::numeric_limits<int>::max()/10;
m_bldHitlineInfo2SituationMap = QSharedPointer<BuildingHitlineInfo2SituationMap>(new BuildingHitlineInfo2SituationMap(m_pdmHandler,
m_particpants.data(),
m_map->objectFactory(),
participantLayername,
drawOrder,
"BldHitlineInfo2SituationMap"));
if (!m_bldHitlineInfo2SituationMap->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
}
// Norbert Thoden, 03/2024
// Overview Layer AES vs. AesCentral:
//
// Layer "AES" -> initRenderer3D_AesExtrusion
// assignUniqueValueRendererAesCentral3DExtrusion()
// UniqueValue-Renderer on this->getGraphicsLayer3DExtrusion(logicalName)
//
// Layer "AESCentral" -> initRenderer3D_AesCentral_Booby (prepare CONE, SPERE etc:)
// assignUniqueValueRendererAesCentral()
// UniqueValue-Renderer on this->getGraphicsLayer3DExtrusion(logicalName)
//
// => die beiden UniqueValue-Renderer sind also derzeit NICHT kombinierbar!!
// Layer "AES" AtExplosionSingle
// Layer "AES" AtExplosionSingleCentral
// Layer "AES" AtExplosionArea
// Layer "AES" AtMineArea
// Layer "AES" MineAreaNull2SituationMap
// Layer "AES" AtMineCorridor
// Layer "AES" AtBCContamination
// Layer "AES" AtNContamination
// Layer "AES" AtNContamination
// Layer "AES" AtDangerArea
// Layer "AES" AtFunctionalArea
// Layer "AES" AtBorderline
// Layer "AES" AtReconArea
// Layer "AES" AtDusSingleMine
// Layer "AES" AtGasPipe
// Layer "AES" AtAirSupportImpact
// Layer "AES" AtTechnicalArea
// Layer "AESCentral" AtExplosionCluster
// Layer "AESCentral" AtBoobyTrap
// Layer "AESCentral" AtOffRouteMine
// Layer "AESCentral" AtExplosionCluster
{
if (m_map->mode() == Mode::Mode_3D)
{
// relevant for Overview
initRenderer3D_AesExtrusion();
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtExplosionSingle;
ExplosionSingle2SituationMap *sim2Map = static_cast<ExplosionSingle2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new ExplosionSingle2SituationMap(m_pdmHandler,
m_map->objectFactory(),
QLatin1String("AES"),
"ExplosionSingle2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if(!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
// SingleCentral is outdated
// {
// AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtExplosionSingleCentral;
// ExplosionSingleCentral2SituationMap *sim2Map = static_cast<ExplosionSingleCentral2SituationMap *>(m_aes2MapCont.value(aesType));
// if (! sim2Map)
// {
// sim2Map = new ExplosionSingleCentral2SituationMap(m_pdmHandler,
// m_map->objectFactory(),
// QLatin1String("AESCentral"),
// "ExplosionSingleCentral2SituationMap");
// m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
// }
// if(!sim2Map->init(m_pluginProvider))
// ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// }
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtExplosionArea;
ExplosionArea2SituationMap *sim2Map = static_cast<ExplosionArea2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new ExplosionArea2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"ExplosionArea2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtMineArea;
MineArea2SituationMap *sim2Map = static_cast<MineArea2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new MineArea2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"MineArea2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
const int contIdx = 0;
MineAreaNull2SituationMap *sim2Map = static_cast<MineAreaNull2SituationMap *>(m_aes2MapCont.value(contIdx));
if (! sim2Map)
{
sim2Map = new MineAreaNull2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"MineAreaNull2SituationMap");
m_aes2MapCont[static_cast<int>(contIdx)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtMineCorridor;
MineCorridor2SituationMap *sim2Map = static_cast<MineCorridor2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new MineCorridor2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"MineCorridor2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtBCContamination;
BCContamination2SituationMap *sim2Map = static_cast<BCContamination2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new BCContamination2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"BContamination2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
//
// AESCentral :
//
{
// prepare UniqueValueRenderer here:
// relevant for Overview
static const QString layernameAesCentral(QStringLiteral("AESCentral"));
// !!! new feature SceneMarker reuquires NContamination2SituationMap to be moved to layer with RenderingMode::Dynamic !!!
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtNContamination;
NContamination2SituationMap *sim2Map = static_cast<NContamination2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new NContamination2SituationMap(m_map->objectFactory(),
layernameAesCentral,
"NContamination2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
int drawOrder = 0;
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtExplosionCluster;
ExplosionCluster2SituationMap *sim2Map = static_cast<ExplosionCluster2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new ExplosionCluster2SituationMap(m_pdmHandler,
m_map->objectFactory(),
layernameAesCentral,
drawOrder++,
"ExplosionCluster2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtEffectCluster;
EffectCluster2SituationMap *sim2Map = static_cast<EffectCluster2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new EffectCluster2SituationMap(m_pdmHandler,
m_map->objectFactory(),
layernameAesCentral,
drawOrder++,
"EffectCluster2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
// ChargeEffect @ layernameAesCentral
{
if (m_pluginProvider->partitionId() > 0)
{
m_chargeEffects = QSharedPointer<ChargeEffectToMap>(new ChargeEffectToMap(m_map->objectFactory(),
layernameAesCentral,
drawOrder++,
"ChargeEffectToMap"));
if (!m_chargeEffects->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed (ChargeEffectToMap)";
else
DEBUG_LOG(m_logger) << LOGFUNCTION << " ChargeEffect2Map for ChargeEffect prepared";
}
}
if (m_map->mode() == Mode::Mode_3D)
{
INFO_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral";
initRenderer3D_AesCentral_Booby(layernameAesCentral, {AreaEffectSimulation::AesType_def::AtBoobyTrap, AreaEffectSimulation::AesType_def::AtOffRouteMine});
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtBoobyTrap;
BoobyTrap2SituationMap *sim2Map = static_cast<BoobyTrap2SituationMap *>(m_aes2MapCont.value(aesType));
if (!sim2Map)
{
sim2Map = new BoobyTrap2SituationMap(m_map->objectFactory(),
layernameAesCentral,
"BoobyTrap2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger)<<LOGFUNCTION <<" init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtOffRouteMine;
OffRoute2SituationMap *sim2Map = static_cast<OffRoute2SituationMap *>(m_aes2MapCont.value(aesType));
if (!sim2Map)
{
sim2Map = new OffRoute2SituationMap(m_map->objectFactory(),
layernameAesCentral,
"OffRoute2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger)<<LOGFUNCTION <<" init failed";
}
}
//
// : AESCentral
//
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtDangerArea;
DangerArea2SituationMap *sim2Map = static_cast<DangerArea2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new DangerArea2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"DangerArea2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtFunctionalArea;
FunctionalArea2SituationMap *sim2Map = static_cast<FunctionalArea2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new FunctionalArea2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"FunctionalArea2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtBorderline;
Borderline2SituationMap *sim2Map = static_cast<Borderline2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new Borderline2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"Borderline2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtReconArea;
ReconArea2SituationMap *sim2Map = static_cast<ReconArea2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new ReconArea2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"ReconArea2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
//
// AHTC -> DusSingleMine2SituationMap
//
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtDusSingleMine;
DusSingleMine2SituationMap *sim2Map = static_cast<DusSingleMine2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new DusSingleMine2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"DusSingleMine2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
//
// AHTC -> DusSingleMine2SituationMap
//
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtGasPipe;
GasPipe2SituationMap *sim2Map = static_cast<GasPipe2SituationMap *>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new GasPipe2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"GasPipe2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
//
// AtAirSupport
//
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtAirSupportImpact;
AirSupportImpact2SituationMap *sim2Map = static_cast<AirSupportImpact2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new AirSupportImpact2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
"AirSupportImpact2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
// AtTechnicalArea (Mout/Wls Area, ...)
{
AreaEffectSimulation::AesType::inner_enum aesType = AreaEffectSimulation::AesType_def::AtTechnicalArea;
TechnicalArea2SituationMap *sim2Map = static_cast<TechnicalArea2SituationMap*>(m_aes2MapCont.value(aesType));
if (! sim2Map)
{
sim2Map = new TechnicalArea2SituationMap(m_map->objectFactory(),
QLatin1String("TechnicalAreas"), // AES -> TechnicalAreas
"TechnicalArea2SituationMap");
m_aes2MapCont[static_cast<int>(aesType)] = sim2Map;
}
if (!sim2Map->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
} // AES:
// ALM:
// if (m_pluginProvider->partitionId() > 0) // not for adminSession
// {
// m_alarms = QSharedPointer<AlarmToMap>(new AlarmToMap(m_map->objectFactory(),
// QStringLiteral("JumpPoints"), // Check!!!
// 0,
// "AlarmToMap"));
// if (!m_alarms->init(m_pluginProvider))
// ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// // create JumpPoint for EmergencyCall:
// connect(m_alarms.data(), &AlarmToMap::alarmUpdated,
// this, [this](const QString &name, const Point3D &geoPosition) {
// m_map->addJumpPoint(name, geoPosition); // scale = -1 -> stay at current scale
// });
// }
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
const bool enableAlmEmergencyCall = ps->value(QStringLiteral("alm"),
QStringLiteral("enableEmergencyCalls")).toBool();
if (enableAlmEmergencyCall)
{
if (m_pluginProvider->partitionId() > 0)
{
// will createLogicalLayer "EmergencyCall" implicit:
const QString &emergencyCallLayername = m_map->layerFactory().emergencyCallLayer();
// create according adapter:
m_emergencyCalls = QSharedPointer<EmergencyCallToMap>(new EmergencyCallToMap(m_map->objectFactory(),
emergencyCallLayername,
0, "EmergencyCallToMap"));
if (!m_emergencyCalls->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed (EmergencyCallToMap)";
else
DEBUG_LOG(m_logger) << LOGFUNCTION << " EmergencyCallToMap for AlmEmergencyCalls prepared";
}
}
// ISM:
int drawOrder = 0;
// Building2SituationMap
m_buildings = QSharedPointer<Building2SituationMap>(new Building2SituationMap(m_map->objectFactory(),
QStringLiteral("Buildings"),
drawOrder++,
"Building2SituationMap"));
const bool enableDamageVisualization =
ps->value(QStringLiteral("SituationMap"), QStringLiteral("enableDamageVisualizationAtBuilding2Map")).toBool();
if (!m_buildings->init(m_pluginProvider, enableDamageVisualization))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// TrainingAreaSituationMap
const bool enableTrainingAreaBorder =
ps->value(QStringLiteral("SituationMap"), QStringLiteral("enableTrainingAreaBorder"), false).toBool();
if (enableTrainingAreaBorder)
{
m_trainingAreas = QSharedPointer<TrainingAreaToSituationMap>(new TrainingAreaToSituationMap(m_map->objectFactory(),
QStringLiteral("TechnicalAreas"),
drawOrder++,
"TrainingAreaToSituationMap"));
if (!m_trainingAreas->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
m_specialAreas = QSharedPointer<SpecialAreaToSituationMap>(new SpecialAreaToSituationMap(m_map->objectFactory(),
QStringLiteral("TechnicalAreas"),
drawOrder++,
"SpecialAreaToSituationMap"));
if (!m_specialAreas->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// MountingPointToMap
m_mountingPoints = QSharedPointer<MountingPointToMap>(new MountingPointToMap(m_map->objectFactory(),
QStringLiteral("MountingPoints"),
drawOrder++,
"MountingPointToMap"));
if (!m_mountingPoints->init(m_pluginProvider, resourceMode))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// SoundAreaToMap
m_soundAreas = QSharedPointer<SoundAreaToMap>(new SoundAreaToMap(m_map->objectFactory(),
QStringLiteral("MountingPoints"),
drawOrder++,
"SoundAreaToMap"));
if (!m_soundAreas->init(m_pluginProvider, resourceMode))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
if (!resourceMode) // these MSE do not show in ResourceManagement
{
// MSEPointsToMap
m_msePoints = QSharedPointer<MSEPointToMap>(new MSEPointToMap(m_map->objectFactory(),
QStringLiteral("MountingPoints"), // seperate layer?
drawOrder++,
"MsePointToMap"));
if (!m_msePoints->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// MSEBridgeToMap
m_mseBridges = QSharedPointer<MSEBridgeToMap>(new MSEBridgeToMap(m_map->objectFactory(),
QStringLiteral("TechnicalAreas"), // TechnicalAreas->Draped // seperate layer?
drawOrder++,
"MseBridgeToMap"));
if (!m_mseBridges->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
// TGT:
m_shootbackAreas = QSharedPointer<ShootbackAreaToSituationMap>(new ShootbackAreaToSituationMap(m_map->objectFactory(),
QLatin1String("TechnicalAreas"),
drawOrder++,
"ShootbackAreaToSituationMap"));
if (!m_shootbackAreas->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
const bool bIsOfTypeOrganizer =
(m_pluginProvider->operatorId() == 99) || // 99 == Organisator
(m_pluginProvider->operatorId() == 98); // 98 == Organizer
// GIM:
if (!bIsOfTypeOrganizer)
{
m_guezIeds = QSharedPointer<GuezIed2SituationMap>(new GuezIed2SituationMap(m_map->objectFactory(),
QLatin1String("IEDs"),
drawOrder++,
"GuezIed2SituationMap"));
if (!m_guezIeds->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
}
// GNA:
m_guezNasat9Liner = QSharedPointer<GuezNasat9Liner2SituationMap>(new GuezNasat9Liner2SituationMap(m_map->objectFactory(),
QLatin1String("AES"),
drawOrder++,
"NineLiner2SituationMap"));
if (!m_guezNasat9Liner->init(m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
//
// BuildingOwnership and Contamination (just for 3D)
//
if ((m_map->mode() == Mode::Mode_3D) && (m_buildingOwnership.isNull()))
m_buildingOwnership = QSharedPointer<BuildingOwnership>(new BuildingOwnership(drawOrder++, this));
if (m_buildingOwnership)
if (!m_buildingOwnership->init(m_map, m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
if ((m_map->mode() == Mode::Mode_3D) && (m_buildingContamination.isNull()))
m_buildingContamination = QSharedPointer<BuildingContamination>(new BuildingContamination(drawOrder++, this));
if (m_buildingContamination)
if (!m_buildingContamination->init(m_map, m_pluginProvider))
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
// finish setting up of all items:
//
// 1.
// signal-signal-connection: mapObjectChanged, mapObjectRemoved
// to update MapObjectSelectionWindow
//
// 2.
// connect to all xy2SituationMap using layer "AES".
// all of mapObject on this layer should be ordered by their DDS::effectStartTime.
// This value is accesable by startTime(UniqueMapId uniqueMapId)
const QList<Sim2SituationMapBase *> &sim2map = listOfSim2Map();
for (const auto &item : qAsConst(sim2map))
{
// 1) to update MapObjectSelectionWindow
connect(item, &Sim2SituationMapBase::mapObjectChanged,
this, &AdapterDds::mapObjectChanged, Qt::UniqueConnection);
connect(item, &Sim2SituationMapBase::mapObjectRemoved,
this, &AdapterDds::mapObjectRemoved, Qt::UniqueConnection);
// use this approach if using layer "AES":
if (item->layername().compare(QLatin1String("AES")) == 0)
{
// switch off default behaviour:
item->setAssignDrawOrder(false);
// switch on behaviour depending on XYChanged etc:
// 2) to update drawOrder of MapObject
connect(item, &Sim2SituationMapBase::mapObjectChanged,
this, &AdapterDds::onMapObjectChangedUpdateDrawOrder, Qt::UniqueConnection);
connect(item, &Sim2SituationMapBase::mapObjectRemoved,
this, &AdapterDds::onMapObjectRemoved, Qt::UniqueConnection);
}
} // for
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return true;
}
bool AdapterDds::initRenderer3D_AesExtrusion()
{
if (m_map->mode() != Mode::Mode_3D)
return false;
INFO_LOG(m_logger) << LOGFUNCTION << " START";
//
// showing the extrusion of aes objects via 3D cubes
// on TechnicalLayerType::GraphicsLayer_3D_Extrusion / "GraphicsLayer_3D_Extr"
// assignUniqueValueRendererAesCentral3DExtrusion
//
// partyData typically arives a little bit later:
QTimer::singleShot(1000, this, [this] () {
static const QString layernameAes(QStringLiteral("AES")); // AES TechnicalAreas Buildings
// changes:
connect(m_map, &Map::partysChangedDelayed, this, [this] () {
DEBUG_LOG(m_logger) << LOGFUNCTION << " partysChangedDelayed ********";
// FIRST
bool successAes = assignUniqueValueRendererAesCentral3DExtrusion(layernameAes);
if (successAes)
INFO_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral3DExtrusion okay" << " ('" << layernameAes << "')";
else
for (int i=0; i<5; ++i)
ERROR_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral3DExtrusion failed" << " ('" << layernameAes << "')";
// SECOND
// re-run some adapter to update colors:
if (isRunning())
{
const QList<Sim2SituationMapBase *> &aes2Map = listOfAes2Map();
for (const auto &item : qAsConst(aes2Map))
if (item)
item->run();
}
});
// initial:
bool successAes = assignUniqueValueRendererAesCentral3DExtrusion(layernameAes);
if (successAes)
INFO_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral3DExtrusion okay" << " ('" << layernameAes << "')";
else
for (int i=0; i<5; ++i)
ERROR_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral3DExtrusion failed" << " ('" << layernameAes << "')";
});
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool AdapterDds::initRenderer3D_AesCentral_Booby(const QString &layernameAesCentral, const QVector<int> &aesTypesForReRunIfPartyColorChanges)
{
if (m_map->mode() != Mode::Mode_3D)
return false;
//
// prepare CONE, SPERE etc:
//
INFO_LOG(m_logger) << LOGFUNCTION << " START, layernameAesCentral=" << layernameAesCentral;
connect(m_map, &Map::partysChangedDelayed, this, [this, layernameAesCentral, aesTypesForReRunIfPartyColorChanges] () {
DEBUG_LOG(m_logger) << LOGFUNCTION << " partysChangedDelayed ********";
// FIRST
bool successAesCentral = assignUniqueValueRendererAesCentral(layernameAesCentral);
if (successAesCentral)
DEBUG_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral okay" << " ('" << layernameAesCentral << "')";
else
for (int i=0; i<5; ++i)
ERROR_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral failed" << " ('" << layernameAesCentral << "')";
// SECOND
// re-run some adapter to update colors:
if (isRunning())
{
for (int aesTypeInt : qAsConst(aesTypesForReRunIfPartyColorChanges))
{
auto it = m_aes2MapCont.find(aesTypeInt);
if (it != m_aes2MapCont.end())
(*it)->run();
} // For
}
});
bool successAesCentral = assignUniqueValueRendererAesCentral(layernameAesCentral);
if (successAesCentral)
DEBUG_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral okay" << " ('" << layernameAesCentral << "')";
else
for (int i=0; i<5; ++i)
ERROR_LOG(m_logger) << LOGFUNCTION << " assignUniqueValueRendererAesCentral failed" << " ('" << layernameAesCentral << "')";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool AdapterDds::assignUniqueValueRendererAesCentral(const QString &layername)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, layername ='" << layername << "'" ;
QVector<LayerFactory::UniqueValueDataAesCentral::TYPE> typeVec;
typeVec << LayerFactory::UniqueValueDataAesCentral::TYPE::CONE;
typeVec << LayerFactory::UniqueValueDataAesCentral::TYPE::SPHERE;
const PartyIdToColorFunctor::ColorMap &colorMap = m_map->partyIdToColorFunctor().colorMap();
if (colorMap.isEmpty())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " colorMap is empty";
return false;
}
QVector<QColor> colVec;
{
colVec.reserve( (colorMap.size()*2) + 5);
colVec << Qt::black; // For areas without a color (they will use the color black)
for (const PartyIdToColorFunctor::PartyData &partyData : qAsConst(colorMap))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " partyName=" << partyData.m_name << "'" << " partyColor=" << partyData.m_color.name() << "'";
colVec << partyData.m_color;
// 27.01.2025 / GUEZE-3307: light not needed:
// colVec << partyData.m_lightColor;
}
}
QVector<float> radiuss;
// Norbert Thoden, 20.03.2024 :
// For BoobyTraps: we need:
// radiuss << 1 << 5 << 10; // (system: 5 and 10 meter, fallback: 1 meter)
// GUI (LTS_DEBUG) for BoobyTraps: {1,2,3,4,5}
// For OffRouteMine we need 1, 2 ... 10;
// // radiuss << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10;
// For ExplosionCluster (3DWirksim) and its charges:
// // radiuss << 15 << 25 << 40 << 60 << 125; // // see pdm.pdm_charge_type
// id=381, name= HE 120mm, bIsPoint 0, bIsVulcano 0, impactRadius4Debug = 15
// id=371, name= HE 155mm, bIsPoint 0, bIsVulcano 0, impactRadius4Debug = 25
// ??
// loop over a) typeVec (2) ; b) colVec (14*2+1) ; c) radiuss (15) == 870!! - Hopefully that is okay...
// : Norbert Thoden, 20.03.2024
// Norbert Thoden, 27.01.2025:
// GUEZE-3307:
// For BoobyTraps : we need: 10m, fallback: 10m
// For OffRouteMine: we need: 10m;
radiuss << 10;
// -> loop over a) typeVec (2) ; b) colVec (14*1+1) ; c) radiuss (1) == 30!! - Hopefully that is okay...
// : Norbert Thoden, 22.01.2025
bool success = false;
{
QVector<LayerFactory::UniqueValueDataAesCentral> uvCont;
for (const LayerFactory::UniqueValueDataAesCentral::TYPE &type : qAsConst(typeVec))
{
for (const QColor &col : qAsConst(colVec))
{
for (float radius : qAsConst(radiuss))
{
LayerFactory::UniqueValueDataAesCentral uvd;
QString singleVal;
// V100.8: order seems to be relevant. Keep alphabetical;
singleVal = QString(QStringLiteral("Impact_Color_%1")).arg(col.name()); // name is without alpha: col.name = #00ff00
uvd.values.append(singleVal);
singleVal = QString(QStringLiteral("Impact_Radius_%1")).arg(radius);
uvd.values.append(singleVal);
singleVal = QString(QStringLiteral("Impact_Type_%1")).arg(LayerFactory::toString(type));
uvd.values.append(singleVal);
uvd.type = type;
uvd.col = col;
uvd.col.setAlphaF(0.5);
uvd.radius = radius;
uvd.height = uvd.radius;
uvCont.append(uvd);
} // for
} // for
} // for
INFO_LOG(m_logger) << LOGFUNCTION
<< " typeVec.size() = " << typeVec.size()
<< " colVec.size() = " << colVec.size() << " (colorMap.size() = " << colorMap.size() << ")"
<< " radiuss.size() = " << radiuss.size()
<< " -> product = " << typeVec.size() * colVec.size() * radiuss.size()
<< " -> uvCont.size() = " << uvCont.size();
QStringList fieldnames;
// V100.8: order seems to be relevant. keep alphabetical
fieldnames.append(QString(QStringLiteral("IMPACT_COLOR")));
fieldnames.append(QString(QStringLiteral("IMPACT_RADIUS")));
fieldnames.append(QString(QStringLiteral("IMPACT_TYPE")));
success = m_map->layerFactory().assignUniqueValueRendererAesCentral(layername,
fieldnames,
uvCont);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END, layername ='" << layername << "'" ;
return success;
}
bool AdapterDds::assignUniqueValueRendererAesCentral3DExtrusion(const QString &layername)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, layername ='" << layername << "'" ;
QVector<QColor> colVec;
{
const PartyIdToColorFunctor::ColorMap &colorMap = m_map->partyIdToColorFunctor().colorMap();
if (colorMap.isEmpty())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " colorMap is empty";
return false;
}
colVec.reserve(colorMap.size());
for (const PartyIdToColorFunctor::PartyData &partyData : colorMap)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " partyName=" << partyData.m_name << "'" << " partyColor=" << partyData.m_color.name() << "'";
colVec << partyData.m_color
<< partyData.m_lightColor;
}
}
static double s_ALPHA_VALUE_F = 0.6;
QVector<LayerFactory::UniqueValueDataAesCentral> uvCont;
uvCont.reserve(colVec.size());
for (const QColor &col : qAsConst(colVec))
{
LayerFactory::UniqueValueDataAesCentral uvd;
uvd.label = col.name(); // more or less optional
uvd.values.append(col.name()); // concrete values
uvd.col = col;
uvd.col.setAlphaF(s_ALPHA_VALUE_F);
uvCont.append(uvd);
} // for
// additional colors: / Qt-builtIn
static QVector<QColor> addColors = {Qt::darkGray, Qt::gray, Qt::lightGray,
Qt::red, Qt::green, Qt::blue,
Qt::cyan, Qt::magenta, Qt::yellow,
Qt::darkRed, Qt::darkGreen, Qt::darkBlue,
Qt::darkCyan, Qt::darkMagenta, Qt::darkYellow};
uvCont.reserve(uvCont.size() + addColors.size());
for (const QColor &addColor : qAsConst(addColors))
{
LayerFactory::UniqueValueDataAesCentral uvd;
uvd.label = addColor.name(); // more or less optional
uvd.values.append(addColor.name()); // concrete values
uvd.col = addColor;
uvd.col.setAlphaF(s_ALPHA_VALUE_F);
uvCont.append(uvd);
}
QStringList fieldnames;
// V100.8: order seems to be relevant. Keep alphabetical
fieldnames.append(QString(QStringLiteral("Extrusion_Color")));
bool success = m_map->layerFactory().assignUniqueValueRendererAesCentral3DExtrusion(layername,
fieldnames,
uvCont);
TRACE_LOG(m_logger) << LOGFUNCTION << " END, layername ='" << layername << "'"
<< " success = " << success;
return success;
}
bool AdapterDds::run()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (m_isRunning)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " already running" ;
return false;
}
bool success = true;
const QList<Sim2SituationMapBase *> &sim2Map = listOfSim2Map();
for (Sim2SituationMapBase *item : qAsConst(sim2Map))
{
success = item->run() && success;
}
//
// BuildingOwnership
//
if (m_buildingOwnership)
{
// the buildingOwnership is most likely less relevant than AES or similar.
// so start this with a short delay:
QTimer::singleShot(1000, this, [this]()
{
m_buildingOwnership->run();
});
}
//
// BuildingContamination
//
if (m_buildingContamination)
{
// the BuildingContamination is most likely less relevant than AES or similar.
// so start this with a short delay:
QTimer::singleShot(1000, this, [this]()
{
m_buildingContamination->run();
});
}
//
// HitlineInfo2SituationMap
//
// is moved to listOfSim2Map...
// if (m_hitlineInfo2SituationMap)
// m_hitlineInfo2SituationMap->run();
//
// BuildingHitlineInfo2SituationMap
//
// is moved to listOfSim2Map...
// if (m_bldHitlineInfo2SituationMap)
// m_bldHitlineInfo2SituationMap->run();
m_isRunning = success;
INFO_LOG(m_logger) << LOGFUNCTION << " connect to SymbolDictionary::changed" ;
connect(&m_map->symbolDictionary(), &AdvancedSymbology::SymbolDictionary::changed,
this, &AdapterDds::startChangedDelayTimer, Qt::UniqueConnection);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return success;
}
bool AdapterDds::isRunning() const
{
return m_isRunning;
}
bool AdapterDds::stop()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" ;
if (m_pluginProvider && !m_pluginProvider->isSessionValid())
{
m_isRunning = false;
DEBUG_LOG(m_logger) << LOGFUNCTION << " no session anymore: ignore 'stop' -> return";
return false;
}
const QList<Sim2SituationMapBase *> &sim2Map = listOfSim2Map();
for (Sim2SituationMapBase *item : qAsConst(sim2Map))
{
item->stop();
}
//
// Alarm
//
// Emergency call
if (m_emergencyCalls)
m_emergencyCalls->stop();
// Charge Effect
if (m_chargeEffects)
m_chargeEffects->stop();
//
// BuildingOwnership
//
if (m_buildingOwnership)
m_buildingOwnership->stop();
//
// BuildingContamination
//
if (m_buildingContamination)
m_buildingContamination->stop();
//
// Hitline2SituationMap
//
if (m_hitlineInfo2SituationMap)
m_hitlineInfo2SituationMap->stop();
//
// BuildingHitlineInfo2SituationMap
//
if (m_bldHitlineInfo2SituationMap)
m_bldHitlineInfo2SituationMap->stop();
m_isRunning = false;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
void AdapterDds::clearObjects()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
const QList<Sim2SituationMapBase *> &sim2Map = listOfSim2Map();
for (Sim2SituationMapBase *item : qAsConst(sim2Map))
{
item->clearObjects();
}
//
// Alarm
//
// Emergency call
if (m_emergencyCalls)
m_emergencyCalls->clearObjects();
// Charge Effect call
if (m_chargeEffects)
m_chargeEffects->clearObjects();
//
// BuildingOwnership
//
if (m_buildingOwnership)
m_buildingOwnership->clearObjects();
//
// BuildingContamination
//
if (m_buildingContamination)
m_buildingContamination->clearObjects();
//
// Hitline2SituationMap
//
if (m_hitlineInfo2SituationMap)
m_hitlineInfo2SituationMap->clearObjects();
//
// BuildingHitlineInfo2SituationMap
//
if (m_bldHitlineInfo2SituationMap)
m_bldHitlineInfo2SituationMap->clearObjects();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
ResourceManagerMode AdapterDds::resourceManagerMode() const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!m_mountingPoints)
return ResourceManagerMode::Undefined;
ResourceManagerMode rmm = m_mountingPoints->resourceManagerMode();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return rmm;
}
bool AdapterDds::setResourceManagerMode(ResourceManagerMode rmm)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!m_mountingPoints)
return false;
bool success = m_mountingPoints->setResourceManagerMode(rmm);
// update icons...
emit resourceManagerModeChanged(m_mountingPoints->resourceManagerMode());
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return success;
}
bool AdapterDds::showExpiredEmergencyCalls(bool bShowExpired)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!m_emergencyCalls)
return false;
m_emergencyCalls->showExpired(bShowExpired);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool AdapterDds::uniqueMapId2SimId(UniqueMapId uniqueMapIdIn, int32_t &simIdOut)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " uniqueMapId=" << uniqueMapIdIn;
if (!SituationMap::isUniqueMapIdValid(uniqueMapIdIn))
return false;
const QList<Sim2SituationMapBase *> &sim2Map = listOfSim2Map();
for (const auto &item : qAsConst(sim2Map))
{
simIdOut = -1;
if (item->uniqueMapId2SimId(uniqueMapIdIn, simIdOut))
return true;
}
return false;
}
bool AdapterDds::unifiedMapObjectData(UniqueMapId uniqueMapIdIn, UnifiedMapObjectData &umodOut) const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " uniqueMapId=" << uniqueMapIdIn;
if (!SituationMap::isUniqueMapIdValid(uniqueMapIdIn))
return false;
const QList<Sim2SituationMapBase *> &sim2Map = listOfSim2Map();
for (const auto &item : qAsConst(sim2Map))
{
if (item->unifiedMapObjectData(uniqueMapIdIn, umodOut))
return true;
}
return false;
}
UniqueMapId AdapterDds::simId2UniqueMapIdParticipant(int32_t simId) const
{
if (!m_particpants)
return SituationMap::INVALID_MAP_ID;
return m_particpants->simId2UniqueMapId(simId);
}
RefPointer<Participant> AdapterDds::simId2Participant(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId ;
UniqueMapId mapId = simId2UniqueMapIdParticipant(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<Participant>();
RefPointer<Participant> mapObj = m_map->objectFactory().get<Participant>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdAes(int32_t simId) const
{
for (const auto &item : qAsConst(m_aes2MapCont))
{
UniqueMapId uniqueMapId = item->simId2UniqueMapId(simId);
if (isUniqueMapIdValid(uniqueMapId))
return uniqueMapId;
}
return INVALID_MAP_ID;
}
RefPointer<AbstractMapObject> AdapterDds::simId2Aes(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId ;
UniqueMapId mapId = simId2UniqueMapIdAes(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<AbstractMapObject>();
RefPointer<AbstractMapObject> mapObj = m_map->objectFactory().get(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdBuilding(int32_t simId) const
{
if (!m_buildings)
return SituationMap::INVALID_MAP_ID;
return m_buildings->simId2UniqueMapId(simId);
}
RefPointer<BuildingOutline> AdapterDds::simId2Building(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdBuilding(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<BuildingOutline>();
RefPointer<BuildingOutline> mapObj = m_map->objectFactory().get<BuildingOutline>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdBridge(int32_t simId) const
{
if (!m_mseBridges)
return SituationMap::INVALID_MAP_ID;
return m_mseBridges->simId2UniqueMapId(simId);
}
RefPointer<BuildingOutline> AdapterDds::simId2Bridge(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdBridge(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<BuildingOutline>();
RefPointer<BuildingOutline> mapObj = m_map->objectFactory().get<BuildingOutline>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdMountingPoint(int32_t simId) const
{
if (!m_mountingPoints)
return SituationMap::INVALID_MAP_ID;
return m_mountingPoints->simId2UniqueMapId(simId);
}
RefPointer<GeoImage> AdapterDds::simId2MountingPoint(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdMountingPoint(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<GeoImage>();
RefPointer<GeoImage> mapObj = m_map->objectFactory().get<GeoImage>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdGuezIed(int32_t simId) const
{
if (!m_guezIeds)
return SituationMap::INVALID_MAP_ID;
return m_guezIeds->simId2UniqueMapId(simId);
}
RefPointer<Participant> AdapterDds::simId2GuezIed(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdGuezIed(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<Participant>();
RefPointer<Participant> mapObj = m_map->objectFactory().get<Participant>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdChargeEffect(int32_t simId) const
{
if (!m_chargeEffects)
return SituationMap::INVALID_MAP_ID;
return m_chargeEffects->simId2UniqueMapId(simId);
}
RefPointer<SingleFire> AdapterDds::simId2ChargeEffect(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdChargeEffect(simId);
if (!isUniqueMapIdValid(mapId))
return RefPointer<SingleFire>();
RefPointer<SingleFire> mapObj = m_map->objectFactory().get<SingleFire>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdTrainingArea(int32_t simId) const
{
if (!m_trainingAreas)
return SituationMap::INVALID_MAP_ID;
return m_trainingAreas->simId2UniqueMapId(simId);
}
RefPointer<Polygon> AdapterDds::simId2TrainingArea(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdTrainingArea(simId);
if (!isUniqueMapIdValid(mapId))
return {};
using MAP_T = TrainingAreaToSituationMap::MAP_T; // Polygon
RefPointer<MAP_T> mapObj = m_map->objectFactory().get<MAP_T>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdSpecialArea(int32_t simId) const
{
if (!m_specialAreas)
return SituationMap::INVALID_MAP_ID;
return m_specialAreas->simId2UniqueMapId(simId);
}
RefPointer<Polygon> AdapterDds::simId2SpecialArea(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdSpecialArea(simId);
if (!isUniqueMapIdValid(mapId))
return {};
using MAP_T = SpecialAreaToSituationMap::MAP_T; // Polygon
RefPointer<MAP_T> mapObj = m_map->objectFactory().get<MAP_T>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapIdShootbackArea(int32_t simId) const
{
if (!m_shootbackAreas)
return SituationMap::INVALID_MAP_ID;
return m_shootbackAreas->simId2UniqueMapId(simId);
}
RefPointer<Polygon> AdapterDds::simId2ShootbackArea(int32_t simId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, simId=" << simId;
UniqueMapId mapId = simId2UniqueMapIdShootbackArea(simId);
if (!isUniqueMapIdValid(mapId))
return {};
using MAP_T = ShootbackAreaToSituationMap::MAP_T; // Polygon
RefPointer<MAP_T> mapObj = m_map->objectFactory().get<MAP_T>(mapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
UniqueMapId AdapterDds::simId2UniqueMapId(MapObjectType mot, int32_t simId) const
{
UniqueMapId uniqueMapId = INVALID_MAP_ID;
switch (mot)
{
case MapObjectType::MOT_Participant:
uniqueMapId = simId2UniqueMapIdParticipant(simId);
break;
case MapObjectType::MOT_TrainingArea:
uniqueMapId = simId2UniqueMapIdTrainingArea(simId);
break;
case MapObjectType::MOT_ShootbackArea:
uniqueMapId = simId2UniqueMapIdShootbackArea(simId);
break;
case MapObjectType::MOT_Building:
uniqueMapId = simId2UniqueMapIdBuilding(simId);
break;
case MapObjectType::MOT_MountingPoint:
uniqueMapId = simId2UniqueMapIdMountingPoint(simId);
break;
case MapObjectType::MOT_Aes:
case MapObjectType::MOT_GuezIed:
{
ERROR_LOG(m_logger) << " not supported yet!!!";
Q_FALLTHROUGH();
}
default:
break;
} //switch
return uniqueMapId;
}
QVector<UniqueMapId> AdapterDds::simIds2UniqueMapIds(MapObjectType mot, QVector<int32_t> simIds) const
{
QVector<UniqueMapId> uniqueMapIds;
uniqueMapIds.reserve(simIds.size());
using namespace std::placeholders;
std::function<UniqueMapId(int32_t)> simToMap = nullptr;
switch (mot)
{
case MapObjectType::MOT_Participant:
simToMap = std::bind(&AdapterDds::simId2UniqueMapIdParticipant, this, _1);
break;
case MapObjectType::MOT_TrainingArea:
simToMap = std::bind(&AdapterDds::simId2UniqueMapIdTrainingArea, this, _1);
break;
case MapObjectType::MOT_ShootbackArea:
simToMap = std::bind(&AdapterDds::simId2UniqueMapIdShootbackArea, this, _1);
break;
case MapObjectType::MOT_Building:
simToMap = std::bind(&AdapterDds::simId2UniqueMapIdBuilding, this, _1);
break;
case MapObjectType::MOT_Bridge:
simToMap = std::bind(&AdapterDds::simId2UniqueMapIdBridge, this, _1);
break;
case MapObjectType::MOT_Aes:
case MapObjectType::MOT_GuezIed:
{
ERROR_LOG(m_logger) << " not supported yet!!!";
Q_FALLTHROUGH();
}
default:
break;
} //switch
for (auto simId : qAsConst(simIds))
{
UniqueMapId uniqueMapId = simToMap(simId);
if (!isUniqueMapIdValid(uniqueMapId))
continue;
uniqueMapIds.push_back(uniqueMapId);
} // for
return uniqueMapIds;
}
RefPointer<AbstractMapObject> AdapterDds::simId2MapObject(MapObjectType mot, int32_t simId)
{
UniqueMapId uniqueMapId = simId2UniqueMapId(mot, simId);
if (!isUniqueMapIdValid(uniqueMapId))
return {};
RefPointer<AbstractMapObject> mapObj = m_map->objectFactory().get(uniqueMapId);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" ;
return mapObj;
}
Sim2SituationMapBase *AdapterDds::situationMapBase(MapObjectType mot) const
{
Sim2SituationMapBase *smBase = nullptr;
switch (mot)
{
case MapObjectType::MOT_Participant:
smBase = m_particpants.data();
break;
case MapObjectType::MOT_TrainingArea:
smBase = m_trainingAreas.data();
break;
case MapObjectType::MOT_SpecialArea:
smBase = m_specialAreas.data();
break;
case MapObjectType::MOT_ShootbackArea:
smBase = m_shootbackAreas.data();
break;
case MapObjectType::MOT_Aes:
case MapObjectType::MOT_Building:
case MapObjectType::MOT_GuezIed:
{
ERROR_LOG(m_logger) << " not supported yet!!!";
Q_FALLTHROUGH();
}
default:
break;
} //switch
return smBase;
}
bool AdapterDds::setMapObjectSelected(MapObjectType mot, const QVector<int> &entityIds, bool selection)
{
Sim2SituationMapBase *smBase = situationMapBase(mot);
if (!smBase)
return false;
const QVector<UniqueMapId> &uniqueMapIds = simIds2UniqueMapIds(mot, entityIds);
auto cb = [uniqueMapIds, selection](RefPointer<AbstractMapObject> &abstractMapObj)
{
// if (mapObj.valid()) return; // already checked at iterateObjects<MAP_T> :-)
if (!uniqueMapIds.contains(abstractMapObj->uniqueMapId()))
return; // not requested
if (abstractMapObj->selected() == selection)
return; // noting to do
abstractMapObj->setSelected(selection);
abstractMapObj->updateView();
};
smBase->iterateObjects<AbstractMapObject>(cb);
return true;
}
bool AdapterDds::clearMapObjectSelection(MapObjectType mot)
{
Sim2SituationMapBase *smBase = situationMapBase(mot);
if (!smBase)
return false;
auto cb = [](RefPointer<AbstractMapObject> &abstractMapObj)
{
// if (mapObj.valid()) return; // already checked at iterateObjects<MAP_T> :-)
if (!abstractMapObj->selected())
return; // noting to do
abstractMapObj->setSelected(false);
abstractMapObj->updateView();
};
smBase->iterateObjects<AbstractMapObject>(cb);
return true;
}
bool AdapterDds::isBuildingOwnershipSupported() const
{
return m_buildingOwnership;
}
bool AdapterDds::isBuildingOwnershipVisible() const
{
if (!m_buildingOwnership)
return false;
return m_buildingOwnership->isVisible();
}
bool AdapterDds::setBuildingOwnershipVisible(bool visible)
{
if (!m_buildingOwnership)
return false;
if(visible && isBuildingContaminationVisible())
m_buildingContamination->setVisible(false);
return m_buildingOwnership->setVisible(visible);
}
bool AdapterDds::isBuildingContaminationSupported() const
{
return m_buildingContamination;
}
bool AdapterDds::isBuildingContaminationVisible() const
{
if (!m_buildingContamination)
return false;
return m_buildingContamination->isVisible();
}
bool AdapterDds::setBuildingContaminationVisible(bool visible)
{
if (!m_buildingContamination)
return false;
if(visible && isBuildingOwnershipVisible())
m_buildingOwnership->setVisible(false);
return m_buildingContamination->setVisible(visible);
}
bool AdapterDds::enableFireEventFlashing(bool enable)
{
if (!m_particpants)
return false;
return m_particpants->enableFireEventFlashing(enable);
}
bool AdapterDds::isFireEventFlashingEnabled() const
{
if (!m_particpants)
return false;
return m_particpants->isFireEventFlashingEnabled();
}
bool AdapterDds::isOwnPositionVisible() const
{
if(!m_map)
return false;
return m_map->locationDisplay().isStarted();
}
bool AdapterDds::setOwnPositionVisible(bool enable)
{
m_isShowOwnPosition = enable;
if(!m_map)
return false;
if(enable)
m_map->locationDisplay().start();
else
m_map->locationDisplay().stop();
return true;
}
void AdapterDds::onSymbolDictionaryChanged()
{
INFO_LOG(m_logger) << LOGFUNCTION << " START, workspaceId" << m_pluginProvider->workspaceId();
if (m_particpants)
m_particpants->reRenderObjects();
if (m_guezIeds)
m_guezIeds->reRenderObjects();
// 'FunctionalArea2SituationMap' -> process all aes2Map:
const QList<Sim2SituationMapBase *> &aes2Map = listOfAes2Map();
for (const auto &item : qAsConst(aes2Map))
item->reRenderObjects();
// not relevant:
// m_hitlineInfo2SituationMap
// m_bldHitlineInfo2SituationMap
// m_buildingOwnership
// m_guezNasat9Liner
INFO_LOG(m_logger) << LOGFUNCTION << " END, workspaceId" << m_pluginProvider->workspaceId();
}
//-----------------------------------------------------------------------------
bool AdapterDds::onMapObjectClicked(const RefPointer<AbstractMapObject> &mapObject)
{
if (!mapObject)
return false;
return onMapObjectClicked(mapObject->uniqueMapId());
}
bool AdapterDds::onMapObjectClicked(UniqueMapId uniqueMapId)
{
if (!SituationMap::isUniqueMapIdValid(uniqueMapId))
return false;
return onMapObjectsClicked(QVector<UniqueMapId>() << uniqueMapId);
}
bool AdapterDds::onMapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds)
{
// participant, buildings, mountingPoints ...
const QList<Sim2SituationMapBase *> &sim2Map = listOfSim2Map();
for (const auto &item : qAsConst(sim2Map))
{
item->mapObjectsClicked(uniqueMapIds);
}
return true;
}
void AdapterDds::onMapObjectChangedUpdateDrawOrder(UniqueMapId uniqueMapId)
{
//
// update own management (m_startTimeMap):
//
qint64 startTime = -1;
for (auto it = m_aes2MapCont.cbegin(); it != m_aes2MapCont.cend(); ++it)
{
startTime = it.value()->startTime(uniqueMapId);
if (startTime > 0)
break;
}
if (startTime < 0)
return;
m_startTimeMap[uniqueMapId] = startTime;
//
// create drawOrder by startTime and transfer to MapObjects:
//
// first, swap key and value:
QMultiMap<qint64, UniqueMapId> startTime2UniqueMapIdMap;
for (auto it = m_startTimeMap.cbegin(); it != m_startTimeMap.cend(); ++it)
startTime2UniqueMapIdMap.insert(it.value(), it.key());
// second, assign drawOrder based on chronological order:
int drawOrderCounter = 0;
const ObjectFactory &objFac = m_map->objectFactory();
for (auto it = startTime2UniqueMapIdMap.cbegin(); it != startTime2UniqueMapIdMap.cend(); ++it)
{
const UniqueMapId curUniqueMapId = it.value();
RefPointer<AbstractMapObject> mapObj = objFac.get<AbstractMapObject>(curUniqueMapId);
if (!mapObj)
{
WARNING_LOG(m_logger) << LOGFUNCTION << " not found in objFac"
<< " curUniqueMapId = " << curUniqueMapId;
return;
}
mapObj->setDrawOrder(++drawOrderCounter);
if (!mapObj->updateView())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << mapObj->debugInfo() << "'"
<< " updateView failed";
}
INFO_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << mapObj->debugInfo() << "'"
<< " set DrawOder to: " << drawOrderCounter;
} // while
}
void AdapterDds::onMapObjectRemoved(UniqueMapId uniqueMapId)
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapId=" << uniqueMapId;
m_startTimeMap.remove(uniqueMapId);
}
/*!
* \brief AdapterDds::onParticipantOwnPositionChanged
* \param newPos
* \author Niklas Schmidt
* \details The own position of the ComMaster Tablet will be shown as a blue dot
*/
void AdapterDds::onParticipantOwnPositionChanged(const Point3D &newPos, int64_t sampleTime)
{
DEBUG_LOG(m_logger) << "Own Position Changed";
if(!m_map)
return;
if(!m_map->locationDisplay().isStarted() && m_isShowOwnPosition == true)
{
m_map->locationDisplay().start();
}
if(sampleTime > QDateTime::currentMSecsSinceEpoch() - 30000)
{
m_map->locationDisplay().setCurrentLocation(newPos); // NOTE: The other params arent available currently
startOwnPositionOutdatedTimer();
}
}
void AdapterDds::startChangedDelayTimer()
{
if (!m_map || !m_map->symbolDictionary().isLoaded())
return;
// connect to SymbolDictionary::changed to trigger reRendering of (XML) symbols.
// (SymbolDictionary::changedDelayed does not fit: It´s emitted 500ms after
// mapReadyAndDictionaryLoaded in normal startup WITHOUT changes...)
if (!m_changedDelayTimer)
{
m_changedDelayTimer = new QTimer(this);
m_changedDelayTimer->setSingleShot(true);
m_changedDelayTimer->setInterval(500);
connect(m_changedDelayTimer, &QTimer::timeout, this, &AdapterDds::onSymbolDictionaryChanged);
}
m_changedDelayTimer->start(); // is restart timer if already running
}
void AdapterDds::startOwnPositionOutdatedTimer()
{
if (!m_ownPositionOutdatedTimer)
{
m_ownPositionOutdatedTimer = new QTimer(this);
m_ownPositionOutdatedTimer->setSingleShot(true);
m_ownPositionOutdatedTimer->setInterval(10000);
connect(m_ownPositionOutdatedTimer, &QTimer::timeout, this, [this](){
if(m_map)
m_map->locationDisplay().setOutdated(true);
});
}
m_ownPositionOutdatedTimer->start(); // is restart timer if already running
}
//-----------------------------------------------------------------------------
QList<Sim2SituationMapBase *> AdapterDds::listOfSim2Map() const
{
QList<Sim2SituationMapBase *> cont;
// Participants:
if (m_particpants)
cont += m_particpants.data();
// AES:
cont += m_aes2MapCont.values();
// GIM
if (m_guezIeds)
cont += m_guezIeds.data();
// GNA
if (m_guezNasat9Liner)
cont += m_guezNasat9Liner.data();
// ISM:
if (m_mountingPoints)
cont.append(m_mountingPoints.data());
if (m_soundAreas)
cont.append(m_soundAreas.data());
if (m_buildings)
cont.append(m_buildings.data());
if (m_msePoints)
cont.append(m_msePoints.data());
if (m_mseBridges)
cont.append(m_mseBridges.data());
// ASM
if (m_trainingAreas)
cont.append(m_trainingAreas.data());
// ISM
if (m_specialAreas)
cont.append(m_specialAreas.data());
// ignore for now:
// // Alarm
if (m_emergencyCalls)
cont.append(m_emergencyCalls.data());
if (m_chargeEffects)
cont.append(m_chargeEffects.data());
// ignore for now:
// // BuildingOwnership ->
// if (m_buildingOwnership)
// cont.append(m_buildingOwnership.data());
// : ignore
if (m_hitlineInfo2SituationMap)
cont.append(m_hitlineInfo2SituationMap.data());
if (m_bldHitlineInfo2SituationMap)
cont.append(m_bldHitlineInfo2SituationMap.data());
if (m_shootbackAreas)
cont.append(m_shootbackAreas.data());
return cont;
}
QList<Sim2SituationMapBase *> AdapterDds::listOfAes2Map() const
{
return m_aes2MapCont.values();
}
}