Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,428 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Interface-Implementation of NuclearAgent
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "nuclear_agent_impl.h"
|
||||
#include <MapImpl/map_impl.h>
|
||||
#include <GraphicalObjects/graphical_object_path.h>
|
||||
#include <GraphicalObjects/graphical_object_text.h>
|
||||
|
||||
#include <Symbology/sidc_codec.h>
|
||||
|
||||
|
||||
// ESRI
|
||||
|
||||
|
||||
// Qt
|
||||
#include <QList>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
// to get access to 'init'
|
||||
using NAgentLocalBasicPathObject = LocalBasicPathObject;
|
||||
|
||||
QImage renderImpactSymbol(const QColor &color, int size, bool filled)
|
||||
{
|
||||
QImage image(size, size, QImage::Format_ARGB32);
|
||||
image.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&image);
|
||||
|
||||
QPen pen(color);
|
||||
int penWidth = size/10;
|
||||
if (penWidth < 2)
|
||||
penWidth = 2;
|
||||
pen.setWidth(penWidth);
|
||||
painter.setPen(pen);
|
||||
|
||||
const int sizeHalf = size / 2;
|
||||
|
||||
QPointF center(sizeHalf, sizeHalf);
|
||||
|
||||
// circle
|
||||
if (filled)
|
||||
painter.setBrush(color);
|
||||
painter.drawEllipse(center, sizeHalf * 0.5, sizeHalf * 0.5);
|
||||
|
||||
// lines
|
||||
QLine newLine(0, sizeHalf, size / 4.0, sizeHalf);
|
||||
painter.drawLine(newLine);
|
||||
|
||||
QTransform trans;
|
||||
trans.translate(sizeHalf, sizeHalf);
|
||||
trans.rotate(45);
|
||||
trans.translate(-sizeHalf, -sizeHalf);
|
||||
|
||||
// 8 are required, one is already draw, so 7:
|
||||
for (int i=0; i<7; ++i)
|
||||
{
|
||||
newLine = trans.map(newLine);
|
||||
painter.drawLine(newLine);
|
||||
}
|
||||
|
||||
painter.end();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
class NuclearAgentImpl::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};
|
||||
|
||||
GraphicalObjectPictureMarker *m_centerImage{nullptr};
|
||||
|
||||
|
||||
struct ValueDataNA
|
||||
{
|
||||
QSharedPointer<BasicPathObjectImpl> basicPathObj;
|
||||
NuclearAgent::OptionalData optData;
|
||||
};
|
||||
|
||||
QMap<int, ValueDataNA> m_cont; /// one polyline per subsidiary line
|
||||
using MAP_IT_T = QMapIterator<int, ValueDataNA>;
|
||||
// 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(); }
|
||||
|
||||
ValueDataNA getPathObject(int key, const OptionalData &optData = OptionalData())
|
||||
{
|
||||
auto ret = m_cont.value(key); // copy
|
||||
if (ret.basicPathObj.isNull())
|
||||
{
|
||||
QString debugInfo = QStringLiteral("%1#SubsidiaryLine(%2)").arg(m_debugInfo).arg(key);
|
||||
NAgentLocalBasicPathObject *temp = new NAgentLocalBasicPathObject(debugInfo);
|
||||
GraphicalObjectPathType pathType = GraphicalObjectPathType::Polyline;
|
||||
if (optData.closed)
|
||||
pathType = GraphicalObjectPathType::Polygon;
|
||||
bool success = temp->init(m_mapImpl, m_logicalLayer, pathType);
|
||||
temp->setUniqueId(m_uniqueMapId);
|
||||
|
||||
if (success)
|
||||
ret.basicPathObj = QSharedPointer<BasicPathObjectImpl>(static_cast<BasicPathObjectImpl *>(temp));
|
||||
else
|
||||
temp->removeMySelf();
|
||||
|
||||
ret.optData.closed = optData.closed;
|
||||
}
|
||||
// transfer optional data (line|fill) to ret and then to container _if_ set:
|
||||
if (optData.lineStyle)
|
||||
ret.optData.lineStyle = optData.lineStyle;
|
||||
if (optData.fillStyle)
|
||||
ret.optData.fillStyle = optData.fillStyle;
|
||||
m_cont.insert(key, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}; // class NuclearAgentImpl::Private
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class NuclearAgentImpl
|
||||
//-----------------------------------------------------------------------------
|
||||
NuclearAgentImpl::NuclearAgentImpl(const QString &debugInfo)
|
||||
: NuclearAgent() // Interface
|
||||
, BaseClass(debugInfo) // Implementation
|
||||
, d(new Private)
|
||||
, m_logger(getLogger("NuclearAgentImpl"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_fillColorAlpha = 200;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
NuclearAgentImpl::~NuclearAgentImpl()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
delete d->m_centerImage;
|
||||
delete d;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::setUniqueId(const UniqueMapId &uniqueId)
|
||||
{
|
||||
BaseClass::setUniqueId(uniqueId);
|
||||
d->m_uniqueMapId = m_uniqueMapId;
|
||||
}
|
||||
|
||||
|
||||
PositionCont NuclearAgentImpl::subsidiaryLine(int key) const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (d->hasPathObject(key))
|
||||
return d->getPathObject(key).basicPathObj->positions();
|
||||
else
|
||||
return PositionCont();
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::setSubsidiaryLine(int key, const PositionCont &positions, const OptionalData &optData)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", key=" << key
|
||||
<< ", closed=" << optData.closed
|
||||
<< ", positions.size=" << positions.size();
|
||||
|
||||
Private::ValueDataNA vd = d->getPathObject(key, optData);
|
||||
QSharedPointer<BasicPathObjectImpl> pathObj = vd.basicPathObj;
|
||||
if (pathObj)
|
||||
pathObj->setPositions(positions);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
QList<int> NuclearAgentImpl::subsidiaryKeysInUse()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return d->keysInUse();
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::removeSubsidiaryLine(int key)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return d->remove(key);
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::removeSubsidiaryLines()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return d->clear();
|
||||
}
|
||||
|
||||
Point3D NuclearAgentImpl::impactOrigin() const
|
||||
{
|
||||
return BaseClass::tacticalOrigin();
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::setImpactOrigin(const Point3D &impactOrigin)
|
||||
{
|
||||
BaseClass::setTacticalOrigin(impactOrigin);
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::setDetonation(const Point3D &origin, double radius)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
BaseClass::setDetonation(origin, radius);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool NuclearAgentImpl::hasDetonation() const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return BaseClass::hasDetonation();
|
||||
}
|
||||
|
||||
void NuclearAgentImpl::resetDetonation()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
BaseClass::resetDetonation();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
bool NuclearAgentImpl::updateViewImpl()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " symbol=" << m_symbol.value().sidc
|
||||
<< " visibility=" << m_visibility
|
||||
<< " visiTechn=" << m_visibilityTechnical
|
||||
<< " visiTact=" << m_visibilityTactical;
|
||||
|
||||
// centerImage:
|
||||
if (!d->m_centerImage)
|
||||
{
|
||||
d->m_centerImage =
|
||||
new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView(),
|
||||
m_graphicsLayer,
|
||||
m_debugInfo + QLatin1String("#CenterImage"),
|
||||
m_uniqueMapId);
|
||||
}
|
||||
// if (partyChanged())
|
||||
{
|
||||
// QImage img = renderImpactSymbol(partyColor(), 20, true); // filled
|
||||
QImage img = renderImpactSymbol(m_mainGraphicalObject->lineStyle().lineColor(), 20, true); // filled
|
||||
d->m_centerImage->setImage(img);
|
||||
}
|
||||
|
||||
// m_centerImage->setScale(m_mainGraphicalObject->scale()); // do not scale centerImage, equal to mine of MineArea
|
||||
|
||||
d->m_centerImage->setOrigin(m_tacticalOrigin.value().originTranslated());
|
||||
d->m_centerImage->setVisibility(m_visibility && m_visibilityTechnical);
|
||||
|
||||
|
||||
|
||||
bool success = BaseClass::updateViewImpl();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nullptr == m_mainGraphicalObject)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_mainGraphicalObject";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// subsidiary :
|
||||
|
||||
Private::MAP_IT_T mapIt(d->m_cont);
|
||||
while (mapIt.hasNext())
|
||||
{
|
||||
mapIt.next();
|
||||
const Private::ValueDataNA &vd = mapIt.value();
|
||||
QSharedPointer<BasicPathObjectImpl> pathObj = vd.basicPathObj;
|
||||
const OptionalData &optData = vd.optData;
|
||||
if (pathObj)
|
||||
{
|
||||
// pathObj->setDebugInfo(m_mainGraphicalObject->debugInfo()); // will overwrite complete string -> skip
|
||||
|
||||
if (optData.lineStyle)
|
||||
pathObj->setLineStyle((*optData.lineStyle.data()));
|
||||
else
|
||||
pathObj->setLineStyle(m_mainGraphicalObject->lineStyle());
|
||||
|
||||
// transfer fillStyle only if relevant:
|
||||
if (pathObj->pathType() == GraphicalObjectPathType::Polygon)
|
||||
{
|
||||
if (optData.fillStyle)
|
||||
pathObj->setFillStyle((*optData.fillStyle.data()));
|
||||
else
|
||||
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(m_internalDrawOrder);
|
||||
|
||||
success = pathObj->updateView();
|
||||
if (!success)
|
||||
{
|
||||
int key = mapIt.key();
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed, key=" << key;
|
||||
}
|
||||
}
|
||||
} // while
|
||||
|
||||
// : subsidiary
|
||||
|
||||
|
||||
// singleSceneMarker :
|
||||
updateSingleSceneMarker(m_visibility); // inclusive updateView()
|
||||
// : singleSceneMarker
|
||||
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool NuclearAgentImpl::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(), "10012500002719000000"); // SymbolSet = 25 271900
|
||||
break;
|
||||
case AdvancedSymbology::SymbologyType::MIL2525C:
|
||||
m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GUMPNR----"); // MIL2525D: 1388 GUMPNR---- -> Polygon (Radioactive Area U)
|
||||
// m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GUMPNZ----"); // MIL2525D: 0359 GUMPNZ---- -> Point (Nuclear Detonations Ground Zero U)
|
||||
break;
|
||||
case AdvancedSymbology::SymbologyType::APP6B:
|
||||
m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GUCPBWR---"); // APP6B: 3935 GUCPBWR--- -> Polygon
|
||||
// m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GUCPBWP---"); // APP6B: 2871 GUCPBWP--- -> Point (Fallout Producing U)
|
||||
break;
|
||||
case AdvancedSymbology::SymbologyType::None:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
} // if (mapImpl)
|
||||
|
||||
|
||||
bool success = BaseClass::init(mapImpl, logicalLayerName, GraphicalObjectPathType::Polygon);
|
||||
|
||||
setLineStyle(LineStyle(Qt::yellow, 2));
|
||||
setFillStyle(FillStyle(Qt::yellow, FillPattern::Null));
|
||||
|
||||
if (!success)
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " init failed";
|
||||
|
||||
// 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 NuclearAgentImpl::onMapExtentChanged()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
bool successCenterImage = true;
|
||||
if (d->m_centerImage)
|
||||
{
|
||||
bool visiScale = m_visibilityScaleRange.scaleHasVisibility(m_mapImpl->scale());
|
||||
d->m_centerImage->setVisibility(visiScale && m_visibility && m_visibilityTechnical);
|
||||
successCenterImage = d->m_centerImage->updateView();
|
||||
}
|
||||
|
||||
bool success = BaseClass::onMapExtentChanged() && successCenterImage;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
Reference in new issue
Block a user