[QGIS Commit] r13437 - trunk/qgis/src/plugins/georeferencer
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Fri May 7 11:13:12 EDT 2010
Author: mmassing
Date: 2010-05-07 11:13:12 -0400 (Fri, 07 May 2010)
New Revision: 13437
Added:
trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.cpp
trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.h
Log:
Add missing files.
Added: trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.cpp
===================================================================
--- trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.cpp (rev 0)
+++ trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.cpp 2010-05-07 15:13:12 UTC (rev 13437)
@@ -0,0 +1,207 @@
+#include "qgsresidualplotitem.h"
+#include "qgsgeorefdatapoint.h"
+#include <QPainter>
+#include <cfloat>
+#ifndef Q_OS_MACX
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+QgsResidualPlotItem::QgsResidualPlotItem( QgsComposition* c ): QgsComposerItem( c ), mConvertScaleToMapUnits( false ), mPixelToMapUnits( 1.0 )
+{
+
+}
+
+QgsResidualPlotItem::~QgsResidualPlotItem()
+{
+
+}
+
+void QgsResidualPlotItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
+{
+ if ( mGCPList.size() < 1 || !painter )
+ {
+ return;
+ }
+
+ double widthMM = rect().width();
+ double heightMM = rect().height();
+
+ QPen enabledPen( QColor( 0, 0, 255, 255 ) );
+ enabledPen.setWidthF( 0.4 );
+ QPen disabledPen( QColor( 0, 0, 255, 127 ) );
+ disabledPen.setWidthF( 0.3 );
+ QBrush enabledBrush( QColor( 255, 0, 0, 255 ) );
+ QBrush disabledBrush( QColor( 255, 0, 0, 127 ) );
+
+ //draw all points and collect minimal mm/pixel ratio
+ double minMMPixelRatio = DBL_MAX;
+ double mmPixelRatio = 1;
+
+ painter->setRenderHint( QPainter::Antialiasing, true );
+
+ QgsGCPList::const_iterator gcpIt = mGCPList.constBegin();
+ for ( ; gcpIt != mGCPList.constEnd(); ++gcpIt )
+ {
+ QgsPoint gcpCoords = ( *gcpIt )->pixelCoords();
+ double gcpItemMMX = ( gcpCoords.x() - mExtent.xMinimum() ) / mExtent.width() * widthMM;
+ double gcpItemMMY = ( 1 - ( gcpCoords.y() - mExtent.yMinimum() ) / mExtent.height() ) * heightMM;
+
+ if (( *gcpIt )->isEnabled() )
+ {
+ painter->setPen( enabledPen );
+ painter->setBrush( enabledBrush );
+ }
+ else
+ {
+ painter->setPen( disabledPen );
+ painter->setBrush( disabledBrush );
+ }
+ painter->drawRect( QRectF( gcpItemMMX - 1, gcpItemMMY - 1, 2, 2 ) );
+ drawText( painter, gcpItemMMX + 2, gcpItemMMY + 2, QString::number(( *gcpIt )->id() ), QFont() );
+
+ mmPixelRatio = maxMMToPixelRatioForGCP( *gcpIt, gcpItemMMX, gcpItemMMY );
+ if ( mmPixelRatio < minMMPixelRatio )
+ {
+ minMMPixelRatio = mmPixelRatio;
+ }
+ }
+
+ //draw residual arrows
+ gcpIt = mGCPList.constBegin();
+ for ( ; gcpIt != mGCPList.constEnd(); ++gcpIt )
+ {
+ QgsPoint gcpCoords = ( *gcpIt )->pixelCoords();
+ double gcpItemMMX = ( gcpCoords.x() - mExtent.xMinimum() ) / mExtent.width() * widthMM;
+ double gcpItemMMY = ( 1 - ( gcpCoords.y() - mExtent.yMinimum() ) / mExtent.height() ) * heightMM;
+ if (( *gcpIt )->isEnabled() )
+ {
+ painter->setPen( enabledPen );
+ }
+ else
+ {
+ painter->setPen( disabledPen );
+ }
+
+ QPointF p1( gcpItemMMX, gcpItemMMY );
+ QPointF p2( gcpItemMMX + ( *gcpIt )->residual().x() * minMMPixelRatio, gcpItemMMY + ( *gcpIt )->residual().y() * minMMPixelRatio );
+ painter->drawLine( p1, p2 );
+ painter->setBrush( QBrush( painter->pen().color() ) );
+ drawArrowHead( painter, p2.x(), p2.y(), angle( p1, p2 ), 1 );
+ }
+
+ //draw scale bar
+ double initialScaleBarWidth = rect().width() / 5;
+ int nUnits;
+ double scaleBarWidth;
+ if ( mConvertScaleToMapUnits ) //map units
+ {
+ nUnits = initialScaleBarWidth / minMMPixelRatio * mPixelToMapUnits;
+ scaleBarWidth = nUnits * minMMPixelRatio / mPixelToMapUnits;
+ }
+ else //pixels
+ {
+ nUnits = initialScaleBarWidth / minMMPixelRatio;
+ scaleBarWidth = nUnits * minMMPixelRatio;
+ }
+
+ painter->setPen( QColor( 0, 0, 0 ) );
+ painter->drawLine( QPointF( 5, rect().height() - 5 ), QPointF( 5 + scaleBarWidth, rect().height() - 5 ) );
+ painter->drawLine( QPointF( 5, rect().height() - 5 ), QPointF( 5, rect().height() - 7 ) );
+ painter->drawLine( QPointF( 5 + scaleBarWidth, rect().height() - 5 ), QPointF( 5 + scaleBarWidth, rect().height() - 7 ) );
+ QFont scaleBarFont;
+ if ( mConvertScaleToMapUnits )
+ {
+ drawText( painter, 5, rect().height() - 4 + fontAscentMillimeters( scaleBarFont ), QString( "%1 map units" ).arg( nUnits ), QFont() );
+ }
+ else
+ {
+ drawText( painter, 5, rect().height() - 4 + fontAscentMillimeters( scaleBarFont ), QString( "%1 pixels" ).arg( nUnits ), QFont() );
+ }
+
+ drawFrame( painter );
+ if ( isSelected() )
+ {
+ drawSelectionBoxes( painter );
+ }
+}
+
+double QgsResidualPlotItem::maxMMToPixelRatioForGCP( const QgsGeorefDataPoint* p, double pixelXMM, double pixelYMM )
+{
+ if ( !p )
+ {
+ return 0;
+ }
+
+ //calculate intersections with upper / lower frame edge depending on the residual y sign
+ double upDownDist = DBL_MAX; //distance to frame intersection with lower or upper frame
+ double leftRightDist = DBL_MAX; //distance to frame intersection with left or right frame
+
+ QPointF residual = p->residual();
+ QLineF residualLine( pixelXMM, pixelYMM, pixelXMM + residual.x(), pixelYMM + residual.y() );
+ QPointF intersectionPoint;
+ double dx, dy;
+
+ if ( residual.y() > 0 )
+ {
+ QLineF lowerFrameLine( 0, rect().height(), rect().width(), rect().height() );
+ if ( residualLine.intersect( lowerFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
+ {
+ upDownDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
+ }
+ }
+ else if ( residual.y() < 0 )
+ {
+ QLineF upperFrameLine( 0, 0, mExtent.xMaximum(), 0 );
+ if ( residualLine.intersect( upperFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
+ {
+ upDownDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
+ }
+ }
+
+ //calculate intersection with left / right frame edge depending on the residual x sign
+ if ( residual.x() > 0 )
+ {
+ QLineF rightFrameLine( rect().width(), 0, rect().width(), rect().height() );
+ if ( residualLine.intersect( rightFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
+ {
+ leftRightDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
+ }
+ }
+ else if ( residual.x() < 0 )
+ {
+ QLineF leftFrameLine( 0, 0 , 0, rect().height() );
+ if ( residualLine.intersect( leftFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
+ {
+ leftRightDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
+ }
+ }
+
+ double resTot = sqrt( residual.x() * residual.x() + residual.y() * residual.y() );
+ if ( leftRightDist <= upDownDist )
+ {
+ return leftRightDist / resTot;
+ }
+ else
+ {
+ return upDownDist / resTot;
+ }
+}
+
+bool QgsResidualPlotItem::writeXML( QDomElement& elem, QDomDocument & doc ) const
+{
+ return false;
+}
+
+bool QgsResidualPlotItem::readXML( const QDomElement& itemElem, const QDomDocument& doc )
+{
+ return false;
+}
+
+double QgsResidualPlotItem::dist( const QPointF& p1, const QPointF& p2 ) const
+{
+ double dx = p2.x() - p1.x();
+ double dy = p2.y() - p1.y();
+ return sqrt( dx * dx + dy * dy );
+}
Added: trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.h
===================================================================
--- trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.h (rev 0)
+++ trunk/qgis/src/plugins/georeferencer/qgsresidualplotitem.h 2010-05-07 15:13:12 UTC (rev 13437)
@@ -0,0 +1,51 @@
+#ifndef QGSRESIDUALPLOTITEM_H
+#define QGSRESIDUALPLOTITEM_H
+
+#include "qgscomposeritem.h"
+#include "qgsgcplist.h"
+#include "qgsrectangle.h"
+
+/**A composer item to visualise the distribution of georeference residuals. For the visualisation, \
+the length of the residual arrows are scaled*/
+class QgsResidualPlotItem: public QgsComposerItem
+{
+ public:
+ QgsResidualPlotItem( QgsComposition* c );
+ ~QgsResidualPlotItem();
+
+ /** \brief Reimplementation of QCanvasItem::paint*/
+ virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );
+
+ void setGCPList( const QgsGCPList& list ) { mGCPList = list; }
+ QgsGCPList GCPList() const { return mGCPList; }
+
+ void setExtent( const QgsRectangle& rect ) { mExtent = rect;}
+ QgsRectangle extent() const { return mExtent; }
+
+ void setPixelToMapUnits( double d ) { mPixelToMapUnits = d; }
+ double pixelToMapUnits() const { return mPixelToMapUnits; }
+
+ void setConvertScaleToMapUnits( bool convert ) { mConvertScaleToMapUnits = convert; }
+ bool convertScaleToMapUnits() const { return mConvertScaleToMapUnits; }
+
+ virtual bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
+ virtual bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
+
+ private:
+ //gcp list
+ QgsGCPList mGCPList;
+
+ QgsRectangle mExtent;
+ /**True if the scale bar units should be converted to map units. This can be done for transformation where the scaling in all directions is the same (helmert)*/
+ bool mConvertScaleToMapUnits;
+ /**Scale factor from pixels to map units*/
+ double mPixelToMapUnits;
+
+ /**Calculates maximal possible mm to pixel ratio such that the residual arrow is still inside the frame*/
+ double maxMMToPixelRatioForGCP( const QgsGeorefDataPoint* p, double pixelXMM, double pixelYMM );
+
+ /**Returns distance between two points*/
+ double dist( const QPointF& p1, const QPointF& p2 ) const;
+};
+
+#endif // QGSRESIDUALPLOTITEM_H
More information about the QGIS-commit
mailing list