28 #include <QPushButton> 30 #if PROJ_VERSION_MAJOR>=6 36 if ( sourceCrs == destinationCrs )
46 if ( dlg.shouldAskUserForSelection() )
66 dlg.applyDefaultTransform();
73 QPair<int, int> selectedDatumTransforms,
75 Qt::WindowFlags f,
const QString &selectedProj )
76 : QDialog( parent, f )
83 if ( !showMakeDefault )
84 mMakeDefaultCheckBox->setVisible(
false );
88 mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Cancel ) );
89 setWindowFlags( windowFlags() | Qt::CustomizeWindowHint );
90 setWindowFlags( windowFlags() & ~Qt::WindowCloseButtonHint );
93 mDatumTransformTableWidget->setColumnCount( 2 );
95 #if PROJ_VERSION_MAJOR>=6 96 headers << tr(
"Transformation" ) << tr(
"Accuracy (meters)" ) ;
98 headers << tr(
"Source Transform" ) << tr(
"Destination Transform" ) ;
100 mDatumTransformTableWidget->setHorizontalHeaderLabels( headers );
102 mSourceProjectionSelectionWidget->setCrs( sourceCrs );
103 mDestinationProjectionSelectionWidget->setCrs( destinationCrs );
104 if ( !allowCrsChanges )
106 mCrsStackedWidget->setCurrentIndex( 1 );
107 mSourceProjectionSelectionWidget->setEnabled(
false );
108 mDestinationProjectionSelectionWidget->setEnabled(
false );
113 #if PROJ_VERSION_MAJOR>=6 115 mHideDeprecatedCheckBox->setVisible(
false );
118 mHideDeprecatedCheckBox->setChecked( settings.
value( QStringLiteral(
"Windows/DatumTransformDialog/hideDeprecated" ),
true ).toBool() );
121 connect( mHideDeprecatedCheckBox, &QCheckBox::stateChanged,
this, [ = ] { load(); } );
122 connect( mDatumTransformTableWidget, &QTableWidget::currentItemChanged,
this, &QgsDatumTransformDialog::tableCurrentItemChanged );
128 mSourceCrs = sourceCrs;
129 mDestinationCrs = destinationCrs;
130 #if PROJ_VERSION_MAJOR>=6 137 mLabelSrcDescription->clear();
138 mLabelDstDescription->clear();
140 load( selectedDatumTransforms, selectedProj );
143 void QgsDatumTransformDialog::load( QPair<int, int> selectedDatumTransforms,
const QString &selectedProj )
145 mDatumTransformTableWidget->setRowCount( 0 );
148 int preferredInitialRow = -1;
149 #if PROJ_VERSION_MAJOR>=6 150 Q_UNUSED( selectedDatumTransforms )
153 bool itemDisabled = !transform.isAvailable;
155 std::unique_ptr< QTableWidgetItem > item = qgis::make_unique< QTableWidgetItem >();
156 item->setData( ProjRole, transform.proj );
157 item->setFlags( item->flags() & ~Qt::ItemIsEditable );
159 item->setText( transform.name );
163 QFont f = item->font();
166 item->setForeground( QBrush( QColor( 0, 120, 0 ) ) );
169 if ( preferredInitialRow < 0 && transform.isAvailable )
172 preferredInitialRow = row;
175 const QString toolTipString = QStringLiteral(
"<b>%1</b><p>%2</p>" ).arg( transform.name, transform.proj );
176 item->setToolTip( toolTipString );
179 item->setFlags( Qt::NoItemFlags );
181 mDatumTransformTableWidget->setRowCount( row + 1 );
182 mDatumTransformTableWidget->setItem( row, 0, item.release() );
184 item = qgis::make_unique< QTableWidgetItem >();
185 item->setFlags( item->flags() & ~Qt::ItemIsEditable );
186 item->setText( transform.accuracy >= 0 ? QString::number( transform.accuracy ) : tr(
"Unknown" ) );
189 item->setFlags( Qt::NoItemFlags );
191 mDatumTransformTableWidget->setItem( row, 1, item.release() );
193 if ( transform.proj == selectedProj )
195 mDatumTransformTableWidget->selectRow( row );
201 Q_UNUSED( selectedProj )
206 bool itemDisabled =
false;
207 bool itemHidden =
false;
209 if ( transform.sourceTransformId == -1 && transform.destinationTransformId == -1 )
214 for (
int i = 0; i < 2; ++i )
216 std::unique_ptr< QTableWidgetItem > item = qgis::make_unique< QTableWidgetItem >();
217 int nr = i == 0 ? transform.sourceTransformId : transform.destinationTransformId;
218 item->setData( TransformIdRole, nr );
219 item->setFlags( item->flags() & ~Qt::ItemIsEditable );
230 itemHidden = mHideDeprecatedCheckBox->isChecked();
231 item->setForeground( QBrush( QColor( 255, 0, 0 ) ) );
236 QFont f = item->font();
239 item->setForeground( QBrush( QColor( 0, 120, 0 ) ) );
245 preferredInitialRow = row;
248 QString toolTipString;
249 if ( gridShiftTransformation( item->text() ) )
251 toolTipString.append( QStringLiteral(
"<p><b>NTv2</b></p>" ) );
255 toolTipString.append( QStringLiteral(
"<p><b>EPSG Transformations Code:</b> %1</p>" ).arg( info.
epsgCode ) );
260 toolTipString.append( QStringLiteral(
"<p><b>Remarks:</b> %1</p>" ).arg( info.
remarks ) );
261 if ( !info.
scope.isEmpty() )
262 toolTipString.append( QStringLiteral(
"<p><b>Scope:</b> %1</p>" ).arg( info.
scope ) );
264 toolTipString.append(
"<p><b>Preferred transformation</b></p>" );
266 toolTipString.append(
"<p><b>Deprecated transformation</b></p>" );
268 item->setToolTip( toolTipString );
270 if ( gridShiftTransformation( item->text() ) && !testGridShiftFileAvailability( item.get() ) )
279 item->setFlags( Qt::NoItemFlags );
281 mDatumTransformTableWidget->setRowCount( row + 1 );
282 mDatumTransformTableWidget->setItem( row, i, item.release() );
286 if ( ( transform.sourceTransformId == selectedDatumTransforms.first &&
287 transform.destinationTransformId == selectedDatumTransforms.second ) ||
288 ( transform.sourceTransformId == selectedDatumTransforms.second &&
289 transform.destinationTransformId == selectedDatumTransforms.first ) )
291 mDatumTransformTableWidget->selectRow( row );
299 if ( mDatumTransformTableWidget->currentRow() < 0 )
300 mDatumTransformTableWidget->selectRow( preferredInitialRow >= 0 ? preferredInitialRow : 0 );
302 mDatumTransformTableWidget->resizeColumnsToContents();
304 tableCurrentItemChanged(
nullptr,
nullptr );
307 void QgsDatumTransformDialog::setOKButtonEnabled()
309 int row = mDatumTransformTableWidget->currentRow();
310 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( mSourceCrs.
isValid() && mDestinationCrs.
isValid() && row >= 0 );
316 settings.
setValue( QStringLiteral(
"Windows/DatumTransformDialog/hideDeprecated" ), mHideDeprecatedCheckBox->isChecked() );
318 for (
int i = 0; i < 2; i++ )
320 settings.
setValue( QStringLiteral(
"Windows/DatumTransformDialog/columnWidths/%1" ).arg( i ), mDatumTransformTableWidget->columnWidth( i ) );
326 if ( mMakeDefaultCheckBox->isChecked() && !mDatumTransformTableWidget->selectedItems().isEmpty() )
329 settings.
beginGroup( QStringLiteral(
"/Projections" ) );
336 QString sourceDatumProj;
338 if ( sourceDatumTransform >= 0 )
341 QString destinationDatumProj;
342 if ( destinationDatumTransform >= 0 )
345 settings.
setValue( srcAuthId + QStringLiteral(
"//" ) + destAuthId + QStringLiteral(
"_srcTransform" ), sourceDatumProj );
346 settings.
setValue( srcAuthId + QStringLiteral(
"//" ) + destAuthId + QStringLiteral(
"_destTransform" ), destinationDatumProj );
347 settings.
setValue( srcAuthId + QStringLiteral(
"//" ) + destAuthId + QStringLiteral(
"_coordinateOp" ), dt.
proj );
354 if ( !mButtonBox->button( QDialogButtonBox::Cancel ) )
360 bool QgsDatumTransformDialog::shouldAskUserForSelection()
const 362 if ( mDatumTransforms.count() > 1 )
376 #if PROJ_VERSION_MAJOR>=6 380 if ( transform.isAvailable )
382 preferred.
proj = transform.proj;
389 preferredNonDeprecated.
sourceCrs = mSourceCrs;
391 bool foundPreferredNonDeprecated =
false;
392 bool foundPreferred =
false;
396 bool foundNonDeprecated =
false;
400 bool foundFallback =
false;
405 if ( transform.sourceTransformId == -1 && transform.destinationTransformId == -1 )
410 if ( !foundPreferredNonDeprecated && ( ( srcInfo.
preferred && !srcInfo.
deprecated ) || transform.sourceTransformId == -1 )
411 && ( ( destInfo.
preferred && !destInfo.
deprecated ) || transform.destinationTransformId == -1 ) )
415 foundPreferredNonDeprecated =
true;
417 else if ( !foundPreferred && ( srcInfo.
preferred || transform.sourceTransformId == -1 ) &&
418 ( destInfo.
preferred || transform.destinationTransformId == -1 ) )
422 foundPreferred =
true;
424 else if ( !foundNonDeprecated && ( !srcInfo.
deprecated || transform.sourceTransformId == -1 )
425 && ( !destInfo.
deprecated || transform.destinationTransformId == -1 ) )
429 foundNonDeprecated =
true;
431 else if ( !foundFallback )
435 foundFallback =
true;
439 if ( foundPreferredNonDeprecated )
440 return preferredNonDeprecated;
441 else if ( foundPreferred )
443 else if ( foundNonDeprecated )
444 return nonDeprecated;
450 void QgsDatumTransformDialog::applyDefaultTransform()
452 if ( mDatumTransforms.count() > 0 )
460 #if PROJ_VERSION_MAJOR>=6 472 int row = mDatumTransformTableWidget->currentRow();
479 QTableWidgetItem *srcItem = mDatumTransformTableWidget->item( row, 0 );
481 QTableWidgetItem *destItem = mDatumTransformTableWidget->item( row, 1 );
483 sdt.
proj = srcItem ? srcItem->data( ProjRole ).toString() : QString();
489 sdt.
proj = QString();
494 bool QgsDatumTransformDialog::gridShiftTransformation(
const QString &itemText )
const 496 return !itemText.isEmpty() && !itemText.contains( QLatin1String(
"towgs84" ), Qt::CaseInsensitive );
499 bool QgsDatumTransformDialog::testGridShiftFileAvailability( QTableWidgetItem *item )
const 506 QString itemText = item->text();
507 if ( itemText.isEmpty() )
512 char *projLib = getenv(
"PROJ_LIB" );
518 QStringList itemEqualSplit = itemText.split(
'=' );
520 for (
int i = 1; i < itemEqualSplit.size(); ++i )
524 filename.append(
'=' );
526 filename.append( itemEqualSplit.at( i ) );
529 QDir projDir( projLib );
530 if ( projDir.exists() )
533 QStringList fileList = projDir.entryList();
534 QStringList::const_iterator fileIt = fileList.constBegin();
535 for ( ; fileIt != fileList.constEnd(); ++fileIt )
537 #if defined(Q_OS_WIN) 538 if ( fileIt->compare( filename, Qt::CaseInsensitive ) == 0 )
540 if ( fileIt->compare( filename ) == 0 )
546 item->setToolTip( tr(
"File '%1' not found in directory '%2'" ).arg( filename, projDir.absolutePath() ) );
552 void QgsDatumTransformDialog::tableCurrentItemChanged( QTableWidgetItem *, QTableWidgetItem * )
554 int row = mDatumTransformTableWidget->currentRow();
557 mLabelSrcDescription->clear();
558 mLabelDstDescription->clear();
563 QTableWidgetItem *srcItem = mDatumTransformTableWidget->item( row, 0 );
564 mLabelSrcDescription->setText( srcItem ? srcItem->toolTip() : QString() );
565 QTableWidgetItem *destItem = mDatumTransformTableWidget->item( row, 1 );
566 mLabelDstDescription->setText( destItem ? destItem->toolTip() : QString() );
569 setOKButtonEnabled();
574 mSourceCrs = sourceCrs;
575 #if PROJ_VERSION_MAJOR>=6 583 setOKButtonEnabled();
588 mDestinationCrs = destinationCrs;
589 #if PROJ_VERSION_MAJOR>=6 597 setOKButtonEnabled();
void removeCoordinateOperation(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs)
Removes the coordinate operation for the specified sourceCrs and destinationCrs.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define Q_NOWARN_DEPRECATED_PUSH
bool addCoordinateOperation(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QString &coordinateOperationProjString)
Adds a new coordinateOperationProjString to use when projecting coordinates from the specified source...
Contains information about the context in which a coordinate transform is executed.
Q_DECL_DEPRECATED bool addSourceDestinationDatumTransform(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, int sourceTransformId, int destinationTransformId)
Adds a new sourceTransform and destinationTransform to use when projecting coordinates from the speci...
QgsCoordinateTransformContext transformContext
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
#define Q_NOWARN_DEPRECATED_POP
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QgsProject * instance()
Returns the QgsProject singleton instance.
This class represents a coordinate reference system (CRS).
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project's coordinate transform context, which stores various information regarding which dat...
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Temporarily removes all cursor overrides for the QApplication for the lifetime of the object...
bool hasTransform(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns true if the context has a valid coordinate operation to use when transforming from the specif...
QString authid() const
Returns the authority identifier for the CRS.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.