Skip to content
Permalink
Browse files

Fix changing project CRS from legend doesn't correctly set CRS

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 ecee43814a3ee13470683e376191cb3719ec0e44
@@ -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
*/
@@ -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;
@@ -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 )
{
@@ -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 );
@@ -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() );
@@ -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 );
@@ -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 );
@@ -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 );
@@ -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() );
@@ -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 )
@@ -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 );
@@ -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
@@ -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 )
@@ -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() );
@@ -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
@@ -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 );
@@ -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
@@ -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.
@@ -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() )
{
@@ -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() )
@@ -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 );

@@ -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
@@ -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++ )
@@ -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 );
@@ -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();
@@ -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() ),
@@ -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();
@@ -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() );
@@ -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

0 comments on commit ecee438

Please sign in to comment.
You can’t perform that action at this time.