Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,494 @@
/**
* @RDE_HEADER@
* Interface-Implementation of VirtualMine
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "virtual_mine_impl.h"
#include <MapImpl/map_impl.h>
#include <GraphicalObjects/graphical_object_path.h>
#include <GraphicalObjects/graphical_object_text.h>
#include <GraphicalObjects/graphical_object_renderer_attributes.h>
#include <GraphicalObjects/graphical_object_scene_marker.h>
#include <Symbology/sidc_codec.h>
// ESRI
#include <arcgis/Graphic.h>
#include <arcgis/GraphicListModel.h>
#include <arcgis/GraphicsOverlay.h>
// Qt
#include <QList>
#include <QSharedPointer>
namespace SituationMap
{
//// to get access to 'init'
//class VMineLocalBasicPathObject final : public BasicPathObjectImpl
//{
//public:
// using BasicPathObjectImpl::BasicPathObjectImpl;
// using BasicPathObjectImpl::init;
// using BasicPathObjectImpl::setUniqueId;
//};
using VMineLocalBasicPathObject = LocalBasicPathObject;
class VirtualMineImpl::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;
struct MarkerSymbolDataRenderer
{
// std::shared_ptr<Esri::ArcGISRuntime::Graphic> m_graphic3D;
QSharedPointer<GraphicalObjectRendererAttributes> m_goRendererAtt;
QVariantMap m_attribMap;
OriginTranslated m_origin;
} m_markerSymbolDataRenderer;
struct MarkerSymbolData
{
QSharedPointer<GraphicalObjectSceneMarker> m_goSceneMarker;
SceneSymbolData m_sceneSymbolData;
OriginTranslated m_origin;
} m_markerSymbolData;
struct ValueDataVM
{
QSharedPointer<BasicPathObjectImpl> basicPathObj;
VirtualMine::OptionalData optData;
};
QMap<int, ValueDataVM> m_cont; /// one polyline per subsidiary line
using MAP_IT_T = QMapIterator<int, ValueDataVM>;
// 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(); }
ValueDataVM 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);
VMineLocalBasicPathObject *temp = new VMineLocalBasicPathObject(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 VirtualMineImpl::Private
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// class VirtualMineImpl
//-----------------------------------------------------------------------------
VirtualMineImpl::VirtualMineImpl(const QString &debugInfo)
: VirtualMine() // Interface
, BaseClass(debugInfo) // Implementation
, d(new Private)
, m_logger(getLogger("VirtualMineImpl"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
m_fillColorAlpha = 200;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
VirtualMineImpl::~VirtualMineImpl()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_markerSymbolDataRenderer.m_goRendererAtt.clear();
d->m_markerSymbolData.m_goSceneMarker.clear();
// // approach for V100.15 ; will maybe crash with older versions
// if (d->m_markerSymbolData.m_graphic3D && m_graphicsLayer && m_graphicsLayer->graphics())
// m_graphicsLayer->graphics()->removeOne(d->m_markerSymbolData.m_graphic3D.get());
// d->m_markerSymbolData.m_graphic3D.reset();
delete d;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void VirtualMineImpl::setUniqueId(const UniqueMapId &uniqueId)
{
BaseClass::setUniqueId(uniqueId);
d->m_uniqueMapId = m_uniqueMapId;
}
PositionCont VirtualMineImpl::subsidiaryLine(int key) const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (d->hasPathObject(key))
return d->getPathObject(key).basicPathObj->positions();
else
return PositionCont();
}
void VirtualMineImpl::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::ValueDataVM vd = d->getPathObject(key, optData);
QSharedPointer<BasicPathObjectImpl> pathObj = vd.basicPathObj;
if (pathObj)
pathObj->setPositions(positions);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
QList<int> VirtualMineImpl::subsidiaryKeysInUse()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->keysInUse();
}
void VirtualMineImpl::removeSubsidiaryLine(int key)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->remove(key);
}
void VirtualMineImpl::removeSubsidiaryLines()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->clear();
}
bool VirtualMineImpl::has3DMarkerRenderer() const
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// TRACE_LOG(m_logger) << LOGFUNCTION << " END, isEmpty = " << d->m_markerSymbolData.m_origin.isEmpty();
return !d->m_markerSymbolDataRenderer.m_origin.isEmpty();
}
void VirtualMineImpl::set3DMarkerRenderer(const Point3D &markerOrigin, const QVariantMap &attribMap)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_markerSymbolDataRenderer.m_origin.setOrigin(markerOrigin);
d->m_markerSymbolDataRenderer.m_attribMap = attribMap;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool VirtualMineImpl::has3DMarkerSceneSymbol() const
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return !d->m_markerSymbolData.m_origin.isEmpty();
}
void VirtualMineImpl::set3DMarkerSceneSymbol(const Point3D &markerOrigin, const SceneSymbolData &sceneSymbolData)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_markerSymbolData.m_origin.setOrigin(markerOrigin);
d->m_markerSymbolData.m_sceneSymbolData = sceneSymbolData;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool VirtualMineImpl::updateViewImpl()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " m_debugInfo=" << m_debugInfo
<< " symbol=" << m_symbol.value().sidc
<< " visibility=" << m_visibility
<< " visiTechn=" << m_visibilityTechnical
<< " visiTact=" << m_visibilityTactical;
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::ValueDataVM &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
<< ", m_debugInfo=" << m_debugInfo;
}
}
} // while
// : subsidiary
// 3DMarkerSceneSymbol :
if (m_mapImpl->mode() == Mode::Mode_3D)
{
const bool successUpdateRender = updateViewImpl3DMarkerRenderer();
if (!successUpdateRender)
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl3DMarkerRenderer failed" << ", m_debugInfo=" << m_debugInfo;
const bool successUpdateSceneSymbol = updateViewImpl3DMarkerSceneSymbol();
if (!successUpdateSceneSymbol)
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl3DMarkerSceneSymbol failed" << ", m_debugInfo=" << m_debugInfo;
success = success && successUpdateRender && successUpdateSceneSymbol;
}
// : 3DMarkerSceneSymbol
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
return success;
}
bool VirtualMineImpl::updateViewImpl3DMarkerRenderer()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
bool success = true;
// qCritical() << " attribMap " << attribMap;
if (m_mapImpl->mode() == Mode::Mode_3D)
{
if (d->m_markerSymbolDataRenderer.m_origin.isEmpty())
{
d->m_markerSymbolDataRenderer.m_goRendererAtt.clear();
} else {
if (!d->m_markerSymbolDataRenderer.m_goRendererAtt)
{
QString debugInfo = QStringLiteral("%1#goRendererAtt").arg(m_debugInfo);
d->m_markerSymbolDataRenderer.m_goRendererAtt = QSharedPointer<GraphicalObjectRendererAttributes>
(new GraphicalObjectRendererAttributes(m_mapImpl->getEsriGeoView()
, m_graphicsLayer
, debugInfo
, m_uniqueMapId)
);
}
d->m_markerSymbolDataRenderer.m_origin.setMapObjectImpl(this);
const Point3D &pos = d->m_markerSymbolDataRenderer.m_origin.originTranslated();
d->m_markerSymbolDataRenderer.m_goRendererAtt->setOrigin(pos);
d->m_markerSymbolDataRenderer.m_goRendererAtt->setAttributeMap(d->m_markerSymbolDataRenderer.m_attribMap);
d->m_markerSymbolDataRenderer.m_goRendererAtt->setVisibility(m_visibility);
d->m_markerSymbolDataRenderer.m_goRendererAtt->setPickable(m_mainGraphicalObject->pickable());
d->m_markerSymbolDataRenderer.m_goRendererAtt->setSelected(m_mainGraphicalObject->selected());
d->m_markerSymbolDataRenderer.m_goRendererAtt->setDrawOrder(m_internalDrawOrder);
// scale does not makes sense :-)
success = d->m_markerSymbolDataRenderer.m_goRendererAtt->updateView();
if (!success)
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed, m_goRendererAtt"
<< ", m_debugInfo=" << m_debugInfo;
}
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
return success;
}
bool VirtualMineImpl::updateViewImpl3DMarkerSceneSymbol()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
bool success = true;
// qCritical() << " attribMap " << attribMap;
if (m_mapImpl->mode() == Mode::Mode_3D)
{
if (d->m_markerSymbolData.m_origin.isEmpty())
{
d->m_markerSymbolData.m_goSceneMarker.clear();
} else {
if (!d->m_markerSymbolData.m_goSceneMarker)
{
SituationMap::SceneMarkerType type = SituationMap::SceneMarkerType::SPHERE;
if (d->m_markerSymbolData.m_sceneSymbolData.cone)
type = SituationMap::SceneMarkerType::CONE;
QString debugInfo = QStringLiteral("%1#goSceneMarker").arg(m_debugInfo);
d->m_markerSymbolData.m_goSceneMarker = QSharedPointer<GraphicalObjectSceneMarker>
(new GraphicalObjectSceneMarker(type,
m_mapImpl->getEsriGeoView()
, m_graphicsLayer
, debugInfo
, m_uniqueMapId)
);
}
d->m_markerSymbolData.m_origin.setMapObjectImpl(this);
const Point3D &pos = d->m_markerSymbolData.m_origin.originTranslated();
d->m_markerSymbolData.m_goSceneMarker->setOrigin(pos);
d->m_markerSymbolData.m_goSceneMarker->setDiameter(d->m_markerSymbolData.m_sceneSymbolData.radius*2.0);
d->m_markerSymbolData.m_goSceneMarker->setHeading(d->m_markerSymbolData.m_sceneSymbolData.heading);
d->m_markerSymbolData.m_goSceneMarker->setPitch(d->m_markerSymbolData.m_sceneSymbolData.pitch);
d->m_markerSymbolData.m_goSceneMarker->setRoll(d->m_markerSymbolData.m_sceneSymbolData.roll);
d->m_markerSymbolData.m_goSceneMarker->setVisibility(m_visibility);
d->m_markerSymbolData.m_goSceneMarker->setPickable(m_mainGraphicalObject->pickable());
d->m_markerSymbolData.m_goSceneMarker->setSelected(m_mainGraphicalObject->selected());
d->m_markerSymbolData.m_goSceneMarker->setDrawOrder(m_internalDrawOrder);
QColor col = d->m_markerSymbolData.m_sceneSymbolData.color;
col.setAlphaF(col.alphaF() / 2.0);
d->m_markerSymbolData.m_goSceneMarker->setFillStyle(FillStyle(col, FillPattern::Solid));
// scale does not makes sense :-)
success = d->m_markerSymbolData.m_goSceneMarker->updateView();
if (!success)
ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed, m_goSceneMarker"
<< ", m_debugInfo=" << m_debugInfo;
}
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success;
return success;
}
bool VirtualMineImpl::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;
}
} // namespace SituationMap