33#include <QResizeEvent>
35#include <QRegularExpression>
42 QFont f = teProjection->font();
43 f.setPointSize( f.pointSize() - 2 );
44 teProjection->setFont( f );
46 leSearch->setShowSearchIcon(
true );
48 connect( lstCoordinateSystems, &QTreeWidget::itemDoubleClicked,
this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystems_itemDoubleClicked );
49 connect( lstRecent, &QTreeWidget::itemDoubleClicked,
this, &QgsProjectionSelectionTreeWidget::lstRecent_itemDoubleClicked );
50 connect( lstCoordinateSystems, &QTreeWidget::currentItemChanged,
this, &QgsProjectionSelectionTreeWidget::lstCoordinateSystems_currentItemChanged );
51 connect( lstRecent, &QTreeWidget::currentItemChanged,
this, &QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged );
52 connect( cbxHideDeprecated, &QCheckBox::stateChanged,
this, &QgsProjectionSelectionTreeWidget::updateFilter );
53 connect( leSearch, &QgsFilterLineEdit::textChanged,
this, &QgsProjectionSelectionTreeWidget::updateFilter );
55 mAreaCanvas->setVisible( mShowMap );
60 lstCoordinateSystems->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
61 lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
62 lstCoordinateSystems->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
65 lstCoordinateSystems->setColumnHidden( QgisCrsIdColumn,
true );
67 lstRecent->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
68 lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
69 lstRecent->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
72 lstRecent->setColumnHidden( QgisCrsIdColumn,
true );
76 mCheckBoxNoProjection->setHidden(
true );
77 mCheckBoxNoProjection->setEnabled(
false );
78 connect( mCheckBoxNoProjection, &QCheckBox::toggled,
this, [ = ]
86 connect( mCheckBoxNoProjection, &QCheckBox::toggled,
this, [ = ](
bool checked )
88 if ( mCheckBoxNoProjection->isEnabled() )
90 mFrameProjections->setDisabled( checked );
95 mSplitter->restoreState( settings.value( QStringLiteral(
"Windows/ProjectionSelector/splitterState" ) ).toByteArray() );
101 settings.
setValue( QStringLiteral(
"Windows/ProjectionSelector/splitterState" ), mSplitter->saveState() );
111 lstCoordinateSystems->header()->resizeSection( NameColumn, event->size().width() - 240 );
112 lstCoordinateSystems->header()->resizeSection( AuthidColumn, 240 );
113 lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
115 lstRecent->header()->resizeSection( NameColumn, event->size().width() - 240 );
116 lstRecent->header()->resizeSection( AuthidColumn, 240 );
117 lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
127 loadCrsList( &mCrsFilter );
128 loadUserCrsList( &mCrsFilter );
130 if ( !mRecentProjListDone )
134 mRecentProjListDone =
true;
138 mBlockSignals =
true;
140 mBlockSignals =
false;
145 QWidget::showEvent( event );
149QString QgsProjectionSelectionTreeWidget::ogcWmsCrsFilterAsSqlExpression( QSet<QString> *crsFilter )
151 QString sqlExpression = QStringLiteral(
"1" );
152 QMap<QString, QStringList> authParts;
155 return sqlExpression;
175 const auto authIds { *crsFilter };
176 for (
const QString &auth_id : authIds )
178 QStringList parts = auth_id.split(
':' );
180 if ( parts.size() < 2 )
183 authParts[ parts.at( 0 ).toUpper()].append( parts.at( 1 ).toUpper() );
186 if ( authParts.isEmpty() )
187 return sqlExpression;
189 if ( !authParts.isEmpty() )
191 QString prefix = QStringLiteral(
" AND (" );
192 for (
auto it = authParts.constBegin(); it != authParts.constEnd(); ++it )
194 sqlExpression += QStringLiteral(
"%1(upper(auth_name)='%2' AND upper(auth_id) IN ('%3'))" )
197 it.value().join( QLatin1String(
"','" ) ) );
198 prefix = QStringLiteral(
" OR " );
200 sqlExpression +=
')';
205 return sqlExpression;
208void QgsProjectionSelectionTreeWidget::applySelection(
int column, QString value )
210 if ( !mProjListDone || !mUserProjListDone )
213 mSearchColumn = column;
214 mSearchValue = value;
218 if ( column == QgsProjectionSelectionTreeWidget::None )
221 column = mSearchColumn;
222 value = mSearchValue;
224 mSearchColumn = QgsProjectionSelectionTreeWidget::None;
225 mSearchValue.clear();
228 if ( column == QgsProjectionSelectionTreeWidget::None )
231 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( value, Qt::MatchExactly | Qt::MatchRecursive, column );
232 if ( !nodes.isEmpty() )
234 QgsDebugMsgLevel( QStringLiteral(
"found %1,%2" ).arg( column ).arg( value ), 4 );
235 lstCoordinateSystems->setCurrentItem( nodes.first() );
239 QgsDebugMsgLevel( QStringLiteral(
"nothing found for %1,%2" ).arg( column ).arg( value ), 4 );
241 lstCoordinateSystems->clearSelection();
242 lstRecent->clearSelection();
243 teProjection->clear();
249 if ( !mProjListDone || !mUserProjListDone )
252 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( QString::number(
crs.
srsid() ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
253 if ( nodes.isEmpty() )
256 lstRecent->insertTopLevelItem( 0,
new QTreeWidgetItem( lstRecent, QStringList()
257 << nodes.first()->text( NameColumn )
258 << nodes.first()->text( AuthidColumn )
259 << nodes.first()->text( QgisCrsIdColumn ) ) );
263QString QgsProjectionSelectionTreeWidget::selectedName()
266 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
267 return lvi ? lvi->text( NameColumn ) : QString();
274 mCheckBoxNoProjection->setChecked(
true );
278 bool changed =
false;
281 changed = mDeferredLoadCrs !=
crs;
282 mDeferredLoadCrs =
crs;
284 mBlockSignals =
true;
285 mCheckBoxNoProjection->setChecked(
false );
286 mBlockSignals =
false;
289 applySelection( AuthidColumn,
crs.
authid() );
291 loadUnknownCrs(
crs );
302 mAreaCanvas->setCanvasRect( rect );
307 return mAreaCanvas->canvasRect();
310QString QgsProjectionSelectionTreeWidget::getSelectedExpression(
const QString &expression )
const
319 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
320 if ( !lvi || lvi->text( QgisCrsIdColumn ).isEmpty() )
327 QString databaseFileName;
331 if ( !QFileInfo::exists( databaseFileName ) )
338 databaseFileName = mSrsDatabaseFileName;
347 int rc = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
351 "Because of this the projection selector will not work…" ).arg( databaseFileName ),
352 Qgis::MessageLevel::Critical );
357 const char *tail =
nullptr;
358 sqlite3_stmt *stmt =
nullptr;
359 QString sql = QStringLiteral(
"select %1 from tbl_srs where srs_id=%2" )
361 lvi->text( QgisCrsIdColumn ) );
363 QgsDebugMsgLevel( QStringLiteral(
"Finding selected attribute using : %1" ).arg( sql ), 4 );
364 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
366 QString attributeValue;
367 if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
370 attributeValue = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
374 sqlite3_finalize( stmt );
376 sqlite3_close( database );
379 return attributeValue;
384 if ( mCheckBoxNoProjection->isEnabled() && mCheckBoxNoProjection->isChecked() )
387 if ( !mInitialized && mDeferredLoadCrs.
isValid() )
388 return mDeferredLoadCrs;
390 const QString srsIdString = getSelectedExpression( QStringLiteral(
"srs_id" ) );
391 if ( !srsIdString.isEmpty() )
393 int srid = srsIdString.toLong();
402 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
403 if ( lvi && lvi->data( 0, RoleWkt ).isValid() )
405 else if ( lvi && lvi->data( 0, RoleProj ).isValid() )
414 mCheckBoxNoProjection->setVisible( show );
415 mCheckBoxNoProjection->setEnabled( show );
418 mFrameProjections->setDisabled( mCheckBoxNoProjection->isChecked() );
425 mAreaCanvas->setVisible( show );
430 return !mCheckBoxNoProjection->isHidden();
435 mCheckBoxNoProjection->setText( text );
445 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
446 if ( mCheckBoxNoProjection->isChecked() )
448 else if ( !mInitialized && mDeferredLoadCrs.
isValid() )
451 return item && ( !item->text( QgisCrsIdColumn ).isEmpty() || item->data( 0, RoleWkt ).isValid() );
454long QgsProjectionSelectionTreeWidget::selectedCrsId()
456 QTreeWidgetItem *item = lstCoordinateSystems->currentItem();
458 if ( item && !item->text( QgisCrsIdColumn ).isEmpty() )
459 return lstCoordinateSystems->currentItem()->text( QgisCrsIdColumn ).toLong();
467 mCrsFilter = crsFilter;
468 mProjListDone =
false;
469 mUserProjListDone =
false;
470 lstCoordinateSystems->clear();
473void QgsProjectionSelectionTreeWidget::loadUserCrsList( QSet<QString> *crsFilter )
475 if ( mUserProjListDone )
478 QgsDebugMsgLevel( QStringLiteral(
"Fetching user projection list..." ), 4 );
482 mUserProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"User Defined Coordinate Systems" ) ) );
483 mUserProjList->setFlags( mUserProjList->flags() & ~Qt::ItemIsSelectable );
485 QFont fontTemp = mUserProjList->font( 0 );
486 fontTemp.setItalic(
true );
487 fontTemp.setBold(
true );
488 mUserProjList->setFont( 0, fontTemp );
494 const QString authid = QStringLiteral(
"USER:%1" ).arg( details.id );
495 if ( crsFilter && !crsFilter->isEmpty() && !crsFilter->contains( authid ) && !crsFilter->contains( authid.toLower() ) )
498 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mUserProjList, QStringList() << details.name );
499 newItem->setText( QgisCrsIdColumn, QString::number( details.id ) );
500 newItem->setText( AuthidColumn, authid );
503 mUserProjListDone =
true;
506void QgsProjectionSelectionTreeWidget::loadCrsList( QSet<QString> *crsFilter )
512 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
518 mGeoList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Geographic Coordinate Systems" ) ) );
519 mGeoList->setFlags( mGeoList->flags() & ~Qt::ItemIsSelectable );
521 QFont fontTemp = mGeoList->font( 0 );
522 fontTemp.setItalic(
true );
523 fontTemp.setBold(
true );
524 mGeoList->setFont( 0, fontTemp );
528 mProjList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Projected Coordinate Systems" ) ) );
529 mProjList->setFlags( mProjList->flags() & ~Qt::ItemIsSelectable );
531 fontTemp = mProjList->font( 0 );
532 fontTemp.setItalic(
true );
533 fontTemp.setBold(
true );
534 mProjList->setFont( 0, fontTemp );
542 if ( !QFileInfo::exists( mSrsDatabaseFileName ) )
544 mProjListDone =
true;
550 int rc = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
555 showDBMissingWarning( mSrsDatabaseFileName );
559 const char *tail =
nullptr;
560 sqlite3_stmt *stmt =
nullptr;
564 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" )
567 rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
569 if ( rc == SQLITE_OK )
571 QTreeWidgetItem *newItem =
nullptr;
574 QString previousSrsType;
575 QTreeWidgetItem *previousSrsTypeNode =
nullptr;
577 while ( sqlite3_step( stmt ) == SQLITE_ROW )
580 int isGeo = sqlite3_column_int( stmt, 3 );
585 newItem =
new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) ) ) );
588 newItem->setText( AuthidColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 2 ) ) );
591 newItem->setText( QgisCrsIdColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 1 ) ) );
596 QTreeWidgetItem *node =
nullptr;
597 QString srsType = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 4 ) );
598 if ( srsType.isEmpty() )
599 srsType = tr(
"Other" );
603 if ( srsType == previousSrsType )
605 node = previousSrsTypeNode;
610 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NameColumn );
611 if ( nodes.isEmpty() )
615 node =
new QTreeWidgetItem( mProjList, QStringList( srsType ) );
616 node->setFlags( node->flags() & ~Qt::ItemIsSelectable );
618 QFont fontTemp = node->font( 0 );
619 fontTemp.setItalic(
true );
620 node->setFont( 0, fontTemp );
624 node = nodes.first();
627 previousSrsType = srsType;
628 previousSrsTypeNode = node;
631 newItem =
new QTreeWidgetItem( node, QStringList( QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) ) ) );
633 newItem->setText( AuthidColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 2 ) ) );
635 newItem->setText( QgisCrsIdColumn, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 1 ) ) );
637 newItem->parent()->setExpanded(
true );
641 newItem->setData( 0, RoleDeprecated, QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 6 ) ) );
642 newItem->setHidden( cbxHideDeprecated->isChecked() );
644 mProjList->setExpanded(
true );
648 sqlite3_finalize( stmt );
650 sqlite3_close( database );
652 mProjListDone =
true;
659 mUnknownList =
new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr(
"Custom Coordinate Systems" ) ) );
660 mUnknownList->setFlags( mUnknownList->flags() & ~Qt::ItemIsSelectable );
662 QFont fontTemp = mUnknownList->font( 0 );
663 fontTemp.setItalic(
true );
664 fontTemp.setBold(
true );
665 mUnknownList->setFont( 0, fontTemp );
669 QTreeWidgetItem *newItem =
new QTreeWidgetItem( mUnknownList, QStringList(
crs.
description().isEmpty() ? QObject::tr(
"Custom CRS" ) :
crs.
description() ) );
671 newItem->setData( 0, RoleProj,
crs.
toProj() );
673 lstCoordinateSystems->setCurrentItem( newItem );
677void QgsProjectionSelectionTreeWidget::lstCoordinateSystems_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
687 lstCoordinateSystems->scrollToItem( current );
691 if ( current->childCount() == 0 )
694 if ( !mBlockSignals )
700 updateBoundsPreview();
702 const QString crsId = current->text( QgisCrsIdColumn );
703 if ( !crsId.isEmpty() )
705 QList<QTreeWidgetItem *> nodes = lstRecent->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly, QgisCrsIdColumn );
706 if ( !nodes.isEmpty() )
708 QgsDebugMsgLevel( QStringLiteral(
"found srs %1 in recent" ).arg( current->text( QgisCrsIdColumn ) ), 4 );
709 lstRecent->setCurrentItem( nodes.first() );
713 QgsDebugMsgLevel( QStringLiteral(
"srs %1 not recent" ).arg( current->text( QgisCrsIdColumn ) ), 4 );
714 lstRecent->clearSelection();
715 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
720 lstRecent->clearSelection();
721 lstCoordinateSystems->setFocus( Qt::OtherFocusReason );
727 current->setSelected(
false );
728 teProjection->clear();
729 lstRecent->clearSelection();
734void QgsProjectionSelectionTreeWidget::lstCoordinateSystems_itemDoubleClicked( QTreeWidgetItem *current,
int column )
748 if ( current->childCount() == 0 )
752void QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem * )
762 lstRecent->scrollToItem( current );
764 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
765 if ( !nodes.isEmpty() )
766 lstCoordinateSystems->setCurrentItem( nodes.first() );
769void QgsProjectionSelectionTreeWidget::lstRecent_itemDoubleClicked( QTreeWidgetItem *current,
int column )
781 QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( current->text( QgisCrsIdColumn ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
782 if ( !nodes.isEmpty() )
786void QgsProjectionSelectionTreeWidget::updateFilter()
789 filterTxtCopy.replace( QRegularExpression(
"\\s+" ), QStringLiteral(
".*" ) );
790 const QRegularExpression re( filterTxtCopy, QRegularExpression::PatternOption::CaseInsensitiveOption );
792 const bool hideDeprecated = cbxHideDeprecated->isChecked();
794 auto filterTreeWidget = [ = ]( QTreeWidget * tree )
796 QTreeWidgetItemIterator itr( tree );
799 if ( ( *itr )->childCount() == 0 )
801 if ( hideDeprecated && ( *itr )->data( 0, RoleDeprecated ).toBool() )
803 ( *itr )->setHidden(
true );
804 if ( ( *itr )->isSelected() )
806 ( *itr )->setSelected(
false );
807 teProjection->clear();
810 else if ( ( *itr )->text( NameColumn ).contains( re )
811 || ( *itr )->text( AuthidColumn ).contains( re )
814 ( *itr )->setHidden(
false );
815 QTreeWidgetItem *parent = ( *itr )->parent();
818 parent->setExpanded(
true );
819 parent->setHidden(
false );
820 parent = parent->parent();
825 ( *itr )->setHidden(
true );
830 ( *itr )->setHidden(
true );
837 filterTreeWidget( lstRecent );
840 filterTreeWidget( lstCoordinateSystems );
847long QgsProjectionSelectionTreeWidget::getLargestCrsIdMatch(
const QString &sql )
856 const char *tail =
nullptr;
857 sqlite3_stmt *stmt =
nullptr;
864 if ( QFileInfo::exists( databaseFileName ) )
866 result = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
873 showDBMissingWarning( databaseFileName );
877 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
879 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
881 QString srsIdString = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
882 srsId = srsIdString.toLong();
884 sqlite3_finalize( stmt );
885 sqlite3_close( database );
892 result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
895 QgsDebugMsg( QStringLiteral(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
901 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
903 if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW )
905 QString srsIdString = QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
906 srsId = srsIdString.toLong();
910 sqlite3_finalize( stmt );
911 sqlite3_close( database );
916void QgsProjectionSelectionTreeWidget::updateBoundsPreview()
918 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
919 if ( !lvi || ( lvi->text( QgisCrsIdColumn ).isEmpty() && !lvi->data( 0, RoleWkt ).isValid() ) )
927 QString extentString = tr(
"Extent not known" );
928 mAreaCanvas->setPreviewRect( rect );
931 extentString = QStringLiteral(
"%1, %2, %3, %4" )
938 QStringList properties;
940 properties << tr(
"Geographic (uses latitude and longitude for coordinates)" );
945 properties << ( currentCrs.
isDynamic() ? tr(
"Dynamic (relies on a datum which is not plate-fixed)" ) : tr(
"Static (relies on a datum which is plate-fixed)" ) );
950 if ( !celestialBody.isEmpty() )
952 properties << tr(
"Celestial body: %1" ).arg( celestialBody );
966 if ( !ensemble.
code().isEmpty() )
967 id = QStringLiteral(
"<i>%1</i> (%2:%3)" ).arg( ensemble.
name(), ensemble.
authority(), ensemble.
code() );
969 id = QStringLiteral(
"<i>%</i>”" ).arg( ensemble.
name() );
972 properties << tr(
"Based on %1, which has a limited accuracy of <b>at best %2 meters</b>." ).arg(
id ).arg( ensemble.
accuracy() );
976 properties << tr(
"Based on %1, which has a limited accuracy." ).arg(
id );
986 properties << tr(
"Method: %1" ).arg( operation.
description() );
988 const QString propertiesString = QStringLiteral(
"<dt><b>%1</b></dt><dd><ul><li>%2</li></ul></dd>" ).arg( tr(
"Properties" ),
989 properties.join( QLatin1String(
"</li><li>" ) ) );
991 const QString extentHtml = QStringLiteral(
"<dt><b>%1</b></dt><dd>%2</dd>" ).arg( tr(
"Extent" ), extentString );
992 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(
" " ) ) );
993 const QString proj4String = QStringLiteral(
"<dt><b>%1</b></dt><dd><code>%2</code></dd>" ).arg( tr(
"Proj4" ), currentCrs.
toProj() );
996 const int smallerPointSize = std::max( font().pointSize() - 1, 8 );
998 const int smallerPointSize = std::max( font().pointSize() - 2, 6 );
1001 teProjection->setText( QStringLiteral(
"<div style=\"font-size: %1pt\"><h3>%2</h3><dl>" ).arg( smallerPointSize ).arg( selectedName() ) + propertiesString + wktString + proj4String + extentHtml + QStringLiteral(
"</dl></div>" ) );
1004QStringList QgsProjectionSelectionTreeWidget::authorities()
1007 const char *tail =
nullptr;
1008 sqlite3_stmt *stmt =
nullptr;
1010 int result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY,
nullptr );
1013 QgsDebugMsg( QStringLiteral(
"Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
1015 return QStringList();
1018 QString sql = QStringLiteral(
"select distinct auth_name from tbl_srs" );
1019 result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
1021 QStringList authorities;
1022 if ( result == SQLITE_OK )
1024 while ( sqlite3_step( stmt ) == SQLITE_ROW )
1026 authorities << QString::fromUtf8( (
char * )sqlite3_column_text( stmt, 0 ) );
1032 sqlite3_finalize( stmt );
1033 sqlite3_close( database );
1038QString QgsProjectionSelectionTreeWidget::sqlSafeString(
const QString &theSQL )
const
1040 QString retval = theSQL;
1041 retval.replace(
'\\', QLatin1String(
"\\\\" ) );
1042 retval.replace(
'\"', QLatin1String(
"\\\"" ) );
1043 retval.replace(
'\'', QLatin1String(
"\\'" ) );
1044 retval.replace(
'%', QLatin1String(
"\\%" ) );
1048void QgsProjectionSelectionTreeWidget::showDBMissingWarning(
const QString &fileName )
1051 QMessageBox::critical(
this, tr(
"Resource Location Error" ),
1052 tr(
"Error reading database file from: \n %1\n"
1053 "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.
Q_GADGET Qgis::DistanceUnit mapUnits
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,...
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(Qgis::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