24 : QAbstractItemModel( parent )
25 , mRootNode( std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( QString(), QIcon(), QString() ) )
38 if ( !
index.isValid() )
40 return Qt::ItemFlags();
43 QgsCoordinateReferenceSystemModelNode *n = index2node(
index );
45 return Qt::ItemFlags();
47 switch ( n->nodeType() )
49 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
50 return index.column() == 0 ? Qt::ItemIsEnabled : Qt::ItemFlags();
51 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
52 return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
59 if ( !
index.isValid() )
62 QgsCoordinateReferenceSystemModelNode *n = index2node(
index );
69 switch ( n->nodeType() )
71 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
73 QgsCoordinateReferenceSystemModelGroupNode *groupNode = qgis::down_cast< QgsCoordinateReferenceSystemModelGroupNode * >( n );
76 case Qt::DecorationRole:
77 switch (
index.column() )
80 return groupNode->icon();
88 switch (
index.column() )
91 return groupNode->name();
101 font.setItalic(
true );
102 if ( groupNode->parent() == mRootNode.get() )
104 font.setBold(
true );
110 return groupNode->id();
115 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
117 QgsCoordinateReferenceSystemModelCrsNode *crsNode = qgis::down_cast< QgsCoordinateReferenceSystemModelCrsNode * >( n );
120 case Qt::DisplayRole:
121 case Qt::ToolTipRole:
122 switch (
index.column() )
125 return crsNode->record().description;
129 if ( crsNode->record().authName == QLatin1String(
"CUSTOM" ) )
131 return QStringLiteral(
"%1:%2" ).arg( crsNode->record().authName, crsNode->record().authId );
140 return crsNode->record().description;
143 if ( !crsNode->record().authId.isEmpty() )
144 return QStringLiteral(
"%1:%2" ).arg( crsNode->record().authName, crsNode->record().authId );
149 return crsNode->record().deprecated;
152 return QVariant::fromValue( crsNode->record().type );
155 return crsNode->wkt();
158 return crsNode->proj();
171 if ( orientation == Qt::Horizontal )
175 case Qt::DisplayRole:
179 return tr(
"Coordinate Reference System" );
181 return tr(
"Authority ID" );
196 QgsCoordinateReferenceSystemModelNode *n = index2node(
parent );
200 return n->children().count();
210 if ( !hasIndex( row, column,
parent ) )
211 return QModelIndex();
213 QgsCoordinateReferenceSystemModelNode *n = index2node(
parent );
215 return QModelIndex();
217 return createIndex( row, column, n->children().at( row ) );
222 if ( !child.isValid() )
223 return QModelIndex();
225 if ( QgsCoordinateReferenceSystemModelNode *n = index2node( child ) )
227 return indexOfParentTreeNode( n->parent() );
232 return QModelIndex();
238 const QModelIndex startIndex =
index( 0, 0 );
239 const QModelIndexList hits = match( startIndex,
RoleAuthId, authid, 1, Qt::MatchRecursive );
240 return hits.value( 0 );
243void QgsCoordinateReferenceSystemModel::rebuild()
247 mRootNode->deleteChildren();
249 for (
const QgsCrsDbRecord &record : std::as_const( mCrsDbRecords ) )
258 userRecord.
authName = QStringLiteral(
"USER" );
259 userRecord.
authId = QString::number( details.id );
262 addRecord( userRecord );
268void QgsCoordinateReferenceSystemModel::userCrsAdded(
const QString &
id )
273 if ( QStringLiteral(
"USER:%1" ).arg( details.id ) ==
id )
276 userRecord.
authName = QStringLiteral(
"USER" );
277 userRecord.
authId = QString::number( details.id );
280 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"USER" ) );
283 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >(
284 tr(
"User-defined" ),
286 beginInsertRows( QModelIndex(), mRootNode->children().length(), mRootNode->children().length() );
287 mRootNode->addChildNode( newGroup.get() );
289 group = newGroup.release();
292 const QModelIndex parentGroupIndex = node2index( group );
294 beginInsertRows( parentGroupIndex, group->children().size(), group->children().size() );
295 QgsCoordinateReferenceSystemModelCrsNode *crsNode = addRecord( userRecord );
296 crsNode->setProj( details.proj );
297 crsNode->setWkt( details.wkt );
304void QgsCoordinateReferenceSystemModel::userCrsRemoved(
long id )
306 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"USER" ) );
309 for (
int row = 0; row < group->children().size(); ++row )
311 if ( QgsCoordinateReferenceSystemModelCrsNode *crsNode =
dynamic_cast< QgsCoordinateReferenceSystemModelCrsNode *
>( group->children().at( row ) ) )
313 if ( crsNode->record().authId == QString::number(
id ) )
315 const QModelIndex parentIndex = node2index( group );
316 beginRemoveRows( parentIndex, row, row );
317 delete group->takeChild( crsNode );
326void QgsCoordinateReferenceSystemModel::userCrsChanged(
const QString &
id )
328 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"USER" ) );
331 for (
int row = 0; row < group->children().size(); ++row )
333 if ( QgsCoordinateReferenceSystemModelCrsNode *crsNode =
dynamic_cast< QgsCoordinateReferenceSystemModelCrsNode *
>( group->children().at( row ) ) )
335 if ( QStringLiteral(
"USER:%1" ).arg( crsNode->record().authId ) ==
id )
338 const QModelIndex parentIndex = node2index( group );
339 beginRemoveRows( parentIndex, row, row );
340 delete group->takeChild( crsNode );
351QgsCoordinateReferenceSystemModelCrsNode *QgsCoordinateReferenceSystemModel::addRecord(
const QgsCrsDbRecord &record )
353 QgsCoordinateReferenceSystemModelGroupNode *parentNode = mRootNode.get();
354 std::unique_ptr< QgsCoordinateReferenceSystemModelCrsNode > crsNode = std::make_unique< QgsCoordinateReferenceSystemModelCrsNode>( record );
359 if ( record.
authName == QLatin1String(
"USER" ) )
361 groupName = tr(
"User-defined" );
362 groupId = QStringLiteral(
"USER" );
365 else if ( record.
authName == QLatin1String(
"CUSTOM" ) )
368 groupId = QStringLiteral(
"CUSTOM" );
373 switch ( record.
type )
378 groupName = tr(
"Geodetic" );
382 groupName = tr(
"Geocentric" );
386 groupName = tr(
"Geographic (2D)" );
391 groupName = tr(
"Geographic (3D)" );
396 groupName = tr(
"Vertical" );
401 groupName = tr(
"Projected" );
406 groupName = tr(
"Compound" );
410 groupName = tr(
"Temporal" );
414 groupName = tr(
"Engineering" );
418 groupName = tr(
"Bound" );
422 groupName = tr(
"Other" );
427 if ( QgsCoordinateReferenceSystemModelGroupNode *group = parentNode->getChildGroupNode( groupId ) )
433 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( groupName, groupIcon, groupId );
434 parentNode->addChildNode( newGroup.get() );
435 parentNode = newGroup.release();
441 if ( projectionName.isEmpty() )
442 projectionName = tr(
"Other" );
444 if ( QgsCoordinateReferenceSystemModelGroupNode *group = parentNode->getChildGroupNode( record.
projectionAcronym ) )
450 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( projectionName, QIcon(), record.
projectionAcronym );
451 parentNode->addChildNode( newGroup.get() );
452 parentNode = newGroup.release();
456 parentNode->addChildNode( crsNode.get() );
457 return crsNode.release();
463 userRecord.
authName = QStringLiteral(
"CUSTOM" );
467 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"CUSTOM" ) );
470 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >(
473 beginInsertRows( QModelIndex(), mRootNode->children().length(), mRootNode->children().length() );
474 mRootNode->addChildNode( newGroup.get() );
476 group = newGroup.release();
479 const QModelIndex parentGroupIndex = node2index( group );
481 const int newRow = group->children().size();
482 beginInsertRows( parentGroupIndex, newRow, newRow );
483 QgsCoordinateReferenceSystemModelCrsNode *node = addRecord( userRecord );
488 return index( newRow, 0, parentGroupIndex );
491QgsCoordinateReferenceSystemModelNode *QgsCoordinateReferenceSystemModel::index2node(
const QModelIndex &index )
const
493 if ( !
index.isValid() )
494 return mRootNode.get();
496 return reinterpret_cast<QgsCoordinateReferenceSystemModelNode *
>(
index.internalPointer() );
499QModelIndex QgsCoordinateReferenceSystemModel::node2index( QgsCoordinateReferenceSystemModelNode *node )
const
501 if ( !node || !node->parent() )
502 return QModelIndex();
504 QModelIndex parentIndex = node2index( node->parent() );
506 int row = node->parent()->children().indexOf( node );
507 Q_ASSERT( row >= 0 );
508 return index( row, 0, parentIndex );
511QModelIndex QgsCoordinateReferenceSystemModel::indexOfParentTreeNode( QgsCoordinateReferenceSystemModelNode *parentNode )
const
513 Q_ASSERT( parentNode );
515 QgsCoordinateReferenceSystemModelNode *grandParentNode = parentNode->parent();
516 if ( !grandParentNode )
517 return QModelIndex();
519 int row = grandParentNode->children().indexOf( parentNode );
520 Q_ASSERT( row >= 0 );
522 return createIndex( row, 0, parentNode );
526QgsCoordinateReferenceSystemModelNode::~QgsCoordinateReferenceSystemModelNode()
528 qDeleteAll( mChildren );
531QgsCoordinateReferenceSystemModelNode *QgsCoordinateReferenceSystemModelNode::takeChild( QgsCoordinateReferenceSystemModelNode *node )
533 return mChildren.takeAt( mChildren.indexOf( node ) );
536void QgsCoordinateReferenceSystemModelNode::addChildNode( QgsCoordinateReferenceSystemModelNode *node )
541 Q_ASSERT( !node->mParent );
542 node->mParent =
this;
544 mChildren.append( node );
547void QgsCoordinateReferenceSystemModelNode::deleteChildren()
549 qDeleteAll( mChildren );
553QgsCoordinateReferenceSystemModelGroupNode *QgsCoordinateReferenceSystemModelNode::getChildGroupNode(
const QString &
id )
555 for ( QgsCoordinateReferenceSystemModelNode *node : std::as_const( mChildren ) )
557 if ( node->nodeType() == NodeGroup )
559 QgsCoordinateReferenceSystemModelGroupNode *groupNode = qgis::down_cast< QgsCoordinateReferenceSystemModelGroupNode * >( node );
560 if ( groupNode && groupNode->id() ==
id )
568QgsCoordinateReferenceSystemModelGroupNode::QgsCoordinateReferenceSystemModelGroupNode(
const QString &name,
const QIcon &icon,
const QString &
id )
576QgsCoordinateReferenceSystemModelCrsNode::QgsCoordinateReferenceSystemModelCrsNode(
const QgsCrsDbRecord &record )
589 : QSortFilterProxyModel( parent )
592 setSourceModel( mModel );
593 setDynamicSortFilter(
true );
594 setSortLocaleAware(
true );
595 setFilterCaseSensitivity( Qt::CaseInsensitive );
596 setRecursiveFilteringEnabled(
true );
621 mFilterString = filter;
627 if ( mFilterAuthIds == filter )
630 mFilterAuthIds.clear();
631 mFilterAuthIds.reserve( filter.size() );
632 for (
const QString &
id : filter )
634 mFilterAuthIds.insert(
id.toUpper() );
641 if ( mFilterDeprecated == filter )
644 mFilterDeprecated = filter;
650 if ( mFilterString.trimmed().isEmpty() && !mFilters && !mFilterDeprecated && mFilterAuthIds.isEmpty() )
653 const QModelIndex sourceIndex = mModel->
index( sourceRow, 0, sourceParent );
657 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
659 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
664 if ( mFilterDeprecated && deprecated )
702 if ( !mFilterAuthIds.isEmpty() )
704 if ( !mFilterAuthIds.contains( authid.toUpper() ) )
708 if ( !mFilterString.trimmed().isEmpty() )
711 if ( !( name.contains( mFilterString, Qt::CaseInsensitive )
712 || authid.contains( mFilterString, Qt::CaseInsensitive ) ) )
723 if ( leftType != rightType )
725 if ( leftType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
727 else if ( rightType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
731 const QString leftStr = sourceModel()->data( left ).toString().toLower();
732 const QString rightStr = sourceModel()->data( right ).toString().toLower();
734 if ( leftType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
739 if ( leftGroupId == QLatin1String(
"USER" ) )
741 if ( rightGroupId == QLatin1String(
"USER" ) )
744 if ( leftGroupId == QLatin1String(
"CUSTOM" ) )
746 if ( rightGroupId == QLatin1String(
"CUSTOM" ) )
751 return QString::localeAwareCompare( leftStr, rightStr ) < 0;
CrsType
Data provider flags.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
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.
@ RoleNodeType
Corresponds to the node's type.
@ RoleGroupId
The node ID (for group nodes)
@ RoleProj
The coordinate reference system's PROJ representation. This is only used for non-standard CRS (i....
@ RoleName
The coordinate reference system name.
@ RoleDeprecated
true if the CRS is deprecated
@ RoleType
The coordinate reference system type.
@ RoleWkt
The coordinate reference system's WKT representation. This is only used for non-standard CRS (i....
@ RoleAuthId
The coordinate reference system authority name and id.
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.
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)
@ FilterCompound
Include compound CRS.
@ 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.
Contains details of a custom (user defined) CRS.
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.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, 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.
#define BUILTIN_UNREACHABLE
const QgsCoordinateReferenceSystem & crs
QString projectionAcronym