290 lines
8.7 KiB
C++
Executable File
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
|