100519_georefpatch.diff

Marco Hugentobler, 2010-05-19 02:19 AM

Download (15.6 KB)

View differences:

src/plugins/georeferencer/qgsgeorefplugingui.h (Arbeitskopie)
102 102
    void showMouseCoords( const QgsPoint pt );
103 103
    void updateMouseCoordinatePrecision();
104 104

  
105
    bool updateGeorefTransform();
106

  
105 107
  private:
106 108
    enum SaveGCPs
107 109
    {
......
133 135
    bool georeference();
134 136
    bool writeWorldFile( QgsPoint origin, double pixelXSize, double pixelYSize, double rotation );
135 137
    bool writePDFReportFile( const QString& fileName, const QgsGeorefTransform& transform );
138
    void updateTransformParamLabel();
136 139

  
137 140
    // gdal script
138 141
    void showGDALScript( int argNum... );
......
145 148

  
146 149
    // utils
147 150
    bool checkReadyGeoref();
148
    bool updateGeorefTransform();
149 151
    QgsRectangle transformViewportBoundingBox( const QgsRectangle &canvasExtent, const QgsGeorefTransform &t,
150 152
        bool rasterToWorld = true, uint numSamples = 4 );
151 153
    QString convertTransformEnumToString( QgsGeorefTransform::TransformParametrisation transform );
......
158 160
    void logTransformOptions();
159 161
    void logRequaredGCPs();
160 162
    void clearGCPData();
163
    /**Calculates mean transformation error
164
      @param error out: the mean error
165
      @return true in case of success*/
166
    bool calculateMeanError( double& error ) const;
161 167

  
162 168

  
163 169
    QMenu *mPanelMenu;
src/plugins/georeferencer/qgsgcplistmodel.cpp (Arbeitskopie)
16 16

  
17 17
#include "qgsgcplist.h"
18 18
#include "qgsgcplistmodel.h"
19

  
19
#include "qgis.h"
20 20
#include "qgsgeorefdatapoint.h"
21 21
#include "qgsgeoreftransform.h"
22 22

  
......
85 85
  if ( !mGCPList )
86 86
    return;
87 87

  
88
//  // Setup table header
89
  QStringList itemLabels;
90
//  // Set column headers
91
  itemLabels << "on/off" << "id" << "srcX" << "srcY" << "dstX" << "dstY" << "dX" << "dY" << "residual";
92
//  setColumnCount(itemLabels.size());
93
  setHorizontalHeaderLabels( itemLabels );
94
  setRowCount( mGCPList->size() );
88
  bool bTransformUpdated = false;
89
  bool wldTransform = false;
90
  double wldScaleX, wldScaleY, rotation;
91
  QgsPoint origin;
95 92

  
96
  bool bTransformUpdated = false;
97 93
  if ( mGeorefTransform )
98 94
  {
99 95
    vector<QgsPoint> mapCoords, pixelCoords;
......
101 97

  
102 98
    // TODO: the parameters should probable be updated externally (by user interaction)
103 99
    bTransformUpdated = mGeorefTransform->updateParametersFromGCPs( mapCoords, pixelCoords );
100
    //transformation that involves only scaling and rotation (linear or helmert) ?
101
    wldTransform = mGeorefTransform->getOriginScaleRotation( origin, wldScaleX, wldScaleY, rotation );
102
    if ( wldTransform && !doubleNear( rotation, 0.0 ) )
103
    {
104
      wldScaleX *= cos( rotation );
105
      wldScaleY *= cos( rotation );
106
    }
107
    if ( wldTransform )
108
    {
109

  
110
    }
104 111
  }
105 112

  
113
  //  // Setup table header
114
  QStringList itemLabels;
115
  if ( wldTransform )
116
  {
117
    itemLabels << "on/off" << "id" << "srcX" << "srcY" << "dstX" << "dstY" << QString( "dX[" ) + tr( "map units" ) + "]" << QString( "dY[" ) + tr( "map units" ) + "]" << "residual";
118
  }
119
  else
120
  {
121
    itemLabels << "on/off" << "id" << "srcX" << "srcY" << "dstX" << "dstY" << QString( "dX[" ) + tr( "pixels" ) + "]" << QString( "dY[" ) + tr( "pixels" ) + "]" << "residual";
122
  }
123
  setHorizontalHeaderLabels( itemLabels );
124
  setRowCount( mGCPList->size() );
125

  
106 126
  for ( int i = 0; i < mGCPList->sizeAll(); ++i )
107 127
  {
108 128
    int j = 0;
......
135 155
      // As transforms of order >=2 are not invertible, we are only
136 156
      // interested in the residual in this direction
137 157
      mGeorefTransform->transformWorldToRaster( p->mapCoords(), dst );
138
      dX =  ( dst.x() - p->pixelCoords().x() );
158
      dX = ( dst.x() - p->pixelCoords().x() );
139 159
      dY = -( dst.y() - p->pixelCoords().y() );
160
      if ( wldTransform )
161
      {
162
        dX *= wldScaleX;
163
        dY *= wldScaleY;
164
      }
140 165
      residual = sqrt( dX * dX + dY * dY );
141 166
    }
142 167
    else
......
152 177
    if ( residual >= 0.f )
153 178
    {
154 179
      setItem( i, j++, QGSSTANDARDITEM( dX ) /*create_item<double>(dX)*/ );
155
      setItem( i, j++, QGSSTANDARDITEM( dY ) /*create_item<double>(-dY)*/);
180
      setItem( i, j++, QGSSTANDARDITEM( dY ) /*create_item<double>(-dY)*/ );
156 181
      setItem( i, j++, QGSSTANDARDITEM( residual ) /*create_item<double>(residual)*/ );
157 182
    }
158 183
    else
src/plugins/georeferencer/qgsgeorefplugingui.cpp (Arbeitskopie)
108 108

  
109 109
QgsGeorefPluginGui::~QgsGeorefPluginGui()
110 110
{
111
  QgsTransformSettingsDialog::resetSettings();
112 111
  clearGCPData();
113 112

  
114 113
  // delete layer (and don't signal it as it's our private layer)
......
307 306
    mActionLinkQGisToGeoref->setEnabled( false );
308 307
  }
309 308

  
309
  updateTransformParamLabel();
310 310
  return true;
311 311
}
312 312

  
......
443 443
  }
444 444

  
445 445
  connect( mCanvas, SIGNAL( extentsChanged() ), pnt, SLOT( updateCoords() ) );
446
  updateGeorefTransform();
446 447

  
447 448
  //  if (verbose)
448 449
  //    logRequaredGCPs();
......
469 470
      break;
470 471
    }
471 472
  }
473
  updateGeorefTransform();
472 474
}
473 475

  
474 476
void QgsGeorefPluginGui::deleteDataPoint( int index )
......
476 478
  mGCPListWidget->model()->removeRow( index );
477 479
  delete mPoints.takeAt( index );
478 480
  mGCPListWidget->updateGCPList();
481
  updateGeorefTransform();
479 482
}
480 483

  
481 484
void QgsGeorefPluginGui::selectPoint( const QPoint &p )
......
890 893
           this, SLOT( replaceDataPoint( QgsGeorefDataPoint*, int ) ) );
891 894
  connect( mGCPListWidget, SIGNAL( deleteDataPoint( int ) ),
892 895
           this, SLOT( deleteDataPoint( int ) ) );
896
  connect( mGCPListWidget, SIGNAL( pointEnabled( QgsGeorefDataPoint*, int ) ), this, SLOT( updateGeorefTransform() ) );
893 897
}
894 898

  
895 899
void QgsGeorefPluginGui::createStatusBar()
896 900
{
897 901
  QFont myFont( "Arial", 9 );
898 902

  
903
  mTransformParamLabel = new QLabel( statusBar() );
904
  mTransformParamLabel->setFont( myFont );
905
  mTransformParamLabel->setMinimumWidth( 10 );
906
  mTransformParamLabel->setMaximumHeight( 20 );
907
  mTransformParamLabel->setMargin( 3 );
908
  mTransformParamLabel->setAlignment( Qt::AlignCenter );
909
  mTransformParamLabel->setFrameStyle( QFrame::NoFrame );
910
  mTransformParamLabel->setText( tr( "Transform: " ) + convertTransformEnumToString( mTransformParam ) );
911
  mTransformParamLabel->setToolTip( tr( "Current transform parametrisation" ) );
912
  statusBar()->addPermanentWidget( mTransformParamLabel, 0 );
913

  
899 914
  mCoordsLabel = new QLabel( QString(), statusBar() );
900 915
  mCoordsLabel->setFont( myFont );
901 916
  mCoordsLabel->setMinimumWidth( 10 );
......
907 922
  mCoordsLabel->setText( tr( "Coordinate: " ) );
908 923
  mCoordsLabel->setToolTip( tr( "Current map coordinate" ) );
909 924
  statusBar()->addPermanentWidget( mCoordsLabel, 0 );
910

  
911
  mTransformParamLabel = new QLabel( statusBar() );
912
  mTransformParamLabel->setFont( myFont );
913
  mTransformParamLabel->setMinimumWidth( 10 );
914
  mTransformParamLabel->setMaximumHeight( 20 );
915
  mTransformParamLabel->setMargin( 3 );
916
  mTransformParamLabel->setAlignment( Qt::AlignCenter );
917
  mTransformParamLabel->setFrameStyle( QFrame::NoFrame );
918
  mTransformParamLabel->setText( tr( "Transform: " ) + convertTransformEnumToString( mTransformParam ) );
919
  mTransformParamLabel->setToolTip( tr( "Current transform parametrisation" ) );
920
  statusBar()->addPermanentWidget( mTransformParamLabel, 0 );
921 925
}
922 926

  
923 927
void QgsGeorefPluginGui::setupConnections()
......
1168 1172
  return true;
1169 1173
}
1170 1174

  
1175
bool QgsGeorefPluginGui::calculateMeanError( double& error ) const
1176
{
1177
  if ( mGeorefTransform.transformParametrisation() == QgsGeorefTransform::InvalidTransform )
1178
  {
1179
    return false;
1180
  }
1181

  
1182
  int nPointsEnabled = 0;
1183
  QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
1184
  for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
1185
  {
1186
    if (( *gcpIt )->isEnabled() )
1187
    {
1188
      ++nPointsEnabled;
1189
    }
1190
  }
1191

  
1192
  if ( nPointsEnabled == mGeorefTransform.getMinimumGCPCount() )
1193
  {
1194
    error = 0;
1195
    return true;
1196
  }
1197
  else if ( nPointsEnabled < mGeorefTransform.getMinimumGCPCount() )
1198
  {
1199
    return false;
1200
  }
1201

  
1202
  double sumVxSquare = 0;
1203
  double sumVySquare = 0;
1204
  double resXMap, resYMap;
1205

  
1206
  gcpIt = mPoints.constBegin();
1207
  for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
1208
  {
1209
    if (( *gcpIt )->isEnabled() )
1210
    {
1211
      sumVxSquare += (( *gcpIt )->residual().x() * ( *gcpIt )->residual().x() );
1212
      sumVySquare += (( *gcpIt )->residual().y() * ( *gcpIt )->residual().y() );
1213
    }
1214
  }
1215

  
1216
  error = sqrt(( sumVxSquare + sumVySquare ) / ( 2 * ( nPointsEnabled - mGeorefTransform.getMinimumGCPCount() ) ) ) * sqrt( 2.0 );
1217
  return true;
1218
}
1219

  
1171 1220
bool QgsGeorefPluginGui::writePDFReportFile( const QString& fileName, const QgsGeorefTransform& transform )
1172 1221
{
1173 1222
  if ( !mCanvas )
......
1210 1259
  titleLabel->setFrame( false );
1211 1260

  
1212 1261
  //composer map
1213
  QgsComposerMap* composerMap = new QgsComposerMap( composition, 2, titleLabel->rect().bottom() + titleLabel->transform().dy(), 206, 277 );
1262
  QgsRectangle canvasExtent = mCanvas->extent();
1263
  //calculate width and height considering extent aspect ratio and max Width 206, maxHeight 70
1264
  double widthExtentRatio = 206 / canvasExtent.width();
1265
  double heightExtentRatio = 70 / canvasExtent.height();
1266
  double mapWidthMM = 0;
1267
  double mapHeightMM = 0;
1268
  if ( widthExtentRatio < heightExtentRatio )
1269
  {
1270
    mapWidthMM = 206;
1271
    mapHeightMM = 206 / canvasExtent.width() * canvasExtent.height();
1272
  }
1273
  else
1274
  {
1275
    mapHeightMM = 70;
1276
    mapWidthMM = 70 / canvasExtent.height() * canvasExtent.width();
1277
  }
1278

  
1279
  QgsComposerMap* composerMap = new QgsComposerMap( composition, 2, titleLabel->rect().bottom() + titleLabel->transform().dy(), mapWidthMM, mapHeightMM );
1214 1280
  composerMap->setLayerSet( canvasRenderer->layerSet() );
1215 1281
  composerMap->setNewExtent( mCanvas->extent() );
1216 1282
  composerMap->setMapCanvas( mCanvas );
......
1226 1292
  //transformation that involves only scaling and rotation (linear or helmert) ?
1227 1293
  bool wldTransform = transform.getOriginScaleRotation( origin, scaleX, scaleY, rotation );
1228 1294

  
1229
  //consider rotation in scale parameter
1230
  double wldScaleX = scaleX;
1231
  double wldScaleY = scaleY;
1232
  if ( wldTransform && !doubleNear( rotation, 0.0 ) )
1233
  {
1234
    wldScaleX *= cos( rotation );
1235
    wldScaleY *= cos( rotation );
1236
  }
1237

  
1238 1295
  if ( wldTransform )
1239 1296
  {
1240
    QString parameterTitle = tr( "Transformation parameters" );
1241
    if ( transform.transformParametrisation() == QgsGeorefTransform::Helmert )
1242
    {
1243
      parameterTitle += " (Helmert)";
1244
    }
1245
    else if ( transform.transformParametrisation() == QgsGeorefTransform::Linear )
1246
    {
1247
      parameterTitle += " (Linear)";
1248
    }
1297
    QString parameterTitle = tr( "Transformation parameters" ) + QString( " (" ) + convertTransformEnumToString( transform.transformParametrisation() ) + QString( ")" );
1249 1298
    parameterLabel = new QgsComposerLabel( composition );
1250 1299
    parameterLabel->setFont( titleFont );
1251 1300
    parameterLabel->setText( parameterTitle );
......
1264 1313
      }
1265 1314
    }
1266 1315

  
1267
    //calculate mean error (in map units)
1316
    //calculate mean error
1268 1317
    double meanError = 0;
1269
    if ( nPointsEnabled > 2 )
1270
    {
1271
      double sumVxSquare = 0;
1272
      double sumVySquare = 0;
1273
      double resXMap, resYMap;
1318
    calculateMeanError( meanError );
1274 1319

  
1275
      QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
1276
      for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
1277
      {
1278
        if (( *gcpIt )->isEnabled() )
1279
        {
1280
          resXMap = ( *gcpIt )->residual().x() * wldScaleX;
1281
          resYMap = ( *gcpIt )->residual().y() * wldScaleY;
1282
          sumVxSquare += ( resXMap * resXMap );
1283
          sumVySquare += ( resYMap * resYMap );
1284
        }
1285
      }
1286

  
1287
      meanError = sqrt(( sumVxSquare + sumVySquare ) / ( 2 * nPointsEnabled - 4 ) ) * sqrt( 2.0 );
1288
    }
1289

  
1290

  
1291 1320
    parameterTable = new QgsComposerTextTable( composition );
1292 1321
    parameterTable->setHeaderFont( tableHeaderFont );
1293 1322
    parameterTable->setContentFont( tableContentFont );
......
1326 1355
  //convert residual scale bar plot to map units if scaling is equal in x- and y-direction (e.g. helmert)
1327 1356
  if ( wldTransform )
1328 1357
  {
1329
    if ( doubleNear( wldScaleX, wldScaleY ) )
1358
    if ( doubleNear( scaleX, scaleX ) )
1330 1359
    {
1331 1360
      resPlotItem->setPixelToMapUnits( scaleX );
1332 1361
      resPlotItem->setConvertScaleToMapUnits( true );
......
1354 1383
  {
1355 1384
    QStringList currentGCPStrings;
1356 1385
    QPointF residual = ( *gcpIt )->residual();
1357
    double residualX = residual.x();
1358
    if ( wldTransform )
1359
    {
1360
      residualX *= wldScaleX;
1361
    }
1362
    double residualY = residual.y();
1363
    if ( wldTransform )
1364
    {
1365
      residualY *= wldScaleY;
1366
    }
1367
    double residualTot = sqrt( residualX * residualX + residualY * residualY );
1386
    double residualTot = sqrt( residual.x() * residual.x() +  residual.y() * residual.y() );
1368 1387

  
1369 1388
    currentGCPStrings << QString::number(( *gcpIt )->id() );
1370 1389
    if (( *gcpIt )->isEnabled() )
......
1376 1395
      currentGCPStrings << tr( "no" );
1377 1396
    }
1378 1397
    currentGCPStrings << QString::number(( *gcpIt )->pixelCoords().x(), 'f', 2 ) << QString::number(( *gcpIt )->pixelCoords().y(), 'f', 2 ) << QString::number(( *gcpIt )->mapCoords().x(), 'f', 2 )\
1379
    <<  QString::number(( *gcpIt )->mapCoords().y(), 'f', 2 ) <<  QString::number( residualX ) <<  QString::number( residualY ) << QString::number( residualTot );
1398
    <<  QString::number(( *gcpIt )->mapCoords().y(), 'f', 2 ) <<  QString::number( residual.x() ) <<  QString::number( residual.y() ) << QString::number( residualTot );
1380 1399
    gcpTable->addRow( currentGCPStrings );
1381 1400
  }
1382 1401

  
......
1403 1422
  return true;
1404 1423
}
1405 1424

  
1425
void QgsGeorefPluginGui::updateTransformParamLabel()
1426
{
1427
  if ( !mTransformParamLabel )
1428
  {
1429
    return;
1430
  }
1431

  
1432
  QString transformName = convertTransformEnumToString( mGeorefTransform.transformParametrisation() );
1433
  QString labelString = tr( "Transform: " ) + transformName;
1434

  
1435
  QgsPoint origin;
1436
  double scaleX, scaleY, rotation;
1437
  if ( mGeorefTransform.getOriginScaleRotation( origin, scaleX, scaleY, rotation ) )
1438
  {
1439
    labelString += " ";
1440
    labelString += tr( "Translation (%1, %2)" ).arg( origin.x() ).arg( origin.y() ); labelString += " ";
1441
    labelString += tr( "Scale (%1, %2)" ).arg( scaleX ).arg( scaleY ); labelString += " ";
1442
    labelString += tr( "Rotation: %1" ).arg( rotation );
1443
  }
1444

  
1445
  double meanError = 0;
1446
  if ( calculateMeanError( meanError ) )
1447
  {
1448
    labelString += " ";
1449
    labelString += tr( "Mean error: %1" ).arg( meanError );
1450
  }
1451
  mTransformParamLabel->setText( labelString );
1452
}
1453

  
1406 1454
// Gdal script
1407 1455
void QgsGeorefPluginGui::showGDALScript( int argNum... )
1408 1456
{
......
1565 1613

  
1566 1614
bool QgsGeorefPluginGui::updateGeorefTransform()
1567 1615
{
1568
  if ( mGCPsDirty || !mGeorefTransform.parametersInitialized() )
1616
  std::vector<QgsPoint> mapCoords, pixelCoords;
1617
  if ( mGCPListWidget->gcpList() )
1618
    mGCPListWidget->gcpList()->createGCPVectors( mapCoords, pixelCoords );
1619
  else
1620
    return false;
1621

  
1622
  // Parametrize the transform with GCPs
1623
  if ( !mGeorefTransform.updateParametersFromGCPs( mapCoords, pixelCoords ) )
1569 1624
  {
1570
    std::vector<QgsPoint> mapCoords, pixelCoords;
1571
    if ( mGCPListWidget->gcpList() )
1572
      mGCPListWidget->gcpList()->createGCPVectors( mapCoords, pixelCoords );
1573
    else
1574
      return false;
1625
    return false;
1626
  }
1575 1627

  
1576
    // Parametrize the transform with GCPs
1577
    if ( !mGeorefTransform.updateParametersFromGCPs( mapCoords, pixelCoords ) )
1578
    {
1579
      return false;
1580
    }
1581

  
1582
    mGCPsDirty = false;
1583
  }
1628
  mGCPsDirty = false;
1629
  updateTransformParamLabel();
1584 1630
  return true;
1585 1631
}
1586 1632