/** ** ** @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 #include #include #include 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(_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( _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 & 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( _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( _lineSymbol); line->setLine( _coordinates[0]._sceneCoordinate.x(), _coordinates[0]._sceneCoordinate.y() , _coordinates[1]._sceneCoordinate.x(), _coordinates[1]._sceneCoordinate.y() ); } } /* RubberbandLineHandle::updateCoordinate */ QVector 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 */