/** * @RDE_HEADER@ * Interface-Implementation of NineLiner * $Id$ * $HeadURL$ * $Author$ */ // Own #include "nine_liner_impl.h" #include #include #include #include #include // ESRI #include // Qt #include namespace SituationMap { double adaptScale(double scale) { if (scale<1.0) return scale; return (0.33 * scale) + 0.66; } //----------------------------------------------------------------------------- // class NineLinerImpl //----------------------------------------------------------------------------- NineLinerImpl::NineLinerImpl(const QString &debugInfo) : NineLiner() // Interface , BaseClass(debugInfo) // Implementation , m_logger(getLogger("NineLinerImpl")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; m_color = Qt::blue; m_otInitialPoint.setMapObjectImpl(this); m_otTargetPosition.setMapObjectImpl(this); m_otFriendliesPosition.setMapObjectImpl(this); // setArrowHeadStart(true); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } NineLinerImpl::~NineLinerImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QString NineLinerImpl::identifier() const { return this->textOnSegment(0); } void NineLinerImpl::setIdentifier(const QString &identifier) { this->setTextOnSegment(0, identifier); } void NineLinerImpl::setScale(float scale) { m_ownScale = scale; // to use m_ownScale.changed(); BaseClass::setScale(scale); } bool NineLinerImpl::updateViewInitialPoint() { bool success = false; const NineLinerData &data = m_data.value(); // InitialPoint / square const Point3D &ip = data.initialPoint; if (ip.isNull()) { m_pmInitialPoint.clear(); success = true; } else { if(!m_pmInitialPoint) { QString debugInfo = QStringLiteral("%1#InitialPointMarker").arg(m_debugInfo); m_pmInitialPoint = QSharedPointer (new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView() , m_graphicsLayer , debugInfo , m_uniqueMapId)); } m_pmInitialPoint->setMarkerSymbol(MarkerSymbolType::Square, 20*adaptScale(m_mainGraphicalObject->scale()), // cover the lines less by reduced growing of pointSymbols m_color.value()); m_otInitialPoint.setOrigin(ip); m_pmInitialPoint->setOrigin(m_otInitialPoint.originTranslated()); m_pmInitialPoint->setPickable(m_mainGraphicalObject->pickable()); m_pmInitialPoint->setVisibility(m_mainGraphicalObject->visibility()); success = m_pmInitialPoint->updateView(); } TRACE_LOG(m_logger) << LOGFUNCTION << " success=" << success; return success; } bool NineLinerImpl::updateViewTargetPosition() { bool success = false; const NineLinerData &data = m_data.value(); // TargetPosition / triangle const Point3D &ip = data.targetPosition; if (ip.isNull()) { m_pmTargetPosition.clear(); success = true; } else { if(!m_pmTargetPosition) { QString debugInfo = QStringLiteral("%1#TargetPositionMarker").arg(m_debugInfo); m_pmTargetPosition = QSharedPointer (new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView() , m_graphicsLayer , debugInfo , m_uniqueMapId)); } m_pmTargetPosition->setMarkerSymbol(MarkerSymbolType::Triangle, 20*adaptScale(m_mainGraphicalObject->scale()), // cover the lines less by reduced growing of pointSymbols m_color.value()); m_otTargetPosition.setOrigin(ip); m_pmTargetPosition->setOrigin(m_otTargetPosition.originTranslated()); m_pmTargetPosition->setPickable(m_mainGraphicalObject->pickable()); m_pmTargetPosition->setVisibility(m_mainGraphicalObject->visibility()); success = m_pmTargetPosition->updateView(); } TRACE_LOG(m_logger) << LOGFUNCTION << " success=" << success; return success; } Point3D movePoint(const Point3D& point, int length, int angle) { QList pColl; constexpr double deg2rad = LtsCoordTrans::deg2rad(); constexpr double rad2deg = LtsCoordTrans::rad2deg(); // to wgs84 / degree Esri::ArcGISRuntime::Point p(point.x()*rad2deg, point.y()*rad2deg, point.z()*rad2deg, Esri::ArcGISRuntime::SpatialReference::wgs84()); pColl = Esri::ArcGISRuntime::GeometryEngine::moveGeodetic({p}, length, Esri::ArcGISRuntime::LinearUnit::meters(), angle, Esri::ArcGISRuntime::AngularUnit::degrees(), Esri::ArcGISRuntime::GeodeticCurveType::Geodesic); p = pColl.first(); // back to rad const Point3D movedPoint (p.x()*deg2rad, p.y()*deg2rad, p.z()*deg2rad); // qCritical() << " length = " << length << " angle= " << angle; return movedPoint; } Point3D movePointFah(const Point3D& point, int length, int angle) { if (length < 1000) length = 1000; if (length > 100000) length = 100000; return movePoint(point, length, angle+180); } bool NineLinerImpl::updateViewFriendlies() { bool success = false; const NineLinerData &data = m_data.value(); if (data.friendliesDistance < 0) { m_pmFriendlies.clear(); success = true; } else { const Point3D &tartgetPosition = m_otTargetPosition.origin(); const Point3D &friendliesOrigin = movePoint(tartgetPosition, static_cast(data.friendliesDistance), data.friendliesBearing); if(!m_pmFriendlies) { QString debugInfo = QStringLiteral("%1#FriendliesPositionMarker").arg(m_debugInfo); m_pmFriendlies = QSharedPointer (new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView() , m_graphicsLayer , debugInfo , m_uniqueMapId)); } m_pmFriendlies->setMarkerSymbol(MarkerSymbolType::Circle, 15*adaptScale(m_mainGraphicalObject->scale()), // cover the lines less by reduced growing of pointSymbols m_color.value()); m_otFriendliesPosition.setOrigin(friendliesOrigin); m_pmFriendlies->setOrigin(m_otFriendliesPosition.originTranslated()); m_pmFriendlies->setPickable(m_mainGraphicalObject->pickable()); m_pmFriendlies->setVisibility(m_mainGraphicalObject->visibility()); success = m_pmFriendlies->updateView(); } TRACE_LOG(m_logger) << LOGFUNCTION << " success=" << success; return success; } bool NineLinerImpl::updateViewFinalAttackHeading(int length) { const NineLinerData &data = m_data.value(); const Point3D &tartgetPosition = m_otTargetPosition.origin(); const Point3D &fahOrigin = movePointFah(tartgetPosition, length, data.fah); m_positions.setPositions(PositionCont() << fahOrigin << tartgetPosition); return true; } bool NineLinerImpl::updateViewFahSector(QSharedPointer &path, const QString &debugInfo, int length, int angle) { const Point3D &tartgetPosition = m_otTargetPosition.origin(); const Point3D &origin = movePointFah(tartgetPosition, length, angle); bool success = false; if (angle < 0) { path.clear(); success = true; } else { if(!path) { path = QSharedPointer (new GraphicalObjectPath(GraphicalObjectPathType::Polyline, m_mapImpl->getEsriGeoView() , m_graphicsLayer , debugInfo , m_uniqueMapId)); path->setDrawOrder(m_internalDrawOrder - 1); } path->setLineStyle(LineStyle(m_color.value(), 3, LinePattern::Dash)); PositionsTranslated positions; positions.setMapObjectImpl(this); positions.addSinglePosition(tartgetPosition); positions.addSinglePosition(origin); path->setPositions(positions.positionsTranslated()); path->setScale(m_mainGraphicalObject->scale()); path->setPickable(m_mainGraphicalObject->pickable()); path->setVisibility(m_mainGraphicalObject->visibility()); success = path->updateView(); } TRACE_LOG(m_logger) << LOGFUNCTION << " success=" << success; return success; } bool NineLinerImpl::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_data=" << m_data.value().toString() << " visibility=" << m_visibility << " visiTechn=" << m_visibilityTechnical << " visiTact=" << m_visibilityTactical; BaseClass::updateViewImpl(); m_color = partyColor(); // if (m_data.changed() || m_color.changed() || m_ownScale.changed()) { updateViewInitialPoint(); updateViewTargetPosition(); updateViewFriendlies(); const int length = static_cast(m_mapImpl->pixelSizeMeter() * 100); updateViewFinalAttackHeading(length); updateViewFahSector(m_pathFahSectorLow, QStringLiteral("%1#FahSectorLow").arg(m_debugInfo), length, m_data.value().fahLow); updateViewFahSector(m_pathFahSectorHigh, QStringLiteral("%1#FahSectorHigh").arg(m_debugInfo), length, m_data.value().fahHigh); } setArrowHeadsSelected(m_selected); bool success = BaseClass::updateViewImpl(); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed"; // reset changed flag -> updateViewImplPost TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool NineLinerImpl::onMapExtentChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; bool success = BaseClass::onMapExtentChanged(); // to handle unchanged pixelSizeMeter const int newFahLength = static_cast(m_mapImpl->pixelSizeMeter() * 100); if (m_fahLength == newFahLength) return true; // store new value m_fahLength = newFahLength; updateViewFinalAttackHeading(m_fahLength); m_mainGraphicalObject->setPositions(m_positions.positionsTranslated()); if(!m_mainGraphicalObject->updateView()) ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed (m_mainGraphicalObject)"; if (!updateViewFahSector(m_pathFahSectorLow, QStringLiteral("%1#FahSectorLow").arg(m_debugInfo), m_fahLength, m_data.value().fahLow)) ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed (m_pathFahSectorLow)"; if (!updateViewFahSector(m_pathFahSectorHigh, QStringLiteral("%1#FahSectorHigh").arg(m_debugInfo), m_fahLength, m_data.value().fahHigh)) ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed (m_pathFahSectorHigh)"; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return success; } bool NineLinerImpl::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(), "10032500001406030000"); // SymbolSet = 25 140602 // ^^ ^^^^^^ break; case AdvancedSymbology::SymbologyType::MIL2525C: m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GFGPOLKGS-"); // 1047 - Direction Of Attack Ground Supporting Attack F // m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GHGPOLKA--"); // // m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(),"GHGPOLKGM-"); // break; case AdvancedSymbology::SymbologyType::APP6B: m_symbol.refValue().sidc = AdvancedSymbology::SidcCodec::encodeComplete(mapImpl->symbologyType(), "GFCPMOLDS-"); // APP6B-3733 GFCPMOLDS- -> Direction Of Attack Ground Supporting Attack F break; case AdvancedSymbology::SymbologyType::None: // empty break; } // switch } // if (mapImpl) bool success = BaseClass::init(mapImpl, logicalLayerName, GraphicalObjectPathType::Polyline); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " init failed"; m_mainGraphicalObject->setLineStyle(LineStyle(Qt::cyan, 2, LinePattern::Solid)); TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool NineLinerImpl::setPositions(const PositionCont &) { FATAL_LOG(m_logger) << LOGFUNCTION << " DO NOT CALL!!!"; assert(false); return false; } } // namespace SituationMap