495 lines
17 KiB
C++
Executable File
495 lines
17 KiB
C++
Executable File
/**
|
|
* @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
|