QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgscoordinatereferencesystemmodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscoordinatereferencesystemmodel.h
3 -------------------
4 begin : July 2023
5 copyright : (C) 2023 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 ***************************************************************************/
19#include "qgsapplication.h"
20
21#include <QFont>
22
24 : QAbstractItemModel( parent )
25 , mRootNode( std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( QString(), QIcon(), QString() ) )
26{
28
29 rebuild();
30
31 connect( QgsApplication::coordinateReferenceSystemRegistry(), &QgsCoordinateReferenceSystemRegistry::userCrsAdded, this, &QgsCoordinateReferenceSystemModel::userCrsAdded );
32 connect( QgsApplication::coordinateReferenceSystemRegistry(), &QgsCoordinateReferenceSystemRegistry::userCrsRemoved, this, &QgsCoordinateReferenceSystemModel::userCrsRemoved );
33 connect( QgsApplication::coordinateReferenceSystemRegistry(), &QgsCoordinateReferenceSystemRegistry::userCrsChanged, this, &QgsCoordinateReferenceSystemModel::userCrsChanged );
34}
35
36Qt::ItemFlags QgsCoordinateReferenceSystemModel::flags( const QModelIndex &index ) const
37{
38 if ( !index.isValid() )
39 {
40 return Qt::ItemFlags();
41 }
42
43 QgsCoordinateReferenceSystemModelNode *n = index2node( index );
44 if ( !n )
45 return Qt::ItemFlags();
46
47 switch ( n->nodeType() )
48 {
49 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
50 return index.column() == 0 ? Qt::ItemIsEnabled : Qt::ItemFlags();
51 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
52 return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
53 }
55}
56
57QVariant QgsCoordinateReferenceSystemModel::data( const QModelIndex &index, int role ) const
58{
59 if ( !index.isValid() )
60 return QVariant();
61
62 QgsCoordinateReferenceSystemModelNode *n = index2node( index );
63 if ( !n )
64 return QVariant();
65
66 if ( role == static_cast< int >( CustomRole::NodeType ) )
67 return n->nodeType();
68
69 switch ( n->nodeType() )
70 {
71 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
72 {
73 QgsCoordinateReferenceSystemModelGroupNode *groupNode = qgis::down_cast< QgsCoordinateReferenceSystemModelGroupNode * >( n );
74 switch ( role )
75 {
76 case Qt::DecorationRole:
77 switch ( index.column() )
78 {
79 case 0:
80 return groupNode->icon();
81 default:
82 break;
83 }
84 break;
85
86 case Qt::DisplayRole:
87 case Qt::ToolTipRole:
88 switch ( index.column() )
89 {
90 case 0:
91 return groupNode->name();
92
93 default:
94 break;
95 }
96 break;
97
98 case Qt::FontRole:
99 {
100 QFont font;
101 font.setItalic( true );
102 if ( groupNode->parent() == mRootNode.get() )
103 {
104 font.setBold( true );
105 }
106 return font;
107 }
108
109 case static_cast< int >( CustomRole::GroupId ):
110 return groupNode->id();
111 }
112 return QVariant();
113
114 }
115 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
116 {
117 QgsCoordinateReferenceSystemModelCrsNode *crsNode = qgis::down_cast< QgsCoordinateReferenceSystemModelCrsNode * >( n );
118 switch ( role )
119 {
120 case Qt::DisplayRole:
121 case Qt::ToolTipRole:
122 switch ( index.column() )
123 {
124 case 0:
125 return crsNode->record().description;
126
127 case 1:
128 {
129 if ( crsNode->record().authName == QLatin1String( "CUSTOM" ) )
130 return QString();
131 return QStringLiteral( "%1:%2" ).arg( crsNode->record().authName, crsNode->record().authId );
132 }
133
134 default:
135 break;
136 }
137 break;
138
139 case static_cast< int >( CustomRole::Name ):
140 return crsNode->record().description;
141
142 case static_cast< int >( CustomRole::AuthId ):
143 if ( !crsNode->record().authId.isEmpty() )
144 return QStringLiteral( "%1:%2" ).arg( crsNode->record().authName, crsNode->record().authId );
145 else
146 return QVariant();
147
148 case static_cast< int >( CustomRole::Deprecated ):
149 return crsNode->record().deprecated;
150
151 case static_cast< int >( CustomRole::Type ):
152 return QVariant::fromValue( crsNode->record().type );
153
154 case static_cast< int >( CustomRole::Wkt ):
155 return crsNode->wkt();
156
157 case static_cast< int >( CustomRole::Proj ):
158 return crsNode->proj();
159
160 default:
161 break;
162
163 }
164 }
165 }
166 return QVariant();
167}
168
169QVariant QgsCoordinateReferenceSystemModel::headerData( int section, Qt::Orientation orientation, int role ) const
170{
171 if ( orientation == Qt::Horizontal )
172 {
173 switch ( role )
174 {
175 case Qt::DisplayRole:
176 switch ( section )
177 {
178 case 0:
179 return tr( "Coordinate Reference System" );
180 case 1:
181 return tr( "Authority ID" );
182 default:
183 break;
184 }
185 break;
186
187 default:
188 break;
189 }
190 }
191 return QVariant();
192}
193
194int QgsCoordinateReferenceSystemModel::rowCount( const QModelIndex &parent ) const
195{
196 QgsCoordinateReferenceSystemModelNode *n = index2node( parent );
197 if ( !n )
198 return 0;
199
200 return n->children().count();
201}
202
204{
205 return 2;
206}
207
208QModelIndex QgsCoordinateReferenceSystemModel::index( int row, int column, const QModelIndex &parent ) const
209{
210 if ( !hasIndex( row, column, parent ) )
211 return QModelIndex();
212
213 QgsCoordinateReferenceSystemModelNode *n = index2node( parent );
214 if ( !n )
215 return QModelIndex(); // have no children
216
217 return createIndex( row, column, n->children().at( row ) );
218}
219
220QModelIndex QgsCoordinateReferenceSystemModel::parent( const QModelIndex &child ) const
221{
222 if ( !child.isValid() )
223 return QModelIndex();
224
225 if ( QgsCoordinateReferenceSystemModelNode *n = index2node( child ) )
226 {
227 return indexOfParentTreeNode( n->parent() ); // must not be null
228 }
229 else
230 {
231 Q_ASSERT( false ); // no other node types!
232 return QModelIndex();
233 }
234}
235
236QModelIndex QgsCoordinateReferenceSystemModel::authIdToIndex( const QString &authid ) const
237{
238 const QModelIndex startIndex = index( 0, 0 );
239 const QModelIndexList hits = match( startIndex, static_cast< int >( CustomRole::AuthId ), authid, 1, Qt::MatchRecursive );
240 return hits.value( 0 );
241}
242
243void QgsCoordinateReferenceSystemModel::rebuild()
244{
245 beginResetModel();
246
247 mRootNode->deleteChildren();
248
249 for ( const QgsCrsDbRecord &record : std::as_const( mCrsDbRecords ) )
250 {
251 addRecord( record );
252 }
253
254 const QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> userCrsList = QgsApplication::coordinateReferenceSystemRegistry()->userCrsList();
255 for ( const QgsCoordinateReferenceSystemRegistry::UserCrsDetails &details : userCrsList )
256 {
257 QgsCrsDbRecord userRecord;
258 userRecord.authName = QStringLiteral( "USER" );
259 userRecord.authId = QString::number( details.id );
260 userRecord.description = details.name;
261
262 addRecord( userRecord );
263 }
264
265 endResetModel();
266}
267
268void QgsCoordinateReferenceSystemModel::userCrsAdded( const QString &id )
269{
270 const QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> userCrsList = QgsApplication::coordinateReferenceSystemRegistry()->userCrsList();
271 for ( const QgsCoordinateReferenceSystemRegistry::UserCrsDetails &details : userCrsList )
272 {
273 if ( QStringLiteral( "USER:%1" ).arg( details.id ) == id )
274 {
275 QgsCrsDbRecord userRecord;
276 userRecord.authName = QStringLiteral( "USER" );
277 userRecord.authId = QString::number( details.id );
278 userRecord.description = details.name;
279
280 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral( "USER" ) );
281 if ( !group )
282 {
283 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >(
284 tr( "User-defined" ),
285 QgsApplication::getThemeIcon( QStringLiteral( "/user.svg" ) ), QStringLiteral( "USER" ) );
286 beginInsertRows( QModelIndex(), mRootNode->children().length(), mRootNode->children().length() );
287 mRootNode->addChildNode( newGroup.get() );
288 endInsertRows();
289 group = newGroup.release();
290 }
291
292 const QModelIndex parentGroupIndex = node2index( group );
293
294 beginInsertRows( parentGroupIndex, group->children().size(), group->children().size() );
295 QgsCoordinateReferenceSystemModelCrsNode *crsNode = addRecord( userRecord );
296 crsNode->setProj( details.proj );
297 crsNode->setWkt( details.wkt );
298 endInsertRows();
299 break;
300 }
301 }
302}
303
304void QgsCoordinateReferenceSystemModel::userCrsRemoved( long id )
305{
306 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral( "USER" ) );
307 if ( group )
308 {
309 for ( int row = 0; row < group->children().size(); ++row )
310 {
311 if ( QgsCoordinateReferenceSystemModelCrsNode *crsNode = dynamic_cast< QgsCoordinateReferenceSystemModelCrsNode * >( group->children().at( row ) ) )
312 {
313 if ( crsNode->record().authId == QString::number( id ) )
314 {
315 const QModelIndex parentIndex = node2index( group );
316 beginRemoveRows( parentIndex, row, row );
317 delete group->takeChild( crsNode );
318 endRemoveRows();
319 return;
320 }
321 }
322 }
323 }
324}
325
326void QgsCoordinateReferenceSystemModel::userCrsChanged( const QString &id )
327{
328 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral( "USER" ) );
329 if ( group )
330 {
331 for ( int row = 0; row < group->children().size(); ++row )
332 {
333 if ( QgsCoordinateReferenceSystemModelCrsNode *crsNode = dynamic_cast< QgsCoordinateReferenceSystemModelCrsNode * >( group->children().at( row ) ) )
334 {
335 if ( QStringLiteral( "USER:%1" ).arg( crsNode->record().authId ) == id )
336 {
337 // treat a change as a remove + add operation
338 const QModelIndex parentIndex = node2index( group );
339 beginRemoveRows( parentIndex, row, row );
340 delete group->takeChild( crsNode );
341 endRemoveRows();
342
343 userCrsAdded( id );
344 return;
345 }
346 }
347 }
348 }
349}
350
351QgsCoordinateReferenceSystemModelCrsNode *QgsCoordinateReferenceSystemModel::addRecord( const QgsCrsDbRecord &record )
352{
353 QgsCoordinateReferenceSystemModelGroupNode *parentNode = mRootNode.get();
354 std::unique_ptr< QgsCoordinateReferenceSystemModelCrsNode > crsNode = std::make_unique< QgsCoordinateReferenceSystemModelCrsNode>( record );
355
356 QString groupName;
357 QString groupId;
358 QIcon groupIcon;
359 if ( record.authName == QLatin1String( "USER" ) )
360 {
361 groupName = tr( "User-defined" );
362 groupId = QStringLiteral( "USER" );
363 groupIcon = QgsApplication::getThemeIcon( QStringLiteral( "/user.svg" ) );
364 }
365 else if ( record.authName == QLatin1String( "CUSTOM" ) )
366 {
367 // the group is guaranteed to exist at this point
368 groupId = QStringLiteral( "CUSTOM" );
369 }
370 else
371 {
372 groupId = qgsEnumValueToKey( record.type );
373 switch ( record.type )
374 {
376 break;
378 groupName = tr( "Geodetic" );
379 groupIcon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconProjectionEnabled.svg" ) );
380 break;
382 groupName = tr( "Geocentric" );
383 groupIcon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconProjectionEnabled.svg" ) );
384 break;
386 groupName = tr( "Geographic (2D)" );
387 groupIcon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconProjectionEnabled.svg" ) );
388 break;
389
391 groupName = tr( "Geographic (3D)" );
392 groupIcon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconProjectionEnabled.svg" ) );
393 break;
394
396 groupName = tr( "Vertical" );
397 break;
398
401 groupName = tr( "Projected" );
402 groupIcon = QgsApplication::getThemeIcon( QStringLiteral( "/transformed.svg" ) );
403 break;
404
406 groupName = tr( "Compound" );
407 break;
408
410 groupName = tr( "Temporal" );
411 break;
412
414 groupName = tr( "Engineering" );
415 break;
416
418 groupName = tr( "Bound" );
419 break;
420
422 groupName = tr( "Other" );
423 break;
424 }
425 }
426
427 if ( QgsCoordinateReferenceSystemModelGroupNode *group = parentNode->getChildGroupNode( groupId ) )
428 {
429 parentNode = group;
430 }
431 else
432 {
433 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( groupName, groupIcon, groupId );
434 parentNode->addChildNode( newGroup.get() );
435 parentNode = newGroup.release();
436 }
437
438 if ( ( record.authName != QLatin1String( "USER" ) && record.authName != QLatin1String( "CUSTOM" ) ) && ( record.type == Qgis::CrsType::Projected || record.type == Qgis::CrsType::DerivedProjected ) )
439 {
441 if ( projectionName.isEmpty() )
442 projectionName = tr( "Other" );
443
444 if ( QgsCoordinateReferenceSystemModelGroupNode *group = parentNode->getChildGroupNode( record.projectionAcronym ) )
445 {
446 parentNode = group;
447 }
448 else
449 {
450 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( projectionName, QIcon(), record.projectionAcronym );
451 parentNode->addChildNode( newGroup.get() );
452 parentNode = newGroup.release();
453 }
454 }
455
456 parentNode->addChildNode( crsNode.get() );
457 return crsNode.release();
458}
459
461{
462 QgsCrsDbRecord userRecord;
463 userRecord.authName = QStringLiteral( "CUSTOM" );
464 userRecord.description = crs.description().isEmpty() ? tr( "Custom CRS" ) : crs.description();
465 userRecord.type = crs.type();
466
467 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral( "CUSTOM" ) );
468 if ( !group )
469 {
470 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >(
471 tr( "Custom" ),
472 QgsApplication::getThemeIcon( QStringLiteral( "/user.svg" ) ), QStringLiteral( "CUSTOM" ) );
473 beginInsertRows( QModelIndex(), mRootNode->children().length(), mRootNode->children().length() );
474 mRootNode->addChildNode( newGroup.get() );
475 endInsertRows();
476 group = newGroup.release();
477 }
478
479 const QModelIndex parentGroupIndex = node2index( group );
480
481 const int newRow = group->children().size();
482 beginInsertRows( parentGroupIndex, newRow, newRow );
483 QgsCoordinateReferenceSystemModelCrsNode *node = addRecord( userRecord );
484 node->setWkt( crs.toWkt( Qgis::CrsWktVariant::Preferred ) );
485 node->setProj( crs.toProj() );
486 endInsertRows();
487
488 return index( newRow, 0, parentGroupIndex );
489}
490
491QgsCoordinateReferenceSystemModelNode *QgsCoordinateReferenceSystemModel::index2node( const QModelIndex &index ) const
492{
493 if ( !index.isValid() )
494 return mRootNode.get();
495
496 return reinterpret_cast<QgsCoordinateReferenceSystemModelNode *>( index.internalPointer() );
497}
498
499QModelIndex QgsCoordinateReferenceSystemModel::node2index( QgsCoordinateReferenceSystemModelNode *node ) const
500{
501 if ( !node || !node->parent() )
502 return QModelIndex(); // this is the only root item -> invalid index
503
504 QModelIndex parentIndex = node2index( node->parent() );
505
506 int row = node->parent()->children().indexOf( node );
507 Q_ASSERT( row >= 0 );
508 return index( row, 0, parentIndex );
509}
510
511QModelIndex QgsCoordinateReferenceSystemModel::indexOfParentTreeNode( QgsCoordinateReferenceSystemModelNode *parentNode ) const
512{
513 Q_ASSERT( parentNode );
514
515 QgsCoordinateReferenceSystemModelNode *grandParentNode = parentNode->parent();
516 if ( !grandParentNode )
517 return QModelIndex(); // root node -> invalid index
518
519 int row = grandParentNode->children().indexOf( parentNode );
520 Q_ASSERT( row >= 0 );
521
522 return createIndex( row, 0, parentNode );
523}
524
526QgsCoordinateReferenceSystemModelNode::~QgsCoordinateReferenceSystemModelNode()
527{
528 qDeleteAll( mChildren );
529}
530
531QgsCoordinateReferenceSystemModelNode *QgsCoordinateReferenceSystemModelNode::takeChild( QgsCoordinateReferenceSystemModelNode *node )
532{
533 return mChildren.takeAt( mChildren.indexOf( node ) );
534}
535
536void QgsCoordinateReferenceSystemModelNode::addChildNode( QgsCoordinateReferenceSystemModelNode *node )
537{
538 if ( !node )
539 return;
540
541 Q_ASSERT( !node->mParent );
542 node->mParent = this;
543
544 mChildren.append( node );
545}
546
547void QgsCoordinateReferenceSystemModelNode::deleteChildren()
548{
549 qDeleteAll( mChildren );
550 mChildren.clear();
551}
552
553QgsCoordinateReferenceSystemModelGroupNode *QgsCoordinateReferenceSystemModelNode::getChildGroupNode( const QString &id )
554{
555 for ( QgsCoordinateReferenceSystemModelNode *node : std::as_const( mChildren ) )
556 {
557 if ( node->nodeType() == NodeGroup )
558 {
559 QgsCoordinateReferenceSystemModelGroupNode *groupNode = qgis::down_cast< QgsCoordinateReferenceSystemModelGroupNode * >( node );
560 if ( groupNode && groupNode->id() == id )
561 return groupNode;
562 }
563 }
564 return nullptr;
565
566}
567
568QgsCoordinateReferenceSystemModelGroupNode::QgsCoordinateReferenceSystemModelGroupNode( const QString &name, const QIcon &icon, const QString &id )
569 : mId( id )
570 , mName( name )
571 , mIcon( icon )
572{
573
574}
575
576QgsCoordinateReferenceSystemModelCrsNode::QgsCoordinateReferenceSystemModelCrsNode( const QgsCrsDbRecord &record )
577 : mRecord( record )
578{
579
580}
582
583
584//
585// QgsCoordinateReferenceSystemProxyModel
586//
587
589 : QSortFilterProxyModel( parent )
590 , mModel( new QgsCoordinateReferenceSystemModel( this ) )
591{
592 setSourceModel( mModel );
593 setDynamicSortFilter( true );
594 setSortLocaleAware( true );
595 setFilterCaseSensitivity( Qt::CaseInsensitive );
596 setRecursiveFilteringEnabled( true );
597 sort( 0 );
598}
599
601{
602 return mModel;
603}
604
606{
607 return mModel;
608}
609
611{
612 if ( mFilters == filters )
613 return;
614
615 mFilters = filters;
616 invalidateFilter();
617}
618
620{
621 mFilterString = filter;
622 invalidateFilter();
623}
624
626{
627 if ( mFilterAuthIds == filter )
628 return;
629
630 mFilterAuthIds.clear();
631 mFilterAuthIds.reserve( filter.size() );
632 for ( const QString &id : filter )
633 {
634 mFilterAuthIds.insert( id.toUpper() );
635 }
636 invalidateFilter();
637}
638
640{
641 if ( mFilterDeprecated == filter )
642 return;
643
644 mFilterDeprecated = filter;
645 invalidateFilter();
646}
647
648bool QgsCoordinateReferenceSystemProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
649{
650 if ( mFilterString.trimmed().isEmpty() && !mFilters && !mFilterDeprecated && mFilterAuthIds.isEmpty() )
651 return true;
652
653 const QModelIndex sourceIndex = mModel->index( sourceRow, 0, sourceParent );
654 const QgsCoordinateReferenceSystemModelNode::NodeType nodeType = static_cast< QgsCoordinateReferenceSystemModelNode::NodeType >( sourceModel()->data( sourceIndex, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::NodeType ) ).toInt() );
655 switch ( nodeType )
656 {
657 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
658 return false;
659 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
660 break;
661 }
662
663 const bool deprecated = sourceModel()->data( sourceIndex, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::Deprecated ) ).toBool();
664 if ( mFilterDeprecated && deprecated )
665 return false;
666
667 if ( mFilters )
668 {
669 const Qgis::CrsType type = sourceModel()->data( sourceIndex, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::Type ) ).value< Qgis::CrsType >();
670 switch ( type )
671 {
674 break;
675
685 if ( !mFilters.testFlag( Filter::FilterHorizontal ) )
686 return false;
687 break;
688
690 if ( !mFilters.testFlag( Filter::FilterVertical ) )
691 return false;
692 break;
693
695 if ( !mFilters.testFlag( Filter::FilterCompound ) )
696 return false;
697 break;
698 }
699 }
700
701 const QString authid = sourceModel()->data( sourceIndex, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::AuthId ) ).toString();
702 if ( !mFilterAuthIds.isEmpty() )
703 {
704 if ( !mFilterAuthIds.contains( authid.toUpper() ) )
705 return false;
706 }
707
708 if ( !mFilterString.trimmed().isEmpty() )
709 {
710 const QString name = sourceModel()->data( sourceIndex, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::Name ) ).toString();
711 if ( !( name.contains( mFilterString, Qt::CaseInsensitive )
712 || authid.contains( mFilterString, Qt::CaseInsensitive ) ) )
713 return false;
714 }
715 return true;
716}
717
718bool QgsCoordinateReferenceSystemProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
719{
720 QgsCoordinateReferenceSystemModelNode::NodeType leftType = static_cast< QgsCoordinateReferenceSystemModelNode::NodeType >( sourceModel()->data( left, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::NodeType ) ).toInt() );
721 QgsCoordinateReferenceSystemModelNode::NodeType rightType = static_cast< QgsCoordinateReferenceSystemModelNode::NodeType >( sourceModel()->data( right, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::NodeType ) ).toInt() );
722
723 if ( leftType != rightType )
724 {
725 if ( leftType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
726 return true;
727 else if ( rightType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
728 return false;
729 }
730
731 const QString leftStr = sourceModel()->data( left ).toString().toLower();
732 const QString rightStr = sourceModel()->data( right ).toString().toLower();
733
734 if ( leftType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
735 {
736 // both are groups -- ensure USER group comes last, and CUSTOM group comes first
737 const QString leftGroupId = sourceModel()->data( left, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::GroupId ) ).toString();
738 const QString rightGroupId = sourceModel()->data( left, static_cast< int >( QgsCoordinateReferenceSystemModel::CustomRole::GroupId ) ).toString();
739 if ( leftGroupId == QLatin1String( "USER" ) )
740 return false;
741 if ( rightGroupId == QLatin1String( "USER" ) )
742 return true;
743
744 if ( leftGroupId == QLatin1String( "CUSTOM" ) )
745 return true;
746 if ( rightGroupId == QLatin1String( "CUSTOM" ) )
747 return false;
748 }
749
750 // default sort is alphabetical order
751 return QString::localeAwareCompare( leftStr, rightStr ) < 0;
752}
753
754
CrsType
Coordinate reference system types.
Definition: qgis.h:1865
@ Vertical
Vertical CRS.
@ Temporal
Temporal CRS.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ Other
Other type.
@ Bound
Bound CRS.
@ DerivedProjected
Derived projected CRS.
@ Unknown
Unknown type.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geodetic
Geodetic CRS.
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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...
A tree model for display of known coordinate reference systems.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QModelIndex addCustomCrs(const QgsCoordinateReferenceSystem &crs)
Adds a custom crs to the model.
QModelIndex parent(const QModelIndex &index) const override
QgsCoordinateReferenceSystemModel(QObject *parent=nullptr)
Constructor for QgsCoordinateReferenceSystemModel, with the specified parent object.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
QModelIndex authIdToIndex(const QString &authId) const
Retrieves the model index corresponding to a CRS with the specified authId.
@ Deprecated
true if the CRS is deprecated
@ AuthId
The coordinate reference system authority name and id.
@ GroupId
The node ID (for group nodes)
@ Name
The coordinate reference system name.
@ NodeType
Corresponds to the node's type.
@ Wkt
The coordinate reference system's WKT representation. This is only used for non-standard CRS (i....
@ Type
The coordinate reference system type.
@ Proj
The coordinate reference system's PROJ representation. This is only used for non-standard CRS (i....
QVariant data(const QModelIndex &index, int role) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
int columnCount(const QModelIndex &=QModelIndex()) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QgsCoordinateReferenceSystemProxyModel(QObject *parent=nullptr)
Constructor for QgsCoordinateReferenceSystemProxyModel, with the given parent object.
void setFilterDeprecated(bool filter)
Sets whether deprecated CRS should be filtered from the results.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
Filters filters() const
Returns any filters that affect how CRS are filtered.
QgsCoordinateReferenceSystemModel * coordinateReferenceSystemModel()
Returns the underlying source model.
void setFilterString(const QString &filter)
Sets a filter string, such that only coordinate reference systems matching the specified string will ...
void setFilterAuthIds(const QSet< QString > &filter)
Sets a filter list of CRS auth ID strings, such that only coordinate reference systems matching the s...
void setFilters(QgsCoordinateReferenceSystemProxyModel::Filters filters)
Set filters that affect how CRS are filtered.
QList< QgsCrsDbRecord > crsDbRecords() const
Returns the list of records from the QGIS srs db.
void userCrsAdded(const QString &id)
Emitted whenever a new user CRS definition is added.
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
void userCrsRemoved(long id)
Emitted when the user CRS with matching id is removed from the database.
QList< QgsCoordinateReferenceSystemRegistry::UserCrsDetails > userCrsList() const
Returns a list containing the details of all registered custom (user-defined) CRSes.
static QString translateProjection(const QString &projection)
Returns a translated string for a projection method.
This class represents a coordinate reference system (CRS).
QString toProj() const
Returns a Proj string representation of this CRS.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Qgis::CrsType type() const
Returns the type of the CRS.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition: qgis.h:5398
#define BUILTIN_UNREACHABLE
Definition: qgis.h:5853
const QgsCoordinateReferenceSystem & crs