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