[composer] Add zoomToExtent for QgsComposerMap, allows easily fitting a set extent into the map item without altering the item's shape

This commit is contained in:
Nyall Dawson 2014-09-01 16:05:27 +10:00
parent dd78f099ab
commit b5835972bb
4 changed files with 73 additions and 32 deletions

View File

@ -129,9 +129,24 @@ class QgsComposerMap : QgsComposerItem
/**Sets new scale and changes only mExtent*/
void setNewScale( double scaleDenominator, bool forceUpdate = true );
/**Sets new Extent and changes width, height (and implicitely also scale)*/
/**Sets new extent for the map. This method may change the width or height of the map
* item to ensure that the extent exactly matches the specified extent, with no
* overlap or margin. This method implicitly alters the map scale.
* @param extent new extent for the map
* @see zoomToExtent
*/
void setNewExtent( const QgsRectangle& extent );
/**Zooms the map so that the specified extent is fully visible within the map item.
* This method will not change the width or height of the map, and may result in
* an overlap or margin from the specified extent. This method implicitly alters the
* map scale.
* @param extent new extent for the map
* @see setNewExtent
* @note added in QGIS 2.5
*/
void zoomToExtent( const QgsRectangle& extent );
/**Sets new Extent for the current atlas preview and changes width, height (and implicitely also scale).
Atlas preview extents are only temporary, and are regenerated whenever the atlas feature changes
*/

View File

@ -447,37 +447,8 @@ void QgsComposerMapWidget::on_mSetToMapCanvasExtentButton_clicked()
QgsRectangle newExtent = mComposerMap->composition()->mapSettings().visibleExtent();
//Make sure the width/height ratio is the same as in current composer map extent.
//This is to keep the map item frame and the page layout fixed
QgsRectangle currentMapExtent = *( mComposerMap->currentMapExtent() );
double currentWidthHeightRatio = currentMapExtent.width() / currentMapExtent.height();
double newWidthHeightRatio = newExtent.width() / newExtent.height();
if ( currentWidthHeightRatio < newWidthHeightRatio )
{
//enlarge height of new extent, ensuring the map center stays the same
double newHeight = newExtent.width() / currentWidthHeightRatio;
double deltaHeight = newHeight - newExtent.height();
newExtent.setYMinimum( newExtent.yMinimum() - deltaHeight / 2 );
newExtent.setYMaximum( newExtent.yMaximum() + deltaHeight / 2 );
}
else
{
//enlarge width of new extent, ensuring the map center stays the same
double newWidth = currentWidthHeightRatio * newExtent.height();
double deltaWidth = newWidth - newExtent.width();
newExtent.setXMinimum( newExtent.xMinimum() - deltaWidth / 2 );
newExtent.setXMaximum( newExtent.xMaximum() + deltaWidth / 2 );
}
//fill text into line edits
mXMinLineEdit->setText( QString::number( newExtent.xMinimum() ) );
mXMaxLineEdit->setText( QString::number( newExtent.xMaximum() ) );
mYMinLineEdit->setText( QString::number( newExtent.yMinimum() ) );
mYMaxLineEdit->setText( QString::number( newExtent.yMaximum() ) );
mComposerMap->beginCommand( tr( "Map extent changed" ) );
mComposerMap->setNewExtent( newExtent );
mComposerMap->zoomToExtent( newExtent );
mComposerMap->endCommand();
}

View File

@ -710,6 +710,46 @@ void QgsComposerMap::setNewExtent( const QgsRectangle& extent )
updateItem();
}
void QgsComposerMap::zoomToExtent( const QgsRectangle &extent )
{
QgsRectangle newExtent = extent;
//Make sure the width/height ratio is the same as the current composer map extent.
//This is to keep the map item frame size fixed
double currentWidthHeightRatio = currentMapExtent()->width() / currentMapExtent()->height();
double newWidthHeightRatio = newExtent.width() / newExtent.height();
if ( currentWidthHeightRatio < newWidthHeightRatio )
{
//enlarge height of new extent, ensuring the map center stays the same
double newHeight = newExtent.width() / currentWidthHeightRatio;
double deltaHeight = newHeight - newExtent.height();
newExtent.setYMinimum( newExtent.yMinimum() - deltaHeight / 2 );
newExtent.setYMaximum( newExtent.yMaximum() + deltaHeight / 2 );
}
else
{
//enlarge width of new extent, ensuring the map center stays the same
double newWidth = currentWidthHeightRatio * newExtent.height();
double deltaWidth = newWidth - newExtent.width();
newExtent.setXMinimum( newExtent.xMinimum() - deltaWidth / 2 );
newExtent.setXMaximum( newExtent.xMaximum() + deltaWidth / 2 );
}
if ( *currentMapExtent() == newExtent )
{
return;
}
*currentMapExtent() = newExtent;
//recalculate data defined scale and extents, since that may override extent
refreshMapExtents();
mCacheUpdated = false;
updateItem();
emit itemChanged();
emit extentChanged();
}
void QgsComposerMap::setNewAtlasFeatureExtent( const QgsRectangle& extent )
{
if ( mAtlasFeatureExtent != extent )

View File

@ -172,9 +172,24 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
/**Sets new scale and changes only mExtent*/
void setNewScale( double scaleDenominator, bool forceUpdate = true );
/**Sets new Extent and changes width, height (and implicitely also scale)*/
/**Sets new extent for the map. This method may change the width or height of the map
* item to ensure that the extent exactly matches the specified extent, with no
* overlap or margin. This method implicitly alters the map scale.
* @param extent new extent for the map
* @see zoomToExtent
*/
void setNewExtent( const QgsRectangle& extent );
/**Zooms the map so that the specified extent is fully visible within the map item.
* This method will not change the width or height of the map, and may result in
* an overlap or margin from the specified extent. This method implicitly alters the
* map scale.
* @param extent new extent for the map
* @see setNewExtent
* @note added in QGIS 2.5
*/
void zoomToExtent( const QgsRectangle& extent );
/**Sets new Extent for the current atlas preview and changes width, height (and implicitely also scale).
Atlas preview extents are only temporary, and are regenerated whenever the atlas feature changes
*/