drop old align raster tool and add processing algorithm to the Raster

menu
This commit is contained in:
Alexander Bruy 2023-07-18 15:17:15 +03:00
parent f9d50bf2ad
commit 051143ff6c
8 changed files with 9 additions and 885 deletions

View File

@ -100,6 +100,7 @@ def initMenusAndToolbars():
'native:createspatialindex': managementToolsMenu})
rasterMenu = iface.rasterMenu().title()
defaultMenuEntries.update({'native:alignrasters': rasterMenu})
projectionsMenu = rasterMenu + "/" + Processing.tr('Projections')
defaultMenuEntries.update({'gdal:warpreproject': projectionsMenu,
'gdal:extractprojection': projectionsMenu,
@ -188,7 +189,8 @@ def createMenus():
icon = None
if menuPath:
paths = menuPath.split("/")
addAlgorithmEntry(alg, paths[0], paths[-1], addButton=addButton, icon=icon)
subMenuName = paths[-1] if len(paths) > 1 else ""
addAlgorithmEntry(alg, paths[0], subMenuName, addButton=addButton, icon=icon)
def removeMenus():
@ -215,8 +217,11 @@ def addAlgorithmEntry(alg, menuName, submenuName, actionText=None, icon=None, ad
if menuName:
menu = getMenu(menuName, iface.mainWindow().menuBar())
submenu = getMenu(submenuName, menu)
submenu.addAction(action)
if submenuName:
submenu = getMenu(submenuName, menu)
submenu.addAction(action)
else:
menu.addAction(action)
if addButton:
global algorithmsToolbar

View File

@ -11,7 +11,6 @@ set(QGIS_APP_SRCS
qgisappinterface.cpp
qgisappstylesheet.cpp
qgsabout.cpp
qgsalignrasterdialog.cpp
qgsappauthrequesthandler.cpp
qgsappbrowserproviders.cpp
qgsappcoordinateoperationhandlers.cpp

View File

@ -202,7 +202,6 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgis.h"
#include "qgsabout.h"
#include "qgsabstractmaptoolhandler.h"
#include "qgsalignrasterdialog.h"
#include "qgsappauthrequesthandler.h"
#include "qgsappbrowserproviders.h"
#include "qgsapplayertreeviewmenuprovider.h"
@ -2973,7 +2972,6 @@ void QgisApp::createActions()
connect( mActionNewVirtualLayer, &QAction::triggered, this, &QgisApp::addVirtualLayer );
connect( mActionShowRasterCalculator, &QAction::triggered, this, &QgisApp::showRasterCalculator );
connect( mActionShowMeshCalculator, &QAction::triggered, this, &QgisApp::showMeshCalculator );
connect( mActionShowAlignRasterTool, &QAction::triggered, this, &QgisApp::showAlignRasterTool );
connect( mActionEmbedLayers, &QAction::triggered, this, &QgisApp::embedLayers );
connect( mActionAddLayerDefinition, &QAction::triggered, this, [] { QgsAppLayerHandling::addLayerDefinition(); } );
connect( mActionAddOgrLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "ogr" ) ); } );
@ -6314,14 +6312,6 @@ void QgisApp::showMeshCalculator()
}
}
void QgisApp::showAlignRasterTool()
{
QgsAlignRasterDialog dlg( this );
dlg.exec();
}
void QgisApp::fileOpen()
{
if ( checkTasksDependOnProject() )

View File

@ -1675,8 +1675,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void showRasterCalculator();
//! Calculate new meshes from existing ones
void showMeshCalculator();
//! Open dialog to align raster layers
void showAlignRasterTool();
/**
* Called whenever user wants to embed layers

View File

@ -1,486 +0,0 @@
/***************************************************************************
qgsalignrasterdialog.cpp
---------------------
begin : June 2015
copyright : (C) 2015 by Martin Dobias
email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsalignrasterdialog.h"
#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgsalignraster.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayercombobox.h"
#include "qgsproject.h"
#include "qgsrasterlayer.h"
#include "qgsiconutils.h"
#include <QCheckBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QLineEdit>
#include <QMessageBox>
#include <QPushButton>
#include <QStandardItemModel>
#include <QVBoxLayout>
static QgsMapLayer *_rasterLayer( const QString &filename )
{
const QMap<QString, QgsMapLayer *> layers = QgsProject::instance()->mapLayers();
const auto constLayers = layers;
for ( QgsMapLayer *layer : constLayers )
{
if ( layer->type() == Qgis::LayerType::Raster && layer->source() == filename )
return layer;
}
return nullptr;
}
static QString _rasterLayerName( const QString &filename )
{
if ( QgsMapLayer *layer = _rasterLayer( filename ) )
return layer->name();
const QFileInfo fi( filename );
return fi.baseName();
}
//! Helper class to report progress
struct QgsAlignRasterDialogProgress : public QgsAlignRaster::ProgressHandler
{
explicit QgsAlignRasterDialogProgress( QProgressBar *pb ) : mPb( pb ) {}
bool progress( double complete ) override
{
mPb->setValue( ( int ) std::round( complete * 100 ) );
qApp->processEvents(); // to actually show the progress in GUI
return true;
}
protected:
QProgressBar *mPb = nullptr;
};
QgsAlignRasterDialog::QgsAlignRasterDialog( QWidget *parent )
: QDialog( parent )
{
setupUi( this );
mBtnAdd->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
mBtnEdit->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.svg" ) ) );
mBtnRemove->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );
mAlign = new QgsAlignRaster;
mAlign->setProgressHandler( new QgsAlignRasterDialogProgress( mProgress ) );
mCrsSelector->setShowAccuracyWarnings( true );
connect( mBtnAdd, &QAbstractButton::clicked, this, &QgsAlignRasterDialog::addLayer );
connect( mBtnRemove, &QAbstractButton::clicked, this, &QgsAlignRasterDialog::removeLayer );
connect( mBtnEdit, &QAbstractButton::clicked, this, &QgsAlignRasterDialog::editLayer );
connect( mCboReferenceLayer, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ] { referenceLayerChanged(); } );
connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsAlignRasterDialog::destinationCrsChanged );
connect( mSpinCellSizeX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAlignRasterDialog::updateParametersFromReferenceLayer );
connect( mSpinCellSizeY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAlignRasterDialog::updateParametersFromReferenceLayer );
connect( mSpinGridOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAlignRasterDialog::updateParametersFromReferenceLayer );
connect( mSpinGridOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAlignRasterDialog::updateParametersFromReferenceLayer );
connect( mChkCustomCRS, &QAbstractButton::clicked, this, &QgsAlignRasterDialog::updateCustomCrs );
connect( mChkCustomCellSize, &QAbstractButton::clicked, this, &QgsAlignRasterDialog::updateCustomCellSize );
connect( mChkCustomGridOffset, &QAbstractButton::clicked, this, &QgsAlignRasterDialog::updateCustomGridOffset );
mClipExtentGroupBox->setChecked( false );
mClipExtentGroupBox->setCollapsed( true );
mClipExtentGroupBox->setTitleBase( tr( "Clip to Extent" ) );
QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
mClipExtentGroupBox->setCurrentExtent( mc->extent(), mc->mapSettings().destinationCrs() );
connect( mClipExtentGroupBox, &QgsExtentGroupBox::extentChanged, this, &QgsAlignRasterDialog::clipExtentChanged );
// TODO: auto-detect reference layer
connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAlignRasterDialog::runAlign );
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsAlignRasterDialog::showHelp );
populateLayersView();
updateCustomCrs();
updateCustomCellSize();
updateCustomGridOffset();
}
QgsAlignRasterDialog::~QgsAlignRasterDialog()
{
delete mAlign;
}
void QgsAlignRasterDialog::showHelp()
{
QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_analysis.html#raster-alignment" ) );
}
void QgsAlignRasterDialog::populateLayersView()
{
mCboReferenceLayer->clear();
const int refLayerIndex = mAlign->suggestedReferenceLayer();
QStandardItemModel *model = new QStandardItemModel();
int i = 0;
const auto constRasters = mAlign->rasters();
for ( const QgsAlignRaster::Item &item : constRasters )
{
QString layerName = _rasterLayerName( item.inputFilename );
QStandardItem *si = new QStandardItem( QgsIconUtils::iconRaster(), layerName );
model->appendRow( si );
if ( i == refLayerIndex )
layerName += tr( " [best reference]" );
mCboReferenceLayer->addItem( layerName );
++i;
}
mViewLayers->setModel( model );
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( model->rowCount() > 0 );
if ( refLayerIndex >= 0 )
mCboReferenceLayer->setCurrentIndex( refLayerIndex );
updateAlignedRasterInfo();
}
void QgsAlignRasterDialog::updateAlignedRasterInfo()
{
if ( !mAlign->checkInputParameters() )
{
mEditOutputSize->setText( mAlign->errorMessage() );
return;
}
const QSize size = mAlign->alignedRasterSize();
const QString msg = QStringLiteral( "%1 x %2" ).arg( size.width() ).arg( size.height() );
mEditOutputSize->setText( msg );
}
void QgsAlignRasterDialog::updateParametersFromReferenceLayer()
{
QString customCRSWkt;
QSizeF customCellSize;
QPointF customGridOffset( -1, -1 );
const int index = mCboReferenceLayer->currentIndex();
if ( index < 0 )
return;
const QgsAlignRaster::RasterInfo refInfo( mAlign->rasters().at( index ).inputFilename );
if ( !refInfo.isValid() )
return;
// get custom values from the GUI (if any)
if ( mChkCustomCRS->isChecked() )
{
const QgsCoordinateReferenceSystem refCRS( refInfo.crs() );
if ( refCRS != mCrsSelector->crs() )
customCRSWkt = mCrsSelector->crs( ).toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL );
}
if ( mChkCustomCellSize->isChecked() )
{
customCellSize = QSizeF( mSpinCellSizeX->value(), mSpinCellSizeY->value() );
}
if ( mChkCustomGridOffset->isChecked() )
{
customGridOffset = QPointF( mSpinGridOffsetX->value(), mSpinGridOffsetY->value() );
}
// calculate the parameters which are not customized already
const bool res = mAlign->setParametersFromRaster( refInfo, customCRSWkt, customCellSize, customGridOffset );
// refresh values that may have changed
if ( res )
{
const QgsCoordinateReferenceSystem destCRS( mAlign->destinationCrs() );
mClipExtentGroupBox->setOutputCrs( destCRS );
if ( !mChkCustomCRS->isChecked() )
{
mCrsSelector->setCrs( destCRS );
}
}
if ( !mChkCustomCellSize->isChecked() )
{
const QSizeF cellSize = mAlign->cellSize();
mSpinCellSizeX->setValue( cellSize.width() );
mSpinCellSizeY->setValue( cellSize.height() );
}
if ( !mChkCustomGridOffset->isChecked() )
{
const QPointF gridOffset = mAlign->gridOffset();
mSpinGridOffsetX->setValue( gridOffset.x() );
mSpinGridOffsetY->setValue( gridOffset.y() );
}
updateAlignedRasterInfo();
}
void QgsAlignRasterDialog::addLayer()
{
QgsAlignRasterLayerConfigDialog d;
if ( !d.exec() )
return;
QgsAlignRaster::List list = mAlign->rasters();
QgsAlignRaster::Item item( d.inputFilename(), d.outputFilename() );
item.resampleMethod = d.resampleMethod();
item.rescaleValues = d.rescaleValues();
list.append( item );
mAlign->setRasters( list );
populateLayersView();
}
void QgsAlignRasterDialog::removeLayer()
{
const QModelIndex current = mViewLayers->currentIndex();
if ( !current.isValid() )
return;
QgsAlignRaster::List list = mAlign->rasters();
list.removeAt( current.row() );
mAlign->setRasters( list );
populateLayersView();
}
void QgsAlignRasterDialog::editLayer()
{
const QModelIndex current = mViewLayers->currentIndex();
if ( !current.isValid() )
return;
QgsAlignRaster::List list = mAlign->rasters();
const QgsAlignRaster::Item item = list.at( current.row() );
QgsAlignRasterLayerConfigDialog d;
d.setItem( item.inputFilename, item.outputFilename, item.resampleMethod, item.rescaleValues );
if ( !d.exec() )
return;
QgsAlignRaster::Item itemNew( d.inputFilename(), d.outputFilename() );
itemNew.resampleMethod = d.resampleMethod();
itemNew.rescaleValues = d.rescaleValues();
list[current.row()] = itemNew;
mAlign->setRasters( list );
populateLayersView();
}
void QgsAlignRasterDialog::referenceLayerChanged()
{
const int index = mCboReferenceLayer->currentIndex();
if ( index < 0 )
return;
const QgsAlignRaster::RasterInfo refInfo( mAlign->rasters().at( index ).inputFilename );
if ( !refInfo.isValid() )
return;
const QgsCoordinateReferenceSystem layerCRS( refInfo.crs() );
mCrsSelector->setLayerCrs( layerCRS );
mClipExtentGroupBox->setOriginalExtent( refInfo.extent(), layerCRS );
updateParametersFromReferenceLayer();
}
void QgsAlignRasterDialog::destinationCrsChanged()
{
if ( mCrsSelector->crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL ) == mAlign->destinationCrs() )
return;
const int index = mCboReferenceLayer->currentIndex();
if ( index < 0 )
return;
const QgsAlignRaster::RasterInfo refInfo( mAlign->rasters().at( index ).inputFilename );
if ( !refInfo.isValid() )
return;
updateParametersFromReferenceLayer();
}
void QgsAlignRasterDialog::clipExtentChanged()
{
mAlign->setClipExtent( mClipExtentGroupBox->outputExtent() );
updateAlignedRasterInfo();
}
void QgsAlignRasterDialog::updateCustomCrs()
{
mCrsSelector->setEnabled( mChkCustomCRS->isChecked() );
updateParametersFromReferenceLayer();
}
void QgsAlignRasterDialog::updateCustomCellSize()
{
mSpinCellSizeX->setEnabled( mChkCustomCellSize->isChecked() );
mSpinCellSizeY->setEnabled( mChkCustomCellSize->isChecked() );
updateParametersFromReferenceLayer();
}
void QgsAlignRasterDialog::updateCustomGridOffset()
{
mSpinGridOffsetX->setEnabled( mChkCustomGridOffset->isChecked() );
mSpinGridOffsetY->setEnabled( mChkCustomGridOffset->isChecked() );
updateParametersFromReferenceLayer();
}
void QgsAlignRasterDialog::runAlign()
{
setEnabled( false );
const bool res = mAlign->run();
setEnabled( true );
if ( res )
{
if ( mChkAddToCanvas->isChecked() )
{
const auto constRasters = mAlign->rasters();
for ( const QgsAlignRaster::Item &item : constRasters )
{
QgsRasterLayer *layer = new QgsRasterLayer( item.outputFilename, QFileInfo( item.outputFilename ).baseName() );
if ( layer->isValid() )
QgsProject::instance()->addMapLayer( layer );
else
delete layer;
}
}
}
else
{
QMessageBox::critical( this, tr( "Align Rasters" ), tr( "Failed to align rasters:" ) + "\n\n" + mAlign->errorMessage() );
}
}
// ------
QgsAlignRasterLayerConfigDialog::QgsAlignRasterLayerConfigDialog()
{
setWindowTitle( tr( "Configure Layer Resampling" ) );
QVBoxLayout *layout = new QVBoxLayout();
cboLayers = new QgsMapLayerComboBox( this );
cboLayers->setFilters( QgsMapLayerProxyModel::RasterLayer );
cboResample = new QComboBox( this );
cboResample->addItem( tr( "Nearest Neighbour" ), QgsAlignRaster::ResampleAlg::RA_NearestNeighbour );
cboResample->addItem( tr( "Bilinear (2x2 Kernel)" ), QgsAlignRaster::ResampleAlg::RA_Bilinear );
cboResample->addItem( tr( "Cubic (4x4 Kernel)" ), QgsAlignRaster::ResampleAlg::RA_Cubic );
cboResample->addItem( tr( "Cubic B-Spline (4x4 Kernel)" ), QgsAlignRaster::ResampleAlg::RA_CubicSpline );
cboResample->addItem( tr( "Lanczos (6x6 Kernel)" ), QgsAlignRaster::ResampleAlg::RA_Lanczos );
cboResample->addItem( tr( "Average" ), QgsAlignRaster::ResampleAlg::RA_Average );
cboResample->addItem( tr( "Mode" ), QgsAlignRaster::ResampleAlg::RA_Mode );
cboResample->addItem( tr( "Maximum" ), QgsAlignRaster::ResampleAlg::RA_Max );
cboResample->addItem( tr( "Minimum" ), QgsAlignRaster::ResampleAlg::RA_Min );
cboResample->addItem( tr( "Median" ), QgsAlignRaster::ResampleAlg::RA_Median );
cboResample->addItem( tr( "First Quartile (Q1)" ), QgsAlignRaster::ResampleAlg::RA_Q1 );
cboResample->addItem( tr( "Third Quartile (Q3)" ), QgsAlignRaster::ResampleAlg::RA_Q3 );
editOutput = new QLineEdit( this );
btnBrowse = new QPushButton( tr( "Browse…" ), this );
connect( btnBrowse, &QAbstractButton::clicked, this, &QgsAlignRasterLayerConfigDialog::browseOutputFilename );
QHBoxLayout *layoutOutput = new QHBoxLayout();
layoutOutput->addWidget( editOutput );
layoutOutput->addWidget( btnBrowse );
chkRescale = new QCheckBox( tr( "Rescale values according to the cell size" ), this );
btnBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this );
connect( btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
connect( btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
layout->addWidget( new QLabel( tr( "Input raster layer:" ), this ) );
layout->addWidget( cboLayers );
layout->addWidget( new QLabel( tr( "Output raster filename:" ), this ) );
layout->addLayout( layoutOutput );
layout->addWidget( new QLabel( tr( "Resampling method:" ), this ) );
layout->addWidget( cboResample );
layout->addWidget( chkRescale );
layout->addWidget( btnBox );
setLayout( layout );
}
QString QgsAlignRasterLayerConfigDialog::inputFilename() const
{
QgsRasterLayer *l = qobject_cast<QgsRasterLayer *>( cboLayers->currentLayer() );
return l ? l->source() : QString();
}
QString QgsAlignRasterLayerConfigDialog::outputFilename() const
{
return editOutput->text();
}
QgsAlignRaster::ResampleAlg QgsAlignRasterLayerConfigDialog::resampleMethod() const
{
return static_cast< QgsAlignRaster::ResampleAlg >( cboResample->currentData().toInt() );
}
bool QgsAlignRasterLayerConfigDialog::rescaleValues() const
{
return chkRescale->isChecked();
}
void QgsAlignRasterLayerConfigDialog::setItem( const QString &inputFilename, const QString &outputFilename,
QgsAlignRaster::ResampleAlg resampleMethod, bool rescaleValues )
{
cboLayers->setLayer( _rasterLayer( inputFilename ) );
editOutput->setText( outputFilename );
cboResample->setCurrentIndex( cboResample->findData( resampleMethod ) );
chkRescale->setChecked( rescaleValues );
}
void QgsAlignRasterLayerConfigDialog::browseOutputFilename()
{
const QgsSettings settings;
const QString dirName = editOutput->text().isEmpty() ? settings.value( QStringLiteral( "UI/lastRasterFileDir" ), QDir::homePath() ).toString() : editOutput->text();
QString fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), dirName, tr( "GeoTIFF" ) + " (*.tif *.tiff *.TIF *.TIFF)" );
if ( !fileName.isEmpty() )
{
// ensure the user never omitted the extension from the file name
if ( !fileName.endsWith( QLatin1String( ".tif" ), Qt::CaseInsensitive ) && !fileName.endsWith( QLatin1String( ".tiff" ), Qt::CaseInsensitive ) )
{
fileName += QLatin1String( ".tif" );
}
editOutput->setText( fileName );
}
}

View File

@ -1,94 +0,0 @@
/***************************************************************************
qgsalignrasterdialog.h
---------------------
begin : June 2015
copyright : (C) 2015 by Martin Dobias
email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSALIGNRASTERDIALOG_H
#define QGSALIGNRASTERDIALOG_H
#include <QDialog>
#include "qgsalignraster.h"
#include "qgshelp.h"
#include "ui_qgsalignrasterdialog.h"
class QgsAlignRaster;
//! Dialog providing user interface for QgsAlignRaster
class QgsAlignRasterDialog : public QDialog, private Ui::QgsAlignRasterDialog
{
Q_OBJECT
public:
explicit QgsAlignRasterDialog( QWidget *parent = nullptr );
~QgsAlignRasterDialog() override;
signals:
protected slots:
void addLayer();
void removeLayer();
void editLayer();
void referenceLayerChanged();
void runAlign();
void destinationCrsChanged();
void clipExtentChanged();
void updateCustomCrs();
void updateCustomCellSize();
void updateCustomGridOffset();
void updateParametersFromReferenceLayer();
void showHelp();
protected:
void populateLayersView();
void updateAlignedRasterInfo();
protected:
QgsAlignRaster *mAlign = nullptr;
};
class QgsMapLayerComboBox;
class QCheckBox;
//! Simple dialog to display details of one layer's configuration
class QgsAlignRasterLayerConfigDialog : public QDialog
{
Q_OBJECT
public:
QgsAlignRasterLayerConfigDialog();
QString inputFilename() const;
QString outputFilename() const;
QgsAlignRaster::ResampleAlg resampleMethod() const;
bool rescaleValues() const;
void setItem( const QString &inputFilename, const QString &outputFilename, QgsAlignRaster::ResampleAlg resampleMethod, bool rescaleValues );
protected slots:
void browseOutputFilename();
protected:
QgsMapLayerComboBox *cboLayers = nullptr;
QLineEdit *editOutput = nullptr;
QPushButton *btnBrowse = nullptr;
QComboBox *cboResample = nullptr;
QCheckBox *chkRescale = nullptr;
QDialogButtonBox *btnBox = nullptr;
};
#endif // QGSALIGNRASTERDIALOG_H

View File

@ -17,7 +17,7 @@
<x>0</x>
<y>0</y>
<width>1277</width>
<height>22</height>
<height>20</height>
</rect>
</property>
<property name="toolTip">
@ -304,7 +304,6 @@
<string>&amp;Raster</string>
</property>
<addaction name="mActionShowRasterCalculator"/>
<addaction name="mActionShowAlignRasterTool"/>
</widget>
<widget class="QMenu" name="mVectorMenu">
<property name="title">
@ -2843,11 +2842,6 @@ Shift+click to snap rotation to 45 degree steps.</string>
<string>Show Statistical Summary</string>
</property>
</action>
<action name="mActionShowAlignRasterTool">
<property name="text">
<string>Align Rasters…</string>
</property>
</action>
<action name="mActionReportaBug">
<property name="text">
<string>Report an Issue</string>

View File

@ -1,282 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsAlignRasterDialog</class>
<widget class="QDialog" name="QgsAlignRasterDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>511</width>
<height>415</height>
</rect>
</property>
<property name="windowTitle">
<string>Align Rasters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Raster layers to align</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="mBtnAdd">
<property name="text">
<string>+</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mBtnEdit">
<property name="text">
<string>/</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mBtnRemove">
<property name="text">
<string>-</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="mViewLayers">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Output size</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Reference layer</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="mCboReferenceLayer"/>
</item>
<item row="1" column="2">
<widget class="QgsProjectionSelectionWidget" name="mCrsSelector" native="true"/>
</item>
<item row="2" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QgsDoubleSpinBox" name="mSpinCellSizeX">
<property name="decimals">
<number>6</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mSpinCellSizeY">
<property name="decimals">
<number>6</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QgsDoubleSpinBox" name="mSpinGridOffsetX">
<property name="decimals">
<number>6</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mSpinGridOffsetY">
<property name="decimals">
<number>6</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="1" colspan="2">
<widget class="QCheckBox" name="mChkAddToCanvas">
<property name="text">
<string>Add aligned rasters to map canvas</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1" 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="2">
<widget class="QLineEdit" name="mEditOutputSize">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="mChkCustomCRS">
<property name="text">
<string>CRS</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="mChkCustomCellSize">
<property name="text">
<string>Cell size</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="mChkCustomGridOffset">
<property name="text">
<string>Grid offset</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QProgressBar" name="mProgress">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>qgsdoublespinbox.h</header>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsExtentGroupBox</class>
<extends>QgsCollapsibleGroupBox</extends>
<header>qgsextentgroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsProjectionSelectionWidget</class>
<extends>QWidget</extends>
<header>qgsprojectionselectionwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mBtnAdd</tabstop>
<tabstop>mBtnEdit</tabstop>
<tabstop>mBtnRemove</tabstop>
<tabstop>mViewLayers</tabstop>
<tabstop>mCboReferenceLayer</tabstop>
<tabstop>mChkCustomCRS</tabstop>
<tabstop>mCrsSelector</tabstop>
<tabstop>mChkCustomCellSize</tabstop>
<tabstop>mSpinCellSizeX</tabstop>
<tabstop>mSpinCellSizeY</tabstop>
<tabstop>mChkCustomGridOffset</tabstop>
<tabstop>mSpinGridOffsetX</tabstop>
<tabstop>mSpinGridOffsetY</tabstop>
<tabstop>mClipExtentGroupBox</tabstop>
<tabstop>mEditOutputSize</tabstop>
<tabstop>mChkAddToCanvas</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsAlignRasterDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>285</x>
<y>394</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>206</y>
</hint>
</hints>
</connection>
</connections>
</ui>