/** * @RDE_HEADER@ * Interface-Implementation of MineField * $Id$ * $HeadURL$ * $Author$ */ // Own #include "mine_field_impl.h" #include #include "basic_path_object_impl.h" #include #include "mine_impl.h" #include // ESRI // Qt #include 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 m_visibilityMines; QMap > m_cont; 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(); } QSharedPointer 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(static_cast(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(MineState::Activated)] = true; d->m_visibilityMines[static_cast(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 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 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(mineState) << " posCont.size()=" << posCont.size(); IndicationContainer &mines = this->rIndicationContainer(); mines.setDebugInfo(m_debugInfo); mines.setPositions(static_cast(mineState), posCont); TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " mineState=" << static_cast(mineState) << " posCont.size()=" << posCont.size(); } bool MineFieldImpl::mineVisibility(MineField::MineState mineState) const { return d->m_visibilityMines[static_cast(mineState)]; } void MineFieldImpl::setMineVisibility(MineField::MineState mineState, bool visible) { d->m_visibilityMines[static_cast(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 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(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 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 &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