QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgsdatumtransformdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatumtransformdialog.cpp
3  ---------------------------
4  begin : November 2013
5  copyright : (C) 2013 by Marco Hugentobler
6  email : marco.hugentobler at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgscoordinatetransform.h"
21 #include "qgslogger.h"
22 #include "qgssettings.h"
23 #include "qgsproject.h"
24 #include "qgsguiutils.h"
25 #include "qgsgui.h"
26 
27 #include <QDir>
28 #include <QPushButton>
29 
30 #if PROJ_VERSION_MAJOR>=6
31 #include "qgsprojutils.h"
32 #endif
33 
34 bool QgsDatumTransformDialog::run( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, QWidget *parent )
35 {
36  if ( sourceCrs == destinationCrs )
37  return true;
38 
40  if ( context.hasTransform( sourceCrs, destinationCrs ) )
41  {
42  return true;
43  }
44 
45  QgsDatumTransformDialog dlg( sourceCrs, destinationCrs, false, true, true, qMakePair( -1, -1 ), parent );
46  if ( dlg.shouldAskUserForSelection() )
47  {
48  if ( dlg.exec() )
49  {
50  const TransformInfo dt = dlg.selectedDatumTransform();
57  return true;
58  }
59  else
60  {
61  return false;
62  }
63  }
64  else
65  {
66  dlg.applyDefaultTransform();
67  return true;
68  }
69 }
70 
72  const QgsCoordinateReferenceSystem &destinationCrs, const bool allowCrsChanges, const bool showMakeDefault, const bool forceChoice,
73  QPair<int, int> selectedDatumTransforms,
74  QWidget *parent,
75  Qt::WindowFlags f, const QString &selectedProj )
76  : QDialog( parent, f )
77  , mPreviousCursorOverride( qgis::make_unique< QgsTemporaryCursorRestoreOverride >() ) // this dialog is often shown while cursor overrides are in place, so temporarily remove them
78 {
79  setupUi( this );
80 
82 
83  if ( !showMakeDefault )
84  mMakeDefaultCheckBox->setVisible( false );
85 
86  if ( forceChoice )
87  {
88  mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Cancel ) );
89  setWindowFlags( windowFlags() | Qt::CustomizeWindowHint );
90  setWindowFlags( windowFlags() & ~Qt::WindowCloseButtonHint );
91  }
92 
93  mDatumTransformTableWidget->setColumnCount( 2 );
94  QStringList headers;
95 #if PROJ_VERSION_MAJOR>=6
96  headers << tr( "Transformation" ) << tr( "Accuracy (meters)" ) ;
97 #else
98  headers << tr( "Source Transform" ) << tr( "Destination Transform" ) ;
99 #endif
100  mDatumTransformTableWidget->setHorizontalHeaderLabels( headers );
101 
102  mSourceProjectionSelectionWidget->setCrs( sourceCrs );
103  mDestinationProjectionSelectionWidget->setCrs( destinationCrs );
104  if ( !allowCrsChanges )
105  {
106  mCrsStackedWidget->setCurrentIndex( 1 );
107  mSourceProjectionSelectionWidget->setEnabled( false );
108  mDestinationProjectionSelectionWidget->setEnabled( false );
109  mSourceCrsLabel->setText( QgsProjectionSelectionWidget::crsOptionText( sourceCrs ) );
110  mDestCrsLabel->setText( QgsProjectionSelectionWidget::crsOptionText( destinationCrs ) );
111  }
112 
113 #if PROJ_VERSION_MAJOR>=6
114  // proj 6 doesn't provide deprecated operations
115  mHideDeprecatedCheckBox->setVisible( false );
116 #else
117  QgsSettings settings;
118  mHideDeprecatedCheckBox->setChecked( settings.value( QStringLiteral( "Windows/DatumTransformDialog/hideDeprecated" ), true ).toBool() );
119 #endif
120 
121  connect( mHideDeprecatedCheckBox, &QCheckBox::stateChanged, this, [ = ] { load(); } );
122  connect( mDatumTransformTableWidget, &QTableWidget::currentItemChanged, this, &QgsDatumTransformDialog::tableCurrentItemChanged );
123 
124  connect( mSourceProjectionSelectionWidget, &QgsProjectionSelectionWidget::crsChanged, this, &QgsDatumTransformDialog::setSourceCrs );
125  connect( mDestinationProjectionSelectionWidget, &QgsProjectionSelectionWidget::crsChanged, this, &QgsDatumTransformDialog::setDestinationCrs );
126 
127  //get list of datum transforms
128  mSourceCrs = sourceCrs;
129  mDestinationCrs = destinationCrs;
130 #if PROJ_VERSION_MAJOR>=6
131  mDatumTransforms = QgsDatumTransform::operations( sourceCrs, destinationCrs );
132 #else
134  mDatumTransforms = QgsDatumTransform::datumTransformations( sourceCrs, destinationCrs );
136 #endif
137  mLabelSrcDescription->clear();
138  mLabelDstDescription->clear();
139 
140  load( selectedDatumTransforms, selectedProj );
141 }
142 
143 void QgsDatumTransformDialog::load( QPair<int, int> selectedDatumTransforms, const QString &selectedProj )
144 {
145  mDatumTransformTableWidget->setRowCount( 0 );
146 
147  int row = 0;
148  int preferredInitialRow = -1;
149 #if PROJ_VERSION_MAJOR>=6
150  Q_UNUSED( selectedDatumTransforms )
151  for ( const QgsDatumTransform::TransformDetails &transform : qgis::as_const( mDatumTransforms ) )
152  {
153  bool itemDisabled = !transform.isAvailable;
154 
155  std::unique_ptr< QTableWidgetItem > item = qgis::make_unique< QTableWidgetItem >();
156  item->setData( ProjRole, transform.proj );
157  item->setFlags( item->flags() & ~Qt::ItemIsEditable );
158 
159  item->setText( transform.name );
160 
161  if ( row == 0 ) // highlight first (preferred) operation
162  {
163  QFont f = item->font();
164  f.setBold( true );
165  item->setFont( f );
166  item->setForeground( QBrush( QColor( 0, 120, 0 ) ) );
167  }
168 
169  if ( preferredInitialRow < 0 && transform.isAvailable )
170  {
171  // try to select a "preferred" entry by default
172  preferredInitialRow = row;
173  }
174 
175  const QString toolTipString = QStringLiteral( "<b>%1</b><p>%2</p>" ).arg( transform.name, transform.proj );
176  item->setToolTip( toolTipString );
177  if ( itemDisabled )
178  {
179  item->setFlags( Qt::NoItemFlags );
180  }
181  mDatumTransformTableWidget->setRowCount( row + 1 );
182  mDatumTransformTableWidget->setItem( row, 0, item.release() );
183 
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" ) );
187  if ( itemDisabled )
188  {
189  item->setFlags( Qt::NoItemFlags );
190  }
191  mDatumTransformTableWidget->setItem( row, 1, item.release() );
192 
193  if ( transform.proj == selectedProj )
194  {
195  mDatumTransformTableWidget->selectRow( row );
196  }
197 
198  row++;
199  }
200 #else
201  Q_UNUSED( selectedProj )
202 
204  for ( const QgsDatumTransform::TransformPair &transform : qgis::as_const( mDatumTransforms ) )
205  {
206  bool itemDisabled = false;
207  bool itemHidden = false;
208 
209  if ( transform.sourceTransformId == -1 && transform.destinationTransformId == -1 )
210  continue;
211 
212  QgsDatumTransform::TransformInfo srcInfo = QgsDatumTransform::datumTransformInfo( transform.sourceTransformId );
213  QgsDatumTransform::TransformInfo destInfo = QgsDatumTransform::datumTransformInfo( transform.destinationTransformId );
214  for ( int i = 0; i < 2; ++i )
215  {
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 );
220 
221  item->setText( QgsDatumTransform::datumTransformToProj( nr ) );
222 
223  //Describe datums in a tooltip
224  QgsDatumTransform::TransformInfo info = i == 0 ? srcInfo : destInfo;
225  if ( info.datumTransformId == -1 )
226  continue;
227 
228  if ( info.deprecated )
229  {
230  itemHidden = mHideDeprecatedCheckBox->isChecked();
231  item->setForeground( QBrush( QColor( 255, 0, 0 ) ) );
232  }
233 
234  if ( ( srcInfo.preferred && !srcInfo.deprecated ) || ( destInfo.preferred && !destInfo.deprecated ) )
235  {
236  QFont f = item->font();
237  f.setBold( true );
238  item->setFont( f );
239  item->setForeground( QBrush( QColor( 0, 120, 0 ) ) );
240  }
241 
242  if ( info.preferred && !info.deprecated && preferredInitialRow < 0 )
243  {
244  // try to select a "preferred" entry by default
245  preferredInitialRow = row;
246  }
247 
248  QString toolTipString;
249  if ( gridShiftTransformation( item->text() ) )
250  {
251  toolTipString.append( QStringLiteral( "<p><b>NTv2</b></p>" ) );
252  }
253 
254  if ( info.epsgCode > 0 )
255  toolTipString.append( QStringLiteral( "<p><b>EPSG Transformations Code:</b> %1</p>" ).arg( info.epsgCode ) );
256 
257  toolTipString.append( QStringLiteral( "<p><b>Source CRS:</b> %1</p><p><b>Destination CRS:</b> %2</p>" ).arg( info.sourceCrsDescription, info.destinationCrsDescription ) );
258 
259  if ( !info.remarks.isEmpty() )
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 ) );
263  if ( info.preferred )
264  toolTipString.append( "<p><b>Preferred transformation</b></p>" );
265  if ( info.deprecated )
266  toolTipString.append( "<p><b>Deprecated transformation</b></p>" );
267 
268  item->setToolTip( toolTipString );
269 
270  if ( gridShiftTransformation( item->text() ) && !testGridShiftFileAvailability( item.get() ) )
271  {
272  itemDisabled = true;
273  }
274 
275  if ( !itemHidden )
276  {
277  if ( itemDisabled )
278  {
279  item->setFlags( Qt::NoItemFlags );
280  }
281  mDatumTransformTableWidget->setRowCount( row + 1 );
282  mDatumTransformTableWidget->setItem( row, i, item.release() );
283  }
284  }
285 
286  if ( ( transform.sourceTransformId == selectedDatumTransforms.first &&
287  transform.destinationTransformId == selectedDatumTransforms.second ) ||
288  ( transform.sourceTransformId == selectedDatumTransforms.second &&
289  transform.destinationTransformId == selectedDatumTransforms.first ) )
290  {
291  mDatumTransformTableWidget->selectRow( row );
292  }
293 
294  row++;
295  }
297 #endif
298 
299  if ( mDatumTransformTableWidget->currentRow() < 0 )
300  mDatumTransformTableWidget->selectRow( preferredInitialRow >= 0 ? preferredInitialRow : 0 );
301 
302  mDatumTransformTableWidget->resizeColumnsToContents();
303 
304  tableCurrentItemChanged( nullptr, nullptr );
305 }
306 
307 void QgsDatumTransformDialog::setOKButtonEnabled()
308 {
309  int row = mDatumTransformTableWidget->currentRow();
310  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( mSourceCrs.isValid() && mDestinationCrs.isValid() && row >= 0 );
311 }
312 
314 {
315  QgsSettings settings;
316  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/hideDeprecated" ), mHideDeprecatedCheckBox->isChecked() );
317 
318  for ( int i = 0; i < 2; i++ )
319  {
320  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/columnWidths/%1" ).arg( i ), mDatumTransformTableWidget->columnWidth( i ) );
321  }
322 }
323 
325 {
326  if ( mMakeDefaultCheckBox->isChecked() && !mDatumTransformTableWidget->selectedItems().isEmpty() )
327  {
328  QgsSettings settings;
329  settings.beginGroup( QStringLiteral( "/Projections" ) );
330 
332 
333  QString srcAuthId = dt.sourceCrs.authid();
334  QString destAuthId = dt.destinationCrs.authid();
335  int sourceDatumTransform = dt.sourceTransformId;
336  QString sourceDatumProj;
338  if ( sourceDatumTransform >= 0 )
339  sourceDatumProj = QgsDatumTransform::datumTransformToProj( sourceDatumTransform );
340  int destinationDatumTransform = dt.destinationTransformId;
341  QString destinationDatumProj;
342  if ( destinationDatumTransform >= 0 )
343  destinationDatumProj = QgsDatumTransform::datumTransformToProj( destinationDatumTransform );
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 );
348  }
349  QDialog::accept();
350 }
351 
353 {
354  if ( !mButtonBox->button( QDialogButtonBox::Cancel ) )
355  return; // users HAVE to make a choice, no click on the dialog "x" to avoid this!
356 
357  QDialog::reject();
358 }
359 
360 bool QgsDatumTransformDialog::shouldAskUserForSelection() const
361 {
362  if ( mDatumTransforms.count() > 1 )
363  {
364  return QgsSettings().value( QStringLiteral( "/projections/promptWhenMultipleTransformsExist" ), false, QgsSettings::App ).toBool();
365  }
366  // TODO: show if transform grids are required, but missing
367  return false;
368 }
369 
370 QgsDatumTransformDialog::TransformInfo QgsDatumTransformDialog::defaultDatumTransform() const
371 {
372  TransformInfo preferred;
373  preferred.sourceCrs = mSourceCrs;
374  preferred.destinationCrs = mDestinationCrs;
375 
376 #if PROJ_VERSION_MAJOR>=6
377  // for proj 6, return the first available transform -- they are sorted by preference by proj already
378  for ( const QgsDatumTransform::TransformDetails &transform : qgis::as_const( mDatumTransforms ) )
379  {
380  if ( transform.isAvailable )
381  {
382  preferred.proj = transform.proj;
383  break;
384  }
385  }
386  return preferred;
387 #else
388  TransformInfo preferredNonDeprecated;
389  preferredNonDeprecated.sourceCrs = mSourceCrs;
390  preferredNonDeprecated.destinationCrs = mDestinationCrs;
391  bool foundPreferredNonDeprecated = false;
392  bool foundPreferred = false;
393  TransformInfo nonDeprecated;
394  nonDeprecated.sourceCrs = mSourceCrs;
395  nonDeprecated.destinationCrs = mDestinationCrs;
396  bool foundNonDeprecated = false;
397  TransformInfo fallback;
398  fallback.sourceCrs = mSourceCrs;
399  fallback.destinationCrs = mDestinationCrs;
400  bool foundFallback = false;
401 
403  for ( const QgsDatumTransform::TransformPair &transform : qgis::as_const( mDatumTransforms ) )
404  {
405  if ( transform.sourceTransformId == -1 && transform.destinationTransformId == -1 )
406  continue;
407 
408  const QgsDatumTransform::TransformInfo srcInfo = QgsDatumTransform::datumTransformInfo( transform.sourceTransformId );
409  const QgsDatumTransform::TransformInfo destInfo = QgsDatumTransform::datumTransformInfo( transform.destinationTransformId );
410  if ( !foundPreferredNonDeprecated && ( ( srcInfo.preferred && !srcInfo.deprecated ) || transform.sourceTransformId == -1 )
411  && ( ( destInfo.preferred && !destInfo.deprecated ) || transform.destinationTransformId == -1 ) )
412  {
413  preferredNonDeprecated.sourceTransformId = transform.sourceTransformId;
414  preferredNonDeprecated.destinationTransformId = transform.destinationTransformId;
415  foundPreferredNonDeprecated = true;
416  }
417  else if ( !foundPreferred && ( srcInfo.preferred || transform.sourceTransformId == -1 ) &&
418  ( destInfo.preferred || transform.destinationTransformId == -1 ) )
419  {
420  preferred.sourceTransformId = transform.sourceTransformId;
421  preferred.destinationTransformId = transform.destinationTransformId;
422  foundPreferred = true;
423  }
424  else if ( !foundNonDeprecated && ( !srcInfo.deprecated || transform.sourceTransformId == -1 )
425  && ( !destInfo.deprecated || transform.destinationTransformId == -1 ) )
426  {
427  nonDeprecated.sourceTransformId = transform.sourceTransformId;
428  nonDeprecated.destinationTransformId = transform.destinationTransformId;
429  foundNonDeprecated = true;
430  }
431  else if ( !foundFallback )
432  {
433  fallback.sourceTransformId = transform.sourceTransformId;
434  fallback.destinationTransformId = transform.destinationTransformId;
435  foundFallback = true;
436  }
437  }
439  if ( foundPreferredNonDeprecated )
440  return preferredNonDeprecated;
441  else if ( foundPreferred )
442  return preferred;
443  else if ( foundNonDeprecated )
444  return nonDeprecated;
445  else
446  return fallback;
447 #endif
448 }
449 
450 void QgsDatumTransformDialog::applyDefaultTransform()
451 {
452  if ( mDatumTransforms.count() > 0 )
453  {
455  const TransformInfo dt = defaultDatumTransform();
459 
460 #if PROJ_VERSION_MAJOR>=6
461  // on proj 6 builds, removing a coordinate operation falls back to default
463 #else
464  context.addCoordinateOperation( dt.sourceCrs, dt.destinationCrs, dt.proj );
465 #endif
467  }
468 }
469 
471 {
472  int row = mDatumTransformTableWidget->currentRow();
473  TransformInfo sdt;
474  sdt.sourceCrs = mSourceCrs;
475  sdt.destinationCrs = mDestinationCrs;
476 
477  if ( row >= 0 )
478  {
479  QTableWidgetItem *srcItem = mDatumTransformTableWidget->item( row, 0 );
480  sdt.sourceTransformId = srcItem ? srcItem->data( TransformIdRole ).toInt() : -1;
481  QTableWidgetItem *destItem = mDatumTransformTableWidget->item( row, 1 );
482  sdt.destinationTransformId = destItem ? destItem->data( TransformIdRole ).toInt() : -1;
483  sdt.proj = srcItem ? srcItem->data( ProjRole ).toString() : QString();
484  }
485  else
486  {
487  sdt.sourceTransformId = -1;
488  sdt.destinationTransformId = -1;
489  sdt.proj = QString();
490  }
491  return sdt;
492 }
493 
494 bool QgsDatumTransformDialog::gridShiftTransformation( const QString &itemText ) const
495 {
496  return !itemText.isEmpty() && !itemText.contains( QLatin1String( "towgs84" ), Qt::CaseInsensitive );
497 }
498 
499 bool QgsDatumTransformDialog::testGridShiftFileAvailability( QTableWidgetItem *item ) const
500 {
501  if ( !item )
502  {
503  return true;
504  }
505 
506  QString itemText = item->text();
507  if ( itemText.isEmpty() )
508  {
509  return true;
510  }
511 
512  char *projLib = getenv( "PROJ_LIB" );
513  if ( !projLib ) //no information about installation directory
514  {
515  return true;
516  }
517 
518  QStringList itemEqualSplit = itemText.split( '=' );
519  QString filename;
520  for ( int i = 1; i < itemEqualSplit.size(); ++i )
521  {
522  if ( i > 1 )
523  {
524  filename.append( '=' );
525  }
526  filename.append( itemEqualSplit.at( i ) );
527  }
528 
529  QDir projDir( projLib );
530  if ( projDir.exists() )
531  {
532  //look if filename in directory
533  QStringList fileList = projDir.entryList();
534  QStringList::const_iterator fileIt = fileList.constBegin();
535  for ( ; fileIt != fileList.constEnd(); ++fileIt )
536  {
537 #if defined(Q_OS_WIN)
538  if ( fileIt->compare( filename, Qt::CaseInsensitive ) == 0 )
539 #else
540  if ( fileIt->compare( filename ) == 0 )
541 #endif //Q_OS_WIN
542  {
543  return true;
544  }
545  }
546  item->setToolTip( tr( "File '%1' not found in directory '%2'" ).arg( filename, projDir.absolutePath() ) );
547  return false; //not found in PROJ_LIB directory
548  }
549  return true;
550 }
551 
552 void QgsDatumTransformDialog::tableCurrentItemChanged( QTableWidgetItem *, QTableWidgetItem * )
553 {
554  int row = mDatumTransformTableWidget->currentRow();
555  if ( row < 0 )
556  {
557  mLabelSrcDescription->clear();
558  mLabelDstDescription->clear();
559  }
560  else
561  {
562 
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() );
567  }
568 
569  setOKButtonEnabled();
570 }
571 
572 void QgsDatumTransformDialog::setSourceCrs( const QgsCoordinateReferenceSystem &sourceCrs )
573 {
574  mSourceCrs = sourceCrs;
575 #if PROJ_VERSION_MAJOR>=6
576  mDatumTransforms = QgsDatumTransform::operations( mSourceCrs, mDestinationCrs );
577 #else
579  mDatumTransforms = QgsDatumTransform::datumTransformations( mSourceCrs, mDestinationCrs );
581 #endif
582  load();
583  setOKButtonEnabled();
584 }
585 
586 void QgsDatumTransformDialog::setDestinationCrs( const QgsCoordinateReferenceSystem &destinationCrs )
587 {
588  mDestinationCrs = destinationCrs;
589 #if PROJ_VERSION_MAJOR>=6
590  mDatumTransforms = QgsDatumTransform::operations( mSourceCrs, mDestinationCrs );
591 #else
593  mDatumTransforms = QgsDatumTransform::datumTransformations( mSourceCrs, mDestinationCrs );
595 #endif
596  load();
597  setOKButtonEnabled();
598 }
Dialog transformation entry info.
void removeCoordinateOperation(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs)
Removes the coordinate operation for the specified sourceCrs and destinationCrs.
QString destinationCrsDescription
Destination CRS description.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QgsCoordinateReferenceSystem destinationCrs
Destination coordinate reference system.
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:624
TransformInfo selectedDatumTransform()
Returns the source and destination transforms, each being a pair of QgsCoordinateReferenceSystems and...
QString proj
Proj coordinate operation description, for Proj >= 6.0 builds only.
static QList< QgsDatumTransform::TransformDetails > operations(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination)
Returns a list of coordinate operations available for transforming coordinates from the source to des...
int datumTransformId
Datum transform ID.
bool addCoordinateOperation(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QString &coordinateOperationProjString)
Adds a new coordinateOperationProjString to use when projecting coordinates from the specified source...
bool deprecated
True if transform is deprecated.
int destinationTransformId
Destination transform ID.
static bool run(const QgsCoordinateReferenceSystem &sourceCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), QWidget *parent=nullptr)
Runs the dialog (if required) prompting for the desired transform to use from sourceCrs to destinatio...
QgsCoordinateReferenceSystem sourceCrs
Source coordinate reference system.
static QString crsOptionText(const QgsCoordinateReferenceSystem &crs)
Returns display text for the specified crs.
static Q_DECL_DEPRECATED QList< QgsDatumTransform::TransformPair > datumTransformations(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination)
Returns a list of datum transformations which are available for the given source and destination CRS...
QgsDatumTransformDialog(const QgsCoordinateReferenceSystem &sourceCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), bool allowCrsChanges=false, bool showMakeDefault=true, bool forceChoice=true, QPair< int, int > selectedDatumTransforms=qMakePair(-1, -1), QWidget *parent=nullptr, Qt::WindowFlags f=nullptr, const QString &selectedProj=QString())
Constructor for QgsDatumTransformDialog.
QString sourceCrsDescription
Source CRS description.
Contains datum transform information.
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...
bool preferred
True if transform is the preferred transform to use for the source/destination CRS combination...
int epsgCode
EPSG code for the transform, or 0 if not found in EPSG database.
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:96
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
Definition: qgssettings.cpp:87
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:625
Contains datum transform information.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:438
This class represents a coordinate reference system (CRS).
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project&#39;s coordinate transform context, which stores various information regarding which dat...
Definition: qgsproject.cpp:679
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...
Definition: qgsgui.cpp:104
static Q_DECL_DEPRECATED QString datumTransformToProj(int datumTransformId)
Returns a proj string representing the specified datumTransformId datum transform ID...
QString remarks
Transform remarks.
Contains information about a coordinate transformation operation.
static Q_DECL_DEPRECATED QgsDatumTransform::TransformInfo datumTransformInfo(int datumTransformId)
Returns detailed information about the specified datumTransformId.
Temporarily removes all cursor overrides for the QApplication for the lifetime of the object...
Definition: qgsguiutils.h:235
QString scope
Scope of transform.
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.