Index: src/plugins/georeferencer/qgsgcpcanvasitem.cpp =================================================================== --- src/plugins/georeferencer/qgsgcpcanvasitem.cpp (revision 13226) +++ src/plugins/georeferencer/qgsgcpcanvasitem.cpp (working copy) @@ -15,19 +15,20 @@ /* $Id$ */ #include "qgsgcpcanvasitem.h" +#include "qgsgeorefdatapoint.h" +#include "qgsmaplayerregistry.h" +#include "qgsmaprenderer.h" +#include "qgsrasterlayer.h" -QgsGCPCanvasItem::QgsGCPCanvasItem( QgsMapCanvas* mapCanvas, const QgsPoint& rasterCoords, - const QgsPoint& worldCoords, bool isGCPSource ) - : QgsMapCanvasItem( mapCanvas ) +QgsGCPCanvasItem::QgsGCPCanvasItem( QgsMapCanvas* mapCanvas, const QgsGeorefDataPoint* dataPoint, bool isGCPSource ) + : QgsMapCanvasItem( mapCanvas ), mDataPoint( dataPoint ) , mPointBrush( Qt::red ) , mLabelBrush( Qt::yellow ) - , mRasterCoords( rasterCoords ) - , mWorldCoords( worldCoords ) - , mId( -1 ) , mIsGCPSource( isGCPSource ) - , mEnabled( true ) { setFlags( QGraphicsItem::ItemIsMovable ); + mResidualPen.setColor( QColor( 255, 0, 0 ) ); + mResidualPen.setWidthF( 2.0 ); updatePosition(); } @@ -35,8 +36,20 @@ void QgsGCPCanvasItem::paint( QPainter* p ) { p->setRenderHint( QPainter::Antialiasing ); - p->setOpacity( mEnabled ? 1.0 : 0.3 ); + bool enabled = true; + QgsPoint worldCoords; + int id = -1; + + if ( mDataPoint ) + { + enabled = mDataPoint->isEnabled(); + worldCoords = mDataPoint->mapCoords(); + id = mDataPoint->id(); + } + + p->setOpacity( enabled ? 1.0 : 0.3 ); + // draw the point p->setPen( Qt::black ); p->setBrush( mPointBrush ); @@ -46,8 +59,8 @@ bool showIDs = s.value( "/Plugin-GeoReferencer/Config/ShowId" ).toBool(); if ( !showIDs && mIsGCPSource ) { - QString msg = QString( "X %1\nY %2" ).arg( QString::number( mWorldCoords.x(), 'f' ) ). - arg( QString::number( mWorldCoords.y(), 'f' ) ); + QString msg = QString( "X %1\nY %2" ).arg( QString::number( worldCoords.x(), 'f' ) ). + arg( QString::number( worldCoords.y(), 'f' ) ); p->setFont( QFont( "helvetica", 9 ) ); QRect textBounds = p->boundingRect( 6, 6, 10, 10, Qt::AlignLeft, msg ); p->setBrush( mLabelBrush ); @@ -58,20 +71,52 @@ else if ( showIDs ) { p->setFont( QFont( "helvetica", 12 ) ); - QString msg = QString::number( mId ); + QString msg = QString::number( id ); p->setBrush( mLabelBrush ); p->drawRect( 5, 4, p->fontMetrics().width( msg ) + 2, 14 ); p->drawText( 6, 16, msg ); QFontMetrics fm = p->fontMetrics(); mTextBounds = QSize( fm.width( msg ) + 4, fm.height() + 4 ); } - // else - // mTextBounds = QSizeF(0, 0); + + drawResidualArrow( p ); } QRectF QgsGCPCanvasItem::boundingRect() const { - return QRectF( -2, -2, mTextBounds.width() + 6, mTextBounds.height() + 6 ); + double residualLeft, residualRight, residualTop, residualBottom; + + QPointF residual; + if ( mDataPoint ) + { + residual = mDataPoint->residual(); + } + double rf = residualToScreenFactor(); + + if ( residual.x() > 0 ) + { + residualRight = residual.x() * rf + mResidualPen.widthF(); + residualLeft = -mResidualPen.widthF(); + } + else + { + residualLeft = residual.x() * rf - mResidualPen.widthF(); + residualRight = mResidualPen.widthF(); + } + if ( residual.y() > 0 ) + { + residualBottom = residual.y() * rf + mResidualPen.widthF(); + residualTop = -mResidualPen.widthF(); + } + else + { + residualBottom = mResidualPen.widthF(); + residualTop = residual.y() * rf - mResidualPen.widthF(); + } + + QRectF residualArrowRect( QPointF( residualLeft, residualTop ), QPointF( residualRight, residualBottom ) ); + QRectF markerRect( -2, -2, mTextBounds.width() + 6, mTextBounds.height() + 6 ); + return residualArrowRect.united( markerRect ); } QPainterPath QgsGCPCanvasItem::shape() const @@ -83,31 +128,63 @@ return p; } -void QgsGCPCanvasItem::setEnabled( bool enabled ) +void QgsGCPCanvasItem::updatePosition() { - mEnabled = enabled; - mPointBrush = enabled ? QBrush( Qt::red ) : QBrush( Qt::gray ); - mLabelBrush = enabled ? QBrush( Qt::yellow ) : QBrush( Qt::gray ); - update(); + if ( !mDataPoint ) + { + return; + } + + setPos( toCanvasCoordinates( mIsGCPSource ? mDataPoint->pixelCoords() : mDataPoint->mapCoords() ) ); } -void QgsGCPCanvasItem::setRasterCoords( QgsPoint p ) +void QgsGCPCanvasItem::drawResidualArrow( QPainter* p ) { - mRasterCoords = p; + if ( !mDataPoint || !mIsGCPSource ) + { + return; + } + + QPointF residual = mDataPoint->residual(); + + double rf = residualToScreenFactor(); + p->setPen( mResidualPen ); + p->drawLine( QPointF( 0, 0 ), QPointF( residual.rx() * rf, residual.ry() * rf ) ); + } -void QgsGCPCanvasItem::setWorldCoords( QgsPoint p ) +double QgsGCPCanvasItem::residualToScreenFactor() const { - mWorldCoords = p; -} + if ( !mMapCanvas ) + { + return 1; + } -void QgsGCPCanvasItem::setId( int id ) -{ - mId = id; - update(); + double mapUnitsPerScreenPixel = mMapCanvas->mapUnitsPerPixel(); + double mapUnitsPerRasterPixel = 1.0; + + if ( mMapCanvas->mapRenderer() ) + { + QStringList canvasLayers = mMapCanvas->mapRenderer()->layerSet(); + if ( canvasLayers.size() > 0 ) + { + QString layerId = canvasLayers.at( 0 ); + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( layerId ); + if ( mapLayer ) + { + QgsRasterLayer* rasterLayer = dynamic_cast( mapLayer ); + if ( rasterLayer ) + { + mapUnitsPerRasterPixel = rasterLayer->rasterUnitsPerPixel(); + } + } + } + } + + return 1.0 / ( mapUnitsPerScreenPixel * mapUnitsPerRasterPixel ); } -void QgsGCPCanvasItem::updatePosition() +void QgsGCPCanvasItem::checkBoundingRectChange() { - setPos( toCanvasCoordinates( mIsGCPSource ? mRasterCoords : mWorldCoords ) ); + prepareGeometryChange(); } Index: src/plugins/georeferencer/qgsgcpcanvasitem.h =================================================================== --- src/plugins/georeferencer/qgsgcpcanvasitem.h (revision 13226) +++ src/plugins/georeferencer/qgsgcpcanvasitem.h (working copy) @@ -20,11 +20,12 @@ #include "qgsmapcanvas.h" #include "qgsmapcanvasitem.h" +class QgsGeorefDataPoint; + class QgsGCPCanvasItem : public QgsMapCanvasItem { public: - QgsGCPCanvasItem( QgsMapCanvas* mapCanvas, const QgsPoint& rasterCoords, - const QgsPoint& worldCoords, bool isGCPSource/* = true*/ ); + QgsGCPCanvasItem( QgsMapCanvas* mapCanvas, const QgsGeorefDataPoint* dataPoint, bool isGCPSource/* = true*/ ); //! draws point information void paint( QPainter* p ); @@ -34,26 +35,23 @@ QPainterPath shape() const; - void setEnabled( bool enabled ); - - void setRasterCoords( QgsPoint p ); - void setWorldCoords( QgsPoint p ); - - int id() { return mId; } - void setId( int id ); - void updatePosition(); + /**Calls prepareGeometryChange()*/ + void checkBoundingRectChange(); + private: + + const QgsGeorefDataPoint* mDataPoint; QSizeF mTextBounds; QBrush mPointBrush; QBrush mLabelBrush; - QgsPoint mRasterCoords; - QgsPoint mWorldCoords; - - int mId; bool mIsGCPSource; - bool mEnabled; + QPen mResidualPen; + + void drawResidualArrow( QPainter* p ); + /**Calculates scale factor for residual display*/ + double residualToScreenFactor() const; }; #endif // QGSGCPCANVASITEM_H Index: src/plugins/georeferencer/qgsgeorefdatapoint.h =================================================================== --- src/plugins/georeferencer/qgsgeorefdatapoint.h (revision 13226) +++ src/plugins/georeferencer/qgsgeorefdatapoint.h (working copy) @@ -39,7 +39,7 @@ bool isEnabled() const { return mEnabled; }; void setEnabled( bool enabled ); - int id() { return mId; } + int id() const { return mId; } void setId( int id ); bool contains( const QPoint &p ); @@ -47,6 +47,9 @@ QgsMapCanvas *srcCanvas() const { return mSrcCanvas; } QgsMapCanvas *dstCanvas() const { return mDstCanvas; } + QPointF residual() const { return mResidual; } + void setResidual( const QPointF& r ); + public slots: void moveTo( const QPoint & ); void updateCoords(); @@ -61,4 +64,5 @@ int mId; bool mEnabled; + QPointF mResidual; }; Index: src/plugins/georeferencer/qgsgeorefdatapoint.cpp =================================================================== --- src/plugins/georeferencer/qgsgeorefdatapoint.cpp (revision 13226) +++ src/plugins/georeferencer/qgsgeorefdatapoint.cpp (working copy) @@ -30,8 +30,8 @@ , mId( -1 ) , mEnabled( enable ) { - mGCPSourceItem = new QgsGCPCanvasItem( srcCanvas, pixelCoords, mapCoords, true ); - mGCPDestinationItem = new QgsGCPCanvasItem( dstCanvas, pixelCoords, mapCoords, false ); + mGCPSourceItem = new QgsGCPCanvasItem( srcCanvas, this, true ); + mGCPDestinationItem = new QgsGCPCanvasItem( dstCanvas, this, false ); mGCPSourceItem->setEnabled( enable ); mGCPDestinationItem->setEnabled( enable ); @@ -58,36 +58,66 @@ void QgsGeorefDataPoint::setPixelCoords( const QgsPoint &p ) { mPixelCoords = p; - mGCPSourceItem->setRasterCoords( p ); - mGCPDestinationItem->setRasterCoords( p ); + mGCPSourceItem->update(); + mGCPDestinationItem->update(); } void QgsGeorefDataPoint::setMapCoords( const QgsPoint &p ) { mMapCoords = p; - mGCPSourceItem->setWorldCoords( p ); - mGCPDestinationItem->setWorldCoords( p ); + if ( mGCPSourceItem ) + { + mGCPSourceItem->update(); + } + if ( mGCPDestinationItem ) + { + mGCPDestinationItem->update(); + } } void QgsGeorefDataPoint::setEnabled( bool enabled ) { - mGCPSourceItem->setEnabled( enabled ); mEnabled = enabled; + if ( mGCPSourceItem ) + { + mGCPSourceItem->update(); + } } void QgsGeorefDataPoint::setId( int id ) { mId = id; - mGCPSourceItem->setId( id ); - mGCPDestinationItem->setId( id ); + if ( mGCPSourceItem ) + { + mGCPSourceItem->update(); + } + if ( mGCPDestinationItem ) + { + mGCPDestinationItem->update(); + } } +void QgsGeorefDataPoint::setResidual( const QPointF& r ) +{ + mResidual = r; + if ( mGCPSourceItem ) + { + mGCPSourceItem->checkBoundingRectChange(); + } +} + void QgsGeorefDataPoint::updateCoords() { - mGCPSourceItem->updatePosition(); - mGCPDestinationItem->updatePosition(); - mGCPSourceItem->update(); - mGCPDestinationItem->update(); + if ( mGCPSourceItem ) + { + mGCPSourceItem->updatePosition(); + mGCPSourceItem->update(); + } + if ( mGCPDestinationItem ) + { + mGCPDestinationItem->updatePosition(); + mGCPDestinationItem->update(); + } } bool QgsGeorefDataPoint::contains( const QPoint &p ) Index: src/plugins/georeferencer/qgsgcplistmodel.cpp =================================================================== --- src/plugins/georeferencer/qgsgcplistmodel.cpp (revision 13226) +++ src/plugins/georeferencer/qgsgcplistmodel.cpp (working copy) @@ -143,6 +143,12 @@ { dX = dY = residual = 0; } + + if ( p ) + { + p->setResidual( QPointF( dX, dY ) ); + } + if ( residual >= 0.f ) { setItem( i, j++, QGSSTANDARDITEM( dX ) /*create_item(dX)*/ );