100423_georefpatch.diff

Marco Hugentobler, 2010-04-23 01:33 AM

Download (50.2 KB)

View differences:

src/plugins/georeferencer/qgsgcpcanvasitem.cpp (working copy)
35 35

  
36 36
void QgsGCPCanvasItem::paint( QPainter* p )
37 37
{
38
  QgsRenderContext context;
39
  if ( !setRenderContextVariables( p, context ) )
40
  {
41
    return;
42
  }
43

  
38 44
  p->setRenderHint( QPainter::Antialiasing );
39 45

  
40 46
  bool enabled = true;
......
57 63

  
58 64
  QSettings s;
59 65
  bool showIDs = s.value( "/Plugin-GeoReferencer/Config/ShowId" ).toBool();
60
  if ( !showIDs && mIsGCPSource )
66
  bool showCoords = s.value( "/Plugin-GeoReferencer/Config/ShowCoords" ).toBool();
67

  
68
  QString msg;
69
  if ( showIDs && showCoords )
61 70
  {
62
    QString msg = QString( "X %1\nY %2" ).arg( QString::number( worldCoords.x(), 'f' ) ).
63
                  arg( QString::number( worldCoords.y(), 'f' ) );
64
    p->setFont( QFont( "helvetica", 9 ) );
65
    QRect textBounds = p->boundingRect( 6, 6, 10, 10, Qt::AlignLeft, msg );
66
    p->setBrush( mLabelBrush );
67
    p->drawRect( textBounds.x() - 2, textBounds.y() - 2, textBounds.width() + 4, textBounds.height() + 4 );
68
    p->drawText( textBounds, Qt::AlignLeft, msg );
69
    mTextBounds = QSizeF( textBounds.width() + 4, textBounds.height() + 4 );
71
    msg = QString( "%1\nX %2\nY %3" ).arg( QString::number( id ) ).arg( QString::number( worldCoords.x(), 'f' ) ).arg( QString::number( worldCoords.y(), 'f' ) );
70 72
  }
71 73
  else if ( showIDs )
72 74
  {
73
    p->setFont( QFont( "helvetica", 12 ) );
74
    QString msg = QString::number( id );
75
    msg = msg = QString::number( id );
76
  }
77
  else if ( showCoords )
78
  {
79
    msg = QString( "X %1\nY %2" ).arg( QString::number( worldCoords.x(), 'f' ) ).arg( QString::number( worldCoords.y(), 'f' ) );
80
  }
81

  
82
  if ( !msg.isEmpty() )
83
  {
75 84
    p->setBrush( mLabelBrush );
76
    p->drawRect( 5, 4, p->fontMetrics().width( msg ) + 2, 14 );
77
    p->drawText( 6, 16, msg );
78
    QFontMetrics fm = p->fontMetrics();
79
    mTextBounds = QSize( fm.width( msg ) + 4, fm.height() + 4 );
85
    QFont textFont( "helvetica" );
86
    textFont.setPixelSize( fontSizePainterUnits( 12, context ) );
87
    p->setFont( textFont );
88
    QRectF textBounds = p->boundingRect( 3 * context.scaleFactor(), 3 * context.scaleFactor(), 5 * context.scaleFactor(), 5 * context.scaleFactor(), Qt::AlignLeft, msg );
89
    mTextBoxRect = QRectF( textBounds.x() - context.scaleFactor() * 1, textBounds.y() - context.scaleFactor() * 1, \
90
                           textBounds.width() + 2 * context.scaleFactor(), textBounds.height() + 2 * context.scaleFactor() );
91
    p->drawRect( mTextBoxRect );
92
    p->drawText( textBounds, Qt::AlignLeft, msg );
80 93
  }
81 94

  
82
  drawResidualArrow( p );
95
  if ( data( 0 ) != "composer" ) //draw residuals only on screen
96
  {
97
    drawResidualArrow( p, context );
98
  }
83 99
}
84 100

  
85 101
QRectF QgsGCPCanvasItem::boundingRect() const
......
91 107
  {
92 108
    residual = mDataPoint->residual();
93 109
  }
110

  
111
  //only considering screen resolution is ok for the bounding box function
94 112
  double rf = residualToScreenFactor();
95 113

  
96 114
  if ( residual.x() > 0 )
......
116 134

  
117 135
  QRectF residualArrowRect( QPointF( residualLeft, residualTop ), QPointF( residualRight, residualBottom ) );
118 136
  QRectF markerRect( -2, -2, mTextBounds.width() + 6, mTextBounds.height() + 6 );
119
  return residualArrowRect.united( markerRect );
137
  QRectF boundingRect =  residualArrowRect.united( markerRect );
138
  if ( !mTextBoxRect.isNull() )
139
  {
140
    boundingRect = boundingRect.united( mTextBoxRect );
141
  }
142
  return boundingRect;
120 143
}
121 144

  
122 145
QPainterPath QgsGCPCanvasItem::shape() const
......
138 161
  setPos( toCanvasCoordinates( mIsGCPSource ? mDataPoint->pixelCoords() : mDataPoint->mapCoords() ) );
139 162
}
140 163

  
141
void QgsGCPCanvasItem::drawResidualArrow( QPainter* p )
164
void QgsGCPCanvasItem::drawResidualArrow( QPainter* p, const QgsRenderContext& context )
142 165
{
143
  if ( !mDataPoint || !mIsGCPSource )
166
  if ( !mDataPoint || !mIsGCPSource || !mMapCanvas )
144 167
  {
145 168
    return;
146 169
  }
......
188 211
{
189 212
  prepareGeometryChange();
190 213
}
214

  
215
double QgsGCPCanvasItem::fontSizePainterUnits( double points, const QgsRenderContext& c )
216
{
217
  return points * 0.3527 * c.scaleFactor();
218
}
219

  
src/plugins/georeferencer/qgsresidualplotitem.cpp (revision 0)
1
#include "qgsresidualplotitem.h"
2
#include "qgsgeorefdatapoint.h"
3
#include <QPainter>
4
#include <cfloat>
5
#ifndef Q_OS_MACX
6
#include <cmath>
7
#else
8
#include <math.h>
9
#endif
10

  
11
QgsResidualPlotItem::QgsResidualPlotItem( QgsComposition* c ): QgsComposerItem( c ), mConvertScaleToMapUnits( false ), mPixelToMapUnits( 1.0 )
12
{
13

  
14
}
15

  
16
QgsResidualPlotItem::~QgsResidualPlotItem()
17
{
18

  
19
}
20

  
21
void QgsResidualPlotItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
22
{
23
  if ( mGCPList.size() < 1 || !painter )
24
  {
25
    return;
26
  }
27

  
28
  double widthMM = rect().width();
29
  double heightMM = rect().height();
30

  
31
  QPen enabledPen( QColor( 0, 0, 255, 255 ) );
32
  enabledPen.setWidthF( 0.4 );
33
  QPen disabledPen( QColor( 0, 0, 255, 127 ) );
34
  disabledPen.setWidthF( 0.3 );
35
  QBrush enabledBrush( QColor( 255, 0, 0, 255 ) );
36
  QBrush disabledBrush( QColor( 255, 0, 0, 127 ) );
37

  
38
  //draw all points and collect minimal mm/pixel ratio
39
  double minMMPixelRatio = DBL_MAX;
40
  double mmPixelRatio = 1;
41

  
42
  painter->setRenderHint( QPainter::Antialiasing, true );
43

  
44
  QgsGCPList::const_iterator gcpIt = mGCPList.constBegin();
45
  for ( ; gcpIt != mGCPList.constEnd(); ++gcpIt )
46
  {
47
    QgsPoint gcpCoords = ( *gcpIt )->pixelCoords();
48
    double gcpItemMMX = ( gcpCoords.x() - mExtent.xMinimum() ) / mExtent.width() * widthMM;
49
    double gcpItemMMY = ( 1 - ( gcpCoords.y() - mExtent.yMinimum() ) / mExtent.height() ) * heightMM;
50

  
51
    if (( *gcpIt )->isEnabled() )
52
    {
53
      painter->setPen( enabledPen );
54
      painter->setBrush( enabledBrush );
55
    }
56
    else
57
    {
58
      painter->setPen( disabledPen );
59
      painter->setBrush( disabledBrush );
60
    }
61
    painter->drawRect( QRectF( gcpItemMMX - 1, gcpItemMMY - 1, 2, 2 ) );
62
    drawText( painter, gcpItemMMX + 2, gcpItemMMY + 2, QString::number(( *gcpIt )->id() ), QFont() );
63

  
64
    mmPixelRatio = maxMMToPixelRatioForGCP( *gcpIt, gcpItemMMX, gcpItemMMY );
65
    if ( mmPixelRatio < minMMPixelRatio )
66
    {
67
      minMMPixelRatio = mmPixelRatio;
68
    }
69
  }
70

  
71
  //draw residual arrows
72
  gcpIt = mGCPList.constBegin();
73
  for ( ; gcpIt != mGCPList.constEnd(); ++gcpIt )
74
  {
75
    QgsPoint gcpCoords = ( *gcpIt )->pixelCoords();
76
    double gcpItemMMX = ( gcpCoords.x() - mExtent.xMinimum() ) / mExtent.width() * widthMM;
77
    double gcpItemMMY = ( 1 - ( gcpCoords.y() - mExtent.yMinimum() ) / mExtent.height() ) * heightMM;
78
    if (( *gcpIt )->isEnabled() )
79
    {
80
      painter->setPen( enabledPen );
81
    }
82
    else
83
    {
84
      painter->setPen( disabledPen );
85
    }
86

  
87
    QPointF p1( gcpItemMMX, gcpItemMMY );
88
    QPointF p2( gcpItemMMX + ( *gcpIt )->residual().x() * minMMPixelRatio, gcpItemMMY + ( *gcpIt )->residual().y() * minMMPixelRatio );
89
    painter->drawLine( p1, p2 );
90
    painter->setBrush( QBrush( painter->pen().color() ) );
91
    drawArrowHead( painter, p2.x(), p2.y(), angle( p1, p2 ), 1 );
92
  }
93

  
94
  //draw scale bar
95
  double initialScaleBarWidth = rect().width() / 5;
96
  int nUnits;
97
  double scaleBarWidth;
98
  if ( mConvertScaleToMapUnits ) //map units
99
  {
100
    nUnits = initialScaleBarWidth / minMMPixelRatio * mPixelToMapUnits;
101
    scaleBarWidth = nUnits * minMMPixelRatio / mPixelToMapUnits;
102
  }
103
  else //pixels
104
  {
105
    nUnits = initialScaleBarWidth / minMMPixelRatio;
106
    scaleBarWidth = nUnits * minMMPixelRatio;
107
  }
108

  
109
  painter->setPen( QColor( 0, 0, 0 ) );
110
  painter->drawLine( QPointF( 5, rect().height() - 5 ), QPointF( 5 + scaleBarWidth, rect().height() - 5 ) );
111
  painter->drawLine( QPointF( 5, rect().height() - 5 ), QPointF( 5, rect().height() - 7 ) );
112
  painter->drawLine( QPointF( 5 + scaleBarWidth, rect().height() - 5 ), QPointF( 5 + scaleBarWidth, rect().height() - 7 ) );
113
  QFont scaleBarFont;
114
  if ( mConvertScaleToMapUnits )
115
  {
116
    drawText( painter, 5, rect().height() - 4 + fontAscentMillimeters( scaleBarFont ), QString( "%1 map units" ).arg( nUnits ), QFont() );
117
  }
118
  else
119
  {
120
    drawText( painter, 5, rect().height() - 4 + fontAscentMillimeters( scaleBarFont ), QString( "%1 pixels" ).arg( nUnits ), QFont() );
121
  }
122

  
123
  drawFrame( painter );
124
  if ( isSelected() )
125
  {
126
    drawSelectionBoxes( painter );
127
  }
128
}
129

  
130
double QgsResidualPlotItem::maxMMToPixelRatioForGCP( const QgsGeorefDataPoint* p, double pixelXMM, double pixelYMM )
131
{
132
  if ( !p )
133
  {
134
    return 0;
135
  }
136

  
137
  //calculate intersections with upper / lower frame edge depending on the residual y sign
138
  double upDownDist = DBL_MAX; //distance to frame intersection with lower or upper frame
139
  double leftRightDist = DBL_MAX; //distance to frame intersection with left or right frame
140

  
141
  QPointF residual = p->residual();
142
  QLineF residualLine( pixelXMM, pixelYMM, pixelXMM + residual.x(), pixelYMM + residual.y() );
143
  QPointF intersectionPoint;
144
  double dx, dy;
145

  
146
  if ( residual.y() > 0 )
147
  {
148
    QLineF lowerFrameLine( 0, rect().height(), rect().width(), rect().height() );
149
    if ( residualLine.intersect( lowerFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
150
    {
151
      upDownDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
152
    }
153
  }
154
  else if ( residual.y() < 0 )
155
  {
156
    QLineF upperFrameLine( 0, 0, mExtent.xMaximum(), 0 );
157
    if ( residualLine.intersect( upperFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
158
    {
159
      upDownDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
160
    }
161
  }
162

  
163
  //calculate intersection with left / right frame edge depending on the residual x sign
164
  if ( residual.x() > 0 )
165
  {
166
    QLineF rightFrameLine( rect().width(), 0, rect().width(), rect().height() );
167
    if ( residualLine.intersect( rightFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
168
    {
169
      leftRightDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
170
    }
171
  }
172
  else if ( residual.x() < 0 )
173
  {
174
    QLineF leftFrameLine( 0, 0 , 0, rect().height() );
175
    if ( residualLine.intersect( leftFrameLine, &intersectionPoint ) != QLineF::NoIntersection )
176
    {
177
      leftRightDist = dist( QPointF( pixelXMM, pixelYMM ) , intersectionPoint );
178
    }
179
  }
180

  
181
  double resTot = sqrt( residual.x() * residual.x() + residual.y() * residual.y() );
182
  if ( leftRightDist <= upDownDist )
183
  {
184
    return leftRightDist / resTot;
185
  }
186
  else
187
  {
188
    return upDownDist / resTot;
189
  }
190
}
191

  
192
bool QgsResidualPlotItem::writeXML( QDomElement& elem, QDomDocument & doc ) const
193
{
194
  return false;
195
}
196

  
197
bool QgsResidualPlotItem::readXML( const QDomElement& itemElem, const QDomDocument& doc )
198
{
199
  return false;
200
}
201

  
202
double QgsResidualPlotItem::dist( const QPointF& p1, const QPointF& p2 ) const
203
{
204
  double dx = p2.x() - p1.x();
205
  double dy = p2.y() - p1.y();
206
  return sqrt( dx * dx + dy * dy );
207
}
src/plugins/georeferencer/qgsgeorefplugingui.h (working copy)
131 131

  
132 132
    // georeference
133 133
    bool georeference();
134
    bool writeWorldFile( QgsPoint origin, double pixelXSize, double pixelYSize );
134
    bool writeWorldFile( QgsPoint origin, double pixelXSize, double pixelYSize, double rotation );
135
    bool writePDFReportFile( const QString& fileName, const QgsGeorefTransform& transform );
135 136

  
136 137
    // gdal script
137 138
    void showGDALScript( int argNum... );
138
    QString generateGDALtranslateCommand( bool generateTFW = true);   
139
    QString generateGDALtranslateCommand( bool generateTFW = true );
139 140
    /* Generate command-line for gdalwarp based on current GCPs and given parameters.
140
     * For values in the range 1 to 3, the parameter "order" prescribes the degree of the interpolating polynomials to use, 
141
     * For values in the range 1 to 3, the parameter "order" prescribes the degree of the interpolating polynomials to use,
141 142
     * a value of -1 indicates that thin plate spline interpolation should be used for warping.*/
142 143
    QString generateGDALwarpCommand( QString resampling, QString compress, bool useZeroForTrans, int order,
143 144
                                     double targetResX, double targetResY );
......
158 159
    void logRequaredGCPs();
159 160
    void clearGCPData();
160 161

  
162
    /**Docks / undocks this window*/
163
    void dockThisWindow( bool dock );
161 164

  
165

  
162 166
    QMenu *mPanelMenu;
163 167
    QMenu *mToolbarMenu;
164 168

  
......
177 181
    QString mTranslatedRasterFileName;
178 182
    QString mGCPpointsFileName;
179 183
    QString mProjection;
184
    QString mPdfOutputFile;
180 185
    double  mUserResX, mUserResY;  // User specified target scale
181 186

  
182 187
    QgsGeorefTransform::TransformParametrisation mTransformParam;
......
205 210
    bool mExtentsChangedRecursionGuard;
206 211
    bool mGCPsDirty;
207 212
    bool mLoadInQgis;
213

  
214
    QDockWidget* mDock;
208 215
};
209 216
#endif
src/plugins/georeferencer/qgsgeorefconfigdialogbase.ui (working copy)
6 6
   <rect>
7 7
    <x>0</x>
8 8
    <y>0</y>
9
    <width>221</width>
10
    <height>102</height>
9
    <width>219</width>
10
    <height>162</height>
11 11
   </rect>
12 12
  </property>
13 13
  <property name="windowTitle">
14 14
   <string>Configure Georeferencer</string>
15 15
  </property>
16
  <layout class="QGridLayout" name="gridLayout">
16
  <layout class="QGridLayout" name="gridLayout_2">
17 17
   <item row="0" column="0">
18 18
    <widget class="QGroupBox" name="mPointTipGroupBox">
19 19
     <property name="title">
20 20
      <string>Point tip</string>
21 21
     </property>
22
     <layout class="QHBoxLayout" name="horizontalLayout">
23
      <item>
24
       <widget class="QRadioButton" name="mShowIDsRadioButton">
22
     <layout class="QGridLayout" name="gridLayout">
23
      <item row="0" column="0">
24
       <widget class="QCheckBox" name="mShowIDsCheckBox">
25 25
        <property name="text">
26 26
         <string>Show IDs</string>
27 27
        </property>
28
        <property name="checked">
29
         <bool>true</bool>
30
        </property>
31 28
       </widget>
32 29
      </item>
33
      <item>
34
       <widget class="QRadioButton" name="mShowCoordsRadioButton">
30
      <item row="1" column="0">
31
       <widget class="QCheckBox" name="mShowCoordsCheckBox">
35 32
        <property name="text">
36 33
         <string>Show coords</string>
37 34
        </property>
......
41 38
    </widget>
42 39
   </item>
43 40
   <item row="1" column="0">
41
    <widget class="QCheckBox" name="mShowDockedCheckBox">
42
     <property name="text">
43
      <string>Show Georeferencer window docked</string>
44
     </property>
45
    </widget>
46
   </item>
47
   <item row="2" column="0">
44 48
    <widget class="QDialogButtonBox" name="buttonBox">
45 49
     <property name="orientation">
46 50
      <enum>Qt::Horizontal</enum>
src/plugins/georeferencer/qgsgeoreftransform.h (working copy)
129 129

  
130 130
    //! \brief Returns origin and scale if this is a linear transform, fails otherwise.
131 131
    bool getLinearOriginScale( QgsPoint &origin, double &scaleX, double &scaleY ) const;
132

  
133
    //! \brief Returns origin, scale and rotation for linear and helmert transform, fails otherwise.
134
    bool getOriginRotationScale( QgsPoint &origin, double &scaleX, double &scaleY, double& rotation ) const;
135

  
132 136
  private:
133 137
    // shallow copy constructor
134 138
    QgsGeorefTransform( const QgsGeorefTransform &other );
src/plugins/georeferencer/qgstransformsettingsdialog.cpp (working copy)
34 34
{
35 35
  setupUi( this );
36 36

  
37
  cmbTransformType->addItem( tr( "Linear" ) ,           (int)QgsGeorefTransform::Linear ) ;
38
  cmbTransformType->addItem( tr( "Helmert" ),           (int)QgsGeorefTransform::Helmert );
39
  cmbTransformType->addItem( tr( "Polynomial 1" ),      (int)QgsGeorefTransform::PolynomialOrder1 );
40
  cmbTransformType->addItem( tr( "Polynomial 2" ),      (int)QgsGeorefTransform::PolynomialOrder2 );
41
  cmbTransformType->addItem( tr( "Polynomial 3" ),      (int)QgsGeorefTransform::PolynomialOrder3 );
42
  cmbTransformType->addItem( tr( "Thin Plate Spline" ), (int)QgsGeorefTransform::ThinPlateSpline );
43
  
37
  cmbTransformType->addItem( tr( "Linear" ) , ( int )QgsGeorefTransform::Linear ) ;
38
  cmbTransformType->addItem( tr( "Helmert" ), ( int )QgsGeorefTransform::Helmert );
39
  cmbTransformType->addItem( tr( "Polynomial 1" ), ( int )QgsGeorefTransform::PolynomialOrder1 );
40
  cmbTransformType->addItem( tr( "Polynomial 2" ), ( int )QgsGeorefTransform::PolynomialOrder2 );
41
  cmbTransformType->addItem( tr( "Polynomial 3" ), ( int )QgsGeorefTransform::PolynomialOrder3 );
42
  cmbTransformType->addItem( tr( "Thin Plate Spline" ), ( int )QgsGeorefTransform::ThinPlateSpline );
43

  
44 44
  leOutputRaster->setText( output );
45 45

  
46 46
  mRegExpValidator = new QRegExpValidator( QRegExp( "(^epsg:{1}\\s*\\d+)|(^\\+proj.*)", Qt::CaseInsensitive ), leTargetSRS );
......
70 70

  
71 71
  tbnOutputRaster->setIcon( getThemeIcon( "/mPushButtonFileOpen.png" ) );
72 72
  tbnTargetSRS->setIcon( getThemeIcon( "/mPushButtonTargetSRSDisabled.png" ) );
73
  tbnReportFile->setIcon( getThemeIcon( "/mActionSaveAsPDF.png" ) );
73 74
}
74 75

  
75 76
void QgsTransformSettingsDialog::getTransformSettings( QgsGeorefTransform::TransformParametrisation &tp,
76 77
    QgsImageWarper::ResamplingMethod &rm,
77 78
    QString &comprMethod, QString &raster,
78
    QString &proj, bool &zt, bool &loadInQgis,
79
    QString &proj, QString& pdfReportFile, bool &zt, bool &loadInQgis,
79 80
    double& resX, double& resY )
80 81
{
81 82
  if ( cmbTransformType->currentIndex() == -1 )
......
87 88
  comprMethod = cmbCompressionComboBox->currentText();
88 89
  raster = leOutputRaster->text();
89 90
  proj = leTargetSRS->text();
91
  pdfReportFile = mReportFileLineEdit->text();
90 92
  zt = cbxZeroAsTrans->isChecked();
91 93
  loadInQgis = cbxLoadInQgisWhenDone->isChecked();
92 94
  resX = 0.0;
......
130 132
  int minGCPpoints;
131 133
  if ( checkGCPpoints( cmbTransformType->currentIndex(), minGCPpoints ) )
132 134
  {
133
    if ( leOutputRaster->text().isEmpty() && cmbTransformType->currentIndex() != 0 )
135
    if ( leOutputRaster->text().isEmpty() && cmbTransformType->currentIndex() > 1 )
134 136
    {
135 137
      QMessageBox::information( this, tr( "Info" ), tr( "Please set output name" ) );
136 138
      return;
......
156 158
  s.setValue( "/Plugin-GeoReferencer/user_specified_resolution", cbxUserResolution->isChecked() );
157 159
  s.setValue( "/Plugin-GeoReferencer/user_specified_resx", dsbHorizRes->value() );
158 160
  s.setValue( "/Plugin-GeoReferencer/user_specified_resy", dsbVerticalRes->value() );
161
  QString pdfReportFileName = mReportFileLineEdit->text();
162
  if ( !pdfReportFileName.isEmpty() )
163
  {
164
    QFileInfo fi( pdfReportFileName );
165
    s.setValue( "/Plugin-GeoReferencer/lastPDFReportDir", fi.absolutePath() );
166
  }
159 167
}
160 168

  
161 169
void QgsTransformSettingsDialog::on_tbnOutputRaster_clicked()
......
201 209
  }
202 210
}
203 211

  
212
void QgsTransformSettingsDialog::on_tbnReportFile_clicked()
213
{
214
  QSettings s;
215
  QString myLastUsedDir = s.value( "/Plugin-GeoReferencer/lastPDFReportDir", "" ).toString();
216
  QString outputFileName = QFileDialog::getSaveFileName( 0, tr( "Select save PDF file" ), myLastUsedDir, tr( "PDF Format" ) + " (*.pdf *PDF)" );
217
  if ( !outputFileName.isNull() )
218
  {
219
    mReportFileLineEdit->setText( outputFileName );
220
  }
221
}
222

  
204 223
void QgsTransformSettingsDialog::on_leTargetSRS_textChanged( const QString &text )
205 224
{
206 225
  QString t = text;
src/plugins/georeferencer/qgsgeorefconfigdialog.cpp (working copy)
54 54
{
55 55
  QSettings s;
56 56
  if ( s.value( "/Plugin-GeoReferencer/Config/ShowId" ).toBool() )
57
    mShowIDsRadioButton->setChecked( true );
57
  {
58
    mShowIDsCheckBox->setChecked( true );
59
  }
58 60
  else
59
    mShowCoordsRadioButton->setChecked( true );
61
  {
62
    mShowIDsCheckBox->setChecked( false );
63
  }
64

  
65
  if ( s.value( "/Plugin-GeoReferencer/Config/ShowCoords" ).toBool() )
66
  {
67
    mShowCoordsCheckBox->setChecked( true );
68
  }
69
  else
70
  {
71
    mShowCoordsCheckBox->setChecked( false );
72
  }
73

  
74
  if ( s.value( "/Plugin-GeoReferencer/Config/ShowDocked" ).toBool() )
75
  {
76
    mShowDockedCheckBox->setChecked( true );
77
  }
78
  else
79
  {
80
    mShowDockedCheckBox->setChecked( false );
81
  }
60 82
}
61 83

  
62 84
void QgsGeorefConfigDialog::writeSettings()
63 85
{
64 86
  QSettings s;
65
  s.setValue( "/Plugin-GeoReferencer/Config/ShowId", mShowIDsRadioButton->isChecked() );
87
  s.setValue( "/Plugin-GeoReferencer/Config/ShowId", mShowIDsCheckBox->isChecked() );
88
  s.setValue( "/Plugin-GeoReferencer/Config/ShowCoords", mShowCoordsCheckBox->isChecked() );
89
  s.setValue( "/Plugin-GeoReferencer/Config/ShowDocked", mShowDockedCheckBox->isChecked() );
66 90
}
src/plugins/georeferencer/qgsgeorefdatapoint.h (working copy)
13 13
 *                                                                         *
14 14
 ***************************************************************************/
15 15
/* $Id$ */
16

  
17
#ifndef QGSGEOREFDATAPOINT_H
18
#define QGSGEOREFDATAPOINT_H
19

  
16 20
#include "qgsmapcanvasitem.h"
17 21

  
18 22
class QgsGCPCanvasItem;
......
66 70
    bool mEnabled;
67 71
    QPointF mResidual;
68 72
};
73

  
74
#endif //QGSGEOREFDATAPOINT_H
src/plugins/georeferencer/CMakeLists.txt (working copy)
15 15
     qgsgeorefvalidators.cpp
16 16
     qgsleastsquares.cpp
17 17
     qgsmapcoordsdialog.cpp
18
     qgsresidualplotitem.cpp
18 19
     qgstransformsettingsdialog.cpp
19 20

  
20 21
     qgsgcplist.cpp
......
67 68
INCLUDE_DIRECTORIES(
68 69
     ${CMAKE_CURRENT_SOURCE_DIR}
69 70
     ${CMAKE_CURRENT_BINARY_DIR}
70
     ../../core ../../core/raster ../../core/renderer ../../core/symbology
71
     ../../core ../../core/raster ../../core/renderer ../../core/symbology ../../core/composer
71 72
     ../../gui
72 73
     ..
73 74
     ${GSL_INCLUDE_DIR}
src/plugins/georeferencer/qgsgcpcanvasitem.h (working copy)
49 49
    bool mIsGCPSource;
50 50
    QPen mResidualPen;
51 51

  
52
    void drawResidualArrow( QPainter* p );
52
    //text box rect for bounding rect calculation (updated in the paint event)
53
    QRectF mTextBoxRect;
54

  
55
    void drawResidualArrow( QPainter* p, const QgsRenderContext& context );
53 56
    /**Calculates scale factor for residual display*/
54 57
    double residualToScreenFactor() const;
58
    /**Calculates pixel size for a font point size*/
59
    double fontSizePainterUnits( double points, const QgsRenderContext& c );
55 60
};
56 61

  
57 62
#endif // QGSGCPCANVASITEM_H
src/plugins/georeferencer/qgsgeorefplugingui.cpp (working copy)
23 23
#include <QMouseEvent>
24 24
#include <QPainter>
25 25
#include <QPlainTextEdit>
26
#include <QPrinter>
26 27
#include <QProgressDialog>
27 28
#include <QPushButton>
28 29
#include <QSettings>
......
32 33
#include "qgslegendinterface.h"
33 34
#include "qgsapplication.h"
34 35

  
36
#include "qgscomposerlabel.h"
37
#include "qgscomposermap.h"
38
#include "qgscomposertexttable.h"
35 39
#include "qgsmapcanvas.h"
36 40
#include "qgsmapcoordsdialog.h"
37 41
#include "qgsmaplayerregistry.h"
42
#include "qgsmaprenderer.h"
38 43
#include "qgsmaptoolzoom.h"
39 44
#include "qgsmaptoolpan.h"
40 45

  
......
52 57

  
53 58
#include "qgsgeorefconfigdialog.h"
54 59
#include "qgsgeorefdescriptiondialog.h"
60
#include "qgsresidualplotitem.h"
55 61
#include "qgstransformsettingsdialog.h"
56 62

  
57 63
#include "qgsgeorefplugingui.h"
58 64

  
65
class QgsGeorefDockWidget : public QDockWidget
66
{
67
  public:
68
    QgsGeorefDockWidget( const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = 0 )
69
        : QDockWidget( title, parent, flags )
70
    {
71
      setObjectName( "GeorefDockWidget" ); // set object name so the position can be saved
72
    }
73

  
74
    virtual void closeEvent( QCloseEvent * ev )
75
    {
76
      deleteLater();
77
    }
78
};
79

  
59 80
QgsGeorefPluginGui::QgsGeorefPluginGui( QgisInterface* theQgisInterface, QWidget* parent, Qt::WFlags fl )
60 81
    : QMainWindow( parent, fl )
61 82
    , mTransformParam( QgsGeorefTransform::InvalidTransform )
......
65 86
    , mMapCoordsDialog( 0 )
66 87
    , mUseZeroForTrans( false )
67 88
    , mLoadInQgis( false )
89
    , mDock( 0 )
68 90
{
69 91
  setupUi( this );
70 92

  
......
83 105
  mActionLinkQGisToGeoref->setEnabled( false );
84 106

  
85 107
  mCanvas->clearExtentHistory(); // reset zoomnext/zoomlast
108

  
109
  QSettings s;
110
  if ( s.value( "/Plugin-GeoReferencer/Config/ShowDocked" ).toBool() )
111
  {
112
    dockThisWindow( true );
113
  }
86 114
}
87 115

  
116
void QgsGeorefPluginGui::dockThisWindow( bool dock )
117
{
118
  if ( mDock )
119
  {
120
    setParent( 0 );
121
    show();
122
    mIface->removeDockWidget( mDock );
123
    mDock->setWidget( 0 );
124
    delete mDock;
125
    mDock = 0;
126
  }
127

  
128
  if ( dock )
129
  {
130
    mDock = new QgsGeorefDockWidget( tr( "Georeferencer" ), mIface->mainWindow() );
131
    mDock->setWidget( this );
132
    connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) );
133
    mIface->addDockWidget( Qt::BottomDockWidgetArea, mDock );
134
  }
135
}
136

  
88 137
QgsGeorefPluginGui::~QgsGeorefPluginGui()
89 138
{
90 139
  QgsTransformSettingsDialog::resetSettings();
......
102 151
  delete mToolAddPoint;
103 152
  delete mToolDeletePoint;
104 153
  delete mToolMovePoint;
154
  delete mDock;
105 155
}
106 156

  
107 157
// ----------------------------- protected --------------------------------- //
......
232 282
  {
233 283
    if ( mLoadInQgis )
234 284
    {
235
      if ( QgsGeorefTransform::Linear == mTransformParam )
285
      if ( mModifiedRasterFileName.isEmpty() )
236 286
      {
237 287
        mIface->addRasterLayer( mRasterFileName );
238 288
      }
......
264 314
  }
265 315

  
266 316
  d.getTransformSettings( mTransformParam, mResamplingMethod, mCompressionMethod,
267
                          mModifiedRasterFileName, mProjection, mUseZeroForTrans, mLoadInQgis, mUserResX, mUserResY );
317
                          mModifiedRasterFileName, mProjection, mPdfOutputFile, mUseZeroForTrans, mLoadInQgis, mUserResX, mUserResY );
268 318
  mTransformParamLabel->setText( tr( "Transform: " ) + convertTransformEnumToString( mTransformParam ) );
269 319
  mGeorefTransform.selectTransformParametrisation( mTransformParam );
270 320
  mGCPListWidget->setGeorefTransform( &mGeorefTransform );
......
294 344
  if ( !checkReadyGeoref() )
295 345
    return;
296 346

  
297
  switch (mTransformParam)
347
  switch ( mTransformParam )
298 348
  {
299 349
    case QgsGeorefTransform::PolynomialOrder1:
300 350
    case QgsGeorefTransform::PolynomialOrder2:
......
309 359
      QString resamplingStr = convertResamplingEnumToString( mResamplingMethod );
310 360

  
311 361
      int order = polynomialOrder( mTransformParam );
312
      if (order != 0)
362
      if ( order != 0 )
313 363
      {
314 364
        gdalwarpCommand = generateGDALwarpCommand( resamplingStr, mCompressionMethod, mUseZeroForTrans, order,
315
                                                   mUserResX, mUserResY );
365
                          mUserResX, mUserResY );
316 366
        showGDALScript( 2, translateCommand.toAscii().data(), gdalwarpCommand.toAscii().data() );
317 367
        break;
318 368
      }
......
543 593
void QgsGeorefPluginGui::showGeorefConfigDialog()
544 594
{
545 595
  QgsGeorefConfigDialog config;
546
  config.exec();
547
  mCanvas->refresh();
548
  mIface->mapCanvas()->refresh();
596
  if ( config.exec() == QDialog::Accepted )
597
  {
598
    mCanvas->refresh();
599
    mIface->mapCanvas()->refresh();
600
    QSettings s;
601
    //update dock state
602
    bool dock = s.value( "/Plugin-GeoReferencer/Config/ShowDocked" ).toBool();
603
    if ( dock && !mDock )
604
    {
605
      dockThisWindow( true );
606
    }
607
    else if ( !dock && mDock )
608
    {
609
      dockThisWindow( false );
610
    }
611
  }
549 612
}
550 613

  
551 614
// Info slots
......
1042 1105
  if ( !checkReadyGeoref() )
1043 1106
    return false;
1044 1107

  
1045
  if ( QgsGeorefTransform::Linear == mGeorefTransform.transformParametrisation() )
1108
  if ( mModifiedRasterFileName.isEmpty() && ( QgsGeorefTransform::Linear == mGeorefTransform.transformParametrisation() || \
1109
       QgsGeorefTransform::Helmert == mGeorefTransform.transformParametrisation() ) )
1046 1110
  {
1047 1111
    QgsPoint origin;
1048
    double pixelXSize, pixelYSize;
1049
    if ( !mGeorefTransform.getLinearOriginScale( origin, pixelXSize, pixelYSize ) )
1112
    double pixelXSize, pixelYSize, rotation;
1113
    if ( !mGeorefTransform.getOriginRotationScale( origin, pixelXSize, pixelYSize, rotation ) )
1050 1114
    {
1051 1115
      QMessageBox::information( this, tr( "Info" ),
1052 1116
                                tr( "Failed to get linear transform parameters" ) );
......
1076 1140
      return false;
1077 1141
    }
1078 1142

  
1079
    return writeWorldFile( origin, pixelXSize, pixelYSize );
1143
    bool success = writeWorldFile( origin, pixelXSize, pixelYSize, rotation );
1144
    if ( success && !mPdfOutputFile.isEmpty() )
1145
    {
1146
      writePDFReportFile( mPdfOutputFile, mGeorefTransform );
1147
    }
1080 1148
  }
1081 1149
  else // Helmert, Polinom 1, Polinom 2, Polinom 3
1082 1150
  {
......
1097 1165
    }
1098 1166
    else // 1 all right
1099 1167
    {
1168
      if ( !mPdfOutputFile.isEmpty() )
1169
      {
1170
        writePDFReportFile( mPdfOutputFile, mGeorefTransform );
1171
      }
1100 1172
      return true;
1101 1173
    }
1102 1174
  }
1103 1175
}
1104 1176

  
1105
bool QgsGeorefPluginGui::writeWorldFile( QgsPoint origin, double pixelXSize, double pixelYSize )
1177
bool QgsGeorefPluginGui::writeWorldFile( QgsPoint origin, double pixelXSize, double pixelYSize, double rotation )
1106 1178
{
1107 1179
  // write the world file
1108 1180
  QFile file( mWorldFileName );
......
1112 1184
                           tr( "Could not write to %1" ).arg( mWorldFileName ) );
1113 1185
    return false;
1114 1186
  }
1187

  
1188
  double rotationX = 0;
1189
  double rotationY = 0;
1190

  
1191
  if ( !doubleNear( rotation, 0.0 ) )
1192
  {
1193
    rotationX = pixelXSize * sin( rotation );
1194
    rotationY = pixelYSize * sin( rotation );
1195
    pixelXSize *= cos( rotation );
1196
    pixelYSize *= cos( rotation );
1197
  }
1198

  
1115 1199
  QTextStream stream( &file );
1116 1200
  stream << QString::number( pixelXSize, 'f', 15 ) << endl
1117
  << 0 << endl
1118
  << 0 << endl
1201
  << rotationX << endl
1202
  << rotationY << endl
1119 1203
  << QString::number( -pixelYSize, 'f', 15 ) << endl
1120 1204
  << QString::number( origin.x(), 'f', 15 ) << endl
1121 1205
  << QString::number( origin.y(), 'f', 15 ) << endl;
1122 1206
  return true;
1123 1207
}
1124 1208

  
1209
bool QgsGeorefPluginGui::writePDFReportFile( const QString& fileName, const QgsGeorefTransform& transform )
1210
{
1211
  if ( !mCanvas )
1212
  {
1213
    return false;
1214
  }
1215

  
1216
  QgsMapRenderer* canvasRenderer = mCanvas->mapRenderer();
1217
  if ( !canvasRenderer )
1218
  {
1219
    return false;
1220
  }
1221

  
1222
  QPrinter printer;
1223
  printer.setOutputFormat( QPrinter::PdfFormat );
1224
  printer.setOutputFileName( fileName );
1225

  
1226
  //create composition A4 with 300 dpi
1227
  QgsComposition* composition = new QgsComposition( mCanvas->mapRenderer() );
1228
  composition->setPaperSize( 210, 297 ); //A4
1229
  composition->setPrintResolution( 300 );
1230
  printer.setPaperSize( QSizeF( composition->paperWidth(), composition->paperHeight() ), QPrinter::Millimeter );
1231

  
1232
  //title
1233
  QFileInfo rasterFi( mRasterFileName );
1234
  QgsComposerLabel* titleLabel = new QgsComposerLabel( composition );
1235
  titleLabel->setText( rasterFi.fileName() );
1236
  composition->addItem( titleLabel );
1237
  titleLabel->setSceneRect( QRectF( 10, 5, composition->paperWidth(), 8 ) );
1238
  titleLabel->setFrame( false );
1239

  
1240
  //composer map
1241
  QgsComposerMap* composerMap = new QgsComposerMap( composition, 10, titleLabel->rect().bottom() + titleLabel->transform().dy(), 190, 277 );
1242
  composerMap->setLayerSet( canvasRenderer->layerSet() );
1243
  composerMap->setNewExtent( mCanvas->extent() );
1244
  composerMap->setMapCanvas( mCanvas );
1245
  composition->addItem( composerMap );
1246
  printer.setFullPage( true );
1247
  printer.setColorMode( QPrinter::Color );
1248

  
1249
  QgsComposerTextTable* parameterTable = 0;
1250
  double scaleX, scaleY, rotation;
1251
  QgsPoint origin;
1252

  
1253
  QgsComposerLabel* parameterLabel = 0;
1254
  //transformation that involves only scaling and rotation (linear or helmert) ?
1255
  bool wldTransform = transform.getOriginRotationScale( origin, scaleX, scaleY, rotation );
1256

  
1257
  //consider rotation in scale parameter
1258
  double wldScaleX = scaleX;
1259
  double wldScaleY = scaleY;
1260
  if ( wldTransform && !doubleNear( rotation, 0.0 ) )
1261
  {
1262
    wldScaleX *= cos( rotation );
1263
    wldScaleY *= cos( rotation );
1264
  }
1265

  
1266
  if ( wldTransform )
1267
  {
1268
    parameterLabel = new QgsComposerLabel( composition );
1269
    parameterLabel->setText( tr( "Transformation parameters" ) );
1270
    parameterLabel->adjustSizeToText();
1271
    composition->addItem( parameterLabel );
1272
    parameterLabel->setSceneRect( QRectF( 10, composerMap->rect().bottom() + composerMap->transform().dy() + 5, composition->paperWidth(), 8 ) );
1273
    parameterLabel->setFrame( false );
1274

  
1275
    //calculate mean error (in map units)
1276
    double meanError = 0;
1277
    if ( mPoints.size() > 4 )
1278
    {
1279
      double sumVxSquare = 0;
1280
      double sumVySquare = 0;
1281
      double resXMap, resYMap;
1282

  
1283
      int nPointsEnabled = 0;
1284
      QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
1285
      for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
1286
      {
1287
        if (( *gcpIt )->isEnabled() )
1288
        {
1289
          resXMap = ( *gcpIt )->residual().x() * wldScaleX;
1290
          resYMap = ( *gcpIt )->residual().x() * wldScaleY;
1291
          sumVxSquare += ( resXMap * resXMap );
1292
          sumVySquare += ( resYMap * resYMap );
1293
          ++nPointsEnabled;
1294
        }
1295
      }
1296

  
1297
      if ( nPointsEnabled > 4 )
1298
      {
1299
        meanError = sqrt(( sumVxSquare + sumVySquare ) / ( 2 * nPointsEnabled - 4 ) ) * sqrt( 2 );
1300
      }
1301
    }
1302

  
1303

  
1304
    parameterTable = new QgsComposerTextTable( composition );
1305
    QStringList headers;
1306
    headers << tr( "Translation x" ) << tr( "Translation y" ) << tr( "Scale x" ) << tr( "Scale y" ) << tr( "Rotation [degrees]" ) << tr( "Mean error [map units]" );
1307
    parameterTable->setHeaderLabels( headers );
1308
    QStringList row;
1309
    row << QString::number( origin.x() ) << QString::number( origin.y() ) << QString::number( scaleX ) << QString::number( scaleY ) << QString::number( rotation * 180 / M_PI ) << QString::number( meanError );
1310
    parameterTable->addRow( row );
1311
    composition->addItem( parameterTable );
1312
    parameterTable->setSceneRect( QRectF( 10, parameterLabel->rect().bottom() + parameterLabel->transform().dy() + 5, 50, 20 ) );
1313
    parameterTable->setGridStrokeWidth( 0.1 );
1314
    parameterTable->adjustFrameToSize();
1315
  }
1316

  
1317
  QGraphicsRectItem* previousItem = composerMap;
1318
  if ( parameterTable )
1319
  {
1320
    previousItem = parameterTable;
1321
  }
1322

  
1323
  QgsComposerLabel* residualLabel = new QgsComposerLabel( composition );
1324
  residualLabel->setText( tr( "Residuals" ) );
1325
  composition->addItem( residualLabel );
1326
  residualLabel->setSceneRect( QRectF( 10, previousItem->rect().bottom() + previousItem->transform().dy() + 5, composition->paperWidth(), 6 ) );
1327
  residualLabel->setFrame( false );
1328

  
1329
  //residual plot
1330
  QgsResidualPlotItem* resPlotItem = new QgsResidualPlotItem( composition );
1331
  composition->addItem( resPlotItem );
1332
  resPlotItem->setSceneRect( QRectF( 10, residualLabel->rect().bottom() + residualLabel->transform().dy() + 5, composerMap->rect().width(), composerMap->rect().height() ) );
1333
  resPlotItem->setExtent( composerMap->extent() );
1334
  resPlotItem->setGCPList( mPoints );
1335

  
1336
  //convert residual scale bar plot to map units if scaling is equal in x- and y-direction (e.g. helmert)
1337
  if ( wldTransform )
1338
  {
1339
    if ( doubleNear( wldScaleX, wldScaleY ) )
1340
    {
1341
      resPlotItem->setPixelToMapUnits( scaleX );
1342
      resPlotItem->setConvertScaleToMapUnits( true );
1343
    }
1344
  }
1345

  
1346
  QString residualUnits;
1347
  if ( wldTransform )
1348
  {
1349
    residualUnits = tr( "map units" );
1350
  }
1351
  else
1352
  {
1353
    residualUnits = tr( "pixels" );
1354
  }
1355
  QgsComposerTextTable* gcpTable = new QgsComposerTextTable( composition );
1356
  QStringList gcpHeader;
1357
  gcpHeader << "id" << "enabled" << "pixelCoordX" << "pixelCoordY" << "mapCoordX" << "mapCoordY" << "resX[" + residualUnits + "]" << "resY[" + residualUnits + "]" << "resTot[" + residualUnits + "]";
1358
  gcpTable->setHeaderLabels( gcpHeader );
1359

  
1360
  QgsGCPList::const_iterator gcpIt = mPoints.constBegin();
1361
  for ( ; gcpIt != mPoints.constEnd(); ++gcpIt )
1362
  {
1363
    QStringList currentGCPStrings;
1364
    QPointF residual = ( *gcpIt )->residual();
1365
    double residualX = residual.x();
1366
    if ( wldTransform )
1367
    {
1368
      residualX *= wldScaleX;
1369
    }
1370
    double residualY = residual.y();
1371
    if ( wldTransform )
1372
    {
1373
      residualY *= wldScaleY;
1374
    }
1375
    double residualTot = sqrt( residualX * residualX + residualY * residualY );
1376

  
1377
    currentGCPStrings << QString::number(( *gcpIt )->id() );
1378
    if (( *gcpIt )->isEnabled() )
1379
    {
1380
      currentGCPStrings << tr( "yes" );
1381
    }
1382
    else
1383
    {
1384
      currentGCPStrings << tr( "no" );
1385
    }
1386
    currentGCPStrings << QString::number(( *gcpIt )->pixelCoords().x() ) << QString::number(( *gcpIt )->pixelCoords().y() ) << QString::number(( *gcpIt )->mapCoords().x() )\
1387
    <<  QString::number(( *gcpIt )->mapCoords().y() ) <<  QString::number( residualX ) <<  QString::number( residualY ) << QString::number( residualTot );
1388
    gcpTable->addRow( currentGCPStrings );
1389
  }
1390

  
1391
  composition->addItem( gcpTable );
1392

  
1393
  gcpTable->setSceneRect( QRectF( 10,  resPlotItem->rect().bottom() + resPlotItem->transform().dy() + 5, 170, 100 ) );
1394
  gcpTable->setGridStrokeWidth( 0.1 );
1395

  
1396
  printer.setResolution( composition->printResolution() );
1397
  QPainter p( &printer );
1398
  composition->setPlotStyle( QgsComposition::Print );
1399
  QRectF paperRectMM = printer.pageRect( QPrinter::Millimeter );
1400
  QRectF paperRectPixel = printer.pageRect( QPrinter::DevicePixel );
1401
  composition->render( &p, paperRectPixel, paperRectMM );
1402

  
1403
  delete titleLabel;
1404
  delete parameterLabel;
1405
  delete residualLabel;
1406
  delete resPlotItem;
1407
  delete parameterTable;
1408
  delete gcpTable;
1409
  delete composerMap;
1410
  delete composition;
1411
  return true;
1412
}
1413

  
1125 1414
// Gdal script
1126 1415
void QgsGeorefPluginGui::showGDALScript( int argNum... )
1127 1416
{
......
1181 1470

  
1182 1471
  QFileInfo rasterFileInfo( mRasterFileName );
1183 1472
  mTranslatedRasterFileName = QDir::tempPath() + "/" + rasterFileInfo.fileName();
1184
  gdalCommand << QString("\"%1\"").arg(mRasterFileName) << QString("\"%1\"").arg(mTranslatedRasterFileName);
1473
  gdalCommand << QString( "\"%1\"" ).arg( mRasterFileName ) << QString( "\"%1\"" ).arg( mTranslatedRasterFileName );
1185 1474

  
1186 1475
  return gdalCommand.join( " " );
1187 1476
}
......
1191 1480
{
1192 1481
  QStringList gdalCommand;
1193 1482
  gdalCommand << "gdalwarp" << "-r" << resampling;
1194
 
1195
  if (order > 0 && order <= 3)
1483

  
1484
  if ( order > 0 && order <= 3 )
1196 1485
  {
1197 1486
    // Let gdalwarp use polynomial warp with the given degree
1198 1487
    gdalCommand << "-order" << QString::number( order );
......
1202 1491
    // Otherwise, use thin plate spline interpolation
1203 1492
    gdalCommand << "-tps";
1204 1493
  }
1205
  gdalCommand<< "-co COMPRESS=" + compress << ( useZeroForTrans ? "-dstalpha" : "" );
1494
  gdalCommand << "-co COMPRESS=" + compress << ( useZeroForTrans ? "-dstalpha" : "" );
1206 1495

  
1207 1496
  if ( targetResX != 0.0 && targetResY != 0.0 )
1208 1497
  {
1209 1498
    gdalCommand << "-tr" << QString::number( targetResX, 'f' ) << QString::number( targetResY, 'f' );
1210 1499
  }
1211 1500

  
1212
  gdalCommand << QString("\"%1\"").arg(mTranslatedRasterFileName) << QString("\"%1\"").arg(mModifiedRasterFileName);
1501
  gdalCommand << QString( "\"%1\"" ).arg( mTranslatedRasterFileName ) << QString( "\"%1\"" ).arg( mModifiedRasterFileName );
1213 1502

  
1214 1503
  return gdalCommand.join( " " );
1215 1504
}
......
1248 1537
      continue;
1249 1538
    }
1250 1539

  
1251
    if ( mModifiedRasterFileName.isEmpty() && QgsGeorefTransform::Linear != mTransformParam )
1540
    //MH: helmert transformation without warping disabled until qgis is able to read rotated rasters efficiently
1541
    if ( mModifiedRasterFileName.isEmpty() && QgsGeorefTransform::Linear != mTransformParam /*&& QgsGeorefTransform::Helmert != mTransformParam*/ )
1252 1542
    {
1253 1543
      QMessageBox::information( this, tr( "Info" ), tr( "Please set output raster name" ) );
1254 1544
      if ( !getTransformSettings() )
src/plugins/georeferencer/qgsresidualplotitem.h (revision 0)
1
#ifndef QGSRESIDUALPLOTITEM_H
2
#define QGSRESIDUALPLOTITEM_H
3

  
4
#include "qgscomposeritem.h"
5
#include "qgsgcplist.h"
6
#include "qgsrectangle.h"
7

  
8
/**A composer item to visualise the distribution of georeference residuals. For the visualisation, \
9
the length of the residual arrows are scaled*/
10
class QgsResidualPlotItem: public QgsComposerItem
11
{
12
  public:
13
    QgsResidualPlotItem( QgsComposition* c );
14
    ~QgsResidualPlotItem();
15

  
16
    /** \brief Reimplementation of QCanvasItem::paint*/
17
    virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );
18

  
19
    void setGCPList( const QgsGCPList& list ) { mGCPList = list; }
20
    QgsGCPList GCPList() const { return mGCPList; }
21

  
22
    void setExtent( const QgsRectangle& rect ) { mExtent = rect;}
23
    QgsRectangle extent() const { return mExtent; }
24

  
25
    void setPixelToMapUnits( double d ) { mPixelToMapUnits = d; }
26
    double pixelToMapUnits() const { return mPixelToMapUnits; }
27

  
28
    void setConvertScaleToMapUnits( bool convert ) { mConvertScaleToMapUnits = convert; }
29
    bool convertScaleToMapUnits() const { return mConvertScaleToMapUnits; }
30

  
31
    virtual bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
32
    virtual bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
33

  
34
  private:
35
    //gcp list
36
    QgsGCPList mGCPList;
37

  
38
    QgsRectangle mExtent;
39
    /**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)*/
40
    bool mConvertScaleToMapUnits;
41
    /**Scale factor from pixels to map units*/
42
    double mPixelToMapUnits;
43

  
44
    /**Calculates maximal possible mm to pixel ratio such that the residual arrow is still inside the frame*/
45
    double maxMMToPixelRatioForGCP( const QgsGeorefDataPoint* p, double pixelXMM, double pixelYMM );
46

  
47
    /**Returns distance between two points*/
48
    double dist( const QPointF& p1, const QPointF& p2 ) const;
49
};
50

  
51
#endif // QGSRESIDUALPLOTITEM_H
src/plugins/georeferencer/qgstransformsettingsdialogbase.ui (working copy)
6 6
   <rect>
7 7
    <x>0</x>
8 8
    <y>0</y>
9
    <width>307</width>
10
    <height>328</height>
9
    <width>356</width>
10
    <height>381</height>
11 11
   </rect>
12 12
  </property>
13 13
  <property name="windowTitle">
14 14
   <string>Transformation settings</string>
15 15
  </property>
16
  <layout class="QVBoxLayout" name="verticalLayout">
17
   <item>
18
    <layout class="QFormLayout" name="formLayout">
19
     <property name="fieldGrowthPolicy">
20
      <enum>QFormLayout::ExpandingFieldsGrow</enum>
21
     </property>
16
  <layout class="QGridLayout" name="gridLayout_2">
17
   <item row="0" column="0">
18
    <layout class="QGridLayout" name="gridLayout">
22 19
     <item row="0" column="0">
23 20
      <widget class="QLabel" name="label">
24 21
       <property name="text">
......
161 158
      </layout>
162 159
     </item>
163 160
     <item row="5" column="0">
161
      <widget class="QLabel" name="label_6">
162
       <property name="text">
163
        <string>Generate pdf report:</string>
164
       </property>
165
      </widget>
166
     </item>
167
     <item row="5" column="1">
168
      <layout class="QHBoxLayout" name="horizontalLayout_3">
169
       <item>
170
        <widget class="QLineEdit" name="mReportFileLineEdit"/>
171
       </item>
172
       <item>
173
        <widget class="QToolButton" name="tbnReportFile">
174
         <property name="text">
175
          <string>...</string>
176
         </property>
177
        </widget>
178
       </item>
179
      </layout>
180
     </item>
181
     <item row="6" column="0">
164 182
      <widget class="QCheckBox" name="cbxUserResolution">
165 183
       <property name="text">
166 184
        <string>Set Target Resolution</string>
167 185
       </property>
168 186
      </widget>
169 187
     </item>
170
     <item row="6" column="0">
188
     <item row="7" column="0">
171 189
      <widget class="QLabel" name="label_4">
172 190
       <property name="text">
173 191
        <string>Horizontal</string>
174 192
       </property>
175 193
      </widget>
176 194
     </item>
177
     <item row="7" column="0">
195
     <item row="7" column="1">
196
      <widget class="QgsValidatedDoubleSpinBox" name="dsbHorizRes">
197
       <property name="decimals">
198
        <number>5</number>
199
       </property>
200
       <property name="minimum">
201
        <double>0.000000000000000</double>
202
       </property>
203
       <property name="maximum">
204
        <double>999999.000000000000000</double>
205
       </property>
206
      </widget>
207
     </item>
208
     <item row="8" column="0">
178 209
      <widget class="QLabel" name="label_5">
179 210
       <property name="text">
180 211
        <string>Vertical</string>
181 212
       </property>
182 213
      </widget>
183 214
     </item>
184
     <item row="7" column="1">
215
     <item row="8" column="1">
185 216
      <widget class="QgsValidatedDoubleSpinBox" name="dsbVerticalRes">
186 217
       <property name="sizePolicy">
187 218
        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
......
203 234
       </property>
204 235
      </widget>
205 236
     </item>
206
     <item row="6" column="1">
207
      <widget class="QgsValidatedDoubleSpinBox" name="dsbHorizRes">
208
       <property name="decimals">
209
        <number>5</number>
210
       </property>
211
       <property name="minimum">
212
        <double>0.000000000000000</double>
213
       </property>
214
       <property name="maximum">
215
        <double>999999.000000000000000</double>
216
       </property>
217
      </widget>
218
     </item>
219 237
    </layout>
220 238
   </item>
221
   <item>
239
   <item row="1" column="0">
222 240
    <widget class="QCheckBox" name="cbxZeroAsTrans">
223 241
     <property name="text">
224 242
      <string>Use 0 for transparency when needed</string>
......
228 246
     </property>
229 247
    </widget>
230 248
   </item>
231
   <item>
249
   <item row="2" column="0">
232 250
    <widget class="QCheckBox" name="cbxLoadInQgisWhenDone">
233 251
     <property name="text">
234 252
      <string>Load in QGIS when done</string>
235 253
     </property>
236 254
    </widget>
237 255
   </item>
238
   <item>
256
   <item row="3" column="0">
239 257
    <widget class="QDialogButtonBox" name="buttonBox">
240 258
     <property name="orientation">
241 259
      <enum>Qt::Horizontal</enum>
src/plugins/georeferencer/qgsgeoreftransform.cpp (working copy)
71 71
      double   angle;
72 72
    };
73 73

  
74
    bool getOriginScaleRotation( QgsPoint &origin, double& scale, double& rotation ) const;
74 75
    bool updateParametersFromGCPs( const std::vector<QgsPoint> &mapCoords, const std::vector<QgsPoint> &pixelCoords );
75 76
    uint getMinimumGCPCount() const;
76 77

  
......
246 247
  return dynamic_cast<QgsLinearGeorefTransform *>( mGeorefTransformImplementation )->getOriginScale( origin, scaleX, scaleY );
247 248
}
248 249

  
250
bool QgsGeorefTransform::getOriginRotationScale( QgsPoint &origin, double &scaleX, double &scaleY, double& rotation ) const
251
{
249 252

  
253
  if ( mTransformParametrisation == Linear )
254
  {
255
    rotation = 0.0;
256
    return dynamic_cast<QgsLinearGeorefTransform *>( mGeorefTransformImplementation )->getOriginScale( origin, scaleX, scaleY );
257
  }
258
  else if ( mTransformParametrisation == Helmert )
259
  {
260
    double scale;
261
    if ( ! dynamic_cast<QgsHelmertGeorefTransform*>( mGeorefTransformImplementation )->getOriginScaleRotation( origin, scale, rotation ) )
262
    {
263
      return false;
264
    }
265
    scaleX = scale;
266
    scaleY = scale;
267
    return true;
268
  }
269
  return false;
270
}
271

  
272

  
250 273
bool QgsGeorefTransform::gdal_transform( const QgsPoint &src, QgsPoint &dst, int dstToSrc ) const
251 274
{
252 275
  GDALTransformerFunc t = GDALTransformer();
......
357 380
  return ( void* )&mHelmertParameters;
358 381
}
359 382

  
383
bool QgsHelmertGeorefTransform::getOriginScaleRotation( QgsPoint &origin, double& scale, double& rotation ) const
384
{
385
  origin = mHelmertParameters.origin;
386
  scale = mHelmertParameters.scale;
387
  rotation = mHelmertParameters.angle;
388
  return true;
389
}
360 390

  
361 391
int QgsHelmertGeorefTransform::helmert_transform( void *pTransformerArg, int bDstToSrc, int nPointCount,
362 392
    double *x, double *y, double *z, int *panSuccess )
src/plugins/georeferencer/qgsgeorefdatapoint.cpp (working copy)
47 47
  mPixelCoords = p.pixelCoords();
48 48
  mMapCoords = p.mapCoords();
49 49
  mEnabled = p.isEnabled();
50
  mResidual = p.residual();
51
  mId = p.id();
50 52
}
51 53

  
52 54
QgsGeorefDataPoint::~QgsGeorefDataPoint()
src/plugins/georeferencer/qgstransformsettingsdialog.h (working copy)
32 32
                                int countGCPpoints, QWidget *parent = 0 );
33 33
    void getTransformSettings( QgsGeorefTransform::TransformParametrisation &tp,
34 34
                               QgsImageWarper::ResamplingMethod &rm, QString &comprMethod,
35
                               QString &raster, QString &proj, bool &zt, bool &loadInQgis,
35
                               QString &raster, QString &proj, QString& pdfReportFile, bool &zt, bool &loadInQgis,
36 36
                               double& resX, double& resY );
37 37
    static void resetSettings();
38 38

  
......
43 43
  private slots:
44 44
    void on_tbnOutputRaster_clicked();
45 45
    void on_tbnTargetSRS_clicked();
46
    void on_tbnReportFile_clicked();
46 47
    void on_leTargetSRS_textChanged( const QString &text );
47 48
    QIcon getThemeIcon( const QString &theName );
48 49