Align rasters: configuration of clip extent, reporting of output size

This commit is contained in:
Martin Dobias 2015-06-25 13:33:31 +08:00
parent 9e16952732
commit 3d290ef21a
6 changed files with 138 additions and 33 deletions

View File

@ -128,8 +128,19 @@ class QgsAlignRaster
//! Set destination CRS, cell size and grid offset from a raster file
bool setParametersFromRaster( const QString& filename, const QString& destWkt = QString() );
//! Determine destination extent from the input rasters and calculate derived values
//! @return true on success, sets error on error (see errorMessage())
bool checkInputParameters();
//! Return expected size of the resulting aligned raster
//! @note first need to run checkInputParameters() which returns with success
QSize alignedRasterSize() const;
//! Return expected extent of the resulting aligned raster
//! @note first need to run checkInputParameters() which returns with success
QgsRectangle alignedRasterExtent() const;
//! Run the alignment process
//! @return true on success
//! @return true on success, sets error on error (see errorMessage())
bool run();
//! Return error from a previous run() call.

View File

@ -117,11 +117,15 @@ static CPLErr rescalePostWarpChunkProcessor( void* pKern, void* pArg )
QgsAlignRaster::QgsAlignRaster()
: mProgressHandler( 0 )
{
// parameters
mCellSizeX = mCellSizeY = 0;
mGridOffsetX = mGridOffsetY = 0;
mXSize = mYSize = 0;
mClipExtent[0] = mClipExtent[1] = mClipExtent[2] = mClipExtent[3] = 0;
// derived variables
mXSize = mYSize = 0;
for ( int i = 0; i < 6; ++i )
mGeoTransform[i] = 0;
}
void QgsAlignRaster::setClipExtent( double xmin, double ymin, double xmax, double ymax )
@ -178,8 +182,20 @@ bool QgsAlignRaster::setParametersFromRaster( const RasterInfo& rasterInfo, cons
}
bool QgsAlignRaster::determineTransformAndSize()
bool QgsAlignRaster::checkInputParameters()
{
mErrorMessage.clear();
if ( mCellSizeX == 0 || mCellSizeY == 0 )
{
mErrorMessage = QObject::tr( "Cell size must not be zero." );
return false;
}
mXSize = mYSize = 0;
for ( int i = 0; i < 6; ++i )
mGeoTransform[i] = 0;
double finalExtent[4] = { 0, 0, 0, 0 };
// for each raster: determine their extent in projected cfg
@ -245,15 +261,18 @@ bool QgsAlignRaster::determineTransformAndSize()
double originX = ceil_with_tolerance(( finalExtent[0] - mGridOffsetX ) / mCellSizeX ) * mCellSizeX + mGridOffsetX;;
double originY = ceil_with_tolerance(( finalExtent[1] - mGridOffsetY ) / mCellSizeY ) * mCellSizeY + mGridOffsetY;
mXSize = floor_with_tolerance(( finalExtent[2] - originX ) / mCellSizeX );
mYSize = floor_with_tolerance(( finalExtent[3] - originY ) / mCellSizeY );
int xSize = floor_with_tolerance(( finalExtent[2] - originX ) / mCellSizeX );
int ySize = floor_with_tolerance(( finalExtent[3] - originY ) / mCellSizeY );
if ( mXSize <= 0 || mYSize <= 0 )
if ( xSize <= 0 || ySize <= 0 )
{
mErrorMessage = QObject::tr( "Configured inputs have no common intersecting area." );
mErrorMessage = QObject::tr( "No common intersecting area." );
return false;
}
mXSize = xSize;
mYSize = ySize;
// build final geotransform...
mGeoTransform[0] = originX;
mGeoTransform[1] = mCellSizeX;
@ -266,12 +285,23 @@ bool QgsAlignRaster::determineTransformAndSize()
}
QSize QgsAlignRaster::alignedRasterSize() const
{
return QSize( mXSize, mYSize );
}
QgsRectangle QgsAlignRaster::alignedRasterExtent() const
{
return transform_to_extent( mGeoTransform, mXSize, mYSize );
}
bool QgsAlignRaster::run()
{
mErrorMessage.clear();
// consider extent of all layers and setup geotransform and output grid size
if ( !determineTransformAndSize() )
if ( !checkInputParameters() )
return false;
//dump();

View File

@ -157,10 +157,6 @@ class ANALYSIS_EXPORT QgsAlignRaster
//! Get the output CRS in WKT format
QString destinationCRS() const { return mCrsWkt; }
// TODO: first need to run determineTransformAndSize() before this
//QSize rasterSize() const { return QSize(mXSize, mYSize); }
// TODO: add method for access to final extent
//! Configure clipping extent (region of interest).
//! No extra clipping is done if the rectangle is null
void setClipExtent( double xmin, double ymin, double xmax, double ymax );
@ -176,8 +172,19 @@ class ANALYSIS_EXPORT QgsAlignRaster
//! Set destination CRS, cell size and grid offset from a raster file
bool setParametersFromRaster( const QString& filename, const QString& destWkt = QString() );
//! Determine destination extent from the input rasters and calculate derived values
//! @return true on success, sets error on error (see errorMessage())
bool checkInputParameters();
//! Return expected size of the resulting aligned raster
//! @note first need to run checkInputParameters() which returns with success
QSize alignedRasterSize() const;
//! Return expected extent of the resulting aligned raster
//! @note first need to run checkInputParameters() which returns with success
QgsRectangle alignedRasterExtent() const;
//! Run the alignment process
//! @return true on success
//! @return true on success, sets error on error (see errorMessage())
bool run();
//! Return error from a previous run() call.
@ -189,9 +196,6 @@ class ANALYSIS_EXPORT QgsAlignRaster
protected:
//! Determine destination extent from the input rasters and calculate derived values
bool determineTransformAndSize();
//! Internal function for processing of one raster (1. create output, 2. do the alignment)
bool createAndWarp( const Item& raster );

View File

@ -1,8 +1,10 @@
#include "qgsalignrasterdialog.h"
#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgsalignraster.h"
#include "qgsdataitem.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayercombobox.h"
#include "qgsmaplayerregistry.h"
#include "qgsrasterlayer.h"
@ -75,6 +77,9 @@ QgsAlignRasterDialog::QgsAlignRasterDialog( QWidget *parent )
connect( mCrsSelector, SIGNAL( crsChanged( QgsCoordinateReferenceSystem ) ), this, SLOT( destinationCrsChanged() ) );
mClipExtentGroupBox->setChecked( false );
mClipExtentGroupBox->setCollapsed( true );
mClipExtentGroupBox->setTitleBase( tr( "Clip to Extent" ) );
connect( mClipExtentGroupBox, SIGNAL( extentChanged( QgsRectangle ) ), this, SLOT( clipExtentChanged() ) );
// TODO: auto-detect reference layer
@ -107,8 +112,25 @@ void QgsAlignRasterDialog::populateLayersView()
mViewLayers->setModel( model );
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( model->rowCount() > 0 );
updateAlignedRasterInfo();
}
void QgsAlignRasterDialog::updateAlignedRasterInfo()
{
if ( !mAlign->checkInputParameters() )
{
mEditOutputSize->setText( mAlign->errorMessage() );
return;
}
QSize size = mAlign->alignedRasterSize();
QString msg = QString( "%1 x %2" ).arg( size.width() ).arg( size.height() );
mEditOutputSize->setText( msg );
}
void QgsAlignRasterDialog::addLayer()
{
QgsAlignRasterLayerConfigDialog d;
@ -169,7 +191,11 @@ void QgsAlignRasterDialog::updateConfigFromReferenceLayer()
if ( index < 0 )
return;
mAlign->setParametersFromRaster( mAlign->rasters().at( index ).inputFilename );
QgsAlignRaster::RasterInfo refInfo( mAlign->rasters().at( index ).inputFilename );
if ( !refInfo.isValid() )
return;
mAlign->setParametersFromRaster( refInfo );
QgsCoordinateReferenceSystem destCRS( mAlign->destinationCRS() );
mCrsSelector->setCrs( destCRS );
@ -182,9 +208,15 @@ void QgsAlignRasterDialog::updateConfigFromReferenceLayer()
mSpinGridOffsetX->setValue( gridOffset.x() );
mSpinGridOffsetY->setValue( gridOffset.y() );
mClipExtentGroupBox->setOriginalExtent( mAlign->clipExtent(), destCRS );
QgsMapCanvas* mc = QgisApp::instance()->mapCanvas();
mClipExtentGroupBox->setCurrentExtent( mc->extent(), mc->mapSettings().destinationCrs() );
mClipExtentGroupBox->setOriginalExtent( refInfo.extent(), QgsCoordinateReferenceSystem( QString::fromAscii( refInfo.crs() ) ) );
mClipExtentGroupBox->setOutputCrs( destCRS );
updateAlignedRasterInfo();
}
void QgsAlignRasterDialog::destinationCrsChanged()
{
if ( mCrsSelector->crs().toWkt() == mAlign->destinationCRS() )
@ -194,7 +226,11 @@ void QgsAlignRasterDialog::destinationCrsChanged()
if ( index < 0 )
return;
if ( !mAlign->setParametersFromRaster( mAlign->rasters().at( index ).inputFilename, mCrsSelector->crs().toWkt() ) )
QgsAlignRaster::RasterInfo refInfo( mAlign->rasters().at( index ).inputFilename );
if ( !refInfo.isValid() )
return;
if ( !mAlign->setParametersFromRaster( refInfo, mCrsSelector->crs().toWkt() ) )
{
QMessageBox::warning( this, tr( "Align Rasters" ), tr( "Cannot reproject reference layer to the chosen destination CRS.\n\nPlease select a different CRS" ) );
return;
@ -207,6 +243,17 @@ void QgsAlignRasterDialog::destinationCrsChanged()
QPointF gridOffset = mAlign->gridOffset();
mSpinGridOffsetX->setValue( gridOffset.x() );
mSpinGridOffsetY->setValue( gridOffset.y() );
mClipExtentGroupBox->setOutputCrs( mCrsSelector->crs() );
updateAlignedRasterInfo();
}
void QgsAlignRasterDialog::clipExtentChanged()
{
mAlign->setClipExtent( mClipExtentGroupBox->outputExtent() );
updateAlignedRasterInfo();
}

View File

@ -28,8 +28,11 @@ class QgsAlignRasterDialog : public QDialog, private Ui::QgsAlignRasterDialog
void destinationCrsChanged();
void clipExtentChanged();
protected:
void populateLayersView();
void updateAlignedRasterInfo();
protected:
QgsAlignRaster* mAlign;

View File

@ -80,6 +80,13 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Output Size</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
@ -87,17 +94,6 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QgsExtentGroupBox" name="mClipExtentGroupBox">
<property name="title">
<string>Clip to Extent</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
@ -176,7 +172,7 @@
</item>
</layout>
</item>
<item row="5" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="mChkAddToCanvas">
<property name="text">
<string>Add aligned rasters to map canvas</string>
@ -186,6 +182,21 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QgsExtentGroupBox" name="mClipExtentGroupBox">
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="mEditOutputSize">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -232,7 +243,6 @@
<tabstop>mSpinCellSizeY</tabstop>
<tabstop>mSpinGridOffsetX</tabstop>
<tabstop>mSpinGridOffsetY</tabstop>
<tabstop>mClipExtentGroupBox</tabstop>
<tabstop>mChkAddToCanvas</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>