[QGIS Commit] r13552 - trunk/qgis/src/plugins/georeferencer
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sun May 23 08:43:45 EDT 2010
Author: mmassing
Date: 2010-05-23 08:43:43 -0400 (Sun, 23 May 2010)
New Revision: 13552
Modified:
trunk/qgis/src/plugins/georeferencer/qgsgcplistmodel.cpp
trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.cpp
trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.h
Log:
Applied patch #2731 by mhugent: show georeferencer residuals in map units when possible.
Modified: trunk/qgis/src/plugins/georeferencer/qgsgcplistmodel.cpp
===================================================================
--- trunk/qgis/src/plugins/georeferencer/qgsgcplistmodel.cpp 2010-05-22 21:17:30 UTC (rev 13551)
+++ trunk/qgis/src/plugins/georeferencer/qgsgcplistmodel.cpp 2010-05-23 12:43:43 UTC (rev 13552)
@@ -16,7 +16,7 @@
#include "qgsgcplist.h"
#include "qgsgcplistmodel.h"
-
+#include "qgis.h"
#include "qgsgeorefdatapoint.h"
#include "qgsgeoreftransform.h"
@@ -85,15 +85,11 @@
if ( !mGCPList )
return;
-// // Setup table header
- QStringList itemLabels;
-// // Set column headers
- itemLabels << "on/off" << "id" << "srcX" << "srcY" << "dstX" << "dstY" << "dX" << "dY" << "residual";
-// setColumnCount(itemLabels.size());
- setHorizontalHeaderLabels( itemLabels );
- setRowCount( mGCPList->size() );
+ bool bTransformUpdated = false;
+ bool wldTransform = false;
+ double wldScaleX, wldScaleY, rotation;
+ QgsPoint origin;
- bool bTransformUpdated = false;
if ( mGeorefTransform )
{
vector<QgsPoint> mapCoords, pixelCoords;
@@ -101,8 +97,32 @@
// TODO: the parameters should probable be updated externally (by user interaction)
bTransformUpdated = mGeorefTransform->updateParametersFromGCPs( mapCoords, pixelCoords );
+ //transformation that involves only scaling and rotation (linear or helmert) ?
+ wldTransform = mGeorefTransform->getOriginScaleRotation( origin, wldScaleX, wldScaleY, rotation );
+ if ( wldTransform && !doubleNear( rotation, 0.0 ) )
+ {
+ wldScaleX *= cos( rotation );
+ wldScaleY *= cos( rotation );
+ }
+ if ( wldTransform )
+ {
+
+ }
}
+ // // Setup table header
+ QStringList itemLabels;
+ if ( wldTransform )
+ {
+ itemLabels << "on/off" << "id" << "srcX" << "srcY" << "dstX" << "dstY" << QString( "dX[" ) + tr( "map units" ) + "]" << QString( "dY[" ) + tr( "map units" ) + "]" << "residual";
+ }
+ else
+ {
+ itemLabels << "on/off" << "id" << "srcX" << "srcY" << "dstX" << "dstY" << QString( "dX[" ) + tr( "pixels" ) + "]" << QString( "dY[" ) + tr( "pixels" ) + "]" << "residual";
+ }
+ setHorizontalHeaderLabels( itemLabels );
+ setRowCount( mGCPList->size() );
+
for ( int i = 0; i < mGCPList->sizeAll(); ++i )
{
int j = 0;
@@ -135,8 +155,13 @@
// As transforms of order >=2 are not invertible, we are only
// interested in the residual in this direction
mGeorefTransform->transformWorldToRaster( p->mapCoords(), dst );
- dX = ( dst.x() - p->pixelCoords().x() );
+ dX = ( dst.x() - p->pixelCoords().x() );
dY = -( dst.y() - p->pixelCoords().y() );
+ if ( wldTransform )
+ {
+ dX *= wldScaleX;
+ dY *= wldScaleY;
+ }
residual = sqrt( dX * dX + dY * dY );
}
else
@@ -152,7 +177,7 @@
if ( residual >= 0.f )
{
setItem( i, j++, QGSSTANDARDITEM( dX ) /*create_item<double>(dX)*/ );
- setItem( i, j++, QGSSTANDARDITEM( dY ) /*create_item<double>(-dY)*/);
+ setItem( i, j++, QGSSTANDARDITEM( dY ) /*create_item<double>(-dY)*/ );
setItem( i, j++, QGSSTANDARDITEM( residual ) /*create_item<double>(residual)*/ );
}
else
Modified: trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.cpp
===================================================================
--- trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.cpp 2010-05-22 21:17:30 UTC (rev 13551)
+++ trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.cpp 2010-05-23 12:43:43 UTC (rev 13552)
@@ -136,7 +136,6 @@
QgsGeorefPluginGui::~QgsGeorefPluginGui()
{
- QgsTransformSettingsDialog::resetSettings();
clearGCPData();
// delete layer (and don't signal it as it's our private layer)
@@ -336,6 +335,7 @@
mActionLinkQGisToGeoref->setEnabled( false );
}
+ updateTransformParamLabel();
return true;
}
@@ -472,6 +472,7 @@
}
connect( mCanvas, SIGNAL( extentsChanged() ), pnt, SLOT( updateCoords() ) );
+ updateGeorefTransform();
// if (verbose)
// logRequaredGCPs();
@@ -498,6 +499,7 @@
break;
}
}
+ updateGeorefTransform();
}
void QgsGeorefPluginGui::deleteDataPoint( int index )
@@ -505,6 +507,7 @@
mGCPListWidget->model()->removeRow( index );
delete mPoints.takeAt( index );
mGCPListWidget->updateGCPList();
+ updateGeorefTransform();
}
void QgsGeorefPluginGui::selectPoint( const QPoint &p )
@@ -930,12 +933,24 @@
this, SLOT( replaceDataPoint( QgsGeorefDataPoint*, int ) ) );
connect( mGCPListWidget, SIGNAL( deleteDataPoint( int ) ),
this, SLOT( deleteDataPoint( int ) ) );
+ connect( mGCPListWidget, SIGNAL( pointEnabled( QgsGeorefDataPoint*, int ) ), this, SLOT( updateGeorefTransform() ) );
}
void QgsGeorefPluginGui::createStatusBar()
{
QFont myFont( "Arial", 9 );
+ mTransformParamLabel = new QLabel( statusBar() );
+ mTransformParamLabel->setFont( myFont );
+ mTransformParamLabel->setMinimumWidth( 10 );
+ mTransformParamLabel->setMaximumHeight( 20 );
+ mTransformParamLabel->setMargin( 3 );
+ mTransformParamLabel->setAlignment( Qt::AlignCenter );
+ mTransformParamLabel->setFrameStyle( QFrame::NoFrame );
+ mTransformParamLabel->setText( tr( "Transform: " ) + convertTransformEnumToString( mTransformParam ) );
+ mTransformParamLabel->setToolTip( tr( "Current transform parametrisation" ) );
+ statusBar()->addPermanentWidget( mTransformParamLabel, 0 );
+
mCoordsLabel = new QLabel( QString(), statusBar() );
mCoordsLabel->setFont( myFont );
mCoordsLabel->setMinimumWidth( 10 );
@@ -947,17 +962,6 @@
mCoordsLabel->setText( tr( "Coordinate: " ) );
mCoordsLabel->setToolTip( tr( "Current map coordinate" ) );
statusBar()->addPermanentWidget( mCoordsLabel, 0 );
-
- mTransformParamLabel = new QLabel( statusBar() );
- mTransformParamLabel->setFont( myFont );
- mTransformParamLabel->setMinimumWidth( 10 );
- mTransformParamLabel->setMaximumHeight( 20 );
- mTransformParamLabel->setMargin( 3 );
- mTransformParamLabel->setAlignment( Qt::AlignCenter );
- mTransformParamLabel->setFrameStyle( QFrame::NoFrame );
- mTransformParamLabel->setText( tr( "Transform: " ) + convertTransformEnumToString( mTransformParam ) );
- mTransformParamLabel->setToolTip( tr( "Current transform parametrisation" ) );
- statusBar()->addPermanentWidget( mTransformParamLabel, 0 );
}
void QgsGeorefPluginGui::setupConnections()
@@ -1208,6 +1212,53 @@
return true;
}
+bool QgsGeorefPluginGui::calculateMeanError( double& error ) const
+{
+ if ( mGeorefTransform.transformParametrisation() == QgsGeorefTransform::InvalidTransform )
+ {
+ return false;
+ }
+
+ int nPointsEnabled = 0;
+ QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
+ for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
+ {
+ if (( *gcpIt )->isEnabled() )
+ {
+ ++nPointsEnabled;
+ }
+ }
+
+ if ( nPointsEnabled == mGeorefTransform.getMinimumGCPCount() )
+ {
+ error = 0;
+ return true;
+ }
+ else if ( nPointsEnabled < mGeorefTransform.getMinimumGCPCount() )
+ {
+ return false;
+ }
+
+ double sumVxSquare = 0;
+ double sumVySquare = 0;
+ double resXMap, resYMap;
+
+ gcpIt = mPoints.constBegin();
+ for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
+ {
+ if (( *gcpIt )->isEnabled() )
+ {
+ sumVxSquare += (( *gcpIt )->residual().x() * ( *gcpIt )->residual().x() );
+ sumVySquare += (( *gcpIt )->residual().y() * ( *gcpIt )->residual().y() );
+ }
+ }
+
+ // Calculate the root mean square error, adjusted for degrees of freedom of the transform
+ // Caveat: The number of DoFs is assumed to be even (as each control point fixes two degrees of freedom).
+ error = sqrt(( sumVxSquare + sumVySquare ) / ( nPointsEnabled - mGeorefTransform.getMinimumGCPCount() ));
+ return true;
+}
+
bool QgsGeorefPluginGui::writePDFReportFile( const QString& fileName, const QgsGeorefTransform& transform )
{
if ( !mCanvas )
@@ -1250,7 +1301,24 @@
titleLabel->setFrame( false );
//composer map
- QgsComposerMap* composerMap = new QgsComposerMap( composition, 2, titleLabel->rect().bottom() + titleLabel->transform().dy(), 206, 277 );
+ QgsRectangle canvasExtent = mCanvas->extent();
+ //calculate width and height considering extent aspect ratio and max Width 206, maxHeight 70
+ double widthExtentRatio = 206 / canvasExtent.width();
+ double heightExtentRatio = 70 / canvasExtent.height();
+ double mapWidthMM = 0;
+ double mapHeightMM = 0;
+ if ( widthExtentRatio < heightExtentRatio )
+ {
+ mapWidthMM = 206;
+ mapHeightMM = 206 / canvasExtent.width() * canvasExtent.height();
+ }
+ else
+ {
+ mapHeightMM = 70;
+ mapWidthMM = 70 / canvasExtent.height() * canvasExtent.width();
+ }
+
+ QgsComposerMap* composerMap = new QgsComposerMap( composition, 2, titleLabel->rect().bottom() + titleLabel->transform().dy(), mapWidthMM, mapHeightMM );
composerMap->setLayerSet( canvasRenderer->layerSet() );
composerMap->setNewExtent( mCanvas->extent() );
composerMap->setMapCanvas( mCanvas );
@@ -1266,26 +1334,9 @@
//transformation that involves only scaling and rotation (linear or helmert) ?
bool wldTransform = transform.getOriginScaleRotation( origin, scaleX, scaleY, rotation );
- //consider rotation in scale parameter
- double wldScaleX = scaleX;
- double wldScaleY = scaleY;
- if ( wldTransform && !doubleNear( rotation, 0.0 ) )
- {
- wldScaleX *= cos( rotation );
- wldScaleY *= cos( rotation );
- }
-
if ( wldTransform )
{
- QString parameterTitle = tr( "Transformation parameters" );
- if ( transform.transformParametrisation() == QgsGeorefTransform::Helmert )
- {
- parameterTitle += " (Helmert)";
- }
- else if ( transform.transformParametrisation() == QgsGeorefTransform::Linear )
- {
- parameterTitle += " (Linear)";
- }
+ QString parameterTitle = tr( "Transformation parameters" ) + QString( " (" ) + convertTransformEnumToString( transform.transformParametrisation() ) + QString( ")" );
parameterLabel = new QgsComposerLabel( composition );
parameterLabel->setFont( titleFont );
parameterLabel->setText( parameterTitle );
@@ -1304,30 +1355,10 @@
}
}
- //calculate mean error (in map units)
+ //calculate mean error
double meanError = 0;
- if ( nPointsEnabled > 2 )
- {
- double sumVxSquare = 0;
- double sumVySquare = 0;
- double resXMap, resYMap;
+ calculateMeanError( meanError );
- QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
- for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
- {
- if (( *gcpIt )->isEnabled() )
- {
- resXMap = ( *gcpIt )->residual().x() * wldScaleX;
- resYMap = ( *gcpIt )->residual().y() * wldScaleY;
- sumVxSquare += ( resXMap * resXMap );
- sumVySquare += ( resYMap * resYMap );
- }
- }
-
- meanError = sqrt(( sumVxSquare + sumVySquare ) / ( 2 * nPointsEnabled - 4 ) ) * sqrt( 2.0 );
- }
-
-
parameterTable = new QgsComposerTextTable( composition );
parameterTable->setHeaderFont( tableHeaderFont );
parameterTable->setContentFont( tableContentFont );
@@ -1366,7 +1397,7 @@
//convert residual scale bar plot to map units if scaling is equal in x- and y-direction (e.g. helmert)
if ( wldTransform )
{
- if ( doubleNear( wldScaleX, wldScaleY ) )
+ if ( doubleNear( scaleX, scaleX ) )
{
resPlotItem->setPixelToMapUnits( scaleX );
resPlotItem->setConvertScaleToMapUnits( true );
@@ -1394,17 +1425,7 @@
{
QStringList currentGCPStrings;
QPointF residual = ( *gcpIt )->residual();
- double residualX = residual.x();
- if ( wldTransform )
- {
- residualX *= wldScaleX;
- }
- double residualY = residual.y();
- if ( wldTransform )
- {
- residualY *= wldScaleY;
- }
- double residualTot = sqrt( residualX * residualX + residualY * residualY );
+ double residualTot = sqrt( residual.x() * residual.x() + residual.y() * residual.y() );
currentGCPStrings << QString::number(( *gcpIt )->id() );
if (( *gcpIt )->isEnabled() )
@@ -1416,7 +1437,7 @@
currentGCPStrings << tr( "no" );
}
currentGCPStrings << QString::number(( *gcpIt )->pixelCoords().x(), 'f', 2 ) << QString::number(( *gcpIt )->pixelCoords().y(), 'f', 2 ) << QString::number(( *gcpIt )->mapCoords().x(), 'f', 2 )\
- << QString::number(( *gcpIt )->mapCoords().y(), 'f', 2 ) << QString::number( residualX ) << QString::number( residualY ) << QString::number( residualTot );
+ << QString::number(( *gcpIt )->mapCoords().y(), 'f', 2 ) << QString::number( residual.x() ) << QString::number( residual.y() ) << QString::number( residualTot );
gcpTable->addRow( currentGCPStrings );
}
@@ -1443,6 +1464,35 @@
return true;
}
+void QgsGeorefPluginGui::updateTransformParamLabel()
+{
+ if ( !mTransformParamLabel )
+ {
+ return;
+ }
+
+ QString transformName = convertTransformEnumToString( mGeorefTransform.transformParametrisation() );
+ QString labelString = tr( "Transform: " ) + transformName;
+
+ QgsPoint origin;
+ double scaleX, scaleY, rotation;
+ if ( mGeorefTransform.getOriginScaleRotation( origin, scaleX, scaleY, rotation ) )
+ {
+ labelString += " ";
+ labelString += tr( "Translation (%1, %2)" ).arg( origin.x() ).arg( origin.y() ); labelString += " ";
+ labelString += tr( "Scale (%1, %2)" ).arg( scaleX ).arg( scaleY ); labelString += " ";
+ labelString += tr( "Rotation: %1" ).arg( rotation );
+ }
+
+ double meanError = 0;
+ if ( calculateMeanError( meanError ) )
+ {
+ labelString += " ";
+ labelString += tr( "Mean error: %1" ).arg( meanError );
+ }
+ mTransformParamLabel->setText( labelString );
+}
+
// Gdal script
void QgsGeorefPluginGui::showGDALScript( int argNum... )
{
@@ -1605,22 +1655,20 @@
bool QgsGeorefPluginGui::updateGeorefTransform()
{
- if ( mGCPsDirty || !mGeorefTransform.parametersInitialized() )
+ std::vector<QgsPoint> mapCoords, pixelCoords;
+ if ( mGCPListWidget->gcpList() )
+ mGCPListWidget->gcpList()->createGCPVectors( mapCoords, pixelCoords );
+ else
+ return false;
+
+ // Parametrize the transform with GCPs
+ if ( !mGeorefTransform.updateParametersFromGCPs( mapCoords, pixelCoords ) )
{
- std::vector<QgsPoint> mapCoords, pixelCoords;
- if ( mGCPListWidget->gcpList() )
- mGCPListWidget->gcpList()->createGCPVectors( mapCoords, pixelCoords );
- else
- return false;
+ return false;
+ }
- // Parametrize the transform with GCPs
- if ( !mGeorefTransform.updateParametersFromGCPs( mapCoords, pixelCoords ) )
- {
- return false;
- }
-
- mGCPsDirty = false;
- }
+ mGCPsDirty = false;
+ updateTransformParamLabel();
return true;
}
Modified: trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.h
===================================================================
--- trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.h 2010-05-22 21:17:30 UTC (rev 13551)
+++ trunk/qgis/src/plugins/georeferencer/qgsgeorefplugingui.h 2010-05-23 12:43:43 UTC (rev 13552)
@@ -102,6 +102,8 @@
void showMouseCoords( const QgsPoint pt );
void updateMouseCoordinatePrecision();
+ bool updateGeorefTransform();
+
private:
enum SaveGCPs
{
@@ -133,6 +135,7 @@
bool georeference();
bool writeWorldFile( QgsPoint origin, double pixelXSize, double pixelYSize, double rotation );
bool writePDFReportFile( const QString& fileName, const QgsGeorefTransform& transform );
+ void updateTransformParamLabel();
// gdal script
void showGDALScript( int argNum... );
@@ -145,7 +148,6 @@
// utils
bool checkReadyGeoref();
- bool updateGeorefTransform();
QgsRectangle transformViewportBoundingBox( const QgsRectangle &canvasExtent, const QgsGeorefTransform &t,
bool rasterToWorld = true, uint numSamples = 4 );
QString convertTransformEnumToString( QgsGeorefTransform::TransformParametrisation transform );
@@ -159,6 +161,16 @@
void logRequaredGCPs();
void clearGCPData();
+ /**
+ * Calculates root mean squared error for the currently active
+ * ground control points and transform method.
+ * Note that he RMSE measure is adjusted for the degrees of freedom of the
+ * used polynomial transform.
+ * @param error out: the mean error
+ * @return true in case of success
+ */
+ bool calculateMeanError( double& error ) const;
+
/**Docks / undocks this window*/
void dockThisWindow( bool dock );
More information about the QGIS-commit
mailing list