31 #include <QHeaderView>
32 #include <QResizeEvent>
33 #include <QMessageBox>
34 #include <QRegularExpression>
41 QFont f = teProjection->font();
42 f.setPointSize( f.pointSize() - 2 );
43 teProjection->setFont( f );
45 leSearch->setShowSearchIcon(
true );
47 connect( lstCoordinateSystems, &QTreeWidget::itemDoubleClicked,
this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystems_itemDoubleClicked );
48 connect( lstRecent, &QTreeWidget::itemDoubleClicked,
this, &QgsProjectionSelectionTreeWidget::lstRecent_itemDoubleClicked );
49 connect( lstCoordinateSystems, &QTreeWidget::currentItemChanged,
this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystems_currentItemChanged );
50 connect( lstRecent, &QTreeWidget::currentItemChanged,
this, &QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged );
51 connect( cbxHideDeprecated, &QCheckBox::stateChanged,
this, &QgsProjectionSelectionTreeWidget::updateFilter );
52 connect( leSearch, &QgsFilterLineEdit::textChanged,
this, &QgsProjectionSelectionTreeWidget::updateFilter );
54 mAreaCanvas->setVisible( mShowMap );
59 lstCoordinateSystems->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
60 lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
61 lstCoordinateSystems->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
64 lstCoordinateSystems->setColumnHidden( QgisCrsIdColumn,
true );
66 lstRecent->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
67 lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
68 lstRecent->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
71 lstRecent->setColumnHidden( QgisCrsIdColumn,
true );
75 mCheckBoxNoProjection->setHidden(
true );
76 mCheckBoxNoProjection->setEnabled(
false );
77 connect( mCheckBoxNoProjection, &QCheckBox::toggled,
this, [ = ]
85 connect( mCheckBoxNoProjection, &QCheckBox::toggled,
this, [ = ](
bool checked )
87 if ( mCheckBoxNoProjection->isEnabled() )
89 mFrameProjections->setDisabled( checked );
94 mSplitter->restoreState( settings.value( QStringLiteral(
"Windows/ProjectionSelector/splitterState" ) ).toByteArray() );
100 settings.
setValue( QStringLiteral(
"Windows/ProjectionSelector/splitterState" ), mSplitter->saveState() );
110 lstCoordinateSystems->header()->resizeSection( NameColumn, event->size().width() - 240 );
111 lstCoordinateSystems->header()->resizeSection( AuthidColumn, 240 );
112 lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
114 lstRecent->header()->resizeSection( NameColumn, event->size().width() - 240 );
115 lstRecent->header()->resizeSection( AuthidColumn, 240 );
116 lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
126 loadCrsList( &mCrsFilter );
127 loadUserCrsList( &mCrsFilter );
129 if ( !mRecentProjListDone )
133 mRecentProjListDone =
true;
137 mBlockSignals =
true;
139 mBlockSignals =
false;
144 QWidget::showEvent( event );
148 QString QgsProjectionSelectionTreeWidget::ogcWmsCrsFilterAsSqlExpression( QSet<QString> *crsFilter )
150 QString sqlExpression = QStringLiteral(
"1" );
151 QMap<QString, QStringList> authParts;
154 return sqlExpression;
174 const auto authIds { *crsFilter };
175 for (
const QString &auth_id : authIds )
177 QStringList parts = auth_id.split(
':' );
179 if ( parts.size() < 2 )
182 authParts[ parts.at( 0 ).toUpper()].append( parts.at( 1 ).toUpper() );
185 if ( authParts.isEmpty() )
186 return sqlExpression;
188 if ( !authParts.isEmpty() )
190 QString prefix = QStringLiteral(
" AND (" );
191 for (
auto it = authParts.constBegin(); it != authParts.constEnd(); ++it )
193 sqlExpression += QStringLiteral(
"%1(upper(auth_name)='%2' AND upper(auth_id) IN ('%3'))" )
196 it.value().join( QLatin1String(
"','" ) ) );
197 prefix = QStringLiteral(
" OR " );
199 sqlExpression +=
')';
204 return sqlExpression;
207 void QgsProjectionSelectionTreeWidget::applySelection(
int column, QString value )
209 if ( !mProjListDone || !mUserProjListDone )
212 mSearchColumn = column;
213 mSearchValue = value;
217 if ( column == QgsProjectionSelectionTreeWidget::None )
220 column = mSearchColumn;
221 value = mSearchValue;
223 mSearchColumn = QgsProjectionSelectionTreeWidget::None;
224 mSearchValue.clear();
227 if ( column == QgsProjectionSelectionTreeWidget::None )
230 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( value, Qt::MatchExactly | Qt::MatchRecursive, column );
231 if ( !nodes.isEmpty() )
233 QgsDebugMsgLevel( QStringLiteral(
"found %1,%2" ).arg( column ).arg( value ), 4 );
234 lstCoordinateSystems->setCurrentItem( nodes.first() );
238 QgsDebugMsgLevel( QStringLiteral(
"nothing found for %1,%2" ).arg( column ).arg( value ), 4 );
240 lstCoordinateSystems->clearSelection();
241 lstRecent->clearSelection();
242 teProjection->clear();
248 if ( !mProjListDone || !mUserProjListDone )
251 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( QString::number(
crs.
srsid() ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
252 if ( nodes.isEmpty() )
255 lstRecent->insertTopLevelItem( 0,
new QTreeWidgetItem( lstRecent, QStringList()
256 << nodes.first()->text( NameColumn )
257 << nodes.first()->text( AuthidColumn )
258 << nodes.first()->text( QgisCrsIdColumn ) ) );
262 QString QgsProjectionSelectionTreeWidget::selectedName()
265 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
266 return lvi ? lvi->text( NameColumn ) : QString();
273 mCheckBoxNoProjection->setChecked(
true );
277 bool changed =
false;
280 changed = mDeferredLoadCrs !=
crs;
281 mDeferredLoadCrs =
crs;
283 mBlockSignals =
true;
284 mCheckBoxNoProjection->setChecked(
false );
285 mBlockSignals =
false;
288 applySelection( AuthidColumn,
crs.
authid() );
290 loadUnknownCrs(
crs );
301 mAreaCanvas->setCanvasRect( rect );
306 return mAreaCanvas->canvasRect();
309 QString QgsProjectionSelectionTreeWidget::getSelectedExpression(
const QString &expression )
const
318 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
319 if ( !lvi || lvi->text( QgisCrsIdColumn ).isEmpty() )
326 QString databaseFileName;
330 if ( !QFileInfo::exists( databaseFileName ) )
337 databaseFileName = mSrsDatabaseFileName;
346 int rc = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
350 "Because of this the projection selector will not work…" ).arg( databaseFileName ),
351 Qgis::MessageLevel::Critical );
356 const char *tail =
nullptr;
357 sqlite3_stmt *stmt =
nullptr;
358 QString sql = QStringLiteral(
"select %1 from tbl_srs where srs_id=%2" )
360 lvi->text( QgisCrsIdColumn ) );
362 QgsDebugMsgLevel( QStringLiteral(
"Finding selected attribute using : %1" ).arg( sql ), 4 );
363 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
365 QString attributeValue;
366 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
369 attributeValue = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
373 sqlite3_finalize( stmt );
375 sqlite3_close( database );
378 return attributeValue;
383 if ( mCheckBoxNoProjection->isEnabled() && mCheckBoxNoProjection->isChecked() )
386 if ( !mInitialized && mDeferredLoadCrs.
isValid() )
387 return mDeferredLoadCrs;
389 const QString srsIdString = getSelectedExpression( QStringLiteral(
"srs_id" ) );
390 if ( !srsIdString.isEmpty() )
392 int srid = srsIdString.toLong();
401 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
402 if ( lvi && lvi->data( 0, RoleWkt ).isValid() )
404 else if ( lvi && lvi->data( 0, RoleProj ).isValid() )
413 mCheckBoxNoProjection->setVisible( show );
414 mCheckBoxNoProjection->setEnabled( show );
417 mFrameProjections->setDisabled( mCheckBoxNoProjection->isChecked() );
424 mAreaCanvas->setVisible( show );
429 return !mCheckBoxNoProjection->isHidden();
434 mCheckBoxNoProjection->setText( text );
444 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
445 if ( mCheckBoxNoProjection->isChecked() )
447 else if ( !mInitialized && mDeferredLoadCrs.
isValid() )
450 return item && ( !item->text( QgisCrsIdColumn ).isEmpty() || item->data( 0, RoleWkt ).isValid() );
453 long QgsProjectionSelectionTreeWidget::selectedCrsId()
455 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
457 if ( item && !item->text( QgisCrsIdColumn ).isEmpty() )
458 return lstCoordinateSystems->currentItem()->text( QgisCrsIdColumn ).toLong();
466 mCrsFilter = crsFilter;
467 mProjListDone =
false;
468 mUserProjListDone =
false;
469 lstCoordinateSystems->clear();
472 void QgsProjectionSelectionTreeWidget::loadUserCrsList( QSet<QString> *crsFilter )
474 if ( mUserProjListDone )
477 QgsDebugMsgLevel( QStringLiteral(
"Fetching user projection list..." ), 4 );
481 mUserProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"User Defined Coordinate Systems" ) ) );
482 mUserProjList->setFlags( mUserProjList->flags() & ~Qt::ItemIsSelectable );
484 QFont fontTemp = mUserProjList->font( 0 );
485 fontTemp.setItalic(
true );
486 fontTemp.setBold(
true );
487 mUserProjList->setFont( 0, fontTemp );
493 const QString authid = QStringLiteral(
"USER:%1" ).arg( details.id );
494 if ( crsFilter && !crsFilter->isEmpty() && !crsFilter->contains( authid ) && !crsFilter->contains( authid.toLower() ) )
497 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mUserProjList, QStringList() << details.name );
498 newItem->setText( QgisCrsIdColumn, QString::number( details.id ) );
499 newItem->setText( AuthidColumn, authid );
502 mUserProjListDone =
true;
505 void QgsProjectionSelectionTreeWidget::loadCrsList( QSet<QString> *crsFilter )
511 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
517 mGeoList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Geographic Coordinate Systems" ) ) );
518 mGeoList->setFlags( mGeoList->flags() & ~Qt::ItemIsSelectable );
520 QFont fontTemp = mGeoList->font( 0 );
521 fontTemp.setItalic(
true );
522 fontTemp.setBold(
true );
523 mGeoList->setFont( 0, fontTemp );
527 mProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Projected Coordinate Systems" ) ) );
528 mProjList->setFlags( mProjList->flags() & ~Qt::ItemIsSelectable );
530 fontTemp = mProjList->font( 0 );
531 fontTemp.setItalic(
true );
532 fontTemp.setBold(
true );
533 mProjList->setFont( 0, fontTemp );
541 if ( !QFileInfo::exists( mSrsDatabaseFileName ) )
543 mProjListDone =
true;
549 int rc = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
554 showDBMissingWarning( mSrsDatabaseFileName );
558 const char *tail =
nullptr;
559 sqlite3_stmt *stmt =
nullptr;
563 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" )
566 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
568 if ( rc == SQLITE_OK )
570 QTreeWidgetItem *newItem =
nullptr;
573 QString previousSrsType;
574 QTreeWidgetItem *previousSrsTypeNode =
nullptr;
576 while ( sqlite3_step( stmt ) == SQLITE_ROW )
579 int isGeo = sqlite3_column_int( stmt, 3 );
584 newItem =
new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) ) ) );
587 newItem->setText( AuthidColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 2 ) ) );
590 newItem->setText( QgisCrsIdColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 1 ) ) );
595 QTreeWidgetItem *node =
nullptr;
596 QString srsType = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 4 ) );
597 if ( srsType.isEmpty() )
598 srsType = tr(
"Other" );
602 if ( srsType == previousSrsType )
604 node = previousSrsTypeNode;
609 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NameColumn );
610 if ( nodes.isEmpty() )
614 node =
new QTreeWidgetItem( mProjList, QStringList( srsType ) );
615 node->setFlags( node->flags() & ~Qt::ItemIsSelectable );
617 QFont fontTemp = node->font( 0 );
618 fontTemp.setItalic(
true );
619 node->setFont( 0, fontTemp );
623 node = nodes.first();
626 previousSrsType = srsType;
627 previousSrsTypeNode = node;
630 newItem =
new QTreeWidgetItem( node, QStringList( QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) ) ) );
632 newItem->setText( AuthidColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 2 ) ) );
634 newItem->setText( QgisCrsIdColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 1 ) ) );
636 newItem->parent()->setExpanded(
true );
640 newItem->setData( 0, RoleDeprecated, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 6 ) ) );
641 newItem->setHidden( cbxHideDeprecated->isChecked() );
643 mProjList->setExpanded(
true );
647 sqlite3_finalize( stmt );
649 sqlite3_close( database );
651 mProjListDone =
true;
658 mUnknownList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Custom Coordinate Systems" ) ) );
659 mUnknownList->setFlags( mUnknownList->flags() & ~Qt::ItemIsSelectable );
661 QFont fontTemp = mUnknownList->font( 0 );
662 fontTemp.setItalic(
true );
663 fontTemp.setBold(
true );
664 mUnknownList->setFont( 0, fontTemp );
668 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mUnknownList, QStringList(
crs.
description().isEmpty() ? QObject::tr(
"Custom CRS" ) :
crs.
description() ) );
670 newItem->setData( 0, RoleProj,
crs.
toProj() );
672 lstCoordinateSystems->setCurrentItem( newItem );
676 void QgsProjectionSelectionTreeWidget::lstCoordinateSystems_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
686 lstCoordinateSystems->scrollToItem( current );
690 if ( current->childCount() == 0 )
693 if ( !mBlockSignals )
699 updateBoundsPreview();
701 const QString crsId = current->text( QgisCrsIdColumn );
702 if ( !crsId.isEmpty() )
704 QList<QTreeWidgetItem *> nodes = lstRecent->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly, QgisCrsIdColumn );
705 if ( !nodes.isEmpty() )
707 QgsDebugMsgLevel( QStringLiteral(
"found srs %1 in recent" ).arg( current->text( QgisCrsIdColumn ) ), 4 );
708 lstRecent->setCurrentItem( nodes.first() );
712 QgsDebugMsgLevel( QStringLiteral(
"srs %1 not recent" ).arg( current->text( QgisCrsIdColumn ) ), 4 );
713 lstRecent->clearSelection();
714 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
719 lstRecent->clearSelection();
720 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
726 current->setSelected(
false );
727 teProjection->clear();
728 lstRecent->clearSelection();
733 void QgsProjectionSelectionTreeWidget::lstCoordinateSystems_itemDoubleClicked( QTreeWidgetItem *current,
int column )
747 if ( current->childCount() == 0 )
751 void QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
761 lstRecent->scrollToItem( current );
763 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
764 if ( !nodes.isEmpty() )
765 lstCoordinateSystems->setCurrentItem( nodes.first() );
768 void QgsProjectionSelectionTreeWidget::lstRecent_itemDoubleClicked( QTreeWidgetItem *current,
int column )
780 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
781 if ( !nodes.isEmpty() )
785 void QgsProjectionSelectionTreeWidget::updateFilter()
788 filterTxtCopy.replace( QRegularExpression(
"\\s+" ), QStringLiteral(
".*" ) );
789 const QRegularExpression re( filterTxtCopy, QRegularExpression::PatternOption::CaseInsensitiveOption );
791 const bool hideDeprecated = cbxHideDeprecated->isChecked();
793 auto filterTreeWidget = [ = ]( QTreeWidget * tree )
795 QTreeWidgetItemIterator itr( tree );
798 if ( ( *itr )->childCount() == 0 )
800 if ( hideDeprecated && ( *itr )->data( 0, RoleDeprecated ).toBool() )
802 ( *itr )->setHidden(
true );
803 if ( ( *itr )->isSelected() )
805 ( *itr )->setSelected(
false );
806 teProjection->clear();
809 else if ( ( *itr )->text( NameColumn ).contains( re )
810 || ( *itr )->text( AuthidColumn ).contains( re )
813 ( *itr )->setHidden(
false );
814 QTreeWidgetItem *parent = ( *itr )->parent();
817 parent->setExpanded(
true );
818 parent->setHidden(
false );
819 parent = parent->parent();
824 ( *itr )->setHidden(
true );
829 ( *itr )->setHidden(
true );
836 filterTreeWidget( lstRecent );
839 filterTreeWidget( lstCoordinateSystems );
846 long QgsProjectionSelectionTreeWidget::getLargestCrsIdMatch(
const QString &sql )
855 const char *tail =
nullptr;
856 sqlite3_stmt *stmt =
nullptr;
863 if ( QFileInfo::exists( databaseFileName ) )
865 result = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
872 showDBMissingWarning( databaseFileName );
876 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
878 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
880 QString srsIdString = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
881 srsId = srsIdString.toLong();
883 sqlite3_finalize( stmt );
884 sqlite3_close( database );
891 result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
894 QgsDebugMsg( QStringLiteral(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
900 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
902 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
904 QString srsIdString = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
905 srsId = srsIdString.toLong();
909 sqlite3_finalize( stmt );
910 sqlite3_close( database );
915 void QgsProjectionSelectionTreeWidget::updateBoundsPreview()
917 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
918 if ( !lvi || ( lvi->text( QgisCrsIdColumn ).isEmpty() && !lvi->data( 0, RoleWkt ).isValid() ) )
926 QString extentString = tr(
"Extent not known" );
927 mAreaCanvas->setPreviewRect( rect );
930 extentString = QStringLiteral(
"%1, %2, %3, %4" )
937 QStringList properties;
939 properties << tr(
"Geographic (uses latitude and longitude for coordinates)" );
944 properties << ( currentCrs.
isDynamic() ? tr(
"Dynamic (relies on a datum which is not plate-fixed)" ) : tr(
"Static (relies on a datum which is plate-fixed)" ) );
949 if ( !celestialBody.isEmpty() )
951 properties << tr(
"Celestial body: %1" ).arg( celestialBody );
965 if ( !ensemble.
code().isEmpty() )
966 id = QStringLiteral(
"<i>%1</i> (%2:%3)" ).arg( ensemble.
name(), ensemble.
authority(), ensemble.
code() );
968 id = QStringLiteral(
"<i>%</i>”" ).arg( ensemble.
name() );
971 properties << tr(
"Based on %1, which has a limited accuracy of <b>at best %2 meters</b>." ).arg(
id ).arg( ensemble.
accuracy() );
975 properties << tr(
"Based on %1, which has a limited accuracy." ).arg(
id );
985 properties << tr(
"Method: %1" ).arg( operation.
description() );
987 const QString propertiesString = QStringLiteral(
"<dt><b>%1</b></dt><dd><ul><li>%2</li></ul></dd>" ).arg( tr(
"Properties" ),
988 properties.join( QLatin1String(
"</li><li>" ) ) );
990 const QString extentHtml = QStringLiteral(
"<dt><b>%1</b></dt><dd>%2</dd>" ).arg( tr(
"Extent" ), extentString );
991 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(
" " ) ) );
992 const QString proj4String = QStringLiteral(
"<dt><b>%1</b></dt><dd><code>%2</code></dd>" ).arg( tr(
"Proj4" ), currentCrs.
toProj() );
995 const int smallerPointSize = std::max( font().pointSize() - 1, 8 );
997 const int smallerPointSize = std::max( font().pointSize() - 2, 6 );
1000 teProjection->setText( QStringLiteral(
"<div style=\"font-size: %1pt\"><h3>%2</h3><dl>" ).arg( smallerPointSize ).arg( selectedName() ) + propertiesString + wktString + proj4String + extentHtml + QStringLiteral(
"</dl></div>" ) );
1003 QStringList QgsProjectionSelectionTreeWidget::authorities()
1006 const char *tail =
nullptr;
1007 sqlite3_stmt *stmt =
nullptr;
1009 int result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
1012 QgsDebugMsg( QStringLiteral(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
1014 return QStringList();
1017 QString sql = QStringLiteral(
"select distinct auth_name from tbl_srs" );
1018 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
1020 QStringList authorities;
1021 if ( result == SQLITE_OK )
1023 while ( sqlite3_step( stmt ) == SQLITE_ROW )
1025 authorities << QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
1031 sqlite3_finalize( stmt );
1032 sqlite3_close( database );
1037 QString QgsProjectionSelectionTreeWidget::sqlSafeString(
const QString &theSQL )
const
1039 QString retval = theSQL;
1040 retval.replace(
'\\', QLatin1String(
"\\\\" ) );
1041 retval.replace(
'\"', QLatin1String(
"\\\"" ) );
1042 retval.replace(
'\'', QLatin1String(
"\\'" ) );
1043 retval.replace(
'%', QLatin1String(
"\\%" ) );
1047 void QgsProjectionSelectionTreeWidget::showDBMissingWarning(
const QString &fileName )
1050 QMessageBox::critical(
this, tr(
"Resource Location Error" ),
1051 tr(
"Error reading database file from: \n %1\n"
1052 "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.
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.
@ 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.
This class is a composition of two QSettings instances:
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QString qRegExpEscape(const QString &string)
Returns an escaped string matching the behavior of QRegExp::escape.
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