Skip to content

Commit

Permalink
[composer] Add zoomToExtent for QgsComposerMap, allows easily fitting…
Browse files Browse the repository at this point in the history
… a set extent into the map item without altering the item's shape
  • Loading branch information
nyalldawson committed Sep 1, 2014
1 parent dd78f09 commit b583597
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 32 deletions.
17 changes: 16 additions & 1 deletion python/core/composer/qgscomposermap.sip
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
31 changes: 1 addition & 30 deletions src/app/composer/qgscomposermapwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
40 changes: 40 additions & 0 deletions src/core/composer/qgscomposermap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
17 changes: 16 additions & 1 deletion src/core/composer/qgscomposermap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit b583597

Please sign in to comment.