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

232 lines
7.5 KiB
C++
Executable File

/**
**
** @RDE_HEADER@
** Implementation of base class for rubberband handles
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 27.03.2015, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "rubberband_line_handle.h"
#include <arcgis/MapGraphicsView.h>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsLineItem>
#include <math.h>
namespace SituationMap { namespace RB
{
RubberbandLineHandle::RubberbandLineHandle( Esri::ArcGISRuntime::MapGraphicsView * mapView
, QGraphicsScene * scene
, const QPointF & p1
, const QPointF & p2
, unsigned int lineWidth
, bool dottedLine )
: RubberbandHandle(mapView,scene)
, _lineSymbol(nullptr)
, _lineStyle()
, _coordinates()
, _dottedLine(dottedLine)
{
_lineWidth = lineWidth;
zBufferPlane( ZBufferPlane::LineHandle );
_lineStyle.setWidth(_lineWidth);
if (_scene != nullptr)
{
QGraphicsLineItem * line = new QGraphicsLineItem();
_lineSymbol = line;
_coordinates.resize(2);
_coordinates[0].updateSceneCoordinate(mapView,p1);
_coordinates[1].updateSceneCoordinate(mapView,p2);
if (_lineSymbol != nullptr)
{
_scene -> addItem( _lineSymbol );
line->setLine( _coordinates[0]._sceneCoordinate.x(), _coordinates[0]._sceneCoordinate.y()
, _coordinates[1]._sceneCoordinate.x(), _coordinates[1]._sceneCoordinate.y() );
line -> setZValue(10);
line -> setFlags( QGraphicsItem::ItemIgnoresTransformations );
makeLineStyle( _dottedLine, _lineStyle );
line -> setPen( _lineStyle );
}
}
} /* RubberbandLineHandle::RubberbandLineHandle */
RubberbandLineHandle::~RubberbandLineHandle()
{
if (_scene)
{
if (_lineSymbol)
{
_scene->removeItem(_lineSymbol);
delete _lineSymbol;
}
}
_coordinates.clear();
} /* RubberbandHandle::~Rubberbandhandle */
void RubberbandLineHandle::adjustCoordinates()
{
if (_coordinates.size() >= 2)
{
_coordinates[0].mapToScene( _mapView );
_coordinates[1].mapToScene( _mapView );
static_cast<QGraphicsLineItem*>(_lineSymbol)->setLine( _coordinates[0]._sceneCoordinate.x(), _coordinates[0]._sceneCoordinate.y()
, _coordinates[1]._sceneCoordinate.x(), _coordinates[1]._sceneCoordinate.y() );
}
DEBUG_LOG(_logger) << LOGFUNCTION << " map-coordinate = " << QString::number(_coordinates[0]._mapCoordinate.x(),'f',15)
<< " ; " << QString::number(_coordinates[0]._mapCoordinate.y(),'f',15)
<< " scene-coordinate = " << _coordinates[1]._sceneCoordinate.x() << " ; " << _coordinates[1]._sceneCoordinate.y();
emit adjusted();
} /* RubberbandLineHandle::adjustCoordinates */
void RubberbandLineHandle::adjustWindow( const QRectF& )
{
onDo_adjustCoordinates();
} /* RubberbandLineHandle::adjustWindow */
void RubberbandLineHandle::updateGraphic()
{
if (_lineSymbol)
{
QGraphicsLineItem * line = static_cast<QGraphicsLineItem*>( _lineSymbol);
makeLineStyle( _dottedLine, _lineStyle );
if (_isSelected)
{
_lineStyle.setWidth( _lineStyle.width() + 1 );
_lineStyle.setColor( _selectionColor );
}
line -> setPen( _lineStyle );
line -> setVisible( _isVisible );
}
} /* RubberbandLineHandle::updateGraphic */
void RubberbandLineHandle::updateCoordinates(const QVector<QPointF> & scenePositionVector)
{
if (scenePositionVector.size() == 2)
{
if (_coordinates.isEmpty()) _coordinates.resize(2);
_coordinates[0].updateSceneCoordinate(_mapView,scenePositionVector[0]);
_coordinates[1].updateSceneCoordinate(_mapView,scenePositionVector[1]);
if (_lineSymbol != nullptr)
{
QGraphicsLineItem * line = static_cast<QGraphicsLineItem*>( _lineSymbol);
line->setLine( _coordinates[0]._sceneCoordinate.x(), _coordinates[0]._sceneCoordinate.y()
, _coordinates[1]._sceneCoordinate.x(), _coordinates[1]._sceneCoordinate.y() );
}
}
} /* RubberbandLineHandle::updateCoordinates */
void RubberbandLineHandle::updateCoordinate( unsigned index, const QPointF & scenePosition )
{
if (index < 2)
{
_coordinates[index].updateSceneCoordinate(_mapView,scenePosition);
QGraphicsLineItem * line = static_cast<QGraphicsLineItem*>( _lineSymbol);
line->setLine( _coordinates[0]._sceneCoordinate.x(), _coordinates[0]._sceneCoordinate.y()
, _coordinates[1]._sceneCoordinate.x(), _coordinates[1]._sceneCoordinate.y() );
}
} /* RubberbandLineHandle::updateCoordinate */
QVector<RubberbandHandle::RubberbandCoordinate> RubberbandLineHandle::getCoordinates() const
{
return _coordinates;
} /* RubberbandLineHandle::getCoordinates */
RubberbandHandle::RubberbandCoordinate RubberbandLineHandle::getCoordinate( unsigned index ) const
{
if (index < 2)
{
return _coordinates[index];
}
return RubberbandCoordinate();
} /* RubberbandLineHandle::getCoordinate */
bool RubberbandLineHandle::isPositionInside( const QPointF & scenePosition ) const
{
if (_lineSymbol)
{
if (_lineSymbol->contains( scenePosition ))
{
return true;
}
else
{
// Ok, Qt's methodes doesn't work safely
// if it fails do some own calculations
QPointF V0 = _coordinates[0]._sceneCoordinate;
QPointF V1 = _coordinates[1]._sceneCoordinate;
QPointF R = V1-V0;
QPointF P = scenePosition-V0;
qreal lenR = R.x() * R.x() + R.y() * R.y();
qreal lenP = P.x() * P.x() + P.y() * P.y();
if ((lenR == 0) || (lenP > lenR)) return false; // scene Position is to far away
// now check the direction
lenR = sqrt(lenR);
lenP = sqrt(lenP);
R /= lenR;
P /= lenP;
qreal cosPhi = QPointF::dotProduct(R,P);
if (cosPhi < 0) return false;
qreal epsilon = sqrt(1.0-cosPhi*cosPhi) * lenR;
return (epsilon < qreal(_pickingRatio));
}
}
return false;
} /* RubberbandLineHandle::isPositionInside */
} } /* namespace SituationMap::RB */