[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