Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/MapObjectsImpl/map_object_indicator_impl.cpp
T
2026-08-13 18:33:10 +02:00

290 lines
8.7 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Interface-Implementation of MapObjectIndicator
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "map_object_indicator_impl.h"
#include <MapImpl/map_impl.h>
#include <Map/object_factory.h>
#include <Map/bounding_box.h>
#include "abstract_single_point_map_object_impl.h"
#include <GraphicalObjects/graphical_object_path.h>
#include <GraphicalObjects/graphical_object_text.h>
// ESRI
// Qt
#include <cassert>
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<GraphicalObjectPictureMarker>
(new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView()
, m_graphicsLayer
, debugInfo
, m_uniqueMapId));
}
setArrowHeadsSelected(m_selected);
// real work:
//
// point to desired obj now:
//
RefPointer<AbstractMapObject> 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<AbstractMapObjectImpl *>(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