Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/MapObjectsImpl/mine_field_impl.cpp
T
2026-08-13 18:33:10 +02:00

382 lines
12 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Interface-Implementation of MineField
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "mine_field_impl.h"
#include <MapImpl/map_impl.h>
#include "basic_path_object_impl.h"
#include <GraphicalObjects/stub_graphical_object.h>
#include "mine_impl.h"
#include <Symbology/sidc_codec.h>
// ESRI
// Qt
#include <QMap>
namespace SituationMap
{
// to get access to 'init'
class MineFieldLocalBasicPathObject final : public BasicPathObjectImpl
{
public:
using BasicPathObjectImpl::BasicPathObjectImpl;
using BasicPathObjectImpl::init;
using BasicPathObjectImpl::setUniqueId;
};
//-----------------------------------------------------------------------------
class MineFieldImpl::Private
{
public:
Private() = default;
~Private() = default;
// ESRI data:
Esri::ArcGISRuntime::GraphicsOverlay *m_graphicsLayer = nullptr;
// Own data:
MapImpl *m_mapImpl = nullptr;
QString m_logicalLayer;
QString m_debugInfo; // will be appended by consecutive number
UniqueMapId m_uniqueMapId = INVALID_MAP_ID;
QMap<int, bool> m_visibilityMines;
QMap<int, QSharedPointer<BasicPathObjectImpl> > m_cont;
using MAP_IT_T = QMapIterator<int, QSharedPointer<BasicPathObjectImpl>>;
// int m_drawOrder = 0;
bool hasPathObject(int key) const { return m_cont.contains(key); }
QList<int> keysInUse() const { return m_cont.keys(); }
void remove(int key) { m_cont.remove(key); }
void clear() { m_cont.clear(); }
QSharedPointer<BasicPathObjectImpl> getPathObject(int key)
{
auto ret = m_cont.value(key);
if (ret.isNull())
{
QString debugInfo = QStringLiteral("%1#MineFieldSeg(%2)").arg(m_debugInfo).arg(key);
MineFieldLocalBasicPathObject *temp = new MineFieldLocalBasicPathObject(debugInfo);
bool success = temp->init(m_mapImpl, m_logicalLayer, GraphicalObjectPathType::Polygon);
temp->setUniqueId(m_uniqueMapId);
temp->setFillStyle(FillStyle(FillPattern::Null)); // no fill by default
if (success)
{
ret = QSharedPointer<BasicPathObjectImpl>(static_cast<BasicPathObjectImpl *>(temp));
m_cont.insert(key, ret);
}
else
temp->removeMySelf();
}
return ret;
}
}; // class MineFieldImpl::Private
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// class MineFieldImpl
//-----------------------------------------------------------------------------
MineFieldImpl::MineFieldImpl(const QString &debugInfo)
: MineField() // Interface
, BaseClass(debugInfo) // Implementation
, d(new Private)
, m_logger(getLogger("MineFieldImpl"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_visibilityMines[static_cast<int>(MineState::Activated)] = true;
d->m_visibilityMines[static_cast<int>(MineState::DeActivated)] = true;
m_lineColorFromParty = false;
m_fillColorAlpha = 200;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
MineFieldImpl::~MineFieldImpl()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
delete d;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void MineFieldImpl::setUniqueId(const UniqueMapId &uniqueId)
{
BaseClass::setUniqueId(uniqueId);
d->m_uniqueMapId = m_uniqueMapId;
}
PositionCont MineFieldImpl::segment(int key) const
{
if (d->hasPathObject(key))
return d->getPathObject(key)->positions();
else
return PositionCont();
}
void MineFieldImpl::setSegment(int key, const PositionCont &positions)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " key=" << key
<< " positions.size=" << positions.size();
QSharedPointer<BasicPathObjectImpl> pathObj = d->getPathObject(key);
if (pathObj)
pathObj->setPositions(positions);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void MineFieldImpl::removeSegment(int key)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->remove(key);
}
void MineFieldImpl::removeSegments()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->clear();
}
QList<int> MineFieldImpl::keysInUse() const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->keysInUse();
}
void MineFieldImpl::setPositionsMine(MineField::MineState mineState, const PositionCont &posCont)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " mineState=" << static_cast<int>(mineState)
<< " posCont.size()=" << posCont.size();
IndicationContainer &mines = this->rIndicationContainer();
mines.setDebugInfo(m_debugInfo);
mines.setPositions(static_cast<int>(mineState), posCont);
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
<< " mineState=" << static_cast<int>(mineState)
<< " posCont.size()=" << posCont.size();
}
bool MineFieldImpl::mineVisibility(MineField::MineState mineState) const
{
return d->m_visibilityMines[static_cast<int>(mineState)];
}
void MineFieldImpl::setMineVisibility(MineField::MineState mineState, bool visible)
{
d->m_visibilityMines[static_cast<int>(mineState)] = visible;
}
bool MineFieldImpl::updateViewImpl()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " visibility=" << m_visibility
<< " visiTechn=" << m_visibilityTechnical
<< " visiTact=" << m_visibilityTactical
<< " mineVisibility(MineState::Activated)=" << this->mineVisibility(MineState::Activated)
<< " mineVisibility(MineState::DeActivated)=" << this->mineVisibility(MineState::DeActivated)
<< " m_positions->positions().count()=" << m_positions.positions().count()
<< " m_mainGraphicalObject->positions().count()=" << m_mainGraphicalObject->positions().count()
<< " m_mainGraphicalObject->fillStyle().fillPattern()=" << (int)m_mainGraphicalObject->fillStyle().fillPattern();
// indication :
if (nullptr == m_mainGraphicalObject)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_mainGraphicalObject";
return false;
}
if (m_indicationCont)
{
const QColor &col = m_mainGraphicalObject->lineStyle().lineColor();
const QList<int> idxInUse = m_indicationCont->getIndicationIndexList();
for (int idx : idxInUse)
{
// handle image on if not already set:
if (m_indicationCont->image(idx).isNull())
{
bool filled = (idx == static_cast<int>(MineState::DeActivated));
const QImage &img = MineImpl::renderMineSymbol(col, 20, filled); // filled
m_indicationCont->setImage(idx, img);
}
m_indicationCont->setSelected(idx, m_selected);
m_indicationCont->setPickable(idx, m_pickable);
}
}
// : indication
// m_mainGraphicalObject stores the outline/'bounding box' (techn and tact)
// Those geometry should never be visible.
// The text of should be visible.
this->setVisibilityOfGeometry(false);
bool success = BaseClass::updateViewImpl();
if (!success)
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed";
// segment :
Private::MAP_IT_T mapIt(d->m_cont);
while (mapIt.hasNext())
{
mapIt.next();
QSharedPointer<BasicPathObjectImpl> pathObj = mapIt.value();
if (pathObj)
{
int idx = mapIt.key();
// pathObj->setDebugInfo(m_mainGraphicalObject->debugInfo()); // will overwrite complete string -> skip
pathObj->setLineStyle(m_mainGraphicalObject->lineStyle());
if (idx >= 0)
pathObj->setFillStyle(m_mainGraphicalObject->fillStyle());
pathObj->setVisibility(m_visibility);
pathObj->setVisibility(ObjectAppearance::Technical, m_visibilityTechnical);
// Do not Transfer symbol. Only m_mainGraphicalObject uses ObjectAppearance::Tactical:
// pathObj->setSymbol(this->symbol());
pathObj->setVisibility(ObjectAppearance::Tactical, false);
pathObj->setPickable(m_mainGraphicalObject->pickable());
pathObj->setSelected(m_mainGraphicalObject->selected());
pathObj->setDrawOrder(this->drawOrder()); // use m_drawOrder instead m_internalDrawOrder.
if (!pathObj->updateView())
{
int key = mapIt.key();
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed, key=" << key;
}
}
} // while
// : segment
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
<< " visibility=" << m_visibility
<< " visiTechn=" << m_visibilityTechnical
<< " visiTact=" << m_visibilityTactical
<< " mineVisibility(MineState::Activated)=" << this->mineVisibility(MineState::Activated)
<< " mineVisibility(MineState::DeActivated)=" << this->mineVisibility(MineState::DeActivated)
<< " m_positions->positions().count()=" << m_positions.positions().count()
<< " m_mainGraphicalObject->positions().count()=" << m_mainGraphicalObject->positions().count()
<< " m_mainGraphicalObject->fillStyle().fillPattern()=" << (int)m_mainGraphicalObject->fillStyle().fillPattern();
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
return success;
}
bool MineFieldImpl::init(MapImpl *mapImpl, const QString &logicalLayerName)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (mapImpl)
{
switch (mapImpl->symbologyType())
{
case AdvancedSymbology::SymbologyType::APP6D:
case AdvancedSymbology::SymbologyType::MIL2525D:
// m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"10012500002707060000"); // SymbolSet = 25 270701 , 270705, 270706, 270707
// Case #01977851 - Runitme SDK for Qt: IdentifyGraphicsOverlays crashes
// BUG-000107707 : IdentifyGraphicsOverlays crashes on military symbol "10012500002707060000"]
// -> use another:
m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "10012500001511000000"); // SymbolSet = 25 151100
break;
case AdvancedSymbology::SymbologyType::MIL2525C:
m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GFMPOFA---"); // Mil2525C: 0843: GFMPOFA--- -> Polygon (Minefields Mined Area F)
break;
case AdvancedSymbology::SymbologyType::APP6B:
// m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GFCPBOAIL-"); // APP6B: 3852: GFCPBOAIL- -> Polygon (Minefield - Antipersonnel Mines)
// m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GFCPBOAIN-"); // APP6B: 3853: GFCPBOAIN- -> Polygon (Minefield - Antitank)
m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GFCPBOAIM-"); // APP6B: 3857: GFCPBOAIM- -> Polygon (Minefields Mined Area)
break;
case AdvancedSymbology::SymbologyType::None:
// empty
break;
} // switch
} // if (mapImpl)
bool success = BaseClass::init(mapImpl, logicalLayerName, GraphicalObjectPathType::Polygon);
if (!success)
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
setLineStyle(LineStyle(Qt::green, 2));
setFillStyle(FillStyle(Qt::green, FillPattern::Null));
// set some values to Private:
d->m_mapImpl = m_mapImpl;
d->m_logicalLayer = m_logicalLayerName;
d->m_debugInfo = m_debugInfo;
d->m_uniqueMapId = m_uniqueMapId;
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
return success;
}
bool MineFieldImpl::onMapExtentChanged()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (m_indicationCont)
{
bool visiScale = m_visibilityScaleRange.scaleHasVisibility(m_mapImpl->scale());
const QList<int> &idxInUse = m_indicationCont->getIndicationIndexList(); // idxInUse is representing all values of 'MineState'
for (int idx : qAsConst(idxInUse))
{
m_indicationCont->setVisible(idx, m_visibility && m_visibilityTechnical && d->m_visibilityMines.value(idx) && visiScale);
}
}
bool success = BaseClass::onMapExtentChanged();
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
return success;
}
} // namespace SituationMap