Skip to content

Commit 06b4ad8

Browse files
committedJun 29, 2015
Allow for custom setting of cell size / grid offset in GUI
1 parent 3d290ef commit 06b4ad8

File tree

7 files changed

+253
-109
lines changed

7 files changed

+253
-109
lines changed
 

‎python/analysis/raster/qgsalignraster.sip

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class QgsAlignRaster
3131
QPointF gridOffset() const;
3232
//! Return extent of the raster
3333
QgsRectangle extent() const;
34+
//! Return origin of the raster
35+
QPointF origin() const;
3436

3537
//! write contents of the object to standard error stream - for debugging
3638
void dump() const;
@@ -109,10 +111,6 @@ class QgsAlignRaster
109111
//! Get the output CRS in WKT format
110112
QString destinationCRS() const;
111113

112-
// TODO: first need to run determineTransformAndSize() before this
113-
//QSize rasterSize() const { return QSize(mXSize, mYSize); }
114-
// TODO: add method for access to final extent
115-
116114
//! Configure clipping extent (region of interest).
117115
//! No extra clipping is done if the rectangle is null
118116
void setClipExtent( double xmin, double ymin, double xmax, double ymax );
@@ -123,10 +121,19 @@ class QgsAlignRaster
123121
//! No extra clipping is done if the rectangle is null
124122
QgsRectangle clipExtent() const;
125123

126-
//! Set destination CRS, cell size and grid offset from a raster file
127-
bool setParametersFromRaster( const RasterInfo& rasterInfo, const QString& destWkt = QString() );
128-
//! Set destination CRS, cell size and grid offset from a raster file
129-
bool setParametersFromRaster( const QString& filename, const QString& destWkt = QString() );
124+
//! Set destination CRS, cell size and grid offset from a raster file.
125+
//! The user may provide custom values for some of the parameters - in such case
126+
//! only the remaining parameters are calculated.
127+
//!
128+
//! If default CRS is used, the parameters are set according to the raster file's geo-transform.
129+
//! If a custom CRS is provided, suggested reprojection is calculated first (using GDAL) in order
130+
//! to determine suitable defaults for cell size and grid offset.
131+
//!
132+
//! @return true on success (may fail if it is not possible to reproject raster to given CRS)
133+
bool setParametersFromRaster( const RasterInfo& rasterInfo, const QString& customCRSWkt = QString(), QSizeF customCellSize = QSizeF(), QPointF customGridOffset = QPointF( -1, -1 ) );
134+
//! Overridden variant for convenience, taking filename instead RasterInfo object.
135+
//! See the other variant for details.
136+
bool setParametersFromRaster( const QString& filename, const QString& customCRSWkt = QString(), QSizeF customCellSize = QSizeF(), QPointF customGridOffset = QPointF( -1, -1 ) );
130137

131138
//! Determine destination extent from the input rasters and calculate derived values
132139
//! @return true on success, sets error on error (see errorMessage())

‎src/analysis/raster/qgsalignraster.cpp

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,34 +149,86 @@ QgsRectangle QgsAlignRaster::clipExtent() const
149149
}
150150

151151

152-
bool QgsAlignRaster::setParametersFromRaster( const QString& filename, const QString& destWkt )
152+
bool QgsAlignRaster::setParametersFromRaster( const QString& filename, const QString& destWkt, QSizeF customCellSize, QPointF customGridOffset )
153153
{
154-
return setParametersFromRaster( RasterInfo( filename ), destWkt );
154+
return setParametersFromRaster( RasterInfo( filename ), destWkt, customCellSize, customGridOffset );
155155
}
156156

157-
bool QgsAlignRaster::setParametersFromRaster( const RasterInfo& rasterInfo, const QString& destWkt )
157+
bool QgsAlignRaster::setParametersFromRaster( const RasterInfo& rasterInfo, const QString& customCRSWkt, QSizeF customCellSize, QPointF customGridOffset )
158158
{
159-
if ( destWkt.isEmpty() || destWkt.toAscii() == rasterInfo.crs() )
159+
if ( customCRSWkt.isEmpty() || customCRSWkt.toAscii() == rasterInfo.crs() )
160160
{
161161
// use ref. layer to init input
162162
mCrsWkt = rasterInfo.crs();
163-
mCellSizeX = rasterInfo.cellSize().width();
164-
mCellSizeY = rasterInfo.cellSize().height();
165-
mGridOffsetX = rasterInfo.gridOffset().x();
166-
mGridOffsetY = rasterInfo.gridOffset().y();
163+
164+
if ( !customCellSize.isValid() )
165+
{
166+
mCellSizeX = rasterInfo.cellSize().width();
167+
mCellSizeY = rasterInfo.cellSize().height();
168+
}
169+
else
170+
{
171+
mCellSizeX = customCellSize.width();
172+
mCellSizeY = customCellSize.height();
173+
}
174+
175+
if ( customGridOffset.x() < 0 || customGridOffset.y() < 0 )
176+
{
177+
if ( !customCellSize.isValid() )
178+
{
179+
// using original raster's grid offset to be aligned with origin
180+
mGridOffsetX = rasterInfo.gridOffset().x();
181+
mGridOffsetY = rasterInfo.gridOffset().y();
182+
}
183+
else
184+
{
185+
// if using custom cell size: offset so that we are aligned
186+
// with the original raster's origin point
187+
mGridOffsetX = fmod_with_tolerance( rasterInfo.origin().x(), customCellSize.width() );
188+
mGridOffsetY = fmod_with_tolerance( rasterInfo.origin().y(), customCellSize.height() );
189+
}
190+
}
191+
else
192+
{
193+
mGridOffsetX = customGridOffset.x();
194+
mGridOffsetY = customGridOffset.x();
195+
}
167196
}
168197
else
169198
{
170199
QSizeF cs;
171200
QPointF go;
172-
if ( !suggestedWarpOutput( rasterInfo, destWkt.toAscii(), &cs, &go ) )
201+
if ( !suggestedWarpOutput( rasterInfo, customCRSWkt.toAscii(), &cs, &go ) )
202+
{
203+
mCrsWkt = "_error_";
204+
mCellSizeX = mCellSizeY = 0;
205+
mGridOffsetX = mGridOffsetY = 0;
173206
return false;
207+
}
208+
209+
mCrsWkt = customCRSWkt.toAscii();
174210

175-
mCrsWkt = destWkt.toAscii();
176-
mCellSizeX = cs.width();
177-
mCellSizeY = cs.height();
178-
mGridOffsetX = go.x();
179-
mGridOffsetY = go.y();
211+
if ( !customCellSize.isValid() )
212+
{
213+
mCellSizeX = cs.width();
214+
mCellSizeY = cs.height();
215+
}
216+
else
217+
{
218+
mCellSizeX = customCellSize.width();
219+
mCellSizeY = customCellSize.height();
220+
}
221+
222+
if ( customGridOffset.x() < 0 || customGridOffset.y() < 0 )
223+
{
224+
mGridOffsetX = go.x();
225+
mGridOffsetY = go.y();
226+
}
227+
else
228+
{
229+
mGridOffsetX = customGridOffset.x();
230+
mGridOffsetY = customGridOffset.x();
231+
}
180232
}
181233
return true;
182234
}
@@ -186,6 +238,12 @@ bool QgsAlignRaster::checkInputParameters()
186238
{
187239
mErrorMessage.clear();
188240

241+
if ( mCrsWkt == "_error_" )
242+
{
243+
mErrorMessage = QObject::tr( "Unable to reproject." );
244+
return false;
245+
}
246+
189247
if ( mCellSizeX == 0 || mCellSizeY == 0 )
190248
{
191249
mErrorMessage = QObject::tr( "Cell size must not be zero." );
@@ -502,6 +560,11 @@ QgsRectangle QgsAlignRaster::RasterInfo::extent() const
502560
return transform_to_extent( mGeoTransform, mXSize, mYSize );
503561
}
504562

563+
QPointF QgsAlignRaster::RasterInfo::origin() const
564+
{
565+
return QPointF( mGeoTransform[0], mGeoTransform[3] );
566+
}
567+
505568
void QgsAlignRaster::RasterInfo::dump() const
506569
{
507570
qDebug( "---RASTER INFO------------------" );

‎src/analysis/raster/qgsalignraster.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class ANALYSIS_EXPORT QgsAlignRaster
6363
QPointF gridOffset() const;
6464
//! Return extent of the raster
6565
QgsRectangle extent() const;
66+
//! Return origin of the raster
67+
QPointF origin() const;
6668

6769
//! write contents of the object to standard error stream - for debugging
6870
void dump() const;
@@ -167,10 +169,19 @@ class ANALYSIS_EXPORT QgsAlignRaster
167169
//! No extra clipping is done if the rectangle is null
168170
QgsRectangle clipExtent() const;
169171

170-
//! Set destination CRS, cell size and grid offset from a raster file
171-
bool setParametersFromRaster( const RasterInfo& rasterInfo, const QString& destWkt = QString() );
172-
//! Set destination CRS, cell size and grid offset from a raster file
173-
bool setParametersFromRaster( const QString& filename, const QString& destWkt = QString() );
172+
//! Set destination CRS, cell size and grid offset from a raster file.
173+
//! The user may provide custom values for some of the parameters - in such case
174+
//! only the remaining parameters are calculated.
175+
//!
176+
//! If default CRS is used, the parameters are set according to the raster file's geo-transform.
177+
//! If a custom CRS is provided, suggested reprojection is calculated first (using GDAL) in order
178+
//! to determine suitable defaults for cell size and grid offset.
179+
//!
180+
//! @return true on success (may fail if it is not possible to reproject raster to given CRS)
181+
bool setParametersFromRaster( const RasterInfo& rasterInfo, const QString& customCRSWkt = QString(), QSizeF customCellSize = QSizeF(), QPointF customGridOffset = QPointF( -1, -1 ) );
182+
//! Overridden variant for convenience, taking filename instead RasterInfo object.
183+
//! See the other variant for details.
184+
bool setParametersFromRaster( const QString& filename, const QString& customCRSWkt = QString(), QSizeF customCellSize = QSizeF(), QPointF customGridOffset = QPointF( -1, -1 ) );
174185

175186
//! Determine destination extent from the input rasters and calculate derived values
176187
//! @return true on success, sets error on error (see errorMessage())

‎src/app/qgsalignrasterdialog.cpp

Lines changed: 102 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,33 @@ QgsAlignRasterDialog::QgsAlignRasterDialog( QWidget *parent )
7373
connect( mBtnRemove, SIGNAL( clicked( bool ) ), this, SLOT( removeLayer() ) );
7474
connect( mBtnEdit, SIGNAL( clicked( bool ) ), this, SLOT( editLayer() ) );
7575

76-
connect( mCboReferenceLayer, SIGNAL( currentIndexChanged( int ) ), this, SLOT( updateConfigFromReferenceLayer() ) );
76+
connect( mCboReferenceLayer, SIGNAL( currentIndexChanged( int ) ), this, SLOT( referenceLayerChanged() ) );
7777
connect( mCrsSelector, SIGNAL( crsChanged( QgsCoordinateReferenceSystem ) ), this, SLOT( destinationCrsChanged() ) );
78+
connect( mSpinCellSizeX, SIGNAL( valueChanged( double ) ), this, SLOT( updateParametersFromReferenceLayer() ) );
79+
connect( mSpinCellSizeY, SIGNAL( valueChanged( double ) ), this, SLOT( updateParametersFromReferenceLayer() ) );
80+
connect( mSpinGridOffsetX, SIGNAL( valueChanged( double ) ), this, SLOT( updateParametersFromReferenceLayer() ) );
81+
connect( mSpinGridOffsetY, SIGNAL( valueChanged( double ) ), this, SLOT( updateParametersFromReferenceLayer() ) );
82+
83+
connect( mChkCustomCRS, SIGNAL( clicked( bool ) ), this, SLOT( updateCustomCRS() ) );
84+
connect( mChkCustomCellSize, SIGNAL( clicked( bool ) ), this, SLOT( updateCustomCellSize() ) );
85+
connect( mChkCustomGridOffset, SIGNAL( clicked( bool ) ), this, SLOT( updateCustomGridOffset() ) );
7886

7987
mClipExtentGroupBox->setChecked( false );
8088
mClipExtentGroupBox->setCollapsed( true );
8189
mClipExtentGroupBox->setTitleBase( tr( "Clip to Extent" ) );
90+
QgsMapCanvas* mc = QgisApp::instance()->mapCanvas();
91+
mClipExtentGroupBox->setCurrentExtent( mc->extent(), mc->mapSettings().destinationCrs() );
8292
connect( mClipExtentGroupBox, SIGNAL( extentChanged( QgsRectangle ) ), this, SLOT( clipExtentChanged() ) );
8393

8494
// TODO: auto-detect reference layer
8595

8696
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( runAlign() ) );
8797

8898
populateLayersView();
99+
100+
updateCustomCRS();
101+
updateCustomCellSize();
102+
updateCustomGridOffset();
89103
}
90104

91105
QgsAlignRasterDialog::~QgsAlignRasterDialog()
@@ -130,6 +144,67 @@ void QgsAlignRasterDialog::updateAlignedRasterInfo()
130144
mEditOutputSize->setText( msg );
131145
}
132146

147+
void QgsAlignRasterDialog::updateParametersFromReferenceLayer()
148+
{
149+
QString customCRSWkt;
150+
QSizeF customCellSize;
151+
QPointF customGridOffset( -1, -1 );
152+
153+
int index = mCboReferenceLayer->currentIndex();
154+
if ( index < 0 )
155+
return;
156+
157+
QgsAlignRaster::RasterInfo refInfo( mAlign->rasters().at( index ).inputFilename );
158+
if ( !refInfo.isValid() )
159+
return;
160+
161+
// get custom values from the GUI (if any)
162+
if ( mChkCustomCRS->isChecked() )
163+
{
164+
QgsCoordinateReferenceSystem refCRS( QString::fromAscii( refInfo.crs() ) );
165+
if ( refCRS != mCrsSelector->crs() )
166+
customCRSWkt = mCrsSelector->crs().toWkt();
167+
}
168+
169+
if ( mChkCustomCellSize->isChecked() )
170+
{
171+
customCellSize = QSizeF( mSpinCellSizeX->value(), mSpinCellSizeY->value() );
172+
}
173+
174+
if ( mChkCustomGridOffset->isChecked() )
175+
{
176+
customGridOffset = QPointF( mSpinGridOffsetX->value(), mSpinGridOffsetY->value() );
177+
}
178+
179+
// calculate the parameters which are not customized already
180+
bool res = mAlign->setParametersFromRaster( refInfo, customCRSWkt, customCellSize, customGridOffset );
181+
182+
// refresh values that may have changed
183+
if ( res )
184+
{
185+
QgsCoordinateReferenceSystem destCRS( mAlign->destinationCRS() );
186+
mClipExtentGroupBox->setOutputCrs( destCRS );
187+
if ( !mChkCustomCRS->isChecked() )
188+
{
189+
mCrsSelector->setCrs( destCRS );
190+
}
191+
}
192+
if ( !mChkCustomCellSize->isChecked() )
193+
{
194+
QSizeF cellSize = mAlign->cellSize();
195+
mSpinCellSizeX->setValue( cellSize.width() );
196+
mSpinCellSizeY->setValue( cellSize.height() );
197+
}
198+
if ( !mChkCustomGridOffset->isChecked() )
199+
{
200+
QPointF gridOffset = mAlign->gridOffset();
201+
mSpinGridOffsetX->setValue( gridOffset.x() );
202+
mSpinGridOffsetY->setValue( gridOffset.y() );
203+
}
204+
205+
updateAlignedRasterInfo();
206+
}
207+
133208

134209
void QgsAlignRasterDialog::addLayer()
135210
{
@@ -185,7 +260,7 @@ void QgsAlignRasterDialog::editLayer()
185260
populateLayersView();
186261
}
187262

188-
void QgsAlignRasterDialog::updateConfigFromReferenceLayer()
263+
void QgsAlignRasterDialog::referenceLayerChanged()
189264
{
190265
int index = mCboReferenceLayer->currentIndex();
191266
if ( index < 0 )
@@ -195,25 +270,11 @@ void QgsAlignRasterDialog::updateConfigFromReferenceLayer()
195270
if ( !refInfo.isValid() )
196271
return;
197272

198-
mAlign->setParametersFromRaster( refInfo );
199-
200-
QgsCoordinateReferenceSystem destCRS( mAlign->destinationCRS() );
201-
mCrsSelector->setCrs( destCRS );
202-
203-
QSizeF cellSize = mAlign->cellSize();
204-
mSpinCellSizeX->setValue( cellSize.width() );
205-
mSpinCellSizeY->setValue( cellSize.height() );
273+
QgsCoordinateReferenceSystem layerCRS( QString::fromAscii( refInfo.crs() ) );
274+
mCrsSelector->setLayerCrs( layerCRS );
275+
mClipExtentGroupBox->setOriginalExtent( refInfo.extent(), layerCRS );
206276

207-
QPointF gridOffset = mAlign->gridOffset();
208-
mSpinGridOffsetX->setValue( gridOffset.x() );
209-
mSpinGridOffsetY->setValue( gridOffset.y() );
210-
211-
QgsMapCanvas* mc = QgisApp::instance()->mapCanvas();
212-
mClipExtentGroupBox->setCurrentExtent( mc->extent(), mc->mapSettings().destinationCrs() );
213-
mClipExtentGroupBox->setOriginalExtent( refInfo.extent(), QgsCoordinateReferenceSystem( QString::fromAscii( refInfo.crs() ) ) );
214-
mClipExtentGroupBox->setOutputCrs( destCRS );
215-
216-
updateAlignedRasterInfo();
277+
updateParametersFromReferenceLayer();
217278
}
218279

219280

@@ -230,23 +291,7 @@ void QgsAlignRasterDialog::destinationCrsChanged()
230291
if ( !refInfo.isValid() )
231292
return;
232293

233-
if ( !mAlign->setParametersFromRaster( refInfo, mCrsSelector->crs().toWkt() ) )
234-
{
235-
QMessageBox::warning( this, tr( "Align Rasters" ), tr( "Cannot reproject reference layer to the chosen destination CRS.\n\nPlease select a different CRS" ) );
236-
return;
237-
}
238-
239-
QSizeF cellSize = mAlign->cellSize();
240-
mSpinCellSizeX->setValue( cellSize.width() );
241-
mSpinCellSizeY->setValue( cellSize.height() );
242-
243-
QPointF gridOffset = mAlign->gridOffset();
244-
mSpinGridOffsetX->setValue( gridOffset.x() );
245-
mSpinGridOffsetY->setValue( gridOffset.y() );
246-
247-
mClipExtentGroupBox->setOutputCrs( mCrsSelector->crs() );
248-
249-
updateAlignedRasterInfo();
294+
updateParametersFromReferenceLayer();
250295
}
251296

252297
void QgsAlignRasterDialog::clipExtentChanged()
@@ -256,6 +301,26 @@ void QgsAlignRasterDialog::clipExtentChanged()
256301
updateAlignedRasterInfo();
257302
}
258303

304+
void QgsAlignRasterDialog::updateCustomCRS()
305+
{
306+
mCrsSelector->setEnabled( mChkCustomCRS->isChecked() );
307+
updateParametersFromReferenceLayer();
308+
}
309+
310+
void QgsAlignRasterDialog::updateCustomCellSize()
311+
{
312+
mSpinCellSizeX->setEnabled( mChkCustomCellSize->isChecked() );
313+
mSpinCellSizeY->setEnabled( mChkCustomCellSize->isChecked() );
314+
updateParametersFromReferenceLayer();
315+
}
316+
317+
void QgsAlignRasterDialog::updateCustomGridOffset()
318+
{
319+
mSpinGridOffsetX->setEnabled( mChkCustomGridOffset->isChecked() );
320+
mSpinGridOffsetY->setEnabled( mChkCustomGridOffset->isChecked() );
321+
updateParametersFromReferenceLayer();
322+
}
323+
259324

260325
void QgsAlignRasterDialog::runAlign()
261326
{

0 commit comments

Comments
 (0)
Please sign in to comment.