18#include "moc_qgscoordinatereferencesystemmodel.cpp"
25 : QAbstractItemModel( parent )
26 , mRootNode( std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( QString(), QIcon(), QString() ) )
39 if ( !
index.isValid() )
41 return Qt::ItemFlags();
44 QgsCoordinateReferenceSystemModelNode *n = index2node(
index );
46 return Qt::ItemFlags();
48 switch ( n->nodeType() )
50 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
51 return index.column() == 0 ? Qt::ItemIsEnabled : Qt::ItemFlags();
52 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
53 return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
60 if ( !
index.isValid() )
63 QgsCoordinateReferenceSystemModelNode *n = index2node(
index );
70 switch ( n->nodeType() )
72 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
74 QgsCoordinateReferenceSystemModelGroupNode *groupNode = qgis::down_cast< QgsCoordinateReferenceSystemModelGroupNode * >( n );
77 case Qt::DecorationRole:
78 switch (
index.column() )
81 return groupNode->icon();
89 switch (
index.column() )
92 return groupNode->name();
102 font.setItalic(
true );
103 if ( groupNode->parent() == mRootNode.get() )
105 font.setBold(
true );
111 return groupNode->id();
116 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
118 QgsCoordinateReferenceSystemModelCrsNode *crsNode = qgis::down_cast< QgsCoordinateReferenceSystemModelCrsNode * >( n );
121 case Qt::DisplayRole:
122 case Qt::ToolTipRole:
123 switch (
index.column() )
126 return crsNode->record().description;
130 if ( crsNode->record().authName == QLatin1String(
"CUSTOM" ) )
132 return QStringLiteral(
"%1:%2" ).arg( crsNode->record().authName, crsNode->record().authId );
141 return crsNode->record().description;
144 if ( !crsNode->record().authId.isEmpty() )
145 return QStringLiteral(
"%1:%2" ).arg( crsNode->record().authName, crsNode->record().authId );
150 return crsNode->record().deprecated;
153 return QVariant::fromValue( crsNode->record().type );
156 return crsNode->wkt();
159 return crsNode->proj();
172 if ( orientation == Qt::Horizontal )
176 case Qt::DisplayRole:
180 return tr(
"Coordinate Reference System" );
182 return tr(
"Authority ID" );
197 QgsCoordinateReferenceSystemModelNode *n = index2node(
parent );
201 return n->children().count();
211 if ( !hasIndex( row, column,
parent ) )
212 return QModelIndex();
214 QgsCoordinateReferenceSystemModelNode *n = index2node(
parent );
216 return QModelIndex();
218 return createIndex( row, column, n->children().at( row ) );
223 if ( !child.isValid() )
224 return QModelIndex();
226 if ( QgsCoordinateReferenceSystemModelNode *n = index2node( child ) )
228 return indexOfParentTreeNode( n->parent() );
233 return QModelIndex();
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 );
244void QgsCoordinateReferenceSystemModel::rebuild()
248 mRootNode->deleteChildren();
250 for (
const QgsCrsDbRecord &record : std::as_const( mCrsDbRecords ) )
259 userRecord.
authName = QStringLiteral(
"USER" );
260 userRecord.
authId = QString::number( details.id );
263 addRecord( userRecord );
269void QgsCoordinateReferenceSystemModel::userCrsAdded(
const QString &
id )
274 if ( QStringLiteral(
"USER:%1" ).arg( details.id ) ==
id )
277 userRecord.
authName = QStringLiteral(
"USER" );
278 userRecord.
authId = QString::number( details.id );
281 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"USER" ) );
284 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >(
285 tr(
"User-defined" ),
287 beginInsertRows( QModelIndex(), mRootNode->children().length(), mRootNode->children().length() );
288 mRootNode->addChildNode( newGroup.get() );
290 group = newGroup.release();
293 const QModelIndex parentGroupIndex = node2index( group );
295 beginInsertRows( parentGroupIndex, group->children().size(), group->children().size() );
296 QgsCoordinateReferenceSystemModelCrsNode *crsNode = addRecord( userRecord );
297 crsNode->setProj( details.proj );
298 crsNode->setWkt( details.wkt );
305void QgsCoordinateReferenceSystemModel::userCrsRemoved(
long id )
307 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"USER" ) );
310 for (
int row = 0; row < group->children().size(); ++row )
312 if ( QgsCoordinateReferenceSystemModelCrsNode *crsNode =
dynamic_cast< QgsCoordinateReferenceSystemModelCrsNode *
>( group->children().at( row ) ) )
314 if ( crsNode->record().authId == QString::number(
id ) )
316 const QModelIndex parentIndex = node2index( group );
317 beginRemoveRows( parentIndex, row, row );
318 delete group->takeChild( crsNode );
327void QgsCoordinateReferenceSystemModel::userCrsChanged(
const QString &
id )
329 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"USER" ) );
332 for (
int row = 0; row < group->children().size(); ++row )
334 if ( QgsCoordinateReferenceSystemModelCrsNode *crsNode =
dynamic_cast< QgsCoordinateReferenceSystemModelCrsNode *
>( group->children().at( row ) ) )
336 if ( QStringLiteral(
"USER:%1" ).arg( crsNode->record().authId ) ==
id )
339 const QModelIndex parentIndex = node2index( group );
340 beginRemoveRows( parentIndex, row, row );
341 delete group->takeChild( crsNode );
352QgsCoordinateReferenceSystemModelCrsNode *QgsCoordinateReferenceSystemModel::addRecord(
const QgsCrsDbRecord &record )
354 QgsCoordinateReferenceSystemModelGroupNode *parentNode = mRootNode.get();
355 std::unique_ptr< QgsCoordinateReferenceSystemModelCrsNode > crsNode = std::make_unique< QgsCoordinateReferenceSystemModelCrsNode>( record );
360 if ( record.
authName == QLatin1String(
"USER" ) )
362 groupName = tr(
"User-defined" );
363 groupId = QStringLiteral(
"USER" );
366 else if ( record.
authName == QLatin1String(
"CUSTOM" ) )
369 groupId = QStringLiteral(
"CUSTOM" );
374 switch ( record.
type )
379 groupName = tr(
"Geodetic" );
383 groupName = tr(
"Geocentric" );
387 groupName = tr(
"Geographic (2D)" );
392 groupName = tr(
"Geographic (3D)" );
397 groupName = tr(
"Vertical" );
402 groupName = tr(
"Projected" );
407 groupName = tr(
"Compound" );
411 groupName = tr(
"Temporal" );
415 groupName = tr(
"Engineering" );
419 groupName = tr(
"Bound" );
423 groupName = tr(
"Other" );
428 if ( QgsCoordinateReferenceSystemModelGroupNode *group = parentNode->getChildGroupNode( groupId ) )
434 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( groupName, groupIcon, groupId );
435 parentNode->addChildNode( newGroup.get() );
436 parentNode = newGroup.release();
442 if ( projectionName.isEmpty() )
443 projectionName = tr(
"Other" );
445 if ( QgsCoordinateReferenceSystemModelGroupNode *group = parentNode->getChildGroupNode( record.
projectionAcronym ) )
451 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >( projectionName, QIcon(), record.
projectionAcronym );
452 parentNode->addChildNode( newGroup.get() );
453 parentNode = newGroup.release();
457 parentNode->addChildNode( crsNode.get() );
458 return crsNode.release();
464 userRecord.
authName = QStringLiteral(
"CUSTOM" );
468 QgsCoordinateReferenceSystemModelGroupNode *group = mRootNode->getChildGroupNode( QStringLiteral(
"CUSTOM" ) );
471 std::unique_ptr< QgsCoordinateReferenceSystemModelGroupNode > newGroup = std::make_unique< QgsCoordinateReferenceSystemModelGroupNode >(
474 beginInsertRows( QModelIndex(), mRootNode->children().length(), mRootNode->children().length() );
475 mRootNode->addChildNode( newGroup.get() );
477 group = newGroup.release();
480 const QModelIndex parentGroupIndex = node2index( group );
482 const int newRow = group->children().size();
483 beginInsertRows( parentGroupIndex, newRow, newRow );
484 QgsCoordinateReferenceSystemModelCrsNode *node = addRecord( userRecord );
489 return index( newRow, 0, parentGroupIndex );
492QgsCoordinateReferenceSystemModelNode *QgsCoordinateReferenceSystemModel::index2node(
const QModelIndex &index )
const
494 if ( !
index.isValid() )
495 return mRootNode.get();
497 return reinterpret_cast<QgsCoordinateReferenceSystemModelNode *
>(
index.internalPointer() );
500QModelIndex QgsCoordinateReferenceSystemModel::node2index( QgsCoordinateReferenceSystemModelNode *node )
const
502 if ( !node || !node->parent() )
503 return QModelIndex();
505 QModelIndex parentIndex = node2index( node->parent() );
507 int row = node->parent()->children().indexOf( node );
508 Q_ASSERT( row >= 0 );
509 return index( row, 0, parentIndex );
512QModelIndex QgsCoordinateReferenceSystemModel::indexOfParentTreeNode( QgsCoordinateReferenceSystemModelNode *parentNode )
const
514 Q_ASSERT( parentNode );
516 QgsCoordinateReferenceSystemModelNode *grandParentNode = parentNode->parent();
517 if ( !grandParentNode )
518 return QModelIndex();
520 int row = grandParentNode->children().indexOf( parentNode );
521 Q_ASSERT( row >= 0 );
523 return createIndex( row, 0, parentNode );
527QgsCoordinateReferenceSystemModelNode::~QgsCoordinateReferenceSystemModelNode()
529 qDeleteAll( mChildren );
532QgsCoordinateReferenceSystemModelNode *QgsCoordinateReferenceSystemModelNode::takeChild( QgsCoordinateReferenceSystemModelNode *node )
534 return mChildren.takeAt( mChildren.indexOf( node ) );
537void QgsCoordinateReferenceSystemModelNode::addChildNode( QgsCoordinateReferenceSystemModelNode *node )
542 Q_ASSERT( !node->mParent );
543 node->mParent =
this;
545 mChildren.append( node );
548void QgsCoordinateReferenceSystemModelNode::deleteChildren()
550 qDeleteAll( mChildren );
554QgsCoordinateReferenceSystemModelGroupNode *QgsCoordinateReferenceSystemModelNode::getChildGroupNode(
const QString &
id )
556 for ( QgsCoordinateReferenceSystemModelNode *node : std::as_const( mChildren ) )
558 if ( node->nodeType() == NodeGroup )
560 QgsCoordinateReferenceSystemModelGroupNode *groupNode = qgis::down_cast< QgsCoordinateReferenceSystemModelGroupNode * >( node );
561 if ( groupNode && groupNode->id() ==
id )
569QgsCoordinateReferenceSystemModelGroupNode::QgsCoordinateReferenceSystemModelGroupNode(
const QString &name,
const QIcon &icon,
const QString &
id )
577QgsCoordinateReferenceSystemModelCrsNode::QgsCoordinateReferenceSystemModelCrsNode(
const QgsCrsDbRecord &record )
590 : QSortFilterProxyModel( parent )
593 setSourceModel( mModel );
594 setDynamicSortFilter(
true );
595 setSortLocaleAware(
true );
596 setFilterCaseSensitivity( Qt::CaseInsensitive );
597 setRecursiveFilteringEnabled(
true );
622 mFilterString = filter;
628 if ( mFilterAuthIds == filter )
631 mFilterAuthIds.clear();
632 mFilterAuthIds.reserve( filter.size() );
633 for (
const QString &
id : filter )
635 mFilterAuthIds.insert(
id.toUpper() );
642 if ( mFilterDeprecated == filter )
645 mFilterDeprecated = filter;
651 if ( mFilterString.trimmed().isEmpty() && !mFilters && !mFilterDeprecated && mFilterAuthIds.isEmpty() )
654 const QModelIndex sourceIndex = mModel->
index( sourceRow, 0, sourceParent );
658 case QgsCoordinateReferenceSystemModelNode::NodeGroup:
660 case QgsCoordinateReferenceSystemModelNode::NodeCrs:
665 if ( mFilterDeprecated && deprecated )
703 if ( !mFilterAuthIds.isEmpty() )
705 if ( !mFilterAuthIds.contains( authid.toUpper() ) )
709 if ( !mFilterString.trimmed().isEmpty() )
712 if ( !( name.contains( mFilterString, Qt::CaseInsensitive )
713 || authid.contains( mFilterString, Qt::CaseInsensitive ) ) )
724 if ( leftType != rightType )
726 if ( leftType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
728 else if ( rightType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
732 const QString leftStr = sourceModel()->data( left ).toString().toLower();
733 const QString rightStr = sourceModel()->data( right ).toString().toLower();
735 if ( leftType == QgsCoordinateReferenceSystemModelNode::NodeGroup )
740 if ( leftGroupId == QLatin1String(
"USER" ) )
742 if ( rightGroupId == QLatin1String(
"USER" ) )
745 if ( leftGroupId == QLatin1String(
"CUSTOM" ) )
747 if ( rightGroupId == QLatin1String(
"CUSTOM" ) )
752 return QString::localeAwareCompare( leftStr, rightStr ) < 0;
CrsType
Coordinate reference system types.
@ 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.
@ 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)
@ 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.
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.
#define BUILTIN_UNREACHABLE
const QgsCoordinateReferenceSystem & crs
QString projectionAcronym