/** * @RDE_HEADER@ * Interface-Implementation of SingleFire * $Id$ * $HeadURL$ * $Author$ */ // Own #include "single_fire_impl.h" #include #include #include #include #include // ESRI // Qt #include #include namespace SituationMap { static int s_gunToTargetLine3DKEY = -1; static int s_gunToTargetLineSurfaceKEY = 0; static int s_nonLethalAreaKEY = 1; //----------------------------------------------------------------------------- // class SingleFireImpl //----------------------------------------------------------------------------- SingleFireImpl::SingleFireImpl(const QString &debugInfo) : SingleFire() // Interface , BaseClass(debugInfo) // Implementation , m_logger(getLogger("SingleFireImpl")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; m_fillColorAlpha = 200; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } SingleFireImpl::~SingleFireImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; delete m_centerImage; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QString SingleFireImpl::toString() const { QString str; str.append(BaseClass::toString()); str.append(BasicPathObjectImpl::toString()); return str; } Point3D SingleFireImpl::impactOrigin() const { return BaseClass::tacticalOrigin(); } void SingleFireImpl::setImpactOrigin(const Point3D &impactOrigin) { BaseClass::setTacticalOrigin(impactOrigin); } SingleFire::ImpactType SingleFireImpl::impactType() const { return m_impactType.value(); } void SingleFireImpl::setImpactType(SingleFire::ImpactType impactType) { m_impactType = impactType; } Point3D SingleFireImpl::origin() const { return BaseClass::origin(); } void SingleFireImpl::setOrigin(const Point3D &origin) { BaseClass::setOrigin(origin); } float SingleFireImpl::radius() const { return BaseClass::radius(); } void SingleFireImpl::setRadius(float radius) { BaseClass::setRadius(radius); } void SingleFireImpl::setOriginatorToTargetLineSurface(const Point3D &start, const Point3D &end) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << ", start=" << start << ", end=" << end << ", debugInfo=" << m_debugInfo; PathContainer &path = this->rPathContainer(); // should be SP::Draped path.setDebugInfo(m_debugInfo + QStringLiteral("SpDraped")); if (start.isNull() && end.isNull()) { path.clear(s_gunToTargetLineSurfaceKEY); } else { LineStyle ls = m_mainGraphicalObject->lineStyle(); ls.setLinePattern(LinePattern::Dash); ls.setLineWidth(2); path.setLineStyle(ls); path.setPath(s_gunToTargetLineSurfaceKEY, {start, end}); } TRACE_LOG(m_logger) << LOGFUNCTION << " END" << ", start=" << start << ", end=" << end << ", debugInfo=" << m_debugInfo; } AesEffectState SingleFireImpl::aesState() const { return BaseClass::aesState(); } void SingleFireImpl::setAesState(AesEffectState aesState) { BaseClass::setAesState(aesState); } SymbolImage SingleFireImpl::symbolImage() const { SymbolImage symImage = m_tacticalAppearance->symbolImage(); return symImage; } bool SingleFireImpl::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " origin =" << this->origin() //.x() << ", " << this->origin().y() << " radius =" << this->radius() << " visibility=" << m_visibility << " visiTechn=" << m_visibilityTechnical << " visiTact=" << m_visibilityTactical; if (m_tacticalAppearance) { if (partyChanged()) m_symbol.refValue().color = partyColor(); } // centerImage: if (!m_centerImage) { m_centerImage = new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView(), m_graphicsLayer, m_debugInfo + QLatin1String("#CenterImage"), m_uniqueMapId); m_impactType.setChanged(); } if (m_impactType.changed() || partyChanged()) { QImage img; switch(m_impactType.value()) { case SingleFire::ImpactType::normalImpact: img = renderImpactSymbol(partyColor(), 20, true); // filled break; case SingleFire::ImpactType::doubleImpact: img = renderDoubleImpactSymbol(partyColor(), 20, true); // filled break; } // switch m_centerImage->setImage(img); } // m_centerImage->setScale(m_mainGraphicalObject->scale()); // do not scale centerImage, equal to mine of MineArea m_centerImage->setOrigin(m_tacticalOrigin.value().originTranslated()); m_centerImage->setVisibility(m_visibility && m_visibilityTechnical); bool success = BaseClass::updateViewImpl(); // will call onMapExtentChanged and therefore m_centerImage->updateView if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed"; TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool SingleFireImpl::init(MapImpl *mapImpl, const QString &logicalLayerName) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (mapImpl) { switch (mapImpl->symbologyType()) { case AdvancedSymbology::SymbologyType::MIL2525D: m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "10012500002108000000"); // SymbolSet = 21 270800 , 270900 break; case AdvancedSymbology::SymbologyType::MIL2525C: // m_symbol.refValue().m_sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GUGPGPWP--"); // 0431 GUGPGPWP-- (Predicted Impact Point U) -> Point m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GUGPGPWI--"); // 0293 GHGPGPWI-- (Impact Point H) -> Point break; case AdvancedSymbology::SymbologyType::APP6B: //m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GUOPVMM---"); // APP6B: 2564 GUOPVMM--- -> Point m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GUOPVI----"); // APP6B: 2560 GUOPVI---- -> Point break; case AdvancedSymbology::SymbologyType::APP6D: m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "10012500002108000000"); // SymbolSet = 21 270800 , 270900 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"; TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool SingleFireImpl::onMapExtentChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; bool successCenterImage = true; if (m_centerImage) { bool visiScale = m_visibilityScaleRange.scaleHasVisibility(m_mapImpl->scale()); m_centerImage->setVisibility(visiScale && m_visibility && m_visibilityTechnical); successCenterImage = m_centerImage->updateView(); } bool success = BaseClass::onMapExtentChanged() && successCenterImage; TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } QImage SingleFireImpl::renderDoubleImpactSymbol(const QColor &color, int size, bool filled) { QImage finalImage(2.25*size, size, QImage::Format_ARGB32); finalImage.fill(Qt::transparent); const QImage &singleImg = renderImpactSymbol(color, size, filled); QRect target = singleImg.rect(); QPainter painter(&finalImage); // left painter.drawImage(target, singleImg, singleImg.rect()); // right target.moveTo(finalImage.width() - singleImg.width(), 0); painter.drawImage(target, singleImg, singleImg.rect()); painter.end(); return finalImage; } QImage SingleFireImpl::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; } } // namespace SituationMap