382 lines
12 KiB
C++
Executable File
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
|