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