QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgscoordinateoperationwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscoordinateoperationwidget.cpp
3  ---------------------------
4  begin : December 2019
5  copyright : (C) 2019 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
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 #include "qgshelp.h"
28 
29 #include <QDir>
30 #include <QPushButton>
31 #include <QRegularExpression>
32 
33 #include "qgsprojutils.h"
34 #include <proj.h>
35 
37  : QWidget( parent )
38 {
39  setupUi( this );
40 
41  mLabelSrcDescription->setTextInteractionFlags( Qt::TextBrowserInteraction );
42  mLabelSrcDescription->setOpenExternalLinks( true );
43  mInstallGridButton->hide();
44 
45  connect( mInstallGridButton, &QPushButton::clicked, this, &QgsCoordinateOperationWidget::installGrid );
46  connect( mAllowFallbackCheckBox, &QCheckBox::toggled, this, [ = ]
47  {
48  if ( !mBlockSignals )
49  emit operationChanged();
50  } );
51  mCoordinateOperationTableWidget->setColumnCount( 3 );
52 
53  QStringList headers;
54  headers << tr( "Transformation" ) << tr( "Accuracy (meters)" ) << tr( "Area of Use" );
55  mCoordinateOperationTableWidget->setHorizontalHeaderLabels( headers );
56 
57  mHideDeprecatedCheckBox->setVisible( false );
58  mShowSupersededCheckBox->setVisible( true );
59  mLabelDstDescription->hide();
60 
61  connect( mHideDeprecatedCheckBox, &QCheckBox::stateChanged, this, [ = ] { loadAvailableOperations(); } );
62  connect( mShowSupersededCheckBox, &QCheckBox::toggled, this, &QgsCoordinateOperationWidget::showSupersededToggled );
63  connect( mCoordinateOperationTableWidget, &QTableWidget::currentItemChanged, this, &QgsCoordinateOperationWidget::tableCurrentItemChanged );
64  connect( mCoordinateOperationTableWidget, &QTableWidget::itemDoubleClicked, this, &QgsCoordinateOperationWidget::operationDoubleClicked );
65 
66  mLabelSrcDescription->clear();
67  mLabelDstDescription->clear();
68 }
69 
71 {
72  if ( canvas )
73  {
74  // show canvas extent in preview widget
75  QPolygonF mainCanvasPoly = canvas->mapSettings().visiblePolygon();
76  QgsGeometry g = QgsGeometry::fromQPolygonF( mainCanvasPoly );
77  // close polygon
78  mainCanvasPoly << mainCanvasPoly.at( 0 );
79  if ( QgsProject::instance()->crs() !=
81  {
82  // reproject extent
86  g = g.densifyByCount( 5 );
87  try
88  {
89  g.transform( ct );
90  }
91  catch ( QgsCsException & )
92  {
93  }
94  }
95  mAreaCanvas->setCanvasRect( g.boundingBox() );
96  }
97 }
98 
100 {
101  mMakeDefaultCheckBox->setVisible( show );
102 }
103 
105 {
106  return mMakeDefaultCheckBox->isChecked();
107 }
108 
110 {
111  return !mCoordinateOperationTableWidget->selectedItems().isEmpty();
112 }
113 
114 QList<QgsCoordinateOperationWidget::OperationDetails> QgsCoordinateOperationWidget::availableOperations() const
115 {
116  QList<QgsCoordinateOperationWidget::OperationDetails> res;
117  res.reserve( mDatumTransforms.size() );
118  for ( const QgsDatumTransform::TransformDetails &details : mDatumTransforms )
119  {
120  OperationDetails op;
121  op.proj = details.proj;
122  op.sourceTransformId = -1;
123  op.destinationTransformId = -1;
124  op.isAvailable = details.isAvailable;
125  res << op;
126  }
127  return res;
128 }
129 
130 void QgsCoordinateOperationWidget::loadAvailableOperations()
131 {
132  mCoordinateOperationTableWidget->setRowCount( 0 );
133 
134  int row = 0;
135  int preferredInitialRow = -1;
136 
137  for ( const QgsDatumTransform::TransformDetails &transform : std::as_const( mDatumTransforms ) )
138  {
139  std::unique_ptr< QTableWidgetItem > item = std::make_unique< QTableWidgetItem >();
140  item->setData( ProjRole, transform.proj );
141  item->setData( AvailableRole, transform.isAvailable );
142  item->setFlags( item->flags() & ~Qt::ItemIsEditable );
143 
144  QString name = transform.name;
145  if ( !transform.authority.isEmpty() && !transform.code.isEmpty() )
146  name += QStringLiteral( " %1 %2:%3" ).arg( QString( QChar( 0x2013 ) ), transform.authority, transform.code );
147  item->setText( name );
148 
149  if ( row == 0 ) // highlight first (preferred) operation
150  {
151  QFont f = item->font();
152  f.setBold( true );
153  item->setFont( f );
154  item->setForeground( QBrush( QColor( 0, 120, 0 ) ) );
155  }
156 
157  if ( !transform.isAvailable )
158  {
159  item->setForeground( QBrush( palette().color( QPalette::Disabled, QPalette::Text ) ) );
160  }
161 
162  if ( preferredInitialRow < 0 && transform.isAvailable )
163  {
164  // try to select a "preferred" entry by default
165  preferredInitialRow = row;
166  }
167 
168  QString missingMessage;
169  if ( !transform.isAvailable )
170  {
171  QStringList gridMessages;
172  QStringList missingGrids;
173  QStringList missingGridPackages;
174  QStringList missingGridUrls;
175 
176  for ( const QgsDatumTransform::GridDetails &grid : transform.grids )
177  {
178  if ( !grid.isAvailable )
179  {
180  missingGrids << grid.shortName;
181  missingGridPackages << grid.packageName;
182  missingGridUrls << grid.url;
183  QString m = tr( "This transformation requires the grid file “%1”, which is not available for use on the system." ).arg( grid.shortName );
184  if ( !grid.url.isEmpty() )
185  {
186  if ( !grid.packageName.isEmpty() )
187  {
188  m += ' ' + tr( "This grid is part of the <i>%1</i> package, available for download from <a href=\"%2\">%2</a>." ).arg( grid.packageName, grid.url );
189  }
190  else
191  {
192  m += ' ' + tr( "This grid is available for download from <a href=\"%1\">%1</a>." ).arg( grid.url );
193  }
194  }
195  gridMessages << m;
196  }
197  }
198 
199  item->setData( MissingGridsRole, missingGrids );
200  item->setData( MissingGridPackageNamesRole, missingGridPackages );
201  item->setData( MissingGridUrlsRole, missingGridUrls );
202 
203  if ( gridMessages.count() > 1 )
204  {
205  for ( int k = 0; k < gridMessages.count(); ++k )
206  gridMessages[k] = QStringLiteral( "<li>%1</li>" ).arg( gridMessages.at( k ) );
207 
208  missingMessage = QStringLiteral( "<ul>%1</ul" ).arg( gridMessages.join( QString() ) );
209  }
210  else if ( !gridMessages.empty() )
211  {
212  missingMessage = gridMessages.constFirst();
213  }
214  }
215 
216  QStringList areasOfUse;
217  QStringList authorityCodes;
218 
219  QStringList opText;
220  QString lastSingleOpScope;
221  QString lastSingleOpRemarks;
222  for ( const QgsDatumTransform::SingleOperationDetails &singleOpDetails : transform.operationDetails )
223  {
224  QString text;
225  if ( !singleOpDetails.scope.isEmpty() )
226  {
227  text += QStringLiteral( "<b>%1</b>: %2" ).arg( tr( "Scope" ), formatScope( singleOpDetails.scope ) );
228  lastSingleOpScope = singleOpDetails.scope;
229  }
230  if ( !singleOpDetails.remarks.isEmpty() )
231  {
232  if ( !text.isEmpty() )
233  text += QLatin1String( "<br>" );
234  text += QStringLiteral( "<b>%1</b>: %2" ).arg( tr( "Remarks" ), singleOpDetails.remarks );
235  lastSingleOpRemarks = singleOpDetails.remarks;
236  }
237  if ( !singleOpDetails.areaOfUse.isEmpty() )
238  {
239  if ( !areasOfUse.contains( singleOpDetails.areaOfUse ) )
240  areasOfUse << singleOpDetails.areaOfUse;
241  }
242  if ( !singleOpDetails.authority.isEmpty() && !singleOpDetails.code.isEmpty() )
243  {
244  const QString identifier = QStringLiteral( "%1:%2" ).arg( singleOpDetails.authority, singleOpDetails.code );
245  if ( !authorityCodes.contains( identifier ) )
246  authorityCodes << identifier;
247  }
248 
249  if ( !text.isEmpty() )
250  {
251  opText.append( text );
252  }
253  }
254 
255  QString text;
256  if ( !transform.scope.isEmpty() && transform.scope != lastSingleOpScope )
257  {
258  text += QStringLiteral( "<b>%1</b>: %2" ).arg( tr( "Scope" ), transform.scope );
259  }
260  if ( !transform.remarks.isEmpty() && transform.remarks != lastSingleOpRemarks )
261  {
262  if ( !text.isEmpty() )
263  text += QLatin1String( "<br>" );
264  text += QStringLiteral( "<b>%1</b>: %2" ).arg( tr( "Remarks" ), transform.remarks );
265  }
266  if ( !text.isEmpty() )
267  {
268  opText.append( text );
269  }
270 
271  if ( opText.count() > 1 )
272  {
273  for ( int k = 0; k < opText.count(); ++k )
274  opText[k] = QStringLiteral( "<li>%1</li>" ).arg( opText.at( k ) );
275  }
276 
277  if ( !transform.areaOfUse.isEmpty() && !areasOfUse.contains( transform.areaOfUse ) )
278  areasOfUse << transform.areaOfUse;
279  item->setData( BoundsRole, transform.bounds );
280 
281  const QString id = !transform.authority.isEmpty() && !transform.code.isEmpty() ? QStringLiteral( "%1:%2" ).arg( transform.authority, transform.code ) : QString();
282  if ( !id.isEmpty() && !authorityCodes.contains( id ) )
283  authorityCodes << id;
284 
285  const QColor disabled = palette().color( QPalette::Disabled, QPalette::Text );
286  const QColor active = palette().color( QPalette::Active, QPalette::Text );
287 
288  const QColor codeColor( static_cast< int >( active.red() * 0.6 + disabled.red() * 0.4 ),
289  static_cast< int >( active.green() * 0.6 + disabled.green() * 0.4 ),
290  static_cast< int >( active.blue() * 0.6 + disabled.blue() * 0.4 ) );
291  const QString toolTipString = QStringLiteral( "<b>%1</b>" ).arg( transform.name )
292  + ( !opText.empty() ? ( opText.count() == 1 ? QStringLiteral( "<p>%1</p>" ).arg( opText.at( 0 ) ) : QStringLiteral( "<ul>%1</ul>" ).arg( opText.join( QString() ) ) ) : QString() )
293  + ( !areasOfUse.empty() ? QStringLiteral( "<p><b>%1</b>: %2</p>" ).arg( tr( "Area of use" ), areasOfUse.join( QLatin1String( ", " ) ) ) : QString() )
294  + ( !authorityCodes.empty() ? QStringLiteral( "<p><b>%1</b>: %2</p>" ).arg( tr( "Identifiers" ), authorityCodes.join( QLatin1String( ", " ) ) ) : QString() )
295  + ( !missingMessage.isEmpty() ? QStringLiteral( "<p><b style=\"color: red\">%1</b></p>" ).arg( missingMessage ) : QString() )
296  + QStringLiteral( "<p><code style=\"color: %1\">%2</code></p>" ).arg( codeColor.name(), transform.proj );
297 
298  item->setToolTip( toolTipString );
299  mCoordinateOperationTableWidget->setRowCount( row + 1 );
300  mCoordinateOperationTableWidget->setItem( row, 0, item.release() );
301 
302  item = std::make_unique< QTableWidgetItem >();
303  item->setFlags( item->flags() & ~Qt::ItemIsEditable );
304  item->setText( transform.accuracy >= 0 ? QLocale().toString( transform.accuracy ) : tr( "Unknown" ) );
305  item->setToolTip( toolTipString );
306  if ( !transform.isAvailable )
307  {
308  item->setForeground( QBrush( palette().color( QPalette::Disabled, QPalette::Text ) ) );
309  }
310  mCoordinateOperationTableWidget->setItem( row, 1, item.release() );
311 
312  // area of use column
313  item = std::make_unique< QTableWidgetItem >();
314  item->setFlags( item->flags() & ~Qt::ItemIsEditable );
315  item->setText( areasOfUse.join( QLatin1String( ", " ) ) );
316  item->setToolTip( toolTipString );
317  if ( !transform.isAvailable )
318  {
319  item->setForeground( QBrush( palette().color( QPalette::Disabled, QPalette::Text ) ) );
320  }
321  mCoordinateOperationTableWidget->setItem( row, 2, item.release() );
322 
323  row++;
324  }
325 
326  if ( mCoordinateOperationTableWidget->currentRow() < 0 )
327  mCoordinateOperationTableWidget->selectRow( preferredInitialRow >= 0 ? preferredInitialRow : 0 );
328 
329  mCoordinateOperationTableWidget->resizeColumnsToContents();
330 
331  tableCurrentItemChanged( nullptr, nullptr );
332 }
333 
335 {
336  QgsSettings settings;
337  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/hideDeprecated" ), mHideDeprecatedCheckBox->isChecked() );
338 
339  for ( int i = 0; i < 2; i++ )
340  {
341  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/columnWidths/%1" ).arg( i ), mCoordinateOperationTableWidget->columnWidth( i ) );
342  }
343 }
344 
346 {
347  OperationDetails preferred;
348 
349  // for proj 6, return the first available transform -- they are sorted by preference by proj already
350  for ( const QgsDatumTransform::TransformDetails &transform : std::as_const( mDatumTransforms ) )
351  {
352  if ( transform.isAvailable )
353  {
354  preferred.proj = transform.proj;
355  preferred.isAvailable = transform.isAvailable;
356  break;
357  }
358  }
359  return preferred;
360 }
361 
362 QString QgsCoordinateOperationWidget::formatScope( const QString &s )
363 {
364  QString scope = s;
365 
366  QRegularExpression reGNSS( QStringLiteral( "\\bGNSS\\b" ) );
367  scope.replace( reGNSS, QObject::tr( "GNSS (Global Navigation Satellite System)" ) );
368 
369  QRegularExpression reCORS( QStringLiteral( "\\bCORS\\b" ) );
370  scope.replace( reCORS, QObject::tr( "CORS (Continually Operating Reference Station)" ) );
371 
372  return scope;
373 }
374 
376 {
377  int row = mCoordinateOperationTableWidget->currentRow();
378  OperationDetails op;
379 
380  if ( row >= 0 )
381  {
382  QTableWidgetItem *srcItem = mCoordinateOperationTableWidget->item( row, 0 );
383  op.sourceTransformId = srcItem ? srcItem->data( TransformIdRole ).toInt() : -1;
384  QTableWidgetItem *destItem = mCoordinateOperationTableWidget->item( row, 1 );
385  op.destinationTransformId = destItem ? destItem->data( TransformIdRole ).toInt() : -1;
386  op.proj = srcItem ? srcItem->data( ProjRole ).toString() : QString();
387  op.isAvailable = srcItem ? srcItem->data( AvailableRole ).toBool() : true;
388  op.allowFallback = mAllowFallbackCheckBox->isChecked();
389  }
390  else
391  {
392  op.sourceTransformId = -1;
393  op.destinationTransformId = -1;
394  op.proj = QString();
395  }
396  return op;
397 }
398 
400 {
401  int prevRow = mCoordinateOperationTableWidget->currentRow();
402  mBlockSignals++;
403  for ( int row = 0; row < mCoordinateOperationTableWidget->rowCount(); ++row )
404  {
405  QTableWidgetItem *srcItem = mCoordinateOperationTableWidget->item( row, 0 );
406  if ( srcItem && srcItem->data( ProjRole ).toString() == operation.proj )
407  {
408  mCoordinateOperationTableWidget->selectRow( row );
409  break;
410  }
411  }
412 
413  bool fallbackChanged = mAllowFallbackCheckBox->isChecked() != operation.allowFallback;
414  mAllowFallbackCheckBox->setChecked( operation.allowFallback );
415  mBlockSignals--;
416 
417  if ( mCoordinateOperationTableWidget->currentRow() != prevRow || fallbackChanged )
418  emit operationChanged();
419 }
420 
422 {
423  const QString op = context.calculateCoordinateOperation( mSourceCrs, mDestinationCrs );
424  if ( !op.isEmpty() )
425  {
426  OperationDetails deets;
427  deets.proj = op;
428  deets.allowFallback = context.allowFallbackTransform( mSourceCrs, mDestinationCrs );
429  setSelectedOperation( deets );
430  }
431  else
432  {
434  }
435 }
436 
438 {
439  mAllowFallbackCheckBox->setVisible( visible );
440 }
441 
442 bool QgsCoordinateOperationWidget::gridShiftTransformation( const QString &itemText ) const
443 {
444  return !itemText.isEmpty() && !itemText.contains( QLatin1String( "towgs84" ), Qt::CaseInsensitive );
445 }
446 
447 bool QgsCoordinateOperationWidget::testGridShiftFileAvailability( QTableWidgetItem *item ) const
448 {
449  if ( !item )
450  {
451  return true;
452  }
453 
454  QString itemText = item->text();
455  if ( itemText.isEmpty() )
456  {
457  return true;
458  }
459 
460  char *projLib = getenv( "PROJ_LIB" );
461  if ( !projLib ) //no information about installation directory
462  {
463  return true;
464  }
465 
466  QStringList itemEqualSplit = itemText.split( '=' );
467  QString filename;
468  for ( int i = 1; i < itemEqualSplit.size(); ++i )
469  {
470  if ( i > 1 )
471  {
472  filename.append( '=' );
473  }
474  filename.append( itemEqualSplit.at( i ) );
475  }
476 
477  QDir projDir( projLib );
478  if ( projDir.exists() )
479  {
480  //look if filename in directory
481  QStringList fileList = projDir.entryList();
482  QStringList::const_iterator fileIt = fileList.constBegin();
483  for ( ; fileIt != fileList.constEnd(); ++fileIt )
484  {
485 #if defined(Q_OS_WIN)
486  if ( fileIt->compare( filename, Qt::CaseInsensitive ) == 0 )
487 #else
488  if ( fileIt->compare( filename ) == 0 )
489 #endif //Q_OS_WIN
490  {
491  return true;
492  }
493  }
494  item->setToolTip( tr( "File '%1' not found in directory '%2'" ).arg( filename, projDir.absolutePath() ) );
495  return false; //not found in PROJ_LIB directory
496  }
497  return true;
498 }
499 
500 void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *, QTableWidgetItem * )
501 {
502  int row = mCoordinateOperationTableWidget->currentRow();
503  if ( row < 0 )
504  {
505  mLabelSrcDescription->clear();
506  mLabelDstDescription->clear();
507  mAreaCanvas->hide();
508  mInstallGridButton->hide();
509  }
510  else
511  {
512  QTableWidgetItem *srcItem = mCoordinateOperationTableWidget->item( row, 0 );
513  mLabelSrcDescription->setText( srcItem ? srcItem->toolTip() : QString() );
514  if ( srcItem )
515  {
516  // find area of intersection of operation, source and dest bounding boxes
517  // see https://github.com/OSGeo/PROJ/issues/1549 for justification
518  const QgsRectangle operationRect = srcItem->data( BoundsRole ).value< QgsRectangle >();
519  const QgsRectangle sourceRect = mSourceCrs.bounds();
520  const QgsRectangle destRect = mDestinationCrs.bounds();
521  QgsRectangle rect = operationRect.intersect( sourceRect );
522  rect = rect.intersect( destRect );
523 
524  mAreaCanvas->setPreviewRect( rect );
525  mAreaCanvas->show();
526 
527  const QStringList missingGrids = srcItem->data( MissingGridsRole ).toStringList();
528  mInstallGridButton->setVisible( !missingGrids.empty() );
529  if ( !missingGrids.empty() )
530  {
531  mInstallGridButton->setText( tr( "Install “%1” Grid…" ).arg( missingGrids.at( 0 ) ) );
532  }
533  }
534  else
535  {
536  mAreaCanvas->setPreviewRect( QgsRectangle() );
537  mAreaCanvas->hide();
538  mInstallGridButton->hide();
539  }
540  QTableWidgetItem *destItem = mCoordinateOperationTableWidget->item( row, 1 );
541  mLabelDstDescription->setText( destItem ? destItem->toolTip() : QString() );
542  }
543  OperationDetails newOp = selectedOperation();
544  if ( newOp.proj != mPreviousOp.proj && !mBlockSignals )
545  emit operationChanged();
546  mPreviousOp = newOp;
547 }
548 
550 {
551  mSourceCrs = sourceCrs;
552  mDatumTransforms = QgsDatumTransform::operations( mSourceCrs, mDestinationCrs, mShowSupersededCheckBox->isChecked() );
553  loadAvailableOperations();
554 }
555 
557 {
558  mDestinationCrs = destinationCrs;
559  mDatumTransforms = QgsDatumTransform::operations( mSourceCrs, mDestinationCrs, mShowSupersededCheckBox->isChecked() );
560  loadAvailableOperations();
561 }
562 
563 void QgsCoordinateOperationWidget::showSupersededToggled( bool )
564 {
565  mDatumTransforms = QgsDatumTransform::operations( mSourceCrs, mDestinationCrs, mShowSupersededCheckBox->isChecked() );
566  loadAvailableOperations();
567 }
568 
569 void QgsCoordinateOperationWidget::installGrid()
570 {
571  int row = mCoordinateOperationTableWidget->currentRow();
572  QTableWidgetItem *srcItem = mCoordinateOperationTableWidget->item( row, 0 );
573  if ( !srcItem )
574  return;
575 
576  const QStringList missingGrids = srcItem->data( MissingGridsRole ).toStringList();
577  if ( missingGrids.empty() )
578  return;
579 
580  const QStringList missingGridPackagesNames = srcItem->data( MissingGridPackageNamesRole ).toStringList();
581  const QString packageName = missingGridPackagesNames.value( 0 );
582  const QStringList missingGridUrls = srcItem->data( MissingGridUrlsRole ).toStringList();
583  const QString gridUrl = missingGridUrls.value( 0 );
584 
585  QString downloadMessage;
586  if ( !packageName.isEmpty() )
587  {
588  downloadMessage = tr( "This grid is part of the “<i>%1</i>” package, available for download from <a href=\"%2\">%2</a>." ).arg( packageName, gridUrl );
589  }
590  else if ( !gridUrl.isEmpty() )
591  {
592  downloadMessage = tr( "This grid is available for download from <a href=\"%1\">%1</a>." ).arg( gridUrl );
593  }
594 
595  const QString longMessage = tr( "<p>This transformation requires the grid file “%1”, which is not available for use on the system.</p>" ).arg( missingGrids.at( 0 ) );
596 
597  QgsInstallGridShiftFileDialog *dlg = new QgsInstallGridShiftFileDialog( missingGrids.at( 0 ), this );
598  dlg->setAttribute( Qt::WA_DeleteOnClose );
599  dlg->setWindowTitle( tr( "Install Grid File" ) );
600  dlg->setDescription( longMessage );
601  dlg->setDownloadMessage( downloadMessage );
602  dlg->exec();
603 }
QgsDatumTransform::SingleOperationDetails::scope
QString scope
Scope of operation, from EPSG registry database.
Definition: qgsdatumtransform.h:159
QgsCoordinateOperationWidget::setSelectedOperation
void setSelectedOperation(const QgsCoordinateOperationWidget::OperationDetails &operation)
Sets the details of the operation currently selected within the widget.
Definition: qgscoordinateoperationwidget.cpp:399
QgsDatumTransform::SingleOperationDetails::code
QString code
Authority code, e.g. "8447" (for EPSG:8447).
Definition: qgsdatumtransform.h:171
qgsinstallgridshiftdialog.h
QgsCoordinateTransformContext
Contains information about the context in which a coordinate transform is executed.
Definition: qgscoordinatetransformcontext.h:57
QgsCoordinateOperationWidget::defaultOperation
QgsCoordinateOperationWidget::OperationDetails defaultOperation() const
Returns the details of the default operation suggested by the widget.
Definition: qgscoordinateoperationwidget.cpp:345
QgsDatumTransform::SingleOperationDetails::remarks
QString remarks
Remarks for operation, from EPSG registry database.
Definition: qgsdatumtransform.h:162
QgsDatumTransform::SingleOperationDetails
Contains information about a single coordinate operation.
Definition: qgsdatumtransform.h:156
QgsCoordinateOperationWidget::sourceCrs
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source CRS for the operations shown in the widget.
Definition: qgscoordinateoperationwidget.h:70
qgscoordinateoperationwidget.h
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
QgsCoordinateOperationWidget::QgsCoordinateOperationWidget
QgsCoordinateOperationWidget(QWidget *parent=nullptr)
Constructor for QgsCoordinateOperationWidget.
Definition: qgscoordinateoperationwidget.cpp:36
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:437
qgsgui.h
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsCoordinateOperationWidget::OperationDetails
Coordinate operation details.
Definition: qgscoordinateoperationwidget.h:39
QgsCoordinateOperationWidget::OperationDetails::allowFallback
bool allowFallback
true if fallback transforms can be used
Definition: qgscoordinateoperationwidget.h:54
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsRectangle::intersect
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:333
QgsCoordinateOperationWidget::setShowFallbackOption
void setShowFallbackOption(bool visible)
Sets whether the "allow fallback" operations option is visible.
Definition: qgscoordinateoperationwidget.cpp:437
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsDatumTransform::GridDetails
Contains information about a projection transformation grid file.
Definition: qgsdatumtransform.h:132
QgsCoordinateReferenceSystem::bounds
QgsRectangle bounds() const
Returns the approximate bounds for the region the CRS is usable within.
Definition: qgscoordinatereferencesystem.cpp:1470
QgsCoordinateOperationWidget::~QgsCoordinateOperationWidget
~QgsCoordinateOperationWidget() override
Definition: qgscoordinateoperationwidget.cpp:334
qgsprojectionselectiondialog.h
QgsCoordinateOperationWidget::setShowMakeDefault
void setShowMakeDefault(bool show)
Sets whether the "make default" checkbox should be shown.
Definition: qgscoordinateoperationwidget.cpp:99
QgsCoordinateOperationWidget::makeDefaultSelected
bool makeDefaultSelected() const
Returns true if the "make default" option is selected.
Definition: qgscoordinateoperationwidget.cpp:104
QgsCoordinateTransformContext::allowFallbackTransform
bool allowFallbackTransform(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns true if approximate "ballpark" transforms may be used when transforming between a source and ...
Definition: qgscoordinatetransformcontext.cpp:158
QgsCoordinateOperationWidget::OperationDetails::proj
QString proj
Proj coordinate operation description, for Proj >= 6.0 builds only.
Definition: qgscoordinateoperationwidget.h:48
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsDatumTransform::GridDetails::url
QString url
Url to download grid from.
Definition: qgsdatumtransform.h:141
QgsGeometry::densifyByCount
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
Definition: qgsgeometry.cpp:2263
QgsCoordinateOperationWidget::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to link to the widget, which allows the widget's choices to reflect the current can...
Definition: qgscoordinateoperationwidget.cpp:70
QgsCoordinateTransform::setBallparkTransformsAreAppropriate
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
Definition: qgscoordinatetransform.cpp:939
QgsMapSettings::visiblePolygon
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated)
Definition: qgsmapsettings.cpp:416
QgsCoordinateOperationWidget::selectedOperation
QgsCoordinateOperationWidget::OperationDetails selectedOperation() const
Returns the details of the operation currently selected within the widget.
Definition: qgscoordinateoperationwidget.cpp:375
QgsCoordinateOperationWidget::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs for the operations shown in the widget.
Definition: qgscoordinateoperationwidget.cpp:556
qgscoordinatetransform.h
QgsCoordinateOperationWidget::operationDoubleClicked
void operationDoubleClicked()
Emitted when an operation is double-clicked in the widget.
QgsDatumTransform::GridDetails::shortName
QString shortName
Short name of transform grid.
Definition: qgsdatumtransform.h:135
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:279
QgsCoordinateOperationWidget::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination CRS for the operations shown in the widget.
Definition: qgscoordinateoperationwidget.h:78
QgsCoordinateOperationWidget::availableOperations
QList< QgsCoordinateOperationWidget::OperationDetails > availableOperations() const
Returns a list of the available operations shown in the widget.
Definition: qgscoordinateoperationwidget.cpp:114
QgsDatumTransform::TransformDetails
Contains information about a coordinate transformation operation.
Definition: qgsdatumtransform.h:180
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsCoordinateOperationWidget::OperationDetails::destinationTransformId
int destinationTransformId
Destination transform ID.
Definition: qgscoordinateoperationwidget.h:45
QgsCoordinateOperationWidget::hasSelection
bool hasSelection() const
Returns true if there is a valid selection in the widget.
Definition: qgscoordinateoperationwidget.cpp:109
QgsCoordinateOperationWidget::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs)
Sets the source crs for the operations shown in the widget.
Definition: qgscoordinateoperationwidget.cpp:549
QgsCoordinateOperationWidget::OperationDetails::sourceTransformId
int sourceTransformId
Source transform ID.
Definition: qgscoordinateoperationwidget.h:42
QgsCoordinateOperationWidget::OperationDetails::isAvailable
bool isAvailable
true if operation is available
Definition: qgscoordinateoperationwidget.h:51
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsCoordinateTransformContext::calculateCoordinateOperation
QString calculateCoordinateOperation(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns the Proj coordinate operation string to use when transforming from the specified source CRS t...
Definition: qgscoordinatetransformcontext.cpp:142
qgsprojutils.h
qgssettings.h
QgsDatumTransform::GridDetails::isAvailable
bool isAvailable
true if grid is currently available for use
Definition: qgsdatumtransform.h:147
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:1080
QgsCoordinateReferenceSystem::fromEpsgId
static Q_INVOKABLE QgsCoordinateReferenceSystem fromEpsgId(long epsg)
Creates a CRS from a given EPSG ID.
Definition: qgscoordinatereferencesystem.cpp:202
QgsGeometry::fromQPolygonF
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Definition: qgsgeometry.cpp:3408
QgsDatumTransform::GridDetails::packageName
QString packageName
Name of package the grid is included within.
Definition: qgsdatumtransform.h:139
QgsDatumTransform::SingleOperationDetails::authority
QString authority
Authority name, e.g. EPSG.
Definition: qgsdatumtransform.h:168
QgsDatumTransform::SingleOperationDetails::areaOfUse
QString areaOfUse
Area of use, from EPSG registry database.
Definition: qgsdatumtransform.h:165
qgslogger.h
qgsguiutils.h
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
qgshelp.h
qgsproject.h
QgsCoordinateOperationWidget::setSelectedOperationUsingContext
void setSelectedOperationUsingContext(const QgsCoordinateTransformContext &context)
Automatically sets the selected operation using the settings encapsulated in a transform context.
Definition: qgscoordinateoperationwidget.cpp:421
QgsCoordinateOperationWidget::operationChanged
void operationChanged()
Emitted when the operation selected in the dialog is changed.
QgsDatumTransform::operations
static QList< QgsDatumTransform::TransformDetails > operations(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination, bool includeSuperseded=false)
Returns a list of coordinate operations available for transforming coordinates from the source to des...
Definition: qgsdatumtransform.cpp:26