QGIS API Documentation  2.99.0-Master (ae4d26a)
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"
20 #include "qgslogger.h"
21 #include "qgssettings.h"
22 
23 #include <QDir>
24 
25 QgsDatumTransformDialog::QgsDatumTransformDialog( const QString &layerName, const QList< QList< int > > &dt, QWidget *parent, Qt::WindowFlags f )
26  : QDialog( parent, f )
27  , mDt( dt )
28  , mLayerName( layerName )
29 {
30  setupUi( this );
31  connect( mHideDeprecatedCheckBox, &QCheckBox::stateChanged, this, &QgsDatumTransformDialog::mHideDeprecatedCheckBox_stateChanged );
32  connect( mDatumTransformTreeWidget, &QTreeWidget::currentItemChanged, this, &QgsDatumTransformDialog::mDatumTransformTreeWidget_currentItemChanged );
33 
34  QApplication::setOverrideCursor( Qt::ArrowCursor );
35 
36  updateTitle();
37 
38  QgsSettings settings;
39  restoreGeometry( settings.value( QStringLiteral( "Windows/DatumTransformDialog/geometry" ) ).toByteArray() );
40  mHideDeprecatedCheckBox->setChecked( settings.value( QStringLiteral( "Windows/DatumTransformDialog/hideDeprecated" ), false ).toBool() );
41  mRememberSelectionCheckBox->setChecked( settings.value( QStringLiteral( "Windows/DatumTransformDialog/rememberSelection" ), false ).toBool() );
42 
43  mLabelSrcDescription->clear();
44  mLabelDstDescription->clear();
45 
46  for ( int i = 0; i < 2; i++ )
47  {
48  mDatumTransformTreeWidget->setColumnWidth( i, settings.value( QStringLiteral( "Windows/DatumTransformDialog/columnWidths/%1" ).arg( i ), mDatumTransformTreeWidget->columnWidth( i ) ).toInt() );
49  }
50 
51  load();
52 }
53 
54 void QgsDatumTransformDialog::load()
55 {
56  QgsDebugMsg( "Entered." );
57 
58  mDatumTransformTreeWidget->clear();
59 
60  QList< QList< int > >::const_iterator it = mDt.constBegin();
61  for ( ; it != mDt.constEnd(); ++it )
62  {
63  QTreeWidgetItem *item = new QTreeWidgetItem();
64  bool itemDisabled = false;
65  bool itemHidden = false;
66 
67  for ( int i = 0; i < 2 && i < it->size(); ++i )
68  {
69  int nr = it->at( i );
70  item->setData( i, Qt::UserRole, nr );
71  if ( nr == -1 )
72  continue;
73 
74  item->setText( i, QgsCoordinateTransform::datumTransformString( nr ) );
75 
76  //Describe datums in a tooltip
77  QString srcGeoProj, destGeoProj, remarks, scope;
78  int epsgNr;
79  bool preferred, deprecated;
80  if ( !QgsCoordinateTransform::datumTransformCrsInfo( nr, epsgNr, srcGeoProj, destGeoProj, remarks, scope, preferred, deprecated ) )
81  continue;
82 
83  if ( mHideDeprecatedCheckBox->isChecked() && deprecated )
84  {
85  itemHidden = true;
86  }
87 
88  QString toolTipString;
89  if ( gridShiftTransformation( item->text( i ) ) )
90  {
91  toolTipString.append( QStringLiteral( "<p><b>NTv2</b></p>" ) );
92  }
93 
94  if ( epsgNr > 0 )
95  toolTipString.append( QStringLiteral( "<p><b>EPSG Transformations Code:</b> %1</p>" ).arg( epsgNr ) );
96 
97  toolTipString.append( QStringLiteral( "<p><b>Source CRS:</b> %1</p><p><b>Destination CRS:</b> %2</p>" ).arg( srcGeoProj, destGeoProj ) );
98 
99  if ( !remarks.isEmpty() )
100  toolTipString.append( QStringLiteral( "<p><b>Remarks:</b> %1</p>" ).arg( remarks ) );
101  if ( !scope.isEmpty() )
102  toolTipString.append( QStringLiteral( "<p><b>Scope:</b> %1</p>" ).arg( scope ) );
103  if ( preferred )
104  toolTipString.append( "<p><b>Preferred transformation</b></p>" );
105  if ( deprecated )
106  toolTipString.append( "<p><b>Deprecated transformation</b></p>" );
107 
108  item->setToolTip( i, toolTipString );
109 
110  if ( gridShiftTransformation( item->text( i ) ) && !testGridShiftFileAvailability( item, i ) )
111  {
112  itemDisabled = true;
113  }
114  }
115 
116  if ( !itemHidden )
117  {
118  item->setDisabled( itemDisabled );
119  mDatumTransformTreeWidget->addTopLevelItem( item );
120  }
121  else
122  {
123  delete item;
124  }
125  }
126 }
127 
129 {
130  QgsSettings settings;
131  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/geometry" ), saveGeometry() );
132  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/hideDeprecated" ), mHideDeprecatedCheckBox->isChecked() );
133  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/rememberSelection" ), mRememberSelectionCheckBox->isChecked() );
134 
135  for ( int i = 0; i < 2; i++ )
136  {
137  settings.setValue( QStringLiteral( "Windows/DatumTransformDialog/columnWidths/%1" ).arg( i ), mDatumTransformTreeWidget->columnWidth( i ) );
138  }
139 
140  QApplication::restoreOverrideCursor();
141 }
142 
143 void QgsDatumTransformDialog::setDatumTransformInfo( const QString &srcCRSauthId, const QString &destCRSauthId )
144 {
145  mSrcCRSauthId = srcCRSauthId;
146  mDestCRSauthId = destCRSauthId;
147  updateTitle();
148 }
149 
151 {
152  QList<int> list;
153  QTreeWidgetItem *item = mDatumTransformTreeWidget->currentItem();
154  if ( item )
155  {
156  list.reserve( 2 );
157  for ( int i = 0; i < 2; ++i )
158  {
159  int transformNr = item->data( i, Qt::UserRole ).toInt();
160  list << transformNr;
161  }
162  }
163  return list;
164 }
165 
167 {
168  return mRememberSelectionCheckBox->isChecked();
169 }
170 
171 bool QgsDatumTransformDialog::gridShiftTransformation( const QString &itemText ) const
172 {
173  return !itemText.isEmpty() && !itemText.contains( QLatin1String( "towgs84" ), Qt::CaseInsensitive );
174 }
175 
176 bool QgsDatumTransformDialog::testGridShiftFileAvailability( QTreeWidgetItem *item, int col ) const
177 {
178  if ( !item )
179  {
180  return true;
181  }
182 
183  QString itemText = item->text( col );
184  if ( itemText.isEmpty() )
185  {
186  return true;
187  }
188 
189  char *projLib = getenv( "PROJ_LIB" );
190  if ( !projLib ) //no information about installation directory
191  {
192  return true;
193  }
194 
195  QStringList itemEqualSplit = itemText.split( '=' );
196  QString filename;
197  for ( int i = 1; i < itemEqualSplit.size(); ++i )
198  {
199  if ( i > 1 )
200  {
201  filename.append( '=' );
202  }
203  filename.append( itemEqualSplit.at( i ) );
204  }
205 
206  QDir projDir( projLib );
207  if ( projDir.exists() )
208  {
209  //look if filename in directory
210  QStringList fileList = projDir.entryList();
211  QStringList::const_iterator fileIt = fileList.constBegin();
212  for ( ; fileIt != fileList.constEnd(); ++fileIt )
213  {
214 #if defined(Q_OS_WIN)
215  if ( fileIt->compare( filename, Qt::CaseInsensitive ) == 0 )
216 #else
217  if ( fileIt->compare( filename ) == 0 )
218 #endif //Q_OS_WIN
219  {
220  return true;
221  }
222  }
223  item->setToolTip( col, tr( "File '%1' not found in directory '%2'" ).arg( filename, projDir.absolutePath() ) );
224  return false; //not found in PROJ_LIB directory
225  }
226  return true;
227 }
228 
229 void QgsDatumTransformDialog::mHideDeprecatedCheckBox_stateChanged( int )
230 {
231  load();
232 }
233 
234 void QgsDatumTransformDialog::mDatumTransformTreeWidget_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
235 {
236  if ( !current )
237  return;
238 
239  mLabelSrcDescription->setText( current->toolTip( 0 ) );
240  mLabelDstDescription->setText( current->toolTip( 1 ) );
241 }
242 
243 void QgsDatumTransformDialog::updateTitle()
244 {
245  mLabelLayer->setText( mLayerName );
247  crs.createFromString( mSrcCRSauthId );
248  mLabelSrcCrs->setText( QStringLiteral( "%1 - %2" ).arg( mSrcCRSauthId, crs.isValid() ? crs.description() : tr( "unknown" ) ) );
249  crs.createFromString( mDestCRSauthId );
250  mLabelDstCrs->setText( QStringLiteral( "%1 - %2" ).arg( mDestCRSauthId, crs.isValid() ? crs.description() : tr( "unknown" ) ) );
251 }
void clear()
Removes all entries in the user settings.
QgsDatumTransformDialog(const QString &layerName, const QList< QList< int > > &dt, QWidget *parent=nullptr, Qt::WindowFlags f=0)
bool createFromString(const QString &definition)
Set up this CRS from a string definition.
QList< int > selectedDatumTransform()
getter for selected datum transformations
This class is a composition of two QSettings instances:
Definition: qgssettings.h:55
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
void setDatumTransformInfo(const QString &srcCRSauthId, const QString &destCRSauthId)
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QString datumTransformString(int datumTransform)
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
bool rememberSelection() const
dialog shall remember the selection
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
This class represents a coordinate reference system (CRS).
static bool datumTransformCrsInfo(int datumTransform, int &epsgNr, QString &srcProjection, QString &dstProjection, QString &remarks, QString &scope, bool &preferred, bool &deprecated)
Gets name of source and dest geographical CRS (to show in a tooltip)
bool isValid() const
Returns whether this CRS is correctly initialized and usable.