Skip to content
Permalink
Browse files

[needs-docs] Composer maps default to a "use project CRS" setting

And overriding projection is only done if user has manually
chosen a different CRS from the list.

This means that templates and compositions in server can still
adapt to follow the project CRS, but if desired specific map
items (eg an overview map) can use the CRS override to always
show in a particular CRS.
  • Loading branch information
nyalldawson committed Jan 18, 2017
1 parent 6a4d605 commit a3dd380d35fdeae35abd98e966607097ebdeaf08
@@ -128,6 +128,7 @@ class QgsComposerMap : QgsComposerItem
// QgsRectangle* currentMapExtent();

QgsCoordinateReferenceSystem crs() const;
QgsCoordinateReferenceSystem presetCrs() const;
void setCrs( const QgsCoordinateReferenceSystem& crs );

PreviewMode previewMode() const;
@@ -64,6 +64,9 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap )
mPreviewModeComboBox->insertItem( 1, tr( "Render" ) );
mPreviewModeComboBox->insertItem( 2, tr( "Rectangle" ) );

mCrsSelector->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, true );
mCrsSelector->setNotSetText( tr( "Use project CRS" ) );

// follow preset combo
mFollowVisibilityPresetCombo->setModel( new QStringListModel( mFollowVisibilityPresetCombo ) );
connect( mFollowVisibilityPresetCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( followVisibilityPresetSelected( int ) ) );
@@ -270,7 +273,7 @@ void QgsComposerMapWidget::mapCrsChanged( const QgsCoordinateReferenceSystem& cr
return;
}

if ( mComposerMap->crs() == crs )
if ( mComposerMap->presetCrs() == crs )
return;

// try to reproject to maintain extent
@@ -280,7 +283,7 @@ void QgsComposerMapWidget::mapCrsChanged( const QgsCoordinateReferenceSystem& cr
QgsRectangle newExtent;
try
{
QgsCoordinateTransform xForm( oldCrs, crs );
QgsCoordinateTransform xForm( oldCrs, crs.isValid() ? crs : QgsProject::instance()->crs() );
QgsRectangle prevExtent = *mComposerMap->currentMapExtent();
newExtent = xForm.transformBoundingBox( prevExtent );
updateExtent = true;
@@ -605,7 +608,7 @@ void QgsComposerMapWidget::updateGuiElements()

blockAllSignals( true );

whileBlocking( mCrsSelector )->setCrs( mComposerMap->crs() );
whileBlocking( mCrsSelector )->setCrs( mComposerMap->presetCrs() );

//width, height, scale
double scale = mComposerMap->scale();
@@ -124,9 +124,6 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition )

void QgsComposerMap::init()
{
if ( mComposition && mComposition->project() )
mCrs = mComposition->project()->crs();

mGridStack = new QgsComposerMapGridStack( this );
mOverviewStack = new QgsComposerMapOverviewStack( this );
connectUpdateSlot();
@@ -204,14 +201,15 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, QSizeF
QgsMapSettings QgsComposerMap::mapSettings( const QgsRectangle& extent, QSizeF size, int dpi ) const
{
QgsExpressionContext expressionContext = createExpressionContext();
QgsCoordinateReferenceSystem renderCrs = crs();

QgsMapSettings jobMapSettings;
jobMapSettings.setDestinationCrs( mCrs );
jobMapSettings.setDestinationCrs( renderCrs );
jobMapSettings.setCrsTransformEnabled( true );
jobMapSettings.setExtent( extent );
jobMapSettings.setOutputSize( size.toSize() );
jobMapSettings.setOutputDpi( dpi );
jobMapSettings.setMapUnits( mCrs.mapUnits() );
jobMapSettings.setMapUnits( renderCrs.mapUnits() );
jobMapSettings.setBackgroundColor( Qt::transparent );
jobMapSettings.setRotation( mEvaluatedMapRotation );

@@ -253,7 +251,7 @@ QgsMapSettings QgsComposerMap::mapSettings( const QgsRectangle& extent, QSizeF s
jobMapSettings.setFlag( QgsMapSettings::DrawSelection, false );
jobMapSettings.setFlag( QgsMapSettings::UseAdvancedEffects, mComposition->useAdvancedEffects() ); // respect the composition's useAdvancedEffects flag

jobMapSettings.datumTransformStore().setDestinationCrs( mCrs );
jobMapSettings.datumTransformStore().setDestinationCrs( renderCrs );

return jobMapSettings;
}
@@ -873,7 +871,11 @@ QgsRectangle* QgsComposerMap::currentMapExtent()

QgsCoordinateReferenceSystem QgsComposerMap::crs() const
{
return mCrs;
if ( mCrs.isValid() )
return mCrs;
else if ( mComposition && mComposition->project() )
return mComposition->project()->crs();
return QgsCoordinateReferenceSystem();
}

void QgsComposerMap::setCrs( const QgsCoordinateReferenceSystem& crs )
@@ -1271,9 +1273,12 @@ bool QgsComposerMap::writeXml( QDomElement& elem, QDomDocument & doc ) const
extentElem.setAttribute( QStringLiteral( "ymax" ), qgsDoubleToString( mExtent.yMaximum() ) );
composerMapElem.appendChild( extentElem );

QDomElement crsElem = doc.createElement( QStringLiteral( "crs" ) );
mCrs.writeXml( crsElem, doc );
composerMapElem.appendChild( crsElem );
if ( mCrs.isValid() )
{
QDomElement crsElem = doc.createElement( QStringLiteral( "crs" ) );
mCrs.writeXml( crsElem, doc );
composerMapElem.appendChild( crsElem );
}

// follow map theme
composerMapElem.setAttribute( QStringLiteral( "followPreset" ), mFollowVisibilityPreset ? "true" : "false" );
@@ -1382,6 +1387,10 @@ bool QgsComposerMap::readXml( const QDomElement& itemElem, const QDomDocument& d
QDomElement crsElem = crsNodeList.at( 0 ).toElement();
mCrs.readXml( crsElem );
}
else
{
mCrs = QgsCoordinateReferenceSystem();
}

//map rotation
if ( !qgsDoubleNear( itemElem.attribute( QStringLiteral( "mapRotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
@@ -168,15 +168,33 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
QgsRectangle* currentMapExtent();

/**
* Returns the map's coordinate reference system.
* Returns coordinate reference system used for rendering the map.
* This will match the presetCrs() if that is set, or if a preset
* CRS is not set then the map's CRS will follow the composition's
* project's CRS.
* @note added in QGIS 3.0
* @see presetCrs()
* @see setCrs()
*/
QgsCoordinateReferenceSystem crs() const;

/**
* Sets the map's coordinate reference system.
* Returns the map's preset coordinate reference system. If set, this
* CRS will be used to render the map regardless of any project CRS
* setting. If the returned CRS is not valid then the project CRS
* will be used to render the map.
* @note added in QGIS 3.0
* @see crs()
* @see setCrs()
*/
QgsCoordinateReferenceSystem presetCrs() const { return mCrs; }

/**
* Sets the map's preset coordinate reference system. If a valid CRS is
* set, this CRS will be used to render the map regardless of any project CRS
* setting. If the CRS is not valid then the project CRS will be used to render the map.
* @see crs()
* @see presetCrs()
* @note added in QGIS 3.0
*/
void setCrs( const QgsCoordinateReferenceSystem& crs );
@@ -223,6 +223,7 @@ void QgsProjectionSelectionWidget::comboIndexChanged( int idx )
}
case QgsProjectionSelectionWidget::CrsNotSet:
emit cleared();
emit crsChanged( QgsCoordinateReferenceSystem() );
return;
}
}
@@ -79,8 +79,10 @@ QgsComposition* QgsWmsConfigParser::createPrintComposition( const QString& compo
continue;
}

// Change CRS of map to match requested CRS
if ( mapSettings.destinationCrs().isValid() )
// Change CRS of map set to "project CRS" to match requested CRS
// (if map has a valid preset crs then we keep this crs and don't use the
// requested crs for this map item)
if ( mapSettings.destinationCrs().isValid() && !currentMap->presetCrs().isValid() )
currentMap->setCrs( mapSettings.destinationCrs() );

QStringList coordList = extent.split( QStringLiteral( "," ) );
@@ -156,25 +156,33 @@ def testMapCrs(self):
composition.addComposerMap(map)

self.assertEqual(map.crs().authid(), 'EPSG:4326')
self.assertFalse(map.presetCrs().isValid())

# overwrite CRS
map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
self.assertEqual(map.crs().authid(), 'EPSG:3857')
self.assertEqual(map.presetCrs().authid(), 'EPSG:3857')
checker = QgsCompositionChecker('composermap_crs3857', composition)
checker.setControlPathPrefix("composer_map")
result, message = checker.testComposition()
self.assertTrue(result, message)

# overwrite CRS
map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
self.assertEqual(map.presetCrs().authid(), 'EPSG:4326')
self.assertEqual(map.crs().authid(), 'EPSG:4326')
rectangle = QgsRectangle(-124, 17, -78, 52)
map.zoomToExtent(rectangle)
self.assertEqual(map.crs().authid(), 'EPSG:4326')
checker = QgsCompositionChecker('composermap_crs4326', composition)
checker.setControlPathPrefix("composer_map")
result, message = checker.testComposition()
self.assertTrue(result, message)

# change back to project CRS
map.setCrs(QgsCoordinateReferenceSystem())
self.assertEqual(map.crs().authid(), 'EPSG:4326')
self.assertFalse(map.presetCrs().isValid())

# Fails because addItemsFromXml has been commented out in sip
@unittest.expectedFailure
def testuniqueId(self):

0 comments on commit a3dd380

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