22 #include "qgssettings.h"
30 #include <QHeaderView>
31 #include <QResizeEvent>
32 #include <QMessageBox>
39 QFont f = teProjection->font();
40 f.setPointSize( f.pointSize() - 2 );
41 teProjection->setFont( f );
43 leSearch->setShowSearchIcon(
true );
45 connect( lstCoordinateSystems, &QTreeWidget::itemDoubleClicked,
this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystems_itemDoubleClicked );
46 connect( lstRecent, &QTreeWidget::itemDoubleClicked,
this, &QgsProjectionSelectionTreeWidget::lstRecent_itemDoubleClicked );
47 connect( lstCoordinateSystems, &QTreeWidget::currentItemChanged,
this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystems_currentItemChanged );
48 connect( lstRecent, &QTreeWidget::currentItemChanged,
this, &QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged );
49 connect( cbxHideDeprecated, &QCheckBox::stateChanged,
this, &QgsProjectionSelectionTreeWidget::updateFilter );
50 connect( leSearch, &QgsFilterLineEdit::textChanged,
this, &QgsProjectionSelectionTreeWidget::updateFilter );
52 mAreaCanvas->setVisible( mShowMap );
57 lstCoordinateSystems->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
58 lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
59 lstCoordinateSystems->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
62 lstCoordinateSystems->setColumnHidden( QgisCrsIdColumn,
true );
64 lstRecent->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
65 lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
66 lstRecent->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
69 lstRecent->setColumnHidden( QgisCrsIdColumn,
true );
73 mCheckBoxNoProjection->setHidden(
true );
74 mCheckBoxNoProjection->setEnabled(
false );
75 connect( mCheckBoxNoProjection, &QCheckBox::toggled,
this, [ = ]
83 connect( mCheckBoxNoProjection, &QCheckBox::toggled,
this, [ = ](
bool checked )
85 if ( mCheckBoxNoProjection->isEnabled() )
87 mFrameProjections->setDisabled( checked );
92 mSplitter->restoreState( settings.value( QStringLiteral(
"Windows/ProjectionSelector/splitterState" ) ).toByteArray() );
98 settings.setValue( QStringLiteral(
"Windows/ProjectionSelector/splitterState" ), mSplitter->saveState() );
108 lstCoordinateSystems->header()->resizeSection( NameColumn, event->size().width() - 240 );
109 lstCoordinateSystems->header()->resizeSection( AuthidColumn, 240 );
110 lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
112 lstRecent->header()->resizeSection( NameColumn, event->size().width() - 240 );
113 lstRecent->header()->resizeSection( AuthidColumn, 240 );
114 lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
124 loadCrsList( &mCrsFilter );
125 loadUserCrsList( &mCrsFilter );
127 if ( !mRecentProjListDone )
131 mRecentProjListDone =
true;
135 mBlockSignals =
true;
137 mBlockSignals =
false;
142 QWidget::showEvent( event );
146 QString QgsProjectionSelectionTreeWidget::ogcWmsCrsFilterAsSqlExpression( QSet<QString> *crsFilter )
148 QString sqlExpression = QStringLiteral(
"1" );
149 QMap<QString, QStringList> authParts;
152 return sqlExpression;
172 const auto authIds { *crsFilter };
173 for (
const QString &auth_id : authIds )
175 QStringList parts = auth_id.split(
':' );
177 if ( parts.size() < 2 )
180 authParts[ parts.at( 0 ).toUpper()].append( parts.at( 1 ).toUpper() );
183 if ( authParts.isEmpty() )
184 return sqlExpression;
186 if ( !authParts.isEmpty() )
188 QString prefix = QStringLiteral(
" AND (" );
189 for (
auto it = authParts.constBegin(); it != authParts.constEnd(); ++it )
191 sqlExpression += QStringLiteral(
"%1(upper(auth_name)='%2' AND upper(auth_id) IN ('%3'))" )
194 it.value().join( QLatin1String(
"','" ) ) );
195 prefix = QStringLiteral(
" OR " );
197 sqlExpression +=
')';
202 return sqlExpression;
205 void QgsProjectionSelectionTreeWidget::applySelection(
int column, QString value )
207 if ( !mProjListDone || !mUserProjListDone )
210 mSearchColumn = column;
211 mSearchValue = value;
215 if ( column == QgsProjectionSelectionTreeWidget::None )
218 column = mSearchColumn;
219 value = mSearchValue;
221 mSearchColumn = QgsProjectionSelectionTreeWidget::None;
222 mSearchValue.clear();
225 if ( column == QgsProjectionSelectionTreeWidget::None )
228 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( value, Qt::MatchExactly | Qt::MatchRecursive, column );
229 if ( !nodes.isEmpty() )
231 QgsDebugMsgLevel( QStringLiteral(
"found %1,%2" ).arg( column ).arg( value ), 4 );
232 lstCoordinateSystems->setCurrentItem( nodes.first() );
236 QgsDebugMsgLevel( QStringLiteral(
"nothing found for %1,%2" ).arg( column ).arg( value ), 4 );
238 lstCoordinateSystems->clearSelection();
239 lstRecent->clearSelection();
240 teProjection->clear();
246 if ( !mProjListDone || !mUserProjListDone )
249 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( QString::number(
crs.
srsid() ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
250 if ( nodes.isEmpty() )
253 lstRecent->insertTopLevelItem( 0,
new QTreeWidgetItem( lstRecent, QStringList()
254 << nodes.first()->text( NameColumn )
255 << nodes.first()->text( AuthidColumn )
256 << nodes.first()->text( QgisCrsIdColumn ) ) );
260 QString QgsProjectionSelectionTreeWidget::selectedName()
263 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
264 return lvi ? lvi->text( NameColumn ) : QString();
271 mCheckBoxNoProjection->setChecked(
true );
275 bool changed =
false;
278 changed = mDeferredLoadCrs !=
crs;
279 mDeferredLoadCrs =
crs;
281 mBlockSignals =
true;
282 mCheckBoxNoProjection->setChecked(
false );
283 mBlockSignals =
false;
286 applySelection( AuthidColumn,
crs.
authid() );
288 loadUnknownCrs(
crs );
299 mAreaCanvas->setCanvasRect( rect );
304 return mAreaCanvas->canvasRect();
307 QString QgsProjectionSelectionTreeWidget::getSelectedExpression(
const QString &expression )
const
316 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
317 if ( !lvi || lvi->text( QgisCrsIdColumn ).isEmpty() )
324 QString databaseFileName;
328 if ( !QFileInfo::exists( databaseFileName ) )
335 databaseFileName = mSrsDatabaseFileName;
344 int rc = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
348 "Because of this the projection selector will not work…" ).arg( databaseFileName ),
349 Qgis::MessageLevel::Critical );
354 const char *tail =
nullptr;
355 sqlite3_stmt *stmt =
nullptr;
356 QString sql = QStringLiteral(
"select %1 from tbl_srs where srs_id=%2" )
358 lvi->text( QgisCrsIdColumn ) );
360 QgsDebugMsgLevel( QStringLiteral(
"Finding selected attribute using : %1" ).arg( sql ), 4 );
361 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
363 QString attributeValue;
364 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
367 attributeValue = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
371 sqlite3_finalize( stmt );
373 sqlite3_close( database );
376 return attributeValue;
381 if ( mCheckBoxNoProjection->isEnabled() && mCheckBoxNoProjection->isChecked() )
384 if ( !mInitialized && mDeferredLoadCrs.
isValid() )
385 return mDeferredLoadCrs;
387 const QString srsIdString = getSelectedExpression( QStringLiteral(
"srs_id" ) );
388 if ( !srsIdString.isEmpty() )
390 int srid = srsIdString.toLong();
399 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
400 if ( lvi && lvi->data( 0, RoleWkt ).isValid() )
402 else if ( lvi && lvi->data( 0, RoleProj ).isValid() )
411 mCheckBoxNoProjection->setVisible( show );
412 mCheckBoxNoProjection->setEnabled( show );
415 mFrameProjections->setDisabled( mCheckBoxNoProjection->isChecked() );
422 mAreaCanvas->setVisible( show );
427 return !mCheckBoxNoProjection->isHidden();
432 mCheckBoxNoProjection->setText( text );
442 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
443 if ( mCheckBoxNoProjection->isChecked() )
445 else if ( !mInitialized && mDeferredLoadCrs.
isValid() )
448 return item && ( !item->text( QgisCrsIdColumn ).isEmpty() || item->data( 0, RoleWkt ).isValid() );
451 long QgsProjectionSelectionTreeWidget::selectedCrsId()
453 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
455 if ( item && !item->text( QgisCrsIdColumn ).isEmpty() )
456 return lstCoordinateSystems->currentItem()->text( QgisCrsIdColumn ).toLong();
464 mCrsFilter = crsFilter;
465 mProjListDone =
false;
466 mUserProjListDone =
false;
467 lstCoordinateSystems->clear();
470 void QgsProjectionSelectionTreeWidget::loadUserCrsList( QSet<QString> *crsFilter )
472 if ( mUserProjListDone )
475 QgsDebugMsgLevel( QStringLiteral(
"Fetching user projection list..." ), 4 );
479 mUserProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"User Defined Coordinate Systems" ) ) );
480 mUserProjList->setFlags( mUserProjList->flags() & ~Qt::ItemIsSelectable );
482 QFont fontTemp = mUserProjList->font( 0 );
483 fontTemp.setItalic(
true );
484 fontTemp.setBold(
true );
485 mUserProjList->setFont( 0, fontTemp );
491 const QString authid = QStringLiteral(
"USER:%1" ).arg( details.id );
492 if ( crsFilter && !crsFilter->isEmpty() && !crsFilter->contains( authid ) && !crsFilter->contains( authid.toLower() ) )
495 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mUserProjList, QStringList() << details.name );
496 newItem->setText( QgisCrsIdColumn, QString::number( details.id ) );
497 newItem->setText( AuthidColumn, authid );
500 mUserProjListDone =
true;
503 void QgsProjectionSelectionTreeWidget::loadCrsList( QSet<QString> *crsFilter )
509 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
515 mGeoList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Geographic Coordinate Systems" ) ) );
516 mGeoList->setFlags( mGeoList->flags() & ~Qt::ItemIsSelectable );
518 QFont fontTemp = mGeoList->font( 0 );
519 fontTemp.setItalic(
true );
520 fontTemp.setBold(
true );
521 mGeoList->setFont( 0, fontTemp );
525 mProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Projected Coordinate Systems" ) ) );
526 mProjList->setFlags( mProjList->flags() & ~Qt::ItemIsSelectable );
528 fontTemp = mProjList->font( 0 );
529 fontTemp.setItalic(
true );
530 fontTemp.setBold(
true );
531 mProjList->setFont( 0, fontTemp );
539 if ( !QFileInfo::exists( mSrsDatabaseFileName ) )
541 mProjListDone =
true;
547 int rc = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
552 showDBMissingWarning( mSrsDatabaseFileName );
556 const char *tail =
nullptr;
557 sqlite3_stmt *stmt =
nullptr;
561 QString sql = QStringLiteral(
"select description, srs_id, upper(auth_name||':'||auth_id), is_geo, name, parameters, deprecated from vw_srs where %1 order by name,description" )
564 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
566 if ( rc == SQLITE_OK )
568 QTreeWidgetItem *newItem =
nullptr;
571 QString previousSrsType;
572 QTreeWidgetItem *previousSrsTypeNode =
nullptr;
574 while ( sqlite3_step( stmt ) == SQLITE_ROW )
577 int isGeo = sqlite3_column_int( stmt, 3 );
582 newItem =
new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) ) ) );
585 newItem->setText( AuthidColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 2 ) ) );
588 newItem->setText( QgisCrsIdColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 1 ) ) );
593 QTreeWidgetItem *node =
nullptr;
594 QString srsType = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 4 ) );
595 if ( srsType.isEmpty() )
596 srsType = tr(
"Other" );
600 if ( srsType == previousSrsType )
602 node = previousSrsTypeNode;
607 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NameColumn );
608 if ( nodes.isEmpty() )
612 node =
new QTreeWidgetItem( mProjList, QStringList( srsType ) );
613 node->setFlags( node->flags() & ~Qt::ItemIsSelectable );
615 QFont fontTemp = node->font( 0 );
616 fontTemp.setItalic(
true );
617 node->setFont( 0, fontTemp );
621 node = nodes.first();
624 previousSrsType = srsType;
625 previousSrsTypeNode = node;
628 newItem =
new QTreeWidgetItem( node, QStringList( QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) ) ) );
630 newItem->setText( AuthidColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 2 ) ) );
632 newItem->setText( QgisCrsIdColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 1 ) ) );
634 newItem->parent()->setExpanded(
true );
638 newItem->setData( 0, RoleDeprecated, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 6 ) ) );
639 newItem->setHidden( cbxHideDeprecated->isChecked() );
641 mProjList->setExpanded(
true );
645 sqlite3_finalize( stmt );
647 sqlite3_close( database );
649 mProjListDone =
true;
656 mUnknownList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Custom Coordinate Systems" ) ) );
657 mUnknownList->setFlags( mUnknownList->flags() & ~Qt::ItemIsSelectable );
659 QFont fontTemp = mUnknownList->font( 0 );
660 fontTemp.setItalic(
true );
661 fontTemp.setBold(
true );
662 mUnknownList->setFont( 0, fontTemp );
666 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mUnknownList, QStringList(
crs.
description().isEmpty() ? QObject::tr(
"Custom CRS" ) :
crs.
description() ) );
668 newItem->setData( 0, RoleProj,
crs.
toProj() );
670 lstCoordinateSystems->setCurrentItem( newItem );
674 void QgsProjectionSelectionTreeWidget::lstCoordinateSystems_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
684 lstCoordinateSystems->scrollToItem( current );
688 if ( current->childCount() == 0 )
691 if ( !mBlockSignals )
697 updateBoundsPreview();
699 const QString crsId = current->text( QgisCrsIdColumn );
700 if ( !crsId.isEmpty() )
702 QList<QTreeWidgetItem *> nodes = lstRecent->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly, QgisCrsIdColumn );
703 if ( !nodes.isEmpty() )
705 QgsDebugMsgLevel( QStringLiteral(
"found srs %1 in recent" ).arg( current->text( QgisCrsIdColumn ) ), 4 );
706 lstRecent->setCurrentItem( nodes.first() );
710 QgsDebugMsgLevel( QStringLiteral(
"srs %1 not recent" ).arg( current->text( QgisCrsIdColumn ) ), 4 );
711 lstRecent->clearSelection();
712 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
717 lstRecent->clearSelection();
718 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
724 current->setSelected(
false );
725 teProjection->clear();
726 lstRecent->clearSelection();
731 void QgsProjectionSelectionTreeWidget::lstCoordinateSystems_itemDoubleClicked( QTreeWidgetItem *current,
int column )
745 if ( current->childCount() == 0 )
749 void QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
759 lstRecent->scrollToItem( current );
761 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
762 if ( !nodes.isEmpty() )
763 lstCoordinateSystems->setCurrentItem( nodes.first() );
766 void QgsProjectionSelectionTreeWidget::lstRecent_itemDoubleClicked( QTreeWidgetItem *current,
int column )
778 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
779 if ( !nodes.isEmpty() )
783 void QgsProjectionSelectionTreeWidget::updateFilter()
785 QString filterTxtCopy = QRegExp::escape( leSearch->text() );
786 filterTxtCopy.replace( QRegExp(
"\\s+" ), QStringLiteral(
".*" ) );
787 QRegExp re( filterTxtCopy, Qt::CaseInsensitive );
789 const bool hideDeprecated = cbxHideDeprecated->isChecked();
791 auto filterTreeWidget = [ = ]( QTreeWidget * tree )
793 QTreeWidgetItemIterator itr( tree );
796 if ( ( *itr )->childCount() == 0 )
798 if ( hideDeprecated && ( *itr )->data( 0, RoleDeprecated ).toBool() )
800 ( *itr )->setHidden(
true );
801 if ( ( *itr )->isSelected() )
803 ( *itr )->setSelected(
false );
804 teProjection->clear();
807 else if ( ( *itr )->text( NameColumn ).contains( re )
808 || ( *itr )->text( AuthidColumn ).contains( re )
811 ( *itr )->setHidden(
false );
812 QTreeWidgetItem *parent = ( *itr )->parent();
815 parent->setExpanded(
true );
816 parent->setHidden(
false );
817 parent = parent->parent();
822 ( *itr )->setHidden(
true );
827 ( *itr )->setHidden(
true );
834 filterTreeWidget( lstRecent );
837 filterTreeWidget( lstCoordinateSystems );
844 long QgsProjectionSelectionTreeWidget::getLargestCrsIdMatch(
const QString &sql )
853 const char *tail =
nullptr;
854 sqlite3_stmt *stmt =
nullptr;
861 if ( QFileInfo::exists( databaseFileName ) )
863 result = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
870 showDBMissingWarning( databaseFileName );
874 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
876 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
878 QString srsIdString = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
879 srsId = srsIdString.toLong();
881 sqlite3_finalize( stmt );
882 sqlite3_close( database );
889 result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
892 QgsDebugMsg( QStringLiteral(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
898 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
900 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
902 QString srsIdString = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
903 srsId = srsIdString.toLong();
907 sqlite3_finalize( stmt );
908 sqlite3_close( database );
913 void QgsProjectionSelectionTreeWidget::updateBoundsPreview()
915 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
916 if ( !lvi || ( lvi->text( QgisCrsIdColumn ).isEmpty() && !lvi->data( 0, RoleWkt ).isValid() ) )
924 QString extentString = tr(
"Extent not known" );
925 mAreaCanvas->setPreviewRect( rect );
928 extentString = QStringLiteral(
"%1, %2, %3, %4" )
935 QStringList properties;
937 properties << tr(
"Geographic (uses latitude and longitude for coordinates)" );
942 properties << ( currentCrs.
isDynamic() ? tr(
"Dynamic (relies on a datum which is not plate-fixed)" ) : tr(
"Static (relies on a datum which is plate-fixed)" ) );
947 if ( !celestialBody.isEmpty() )
949 properties << tr(
"Celestial body: %1" ).arg( celestialBody );
963 if ( !ensemble.
code().isEmpty() )
964 id = QStringLiteral(
"<i>%1</i> (%2:%3)" ).arg( ensemble.
name(), ensemble.
authority(), ensemble.
code() );
966 id = QStringLiteral(
"<i>%</i>”" ).arg( ensemble.
name() );
969 properties << tr(
"Based on %1, which has a limited accuracy of <b>at best %2 meters</b>." ).arg(
id ).arg( ensemble.
accuracy() );
973 properties << tr(
"Based on %1, which has a limited accuracy." ).arg(
id );
983 properties << tr(
"Method: %1" ).arg( operation.
description() );
985 const QString propertiesString = QStringLiteral(
"<dt><b>%1</b></dt><dd><ul><li>%2</li></ul></dd>" ).arg( tr(
"Properties" ),
986 properties.join( QLatin1String(
"</li><li>" ) ) );
988 const QString extentHtml = QStringLiteral(
"<dt><b>%1</b></dt><dd>%2</dd>" ).arg( tr(
"Extent" ), extentString );
989 const QString wktString = QStringLiteral(
"<dt><b>%1</b></dt><dd><code>%2</code></dd>" ).arg( tr(
"WKT" ), currentCrs.
toWkt(
QgsCoordinateReferenceSystem::WKT_PREFERRED,
true ).replace(
'\n', QLatin1String(
"<br>" ) ).replace(
' ', QLatin1String(
" " ) ) );
990 const QString proj4String = QStringLiteral(
"<dt><b>%1</b></dt><dd><code>%2</code></dd>" ).arg( tr(
"Proj4" ), currentCrs.
toProj() );
993 const int smallerPointSize = std::max( font().pointSize() - 1, 8 );
995 const int smallerPointSize = std::max( font().pointSize() - 2, 6 );
998 teProjection->setText( QStringLiteral(
"<div style=\"font-size: %1pt\"><h3>%2</h3><dl>" ).arg( smallerPointSize ).arg( selectedName() ) + propertiesString + wktString + proj4String + extentHtml + QStringLiteral(
"</dl></div>" ) );
1001 QStringList QgsProjectionSelectionTreeWidget::authorities()
1004 const char *tail =
nullptr;
1005 sqlite3_stmt *stmt =
nullptr;
1007 int result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
1010 QgsDebugMsg( QStringLiteral(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
1012 return QStringList();
1015 QString sql = QStringLiteral(
"select distinct auth_name from tbl_srs" );
1016 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
1018 QStringList authorities;
1019 if ( result == SQLITE_OK )
1021 while ( sqlite3_step( stmt ) == SQLITE_ROW )
1023 authorities << QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
1029 sqlite3_finalize( stmt );
1030 sqlite3_close( database );
1035 QString QgsProjectionSelectionTreeWidget::sqlSafeString(
const QString &theSQL )
const
1037 QString retval = theSQL;
1038 retval.replace(
'\\', QLatin1String(
"\\\\" ) );
1039 retval.replace(
'\"', QLatin1String(
"\\\"" ) );
1040 retval.replace(
'\'', QLatin1String(
"\\'" ) );
1041 retval.replace(
'%', QLatin1String(
"\\%" ) );
1045 void QgsProjectionSelectionTreeWidget::showDBMissingWarning(
const QString &fileName )
1048 QMessageBox::critical(
this, tr(
"Resource Location Error" ),
1049 tr(
"Error reading database file from: \n %1\n"
1050 "Because of this the projection selector will not work…" )
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
Contains details of a custom (user defined) CRS.
QList< QgsCoordinateReferenceSystemRegistry::UserCrsDetails > userCrsList() const
Returns a list containing the details of all registered custom (user-defined) CRSes.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QgsRectangle bounds() const
Returns the approximate bounds for the region the CRS is usable within.
QString toProj() const
Returns a Proj string representation of this CRS.
static void pushRecentCoordinateReferenceSystem(const QgsCoordinateReferenceSystem &crs)
Pushes a recently used CRS to the top of the recent CRS list.
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
bool isDynamic() const
Returns true if the CRS is a dynamic CRS.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
static QList< QgsCoordinateReferenceSystem > recentCoordinateReferenceSystems()
Returns a list of recently used CRS.
QString authid() const
Returns the authority identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
long srsid() const
Returns the internal CRS ID, if available.
QString celestialBodyName() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve the name of the celestial body associated with the CRS (e.g.
Contains information about a datum ensemble.
QString code() const
Identification code, e.g.
QString authority() const
Authority name, e.g.
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
QString name() const
Display name of datum ensemble.
double accuracy() const
Positional accuracy (in meters).
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Custom exception class which is raised when an operation is not supported.
Contains information about a PROJ operation.
QString description() const
Description.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double area() const SIP_HOLDGIL
Returns the area of the rectangle.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
const int USER_CRS_START_ID
Magick number that determines whether a projection crsid is a system (srs.db) or user (~/....
#define QgsDebugMsgLevel(str, level)
const QgsCoordinateReferenceSystem & crs