Skip to content

Commit

Permalink
Fix changing project CRS from legend doesn't correctly set CRS
Browse files Browse the repository at this point in the history
Also avoid fragile duplicated code for setting/retrieving
common project properties

Fixes #15717
  • Loading branch information
nyalldawson committed Oct 17, 2016
1 parent 9a90a24 commit ecee438
Show file tree
Hide file tree
Showing 31 changed files with 255 additions and 117 deletions.
49 changes: 49 additions & 0 deletions python/core/qgsproject.sip
Expand Up @@ -64,6 +64,38 @@ class QgsProject : QObject
*/
QFileInfo fileInfo() const;

/**
* Returns the project's native coordinate reference system.
* @note added in QGIS 2.18
* @see setCrs()
* @see ellipsoid()
*/
QgsCoordinateReferenceSystem crs() const;

/**
* Sets the project's native coordinate reference system.
* @note added in QGIS 2.18

This comment has been minimized.

Copy link
@3nids

3nids Jan 31, 2017

Member

@nyalldawson this is not available in 2.18. Do you think I can backport to 2.18?

This comment has been minimized.

Copy link
@3nids

3nids Jan 31, 2017

Member

apparently it cannot be backported :(

This comment has been minimized.

Copy link
@nyalldawson

nyalldawson Jan 31, 2017

Author Collaborator

Yeah - I think that was before QgsCoordinateReference system was implicitly shared and there was a bunch of QgsCoordinateReference pointers floating around...

This comment has been minimized.

Copy link
@3nids

3nids Jan 31, 2017

Member

I quickly tried to backport, but there seems to be issues with units too.
Anyway, I could deal with it.
Thanks for the feedback.

* @see crs()
* @see setEllipsoid()
*/
void setCrs( const QgsCoordinateReferenceSystem& crs );

/**
* Returns a proj string representing the project's ellipsoid setting, eg "WGS84".
* @see setEllipsoid()
* @see crs()
* @note added in QGIS 2.18
*/
QString ellipsoid() const;

/**
* Sets the project's ellipsoid from a proj string representation, eg "WGS84".
* @see ellipsoid()
* @see setCrs()
* @note added in QGIS 2.18
*/
void setEllipsoid( const QString& ellipsoid );

/** Clear the project - removes all settings and resets it back to an empty, default state.
* @note added in 2.4
*/
Expand Down Expand Up @@ -258,16 +290,33 @@ class QgsProject : QObject

/** Convenience function to query default distance measurement units for project.
* @note added in QGIS 2.14
* @see setDistanceUnits()
* @see areaUnits()
*/
QgsUnitTypes::DistanceUnit distanceUnits() const;

/**
* Sets the default distance measurement units for the project.
* @note added in QGIS 2.18
* @see distanceUnits()
* @see setAreaUnits()
*/
void setDistanceUnits( QgsUnitTypes::DistanceUnit unit );

/** Convenience function to query default area measurement units for project.
* @note added in QGIS 2.14
* @see distanceUnits()
*/
QgsUnitTypes::AreaUnit areaUnits() const;

/**
* Sets the default area measurement units for the project.
* @note added in QGIS 2.18
* @see areaUnits()
* @see setDistanceUnits()
*/
void setAreaUnits( QgsUnitTypes::AreaUnit unit );

/** Return project's home path
@return home path of project (or QString::null if not set) */
QString homePath() const;
Expand Down
7 changes: 3 additions & 4 deletions src/app/qgisapp.cpp
Expand Up @@ -4435,9 +4435,7 @@ void QgisApp::fileNew( bool thePromptToSaveFlag, bool forceBlank )
QgsCoordinateReferenceSystem srs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( defCrs );
mMapCanvas->setDestinationCrs( srs );
// write the projections _proj string_ to project settings
prj->writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4() );
prj->writeEntry( "SpatialRefSys", "/ProjectCrs", srs.authid() );
prj->writeEntry( "SpatialRefSys", "/ProjectCRSID", static_cast< int >( srs.srsid() ) );
prj->setCrs( srs );
prj->setDirty( false );
if ( srs.mapUnits() != QgsUnitTypes::DistanceUnknownUnit )
{
Expand Down Expand Up @@ -7306,7 +7304,7 @@ void QgisApp::selectByForm()

myDa.setSourceCrs( vlayer->crs().srsid() );
myDa.setEllipsoidalMode( mMapCanvas->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

QgsAttributeEditorContext context;
context.setDistanceArea( myDa );
Expand Down Expand Up @@ -8582,6 +8580,7 @@ void QgisApp::setProjectCrsFromLayer()
QgsCoordinateReferenceSystem crs = mLayerTreeView->currentLayer()->crs();
mMapCanvas->freeze();
mMapCanvas->setDestinationCrs( crs );
QgsProject::instance()->setCrs( crs );
if ( crs.mapUnits() != QgsUnitTypes::DistanceUnknownUnit )
{
mMapCanvas->setMapUnits( crs.mapUnits() );
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgisappinterface.cpp
Expand Up @@ -681,7 +681,7 @@ QgsAttributeDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeat

myDa.setSourceCrs( l->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

QgsAttributeEditorContext context;
context.setDistanceArea( myDa );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsattributeactionpropertiesdialog.cpp
Expand Up @@ -52,7 +52,7 @@ QgsAttributeActionPropertiesDialog::QgsAttributeActionPropertiesDialog( QgsActio
QgsDistanceArea myDa;
myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

mFieldExpression->setLayer( mLayer );
mFieldExpression->setGeomCalculator( myDa );
Expand Down Expand Up @@ -81,7 +81,7 @@ QgsAttributeActionPropertiesDialog::QgsAttributeActionPropertiesDialog( QgsVecto
QgsDistanceArea myDa;
myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

mFieldExpression->setLayer( mLayer );
mFieldExpression->setGeomCalculator( myDa );
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -126,7 +126,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid

myDa->setSourceCrs( mLayer->crs() );
myDa->setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa->setEllipsoid( QgsProject::instance()->ellipsoid() );

mEditorContext.setDistanceArea( *myDa );
mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
Expand Down Expand Up @@ -559,7 +559,7 @@ void QgsAttributeTableDialog::filterExpressionBuilder()
QgsDistanceArea myDa;
myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
dlg.setGeomCalculator( myDa );

if ( dlg.exec() == QDialog::Accepted )
Expand Down Expand Up @@ -920,7 +920,7 @@ void QgsAttributeTableDialog::setFilterExpression( const QString& filterString,

myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

// parse search string and build parsed tree
QgsExpression filterExpression( filter );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsdiagramproperties.cpp
Expand Up @@ -178,7 +178,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer, QWidget* pare
QgsDistanceArea myDa;
myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( mMapCanvas->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
mSizeFieldExpressionWidget->setGeomCalculator( myDa );

//insert all attributes into the combo boxes
Expand Down Expand Up @@ -871,7 +871,7 @@ QString QgsDiagramProperties::showExpressionBuilder( const QString& initialExpre
QgsDistanceArea myDa;
myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( mMapCanvas->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
dlg.setGeomCalculator( myDa );

if ( dlg.exec() == QDialog::Accepted )
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsfeatureaction.cpp
Expand Up @@ -57,7 +57,7 @@ QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )

myDa.setSourceCrs( mLayer->crs() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

context.setDistanceArea( myDa );
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsfieldcalculator.cpp
Expand Up @@ -60,7 +60,7 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl, QWidget* parent )
QgsDistanceArea myDa;
myDa.setSourceCrs( vl->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
builder->setGeomCalculator( myDa );

//default values for field width and precision
Expand Down Expand Up @@ -160,7 +160,7 @@ void QgsFieldCalculator::accept()

myDa.setSourceCrs( mVectorLayer->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );

QString calcString = builder->expressionText();
QgsExpression exp( calcString );
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgslabelinggui.cpp
Expand Up @@ -590,7 +590,7 @@ void QgsLabelingGui::init()
QgsDistanceArea myDa;
myDa.setSourceCrs( mLayer->crs().srsid() );
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
mFieldExpressionWidget->setGeomCalculator( myDa );

// set placement methods page based on geometry type
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsmaptoolmeasureangle.cpp
Expand Up @@ -181,7 +181,7 @@ void QgsMapToolMeasureAngle::updateSettings()

void QgsMapToolMeasureAngle::configureDistanceArea()
{
QString ellipsoidId = QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE );
QString ellipsoidId = QgsProject::instance()->ellipsoid();
mDa.setSourceCrs( mCanvas->mapSettings().destinationCrs().srsid() );
mDa.setEllipsoid( ellipsoidId );
// Only use ellipsoidal calculation when project wide transformation is enabled.
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsmeasuredialog.cpp
Expand Up @@ -79,7 +79,7 @@ void QgsMeasureDialog::updateSettings()
mDistanceUnits = QgsProject::instance()->distanceUnits();
mAreaUnits = QgsProject::instance()->areaUnits();
mDa.setSourceCrs( mTool->canvas()->mapSettings().destinationCrs().srsid() );
mDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
// Only use ellipsoidal calculation when project wide transformation is enabled.
if ( mTool->canvas()->mapSettings().hasCrsTransformEnabled() )
{
Expand Down
18 changes: 8 additions & 10 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -783,9 +783,7 @@ void QgsProjectProperties::apply()
QgsDebugMsg( QString( "Selected CRS " ) + srs.description() );
// write the currently selected projections _proj string_ to project settings
QgsDebugMsg( QString( "SpatialRefSys/ProjectCRSProj4String: %1" ).arg( projectionSelector->selectedProj4String() ) );
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", projectionSelector->selectedProj4String() );
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSID", ( int ) projectionSelector->selectedCrsId() );
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCrs", projectionSelector->selectedAuthId() );
QgsProject::instance()->setCrs( srs );

// Set the map units to the projected coordinates if we are projecting
if ( isProjected() )
Expand Down Expand Up @@ -837,10 +835,10 @@ void QgsProjectProperties::apply()
emit displayPrecisionChanged();

QgsUnitTypes::DistanceUnit distanceUnits = static_cast< QgsUnitTypes::DistanceUnit >( mDistanceUnitsCombo->currentData().toInt() );
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( distanceUnits ) );
QgsProject::instance()->setDistanceUnits( distanceUnits );

QgsUnitTypes::AreaUnit areaUnits = static_cast< QgsUnitTypes::AreaUnit >( mAreaUnitsCombo->currentData().toInt() );
QgsProject::instance()->writeEntry( "Measurement", "/AreaUnits", QgsUnitTypes::encodeUnit( areaUnits ) );
QgsProject::instance()->setAreaUnits( areaUnits );

QgsProject::instance()->writeEntry( "Paths", "/Absolute", cbxAbsolutePath->currentIndex() == 0 );

Expand All @@ -855,13 +853,13 @@ void QgsProjectProperties::apply()
major = QLocale::system().toDouble( leSemiMajor->text() );
minor = QLocale::system().toDouble( leSemiMinor->text() );
}
QgsProject::instance()->writeEntry( "Measure", "/Ellipsoid", QString( "PARAMETER:%1:%2" )
.arg( major, 0, 'g', 17 )
.arg( minor, 0, 'g', 17 ) );
QgsProject::instance()->setEllipsoid( QString( "PARAMETER:%1:%2" )
.arg( major, 0, 'g', 17 )
.arg( minor, 0, 'g', 17 ) );
}
else
{
QgsProject::instance()->writeEntry( "Measure", "/Ellipsoid", mEllipsoidList[ mEllipsoidIndex ].acronym );
QgsProject::instance()->setEllipsoid( mEllipsoidList[ mEllipsoidIndex ].acronym );
}

//set the color for selections
Expand Down Expand Up @@ -2001,7 +1999,7 @@ void QgsProjectProperties::projectionSelectorInitialized()
QgsDebugMsg( "Setting up ellipsoid" );

// Reading ellipsoid from setttings
QStringList mySplitEllipsoid = QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ).split( ':' );
QStringList mySplitEllipsoid = QgsProject::instance()->ellipsoid().split( ':' );

int myIndex = 0;
for ( int i = 0; i < mEllipsoidList.length(); i++ )
Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgscomposerhtml.cpp
Expand Up @@ -548,7 +548,7 @@ void QgsComposerHtml::setExpressionContext( const QgsFeature &feature, QgsVector
{
mDistanceArea->setEllipsoidalMode( mComposition->mapSettings().hasCrsTransformEnabled() );
}
mDistanceArea->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
mDistanceArea->setEllipsoid( QgsProject::instance()->ellipsoid() );

// create JSON representation of feature
QgsJSONExporter exporter( layer );
Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgscomposerlabel.cpp
Expand Up @@ -265,7 +265,7 @@ void QgsComposerLabel::refreshExpressionContext()
mDistanceArea->setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
}
mDistanceArea->setEllipsoidalMode( mComposition->mapSettings().hasCrsTransformEnabled() );
mDistanceArea->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
mDistanceArea->setEllipsoid( QgsProject::instance()->ellipsoid() );
contentChanged();

update();
Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgscomposerscalebar.cpp
Expand Up @@ -304,7 +304,7 @@ double QgsComposerScaleBar::mapWidth() const
QgsDistanceArea da;
da.setEllipsoidalMode( mComposition->mapSettings().hasCrsTransformEnabled() );
da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );
da.setEllipsoid( QgsProject::instance()->ellipsoid() );

QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceMeters;
double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ),
Expand Down
40 changes: 40 additions & 0 deletions src/core/qgsproject.cpp
Expand Up @@ -444,6 +444,36 @@ QFileInfo QgsProject::fileInfo() const
return QFileInfo( imp_->file );
}

QgsCoordinateReferenceSystem QgsProject::crs() const
{
QgsCoordinateReferenceSystem projectCrs;
long currentCRS = readNumEntry( "SpatialRefSys", "/ProjectCRSID", -1 );
if ( currentCRS != -1 )
{
projectCrs = QgsCoordinateReferenceSystem::fromSrsId( currentCRS );
}
return projectCrs;
}

void QgsProject::setCrs( const QgsCoordinateReferenceSystem &crs )
{
writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", crs.toProj4() );
writeEntry( "SpatialRefSys", "/ProjectCRSID", static_cast< int >( crs.srsid() ) );
writeEntry( "SpatialRefSys", "/ProjectCrs", crs.authid() );
setDirty( true );
}

QString QgsProject::ellipsoid() const
{
return readEntry( "Measure", "/Ellipsoid", GEO_NONE );
}

void QgsProject::setEllipsoid( const QString& ellipsoid )
{
writeEntry( "Measure", "/Ellipsoid", ellipsoid );
setDirty( true );
}

void QgsProject::clear()
{
imp_->clear();
Expand Down Expand Up @@ -2108,6 +2138,11 @@ QgsUnitTypes::DistanceUnit QgsProject::distanceUnits() const
return ok ? type : QgsUnitTypes::DistanceMeters;
}

void QgsProject::setDistanceUnits( QgsUnitTypes::DistanceUnit unit )
{
writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( unit ) );
}

QgsUnitTypes::AreaUnit QgsProject::areaUnits() const
{
QString areaUnitString = QgsProject::instance()->readEntry( "Measurement", "/AreaUnits", QString() );
Expand All @@ -2121,6 +2156,11 @@ QgsUnitTypes::AreaUnit QgsProject::areaUnits() const
return ok ? type : QgsUnitTypes::AreaSquareMeters;
}

void QgsProject::setAreaUnits( QgsUnitTypes::AreaUnit unit )
{
writeEntry( "Measurement", "/AreaUnits", QgsUnitTypes::encodeUnit( unit ) );
}

void QgsProjectBadLayerDefaultHandler::handleBadLayers( const QList<QDomNode>& /*layers*/, const QDomDocument& /*projectDom*/ )
{
// just ignore any bad layers
Expand Down

0 comments on commit ecee438

Please sign in to comment.