/** * @RDE_HEADER@ * Interface-Implementation of MapObjectIndicator * $Id$ * $HeadURL$ * $Author$ */ // Own #include "map_object_indicator_impl.h" #include #include #include #include "abstract_single_point_map_object_impl.h" #include #include // ESRI // Qt #include namespace SituationMap { //----------------------------------------------------------------------------- // class MapObjectIndicatorImpl //----------------------------------------------------------------------------- MapObjectIndicatorImpl::MapObjectIndicatorImpl(const QString &debugInfo) : MapObjectIndicator() // Interface , BaseClass(debugInfo) // Implementation , m_logger(getLogger("MapObjectIndicatorImpl")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; setPickable(false); setArrowHeadStart(true); m_arrowHeadLengthHeight = 25; // size of arrow m_arrowHeadHalfWidth = 7; // size of arrow m_pictureMarkerSize = 10; // size of filled circle at the origin (indicating the center of the map) m_lineWidth = 2; // lineWidth of (dahed) line from origin to target TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } MapObjectIndicatorImpl::~MapObjectIndicatorImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; // disconnect lambda!!! Otherwise it will be called with a dangling 'this'pointer. QObject::disconnect(m_extentChangedConnection); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } Point3D MapObjectIndicatorImpl::startPoint() const { // !!! see setStartAndEndPoint() !!! const PositionCont &pos = m_positions.positions(); if (pos.size() < 2) return Point3D(); else return pos[1]; // !!! see setStartAndEndPoint() !!! } Point3D MapObjectIndicatorImpl::endPoint() const { // !!! see setStartAndEndPoint() !!! const PositionCont &pos = m_positions.positions(); if (pos.size() < 2) return Point3D(); else return pos[0]; // !!! see setStartAndEndPoint() !!! } void MapObjectIndicatorImpl::setStartAndEndPoint(const Point3D &start, const Point3D &end) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " start=" << start << " end=" << end; // According MIL2525 a line (like attack) starts with an arrow. // But in this context (HitLine) // start == shooter -> no arrowHead // end == target -> with arrowHead // Therefore we have to add the 'end'/target point first: m_positions.setPositions(PositionCont() << end << start); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } UniqueMapId MapObjectIndicatorImpl::mapObjectToPointTo() { return m_uniqueIdToPointTo; } void MapObjectIndicatorImpl::setMapObjectToPointTo(UniqueMapId uniqueId) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueId=" << uniqueId; m_uniqueIdToPointTo = uniqueId; TRACE_LOG(m_logger) << LOGFUNCTION << " END, uniqueId=" << uniqueId; } bool MapObjectIndicatorImpl::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " symbol=" << m_symbol.value().sidc << " visibility=" << m_visibility << " visiTechn=" << m_visibilityTechnical << " visiTact=" << m_visibilityTactical; // create PictureMarker here, to have m_uniqueMapId already set ( compared to init() ) if (m_pictureMarker.isNull()) { QString debugInfo = QStringLiteral("%1#CenterMarker").arg(m_debugInfo); m_pictureMarker = QSharedPointer (new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView() , m_graphicsLayer , debugInfo , m_uniqueMapId)); } setArrowHeadsSelected(m_selected); // real work: // // point to desired obj now: // RefPointer objToPointTo; if (SituationMap::isUniqueMapIdValid(m_uniqueIdToPointTo)) objToPointTo = m_mapImpl->objectFactory().get(m_uniqueIdToPointTo); else DEBUG_LOG(m_logger) << LOGFUNCTION << " m_uniqueIdToPointTo invalid: " << m_uniqueIdToPointTo; // retrive values from objToPointTo: PositionCont line; QColor color; if (objToPointTo.valid()) { const QString &objToPointToDebugInfo = objToPointTo->debugInfo(); DEBUG_LOG(m_logger) << LOGFUNCTION << " objToPointTo is valid, uniqueIdToPointTo=" << m_uniqueIdToPointTo << " (objToPointToDebugInfo=" << objToPointToDebugInfo << ")"; // 1 AbstractMapObjectImpl *impl = dynamic_cast(objToPointTo.get()); if (impl) { color = impl->majorColor(); // color.setAlpha(255); // no transperency this->setDrawOrder(std::max(this->drawOrder(), impl->drawOrder())); } else { ERROR_LOG(m_logger) << LOGFUNCTION << " dynamic_cast failed, uniqueIdToPointTo=" << m_uniqueIdToPointTo << " (objToPointToDebugInfo=" << objToPointToDebugInfo << ")"; } // get target position: BoundingBox bbox; objToPointTo->boundingBox(bbox); if (!bbox.isValid()) WARNING_LOG(m_logger) << LOGFUNCTION << " boundingBox not valid: bbox=" << bbox; line.append(bbox.center()); const QPointF &curCenterPoint = m_mapImpl->centerPoint(); const Point3D curCenterPoint3D(curCenterPoint.x(), curCenterPoint.y(), .0); line.append(curCenterPoint3D); // Color: LineStyle ls = this->lineStyle(); ls.setLineColor(color); this->setLineStyle(ls); } else // if (objToPointTo.valid()) { WARNING_LOG(m_logger) << LOGFUNCTION << " objToPointTo not found"; const QPointF &curCenterPoint = m_mapImpl->centerPoint(); const Point3D curCenterPoint3D(curCenterPoint.x(), curCenterPoint.y(), .0); line << curCenterPoint3D << curCenterPoint3D; // use curCenterPoint twice (to show a very 'short line'); color = Qt::magenta; } // // transfer values: // if (line.size() == 2) { DEBUG_LOG(m_logger) << LOGFUNCTION << " setStartAndEndPoint, uniqueIdToPointTo=" << m_uniqueIdToPointTo << " line=" << line; m_positions.setPositions(line); } else ERROR_LOG(m_logger) << LOGFUNCTION << " size insufficiant, " << " objToPointTo is valid, uniqueIdToPointTo=" << m_uniqueIdToPointTo; // update marker values: const PositionCont &positionsTranslated = m_positions.positionsTranslated(); if (positionsTranslated.size() >= 2) m_pictureMarker->setOrigin(m_positions.positionsTranslated()[1]); color.setAlpha(255); m_pictureMarker->setMarkerSymbol(MarkerSymbolType::Circle, m_pictureMarkerSize, color); bool successBaseClass = BaseClass::updateViewImpl(); if (!successBaseClass) ERROR_LOG(m_logger) << LOGFUNCTION << " updateViewImpl failed"; m_pictureMarker->setSelected(m_selected); m_pictureMarker->setVisibility((m_mainGraphicalObject) ? m_mainGraphicalObject->visibility() : false); bool successPictureMarker = m_pictureMarker->updateView(); if (!successPictureMarker) ERROR_LOG(m_logger) << LOGFUNCTION << " m_pictureMarker->updateViewImpl failed"; bool success = successPictureMarker && successBaseClass; TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool MapObjectIndicatorImpl::init(MapImpl *mapImpl, const QString &logicalLayerName) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; this->setVisibility(ObjectAppearance::Tactical, false); bool success = BaseClass::init(mapImpl, logicalLayerName, GraphicalObjectPathType::Polyline); if (!success) { ERROR_LOG(m_logger) << LOGFUNCTION << " init failed"; return false; } if (!m_mainGraphicalObject) { ERROR_LOG(m_logger) << LOGFUNCTION << "no m_mainGraphicalObject"; return false; } m_mainGraphicalObject->rLineStyle().setLinePattern(LinePattern::Dash); m_mainGraphicalObject->rLineStyle().setLineWidth(m_lineWidth); // connect to extentChanged... // ! Must be disconnected in dtor ! m_extentChangedConnection = QObject::connect(m_mapImpl, &MapImpl::extentChangedDelayed, m_mapImpl, [this]() // ^^^^ to avoid CLazy warning { this->updateView(); }); TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool MapObjectIndicatorImpl::setPositions(const PositionCont &) { FATAL_LOG(m_logger) << LOGFUNCTION << " DO NOT CALL!!!"; assert(false); return false; } } // namespace SituationMap