/** * @RDE_HEADER@ * Interface-Implementation of VirtualMine * $Id$ * $HeadURL$ * $Author$ */ // Own #include "virtual_mine_impl.h" #include #include #include #include #include #include // ESRI #include #include #include // Qt #include #include 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 m_graphic3D; QSharedPointer m_goRendererAtt; QVariantMap m_attribMap; OriginTranslated m_origin; } m_markerSymbolDataRenderer; struct MarkerSymbolData { QSharedPointer m_goSceneMarker; SceneSymbolData m_sceneSymbolData; OriginTranslated m_origin; } m_markerSymbolData; struct ValueDataVM { QSharedPointer basicPathObj; VirtualMine::OptionalData optData; }; QMap m_cont; /// one polyline per subsidiary line using MAP_IT_T = QMapIterator; // int m_drawOrder = 0; bool hasPathObject(int key) const { return m_cont.contains(key); } QList 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(static_cast(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 pathObj = vd.basicPathObj; if (pathObj) pathObj->setPositions(positions); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QList 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 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 (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 (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