Skip to content

Commit

Permalink
Cleanup handling of recent CRS list, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 20, 2019
1 parent 908684c commit e152685
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 110 deletions.
19 changes: 17 additions & 2 deletions python/core/auto_generated/qgscoordinatereferencesystem.sip.in
Expand Up @@ -827,13 +827,28 @@ Returns auth id of related geographic CRS
%End


static QStringList recentProjections();
static QStringList recentProjections() /Deprecated/;
%Docstring
Returns a list of recently used projections

:return: list of srsid for recently used projections

.. versionadded:: 2.7
.. deprecated::
use recentCoordinateReferenceSystems() instead.
%End

static QList< QgsCoordinateReferenceSystem > recentCoordinateReferenceSystems();
%Docstring
Returns a list of recently used CRS.

.. versionadded:: 3.10.3
%End

static void pushRecentCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &crs );
%Docstring
Pushes a recently used CRS to the top of the recent CRS list.

.. versionadded:: 3.10.3
%End


Expand Down
6 changes: 4 additions & 2 deletions src/app/dwg/qgsdwgimportdialog.cpp
Expand Up @@ -81,7 +81,8 @@ QgsDwgImportDialog::QgsDwgImportDialog( QWidget *parent, Qt::WindowFlags f )

int crsid = s.value( QStringLiteral( "/DwgImport/lastCrs" ), QString::number( QgsProject::instance()->crs().srsid() ) ).toInt();

QgsCoordinateReferenceSystem crs( crsid, QgsCoordinateReferenceSystem::InternalCrsId );
QgsCoordinateReferenceSystem crs;
crs.createFromSrsId( crsid );
mCrsSelector->setCrs( crs );
mCrsSelector->setLayerCrs( crs );
mCrsSelector->setMessage( tr( "Select the coordinate reference system for the dxf file. "
Expand Down Expand Up @@ -162,7 +163,8 @@ void QgsDwgImportDialog::pbLoadDatabase_clicked()
{
leDrawing->setText( f.attribute( idxPath ).toString() );

QgsCoordinateReferenceSystem crs( f.attribute( idxCrs ).toInt(), QgsCoordinateReferenceSystem::InternalCrsId );
QgsCoordinateReferenceSystem crs;
crs.createFromSrsId( f.attribute( idxCrs ).toInt() );
mCrsSelector->setCrs( crs );
mCrsSelector->setLayerCrs( crs );

Expand Down
104 changes: 62 additions & 42 deletions src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -2200,18 +2200,6 @@ long QgsCoordinateReferenceSystem::saveAsUserCrs( const QString &name, Format na
if ( authid().isEmpty() )
setAuthId( QStringLiteral( "USER:%1" ).arg( returnId ) );
setDescription( name );

//We add the just created user CRS to the list of recently used CRS
QgsSettings settings;
//QStringList recentProjections = settings.value( "/UI/recentProjections" ).toStringList();
QStringList projectionsProj4 = settings.value( QStringLiteral( "UI/recentProjectionsProj4" ) ).toStringList();
QStringList projectionsAuthId = settings.value( QStringLiteral( "UI/recentProjectionsAuthId" ) ).toStringList();
//recentProjections.append();
//settings.setValue( "/UI/recentProjections", recentProjections );
projectionsProj4.append( toProj() );
projectionsAuthId.append( authid() );
settings.setValue( QStringLiteral( "UI/recentProjectionsProj4" ), projectionsProj4 );
settings.setValue( QStringLiteral( "UI/recentProjectionsAuthId" ), projectionsAuthId );
}

invalidateCache();
Expand Down Expand Up @@ -3294,43 +3282,75 @@ PJ *QgsCoordinateReferenceSystem::projObject() const
QStringList QgsCoordinateReferenceSystem::recentProjections()
{
QStringList projections;
const QList<QgsCoordinateReferenceSystem> res = recentCoordinateReferenceSystems();
projections.reserve( res.size() );
for ( const QgsCoordinateReferenceSystem &crs : res )
{
projections << QString::number( crs.srsid() );
}
return projections;
}

QList<QgsCoordinateReferenceSystem> QgsCoordinateReferenceSystem::recentCoordinateReferenceSystems()
{
QList<QgsCoordinateReferenceSystem> res;

// Read settings from persistent storage
QgsSettings settings;
projections = settings.value( QStringLiteral( "UI/recentProjections" ) ).toStringList();
/*** The reading (above) of internal id from persistent storage should be removed sometime in the future */
/*** This is kept now for backwards compatibility */

QStringList projectionsProj4 = settings.value( QStringLiteral( "UI/recentProjectionsProj4" ) ).toStringList();
QStringList projectionsWkt = settings.value( QStringLiteral( "UI/recentProjectionsWkt" ) ).toStringList();
QStringList projectionsAuthId = settings.value( QStringLiteral( "UI/recentProjectionsAuthId" ) ).toStringList();
if ( projectionsAuthId.size() >= projections.size() )
int max = std::max( projectionsAuthId.size(), std::max( projectionsProj4.size(), projectionsWkt.size() ) );
res.reserve( max );
for ( int i = 0; i < max; ++i )
{
// We had saved state with AuthId and Proj4. Use that instead
// to find out the crs id
projections.clear();
for ( int i = 0; i < projectionsAuthId.size(); i++ )
{
// Create a crs from the EPSG
QgsCoordinateReferenceSystem crs;
crs.createFromOgcWmsCrs( projectionsAuthId.at( i ) );
if ( ! crs.isValid() )
{
// Couldn't create from EPSG, try the Proj4 string instead
if ( i >= projectionsProj4.size() || !crs.createFromProj( projectionsProj4.at( i ) ) )
{
// No? Skip this entry
continue;
}
//If the CRS can be created but do not correspond to a CRS in the database, skip it (for example a deleted custom CRS)
if ( crs.srsid() == 0 )
{
continue;
}
}
projections << QString::number( crs.srsid() );
}
const QString proj = projectionsProj4.value( i );
const QString wkt = projectionsWkt.value( i );
const QString authid = projectionsAuthId.value( i );

QgsCoordinateReferenceSystem crs;
if ( !authid.isEmpty() )
crs = QgsCoordinateReferenceSystem( authid );
if ( !crs.isValid() && !wkt.isEmpty() )
crs.createFromWkt( wkt );
if ( !crs.isValid() && !proj.isEmpty() )
crs.createFromProj( wkt );

if ( crs.isValid() )
res << crs;
}
return projections;
return res;
}

void QgsCoordinateReferenceSystem::pushRecentCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &crs )
{
// we only want saved and standard CRSes in the recent list
if ( crs.srsid() == 0 || !crs.isValid() )
return;

QList<QgsCoordinateReferenceSystem> recent = recentCoordinateReferenceSystems();
recent.removeAll( crs );
recent.insert( 0, crs );

// trim to max 10 items
recent = recent.mid( 0, 10 );
QStringList authids;
authids.reserve( recent.size() );
QStringList proj;
proj.reserve( recent.size() );
QStringList wkt;
wkt.reserve( recent.size() );
for ( const QgsCoordinateReferenceSystem &c : qgis::as_const( recent ) )
{
authids << c.authid();
proj << c.toProj();
wkt << c.toWkt();
}

QgsSettings settings;
settings.setValue( QStringLiteral( "UI/recentProjectionsAuthId" ), authids );
settings.setValue( QStringLiteral( "UI/recentProjectionsWkt" ), wkt );
settings.setValue( QStringLiteral( "UI/recentProjectionsProj4" ), proj );
}

void QgsCoordinateReferenceSystem::invalidateCache( bool disableCache )
Expand Down
16 changes: 14 additions & 2 deletions src/core/qgscoordinatereferencesystem.h
Expand Up @@ -770,9 +770,21 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
/**
* Returns a list of recently used projections
* \returns list of srsid for recently used projections
* \since QGIS 2.7
* \deprecated use recentCoordinateReferenceSystems() instead.
*/
static QStringList recentProjections();
Q_DECL_DEPRECATED static QStringList recentProjections() SIP_DEPRECATED;

/**
* Returns a list of recently used CRS.
* \since QGIS 3.10.3
*/
static QList< QgsCoordinateReferenceSystem > recentCoordinateReferenceSystems();

/**
* Pushes a recently used CRS to the top of the recent CRS list.
* \since QGIS 3.10.3
*/
static void pushRecentCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &crs );

#ifndef SIP_RUN

Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgscoordinateboundspreviewmapwidget.cpp
Expand Up @@ -31,7 +31,7 @@ QgsCoordinateBoundsPreviewMapWidget::QgsCoordinateBoundsPreviewMapWidget( QWidge
mCanvasCenterMarker->setColor( QColor( 185, 84, 210 ) );
mCanvasCenterMarker->setPenWidth( 3 );

QgsCoordinateReferenceSystem srs( 4326, QgsCoordinateReferenceSystem::EpsgCrsId );
QgsCoordinateReferenceSystem srs( QStringLiteral( "EPSG:4326" ) );
setDestinationCrs( srs );

QString layerPath = QgsApplication::pkgDataPath() + QStringLiteral( "/resources/data/world_map.gpkg|layername=countries" );
Expand Down
42 changes: 6 additions & 36 deletions src/gui/qgsprojectionselectiontreewidget.cpp
Expand Up @@ -71,7 +71,7 @@ QgsProjectionSelectionTreeWidget::QgsProjectionSelectionTreeWidget( QWidget *par
// Hide (internal) ID column
lstRecent->setColumnHidden( QgisCrsIdColumn, true );

mRecentProjections = QgsCoordinateReferenceSystem::recentProjections();
mRecentProjections = QgsCoordinateReferenceSystem::recentCoordinateReferenceSystems();

mCheckBoxNoProjection->setHidden( true );
mCheckBoxNoProjection->setEnabled( false );
Expand Down Expand Up @@ -101,37 +101,7 @@ QgsProjectionSelectionTreeWidget::~QgsProjectionSelectionTreeWidget()
if ( crsId == 0 )
return;

// Save persistent list of projects
mRecentProjections.removeAll( QString::number( crsId ) );
mRecentProjections.prepend( QString::number( crsId ) );
// Prune size of list
while ( mRecentProjections.size() > 8 )
{
mRecentProjections.removeLast();
}

// Save to file *** Should be removed sometime in the future ***
QgsSettings settings;
settings.setValue( QStringLiteral( "/UI/recentProjections" ), mRecentProjections );

// Convert to EPSG and proj4, and save those values also

QStringList projectionsProj4;
QStringList projectionsAuthId;
for ( int i = 0; i < mRecentProjections.size(); i++ )
{
// Create a crs from the crsId
QgsCoordinateReferenceSystem crs( mRecentProjections.at( i ).toLong(), QgsCoordinateReferenceSystem::InternalCrsId );
if ( ! crs.isValid() )
{
// No? Skip this entry
continue;
}
projectionsProj4 << crs.toProj();
projectionsAuthId << crs.authid();
}
settings.setValue( QStringLiteral( "/UI/recentProjectionsProj4" ), projectionsProj4 );
settings.setValue( QStringLiteral( "/UI/recentProjectionsAuthId" ), projectionsAuthId );
QgsCoordinateReferenceSystem::pushRecentCoordinateReferenceSystem( crs() );
}

void QgsProjectionSelectionTreeWidget::resizeEvent( QResizeEvent *event )
Expand All @@ -157,8 +127,8 @@ void QgsProjectionSelectionTreeWidget::showEvent( QShowEvent *event )

if ( !mRecentProjListDone )
{
for ( int i = mRecentProjections.size() - 1; i >= 0; i-- )
insertRecent( mRecentProjections.at( i ).toLong() );
for ( const QgsCoordinateReferenceSystem &crs : qgis::as_const( mRecentProjections ) )
insertRecent( crs );
mRecentProjListDone = true;
}

Expand Down Expand Up @@ -272,12 +242,12 @@ void QgsProjectionSelectionTreeWidget::applySelection( int column, QString value
}
}

void QgsProjectionSelectionTreeWidget::insertRecent( long crsId )
void QgsProjectionSelectionTreeWidget::insertRecent( const QgsCoordinateReferenceSystem &crs )
{
if ( !mProjListDone || !mUserProjListDone )
return;

QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( QString::number( crsId ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( QString::number( crs.srsid() ), Qt::MatchExactly | Qt::MatchRecursive, QgisCrsIdColumn );
if ( nodes.isEmpty() )
return;

Expand Down
7 changes: 3 additions & 4 deletions src/gui/qgsprojectionselectiontreewidget.h
Expand Up @@ -260,15 +260,14 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
long getLargestCrsIdMatch( const QString &sql );

//! add recently used CRS
void insertRecent( long crsId );
void insertRecent( const QgsCoordinateReferenceSystem &crs );

//! Has the Projection List been populated?
bool mProjListDone = false;

//! Has the User Projection List been populated?
bool mUserProjListDone = false;


//! Has the Recent Projection List been populated?
bool mRecentProjListDone = false;

Expand All @@ -281,8 +280,8 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
//! The set of OGC WMS CRSs that want to be applied to this widget
QSet<QString> mCrsFilter;

//! Most recently used projections (trimmed at 25 entries)
QStringList mRecentProjections;
//! Most recently used projections
QList< QgsCoordinateReferenceSystem > mRecentProjections;

//! Hide deprecated CRSes
void hideDeprecated( QTreeWidgetItem *item );
Expand Down
15 changes: 3 additions & 12 deletions src/gui/qgsprojectionselectionwidget.cpp
Expand Up @@ -319,31 +319,22 @@ QString QgsProjectionSelectionWidget::crsOptionText( const QgsCoordinateReferenc

void QgsProjectionSelectionWidget::addRecentCrs()
{
QStringList recentProjections = QgsCoordinateReferenceSystem::recentProjections();
int i = 0;
const auto constRecentProjections = recentProjections;
for ( const QString &projection : constRecentProjections )
const QList< QgsCoordinateReferenceSystem> recentProjections = QgsCoordinateReferenceSystem::recentCoordinateReferenceSystems();
for ( const QgsCoordinateReferenceSystem &crs : recentProjections )
{
long srsid = projection.toLong();
long srsid = crs.srsid();

//check if already shown
if ( crsIsShown( srsid ) )
{
continue;
}

i++;
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromSrsId( srsid );
if ( crs.isValid() )
{
mCrsComboBox->addItem( tr( "%1 - %2" ).arg( crs.authid(), crs.description() ), QgsProjectionSelectionWidget::RecentCrs );
mCrsComboBox->setItemData( mCrsComboBox->count() - 1, QVariant( ( long long )srsid ), Qt::UserRole + 1 );
}
if ( i >= 4 )
{
//limit to 4 recent projections to avoid clutter
break;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/providers/virtual/qgsvirtuallayerprovider.cpp
Expand Up @@ -90,7 +90,9 @@ QgsVirtualLayerProvider::QgsVirtualLayerProvider( QString const &uri, const QgsD

if ( mDefinition.geometrySrid() != -1 )
{
Q_NOWARN_DEPRECATED_PUSH
mCrs = QgsCoordinateReferenceSystem( mDefinition.geometrySrid() );
Q_NOWARN_DEPRECATED_POP
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/providers/virtual/qgsvirtuallayersourceselect.cpp
Expand Up @@ -128,7 +128,9 @@ void QgsVirtualLayerSourceSelect::layerComboChanged( int idx )
{
mGeometryRadio->setChecked( true );
mSrid = def.geometrySrid();
Q_NOWARN_DEPRECATED_PUSH
QgsCoordinateReferenceSystem crs( def.geometrySrid() );
Q_NOWARN_DEPRECATED_POP
mCRS->setText( crs.authid() );
mGeometryType->setCurrentIndex( static_cast<long>( def.geometryWkbType() ) - 1 );
mGeometryField->setText( def.geometryField() );
Expand All @@ -150,7 +152,9 @@ void QgsVirtualLayerSourceSelect::layerComboChanged( int idx )
void QgsVirtualLayerSourceSelect::browseCRS()
{
QgsProjectionSelectionDialog crsSelector( this );
Q_NOWARN_DEPRECATED_PUSH
QgsCoordinateReferenceSystem crs( mSrid );
Q_NOWARN_DEPRECATED_POP
crsSelector.setCrs( crs );
crsSelector.setMessage( QString() );
if ( crsSelector.exec() )
Expand Down
4 changes: 2 additions & 2 deletions src/server/qgsserverapiutils.cpp
Expand Up @@ -438,9 +438,9 @@ QgsExpression QgsServerApiUtils::temporalFilterExpression( const QgsVectorLayer
json QgsServerApiUtils::layerExtent( const QgsVectorLayer *layer )
{
auto extent { layer->extent() };
if ( layer->crs().postgisSrid() != 4326 )
if ( layer->crs().authid() != QLatin1String( "EPSG:4326" ) )
{
static const QgsCoordinateReferenceSystem targetCrs { 4326 };
static const QgsCoordinateReferenceSystem targetCrs( QStringLiteral( "EPSG:4326" ) );
const QgsCoordinateTransform ct( layer->crs(), targetCrs, layer->transformContext() );
extent = ct.transform( extent );
}
Expand Down

0 comments on commit e152685

Please sign in to comment.