|
@@ -15,16 +15,16 @@ |
|
|
|
|
|
#include "qgsresidualplotitem.h" |
|
|
#include "qgsgeorefdatapoint.h" |
|
|
#include "qgscomposerutils.h" |
|
|
#include "qgslayoututils.h" |
|
|
#include <QPainter> |
|
|
#include <cfloat> |
|
|
#include <cmath> |
|
|
|
|
|
QgsResidualPlotItem::QgsResidualPlotItem( QgsComposition *c ) |
|
|
: QgsComposerItem( c ) |
|
|
QgsResidualPlotItem::QgsResidualPlotItem( QgsLayout *layout ) |
|
|
: QgsLayoutItem( layout ) |
|
|
, mConvertScaleToMapUnits( false ) |
|
|
{ |
|
|
|
|
|
setBackgroundEnabled( false ); |
|
|
} |
|
|
|
|
|
void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) |
|
@@ -68,7 +68,7 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt |
|
|
painter->setBrush( disabledBrush ); |
|
|
} |
|
|
painter->drawRect( QRectF( gcpItemMMX - 0.5, gcpItemMMY - 0.5, 1, 1 ) ); |
|
|
QgsComposerUtils::drawText( painter, QPointF( gcpItemMMX + 2, gcpItemMMY + 2 ), QString::number( ( *gcpIt )->id() ), QFont() ); |
|
|
QgsLayoutUtils::drawText( painter, QPointF( gcpItemMMX + 2, gcpItemMMY + 2 ), QString::number( ( *gcpIt )->id() ), QFont() ); |
|
|
|
|
|
mmPixelRatio = maxMMToPixelRatioForGCP( *gcpIt, gcpItemMMX, gcpItemMMY ); |
|
|
if ( mmPixelRatio < minMMPixelRatio ) |
|
@@ -97,7 +97,7 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt |
|
|
QPointF p2( gcpItemMMX + ( *gcpIt )->residual().x() * minMMPixelRatio, gcpItemMMY + ( *gcpIt )->residual().y() * minMMPixelRatio ); |
|
|
painter->drawLine( p1, p2 ); |
|
|
painter->setBrush( QBrush( painter->pen().color() ) ); |
|
|
QgsComposerUtils::drawArrowHead( painter, p2.x(), p2.y(), QgsComposerUtils::angle( p1, p2 ), 1 ); |
|
|
drawArrowHead( painter, p2.x(), p2.y(), angle( p1, p2 ), 1 ); |
|
|
} |
|
|
|
|
|
//draw scale bar |
|
@@ -132,20 +132,29 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt |
|
|
scaleBarFont.setPointSize( 9 ); |
|
|
if ( mConvertScaleToMapUnits ) |
|
|
{ |
|
|
QgsComposerUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsComposerUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 map units" ).arg( scaleBarWidthUnits ), QFont() ); |
|
|
QgsLayoutUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsLayoutUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 map units" ).arg( scaleBarWidthUnits ), QFont() ); |
|
|
} |
|
|
else |
|
|
{ |
|
|
QgsComposerUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsComposerUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 pixels" ).arg( scaleBarWidthUnits ), QFont() ); |
|
|
QgsLayoutUtils::drawText( painter, QPointF( 5, rect().height() - 4 + QgsLayoutUtils::fontAscentMM( scaleBarFont ) ), QStringLiteral( "%1 pixels" ).arg( scaleBarWidthUnits ), QFont() ); |
|
|
} |
|
|
|
|
|
drawFrame( painter ); |
|
|
if ( isSelected() ) |
|
|
if ( frameEnabled() ) |
|
|
{ |
|
|
drawSelectionBoxes( painter ); |
|
|
painter->save(); |
|
|
painter->setPen( pen() ); |
|
|
painter->setBrush( Qt::NoBrush ); |
|
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) ); |
|
|
painter->restore(); |
|
|
} |
|
|
} |
|
|
|
|
|
void QgsResidualPlotItem::draw( QgsRenderContext &, const QStyleOptionGraphicsItem * ) |
|
|
{ |
|
|
|
|
|
} |
|
|
|
|
|
double QgsResidualPlotItem::maxMMToPixelRatioForGCP( const QgsGeorefDataPoint *p, double pixelXMM, double pixelYMM ) |
|
|
{ |
|
|
if ( !p ) |
|
@@ -207,23 +216,65 @@ double QgsResidualPlotItem::maxMMToPixelRatioForGCP( const QgsGeorefDataPoint *p |
|
|
} |
|
|
} |
|
|
|
|
|
bool QgsResidualPlotItem::writeXml( QDomElement &elem, QDomDocument &doc ) const |
|
|
double QgsResidualPlotItem::dist( QPointF p1, QPointF p2 ) const |
|
|
{ |
|
|
Q_UNUSED( elem ); |
|
|
Q_UNUSED( doc ); |
|
|
return false; |
|
|
double dx = p2.x() - p1.x(); |
|
|
double dy = p2.y() - p1.y(); |
|
|
return std::sqrt( dx * dx + dy * dy ); |
|
|
} |
|
|
|
|
|
bool QgsResidualPlotItem::readXml( const QDomElement &itemElem, const QDomDocument &doc ) |
|
|
void QgsResidualPlotItem::drawArrowHead( QPainter *p, const double x, const double y, const double angle, const double arrowHeadWidth ) |
|
|
{ |
|
|
Q_UNUSED( itemElem ); |
|
|
Q_UNUSED( doc ); |
|
|
return false; |
|
|
if ( !p ) |
|
|
{ |
|
|
return; |
|
|
} |
|
|
|
|
|
double angleRad = angle / 180.0 * M_PI; |
|
|
QPointF middlePoint( x, y ); |
|
|
//rotate both arrow points |
|
|
QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth ); |
|
|
QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth ); |
|
|
|
|
|
QPointF p1Rotated, p2Rotated; |
|
|
p1Rotated.setX( p1.x() * std::cos( angleRad ) + p1.y() * -std::sin( angleRad ) ); |
|
|
p1Rotated.setY( p1.x() * std::sin( angleRad ) + p1.y() * std::cos( angleRad ) ); |
|
|
p2Rotated.setX( p2.x() * std::cos( angleRad ) + p2.y() * -std::sin( angleRad ) ); |
|
|
p2Rotated.setY( p2.x() * std::sin( angleRad ) + p2.y() * std::cos( angleRad ) ); |
|
|
|
|
|
QPolygonF arrowHeadPoly; |
|
|
arrowHeadPoly << middlePoint; |
|
|
arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() ); |
|
|
arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() ); |
|
|
|
|
|
p->save(); |
|
|
|
|
|
QPen arrowPen = p->pen(); |
|
|
arrowPen.setJoinStyle( Qt::RoundJoin ); |
|
|
QBrush arrowBrush = p->brush(); |
|
|
arrowBrush.setStyle( Qt::SolidPattern ); |
|
|
p->setPen( arrowPen ); |
|
|
p->setBrush( arrowBrush ); |
|
|
arrowBrush.setStyle( Qt::SolidPattern ); |
|
|
p->drawPolygon( arrowHeadPoly ); |
|
|
|
|
|
p->restore(); |
|
|
} |
|
|
|
|
|
double QgsResidualPlotItem::dist( QPointF p1, QPointF p2 ) const |
|
|
double QgsResidualPlotItem::angle( QPointF p1, QPointF p2 ) |
|
|
{ |
|
|
double dx = p2.x() - p1.x(); |
|
|
double dy = p2.y() - p1.y(); |
|
|
return std::sqrt( dx * dx + dy * dy ); |
|
|
double xDiff = p2.x() - p1.x(); |
|
|
double yDiff = p2.y() - p1.y(); |
|
|
double length = std::sqrt( xDiff * xDiff + yDiff * yDiff ); |
|
|
if ( length <= 0 ) |
|
|
{ |
|
|
return 0; |
|
|
} |
|
|
|
|
|
double angle = std::acos( ( -yDiff * length ) / ( length * length ) ) * 180 / M_PI; |
|
|
if ( xDiff < 0 ) |
|
|
{ |
|
|
return ( 360 - angle ); |
|
|
} |
|
|
return angle; |
|
|
} |