Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add autocentering of overview

Work funded by Tuscany Region - SITA. Contract "Support to the use
of GFOSS (Geographic Free and Open Source Software) Desktop tools"
(CIG Z3B06FA6D7).
  • Loading branch information...
commit 1556185d7ee1ce4711a6c32e83f2287855ef258f 1 parent bdd61d5
@mhugo mhugo authored
View
11 src/app/composer/qgscomposermapwidget.cpp
@@ -303,6 +303,8 @@ void QgsComposerMapWidget::updateGuiElements()
mOverviewBlendModeComboBox->setBlendMode( mComposerMap->overviewBlendMode() );
//overview inverted
mOverviewInvertCheckbox->setChecked( mComposerMap->overviewInverted() );
+ //center overview
+ mOverviewCenterCheckbox->setChecked( mComposerMap->overviewCentered() );
//grid
if ( mComposerMap->gridEnabled() )
@@ -452,6 +454,7 @@ void QgsComposerMapWidget::blockAllSignals( bool b )
mOverviewFrameStyleButton->blockSignals( b );
mOverviewBlendModeComboBox->blockSignals( b );
mOverviewInvertCheckbox->blockSignals( b );
+ mOverviewCenterCheckbox->blockSignals( b );
}
void QgsComposerMapWidget::on_mUpdatePreviewButton_clicked()
@@ -591,6 +594,14 @@ void QgsComposerMapWidget::on_mOverviewInvertCheckbox_toggled( bool state )
}
}
+void QgsComposerMapWidget::on_mOverviewCenterCheckbox_toggled( bool state )
+{
+ if ( mComposerMap )
+ {
+ mComposerMap->setOverviewCentered( state );
+ }
+}
+
void QgsComposerMapWidget::on_mGridCheckBox_toggled( bool state )
{
if ( !mComposerMap )
View
1  src/app/composer/qgscomposermapwidget.h
@@ -46,6 +46,7 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
void on_mOverviewFrameStyleButton_clicked();
void on_mOverviewBlendModeComboBox_currentIndexChanged( int index );
void on_mOverviewInvertCheckbox_toggled( bool state );
+ void on_mOverviewCenterCheckbox_toggled( bool state );
void on_mXMinLineEdit_editingFinished();
void on_mXMaxLineEdit_editingFinished();
View
126 src/core/composer/qgscomposermap.cpp
@@ -41,7 +41,8 @@
QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int width, int height )
: QgsComposerItem( x, y, width, height, composition ), mKeepLayerSet( false ),
- mOverviewFrameMapId( -1 ), mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mGridEnabled( false ), mGridStyle( Solid ),
+ mOverviewFrameMapId( -1 ), mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mOverviewCentered( false ),
+ mGridEnabled( false ), mGridStyle( Solid ),
mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationFontColor( QColor( 0, 0, 0 ) ),
mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ), mGridBlendMode( QPainter::CompositionMode_SourceOver ),
mLeftGridAnnotationPosition( OutsideMapFrame ), mRightGridAnnotationPosition( OutsideMapFrame ),
@@ -86,7 +87,8 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
QgsComposerMap::QgsComposerMap( QgsComposition *composition )
: QgsComposerItem( 0, 0, 10, 10, composition ), mKeepLayerSet( false ), mOverviewFrameMapId( -1 ),
- mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mGridEnabled( false ), mGridStyle( Solid ),
+ mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mOverviewCentered( false ),
+ mGridEnabled( false ), mGridStyle( Solid ),
mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationFontColor( QColor( 0, 0, 0 ) ),
mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ), mGridBlendMode( QPainter::CompositionMode_SourceOver ),
mLeftGridAnnotationPosition( OutsideMapFrame ), mRightGridAnnotationPosition( OutsideMapFrame ),
@@ -116,6 +118,28 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition )
initGridAnnotationFormatFromProject();
}
+void QgsComposerMap::extentCenteredOnOverview( QgsRectangle& extent ) const
+{
+ extent = mExtent;
+ if ( ! mOverviewCentered ) {
+ return;
+ }
+
+ if ( mOverviewFrameMapId != -1 ) {
+ const QgsComposerMap* overviewFrameMap = mComposition->getComposerMapById( mOverviewFrameMapId );
+ QgsRectangle otherExtent = overviewFrameMap->extent();
+
+ if ( ! mExtent.contains( otherExtent ) ) {
+ QgsPoint center = otherExtent.center();
+ QgsRectangle movedExtent( center.x() - mExtent.width() / 2,
+ center.y() - mExtent.height() / 2,
+ center.x() - mExtent.width() / 2 + mExtent.width(),
+ center.y() - mExtent.height() / 2 + mExtent.height() );
+ extent = movedExtent;
+ }
+ }
+}
+
QgsComposerMap::~QgsComposerMap()
{
delete mOverviewFrameMapSymbol;
@@ -297,6 +321,10 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
QgsRectangle requestRectangle;
requestedExtent( requestRectangle );
+
+ QgsRectangle cExtent;
+ extentCenteredOnOverview( cExtent );
+
double horizontalVScaleFactor = horizontalViewScaleFactor();
if ( horizontalVScaleFactor < 0 )
{
@@ -305,15 +333,15 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
double imagePixelWidth = mExtent.width() / requestRectangle.width() * mCacheImage.width() ; //how many pixels of the image are for the map extent?
double scale = rect().width() / imagePixelWidth;
- QgsPoint rotationPoint = QgsPoint(( mExtent.xMaximum() + mExtent.xMinimum() ) / 2.0, ( mExtent.yMaximum() + mExtent.yMinimum() ) / 2.0 );
+ QgsPoint rotationPoint = QgsPoint(( cExtent.xMaximum() + cExtent.xMinimum() ) / 2.0, ( cExtent.yMaximum() + cExtent.yMinimum() ) / 2.0 );
//shift such that rotation point is at 0/0 point in the coordinate system
double yShiftMM = ( requestRectangle.yMaximum() - rotationPoint.y() ) * mapUnitsToMM();
double xShiftMM = ( requestRectangle.xMinimum() - rotationPoint.x() ) * mapUnitsToMM();
//shift such that top left point of the extent at point 0/0 in item coordinate system
- double xTopLeftShift = ( rotationPoint.x() - mExtent.xMinimum() ) * mapUnitsToMM();
- double yTopLeftShift = ( mExtent.yMaximum() - rotationPoint.y() ) * mapUnitsToMM();
+ double xTopLeftShift = ( rotationPoint.x() - cExtent.xMinimum() ) * mapUnitsToMM();
+ double yTopLeftShift = ( cExtent.yMaximum() - rotationPoint.y() ) * mapUnitsToMM();
painter->save();
@@ -351,16 +379,20 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
QgsRectangle requestRectangle;
requestedExtent( requestRectangle );
+ QgsRectangle cExtent;
+ extentCenteredOnOverview( cExtent );
+
QSizeF theSize( requestRectangle.width() * mapUnitsToMM(), requestRectangle.height() * mapUnitsToMM() );
- QgsPoint rotationPoint = QgsPoint(( mExtent.xMaximum() + mExtent.xMinimum() ) / 2.0, ( mExtent.yMaximum() + mExtent.yMinimum() ) / 2.0 );
+
+ QgsPoint rotationPoint = QgsPoint(( cExtent.xMaximum() + cExtent.xMinimum() ) / 2.0, ( cExtent.yMaximum() + cExtent.yMinimum() ) / 2.0 );
//shift such that rotation point is at 0/0 point in the coordinate system
double yShiftMM = ( requestRectangle.yMaximum() - rotationPoint.y() ) * mapUnitsToMM();
double xShiftMM = ( requestRectangle.xMinimum() - rotationPoint.x() ) * mapUnitsToMM();
//shift such that top left point of the extent at point 0/0 in item coordinate system
- double xTopLeftShift = ( rotationPoint.x() - mExtent.xMinimum() ) * mapUnitsToMM();
- double yTopLeftShift = ( mExtent.yMaximum() - rotationPoint.y() ) * mapUnitsToMM();
+ double xTopLeftShift = ( rotationPoint.x() - cExtent.xMinimum() ) * mapUnitsToMM();
+ double yTopLeftShift = ( cExtent.yMaximum() - rotationPoint.y() ) * mapUnitsToMM();
painter->save();
painter->translate( mXOffset, mYOffset );
painter->translate( xTopLeftShift, yTopLeftShift );
@@ -757,6 +789,9 @@ bool QgsComposerMap::writeXML( QDomElement& elem, QDomDocument & doc ) const
{
overviewFrameElem.setAttribute( "overviewInverted", "false" );
}
+
+ overviewFrameElem.setAttribute( "overviewCentered", mOverviewCentered ? "true" : "false" );
+
QDomElement overviewFrameStyleElem = QgsSymbolLayerV2Utils::saveSymbol( QString(), mOverviewFrameMapSymbol, doc );
overviewFrameElem.appendChild( overviewFrameStyleElem );
composerMapElem.appendChild( overviewFrameElem );
@@ -874,6 +909,15 @@ bool QgsComposerMap::readXML( const QDomElement& itemElem, const QDomDocument& d
setOverviewInverted( false );
}
+ if ( overviewFrameElem.attribute( "overviewCentered" ).compare( "true", Qt::CaseInsensitive ) == 0 )
+ {
+ setOverviewCentered( true );
+ }
+ else
+ {
+ setOverviewCentered( false );
+ }
+
QDomElement overviewFrameSymbolElem = overviewFrameElem.firstChildElement( "symbol" );
if ( !overviewFrameSymbolElem.isNull() )
{
@@ -1727,63 +1771,70 @@ double QgsComposerMap::maxExtension() const
return maxExtension + mAnnotationFrameDistance + gridFrameDist;
}
-void QgsComposerMap::mapPolygon( QPolygonF& poly ) const
+void QgsComposerMap::mapPolygon( const QgsRectangle& extent, QPolygonF& poly ) const
{
poly.clear();
if ( mRotation == 0 )
{
- poly << QPointF( mExtent.xMinimum(), mExtent.yMaximum() );
- poly << QPointF( mExtent.xMaximum(), mExtent.yMaximum() );
- poly << QPointF( mExtent.xMaximum(), mExtent.yMinimum() );
- poly << QPointF( mExtent.xMinimum(), mExtent.yMinimum() );
+ poly << QPointF( extent.xMinimum(), extent.yMaximum() );
+ poly << QPointF( extent.xMaximum(), extent.yMaximum() );
+ poly << QPointF( extent.xMaximum(), extent.yMinimum() );
+ poly << QPointF( extent.xMinimum(), extent.yMinimum() );
return;
}
//there is rotation
- QgsPoint rotationPoint(( mExtent.xMaximum() + mExtent.xMinimum() ) / 2.0, ( mExtent.yMaximum() + mExtent.yMinimum() ) / 2.0 );
+ QgsPoint rotationPoint(( extent.xMaximum() + extent.xMinimum() ) / 2.0, ( extent.yMaximum() + extent.yMinimum() ) / 2.0 );
double dx, dy; //x-, y- shift from rotation point to corner point
//top left point
- dx = rotationPoint.x() - mExtent.xMinimum();
- dy = rotationPoint.y() - mExtent.yMaximum();
+ dx = rotationPoint.x() - extent.xMinimum();
+ dy = rotationPoint.y() - extent.yMaximum();
rotate( mRotation, dx, dy );
poly << QPointF( rotationPoint.x() + dx, rotationPoint.y() + dy );
//top right point
- dx = rotationPoint.x() - mExtent.xMaximum();
- dy = rotationPoint.y() - mExtent.yMaximum();
+ dx = rotationPoint.x() - extent.xMaximum();
+ dy = rotationPoint.y() - extent.yMaximum();
rotate( mRotation, dx, dy );
poly << QPointF( rotationPoint.x() + dx, rotationPoint.y() + dy );
//bottom right point
- dx = rotationPoint.x() - mExtent.xMaximum();
- dy = rotationPoint.y() - mExtent.yMinimum();
+ dx = rotationPoint.x() - extent.xMaximum();
+ dy = rotationPoint.y() - extent.yMinimum();
rotate( mRotation, dx, dy );
poly << QPointF( rotationPoint.x() + dx, rotationPoint.y() + dy );
//bottom left point
- dx = rotationPoint.x() - mExtent.xMinimum();
- dy = rotationPoint.y() - mExtent.yMinimum();
+ dx = rotationPoint.x() - extent.xMinimum();
+ dy = rotationPoint.y() - extent.yMinimum();
rotate( mRotation, dx, dy );
poly << QPointF( rotationPoint.x() + dx, rotationPoint.y() + dy );
}
+void QgsComposerMap::mapPolygon( QPolygonF& poly ) const
+{
+ return mapPolygon( mExtent, poly );
+}
+
void QgsComposerMap::requestedExtent( QgsRectangle& extent ) const
{
+ QgsRectangle newExtent;
+ extentCenteredOnOverview( newExtent );
if ( mRotation == 0 )
{
- extent = mExtent;
- return;
+ extent = newExtent;
+ }
+ else
+ {
+ QPolygonF poly;
+ mapPolygon( newExtent, poly );
+ QRectF bRect = poly.boundingRect();
+ extent.setXMinimum( bRect.left() );
+ extent.setXMaximum( bRect.right() );
+ extent.setYMinimum( bRect.top() );
+ extent.setYMaximum( bRect.bottom() );
}
-
- QPolygonF poly;
- mapPolygon( poly );
- QRectF bRect = poly.boundingRect();
- extent.setXMinimum( bRect.left() );
- extent.setXMaximum( bRect.right() );
- extent.setYMinimum( bRect.top() );
- extent.setYMaximum( bRect.bottom() );
- return;
}
double QgsComposerMap::mapUnitsToMM() const
@@ -1836,6 +1887,12 @@ void QgsComposerMap::setOverviewInverted( bool inverted )
update();
}
+void QgsComposerMap::setOverviewCentered( bool centered )
+{
+ mOverviewCentered = centered;
+ update();
+}
+
void QgsComposerMap::setGridLineSymbol( QgsLineSymbolV2* symbol )
{
delete mGridLineSymbol;
@@ -2165,7 +2222,8 @@ void QgsComposerMap::drawOverviewMapExtent( QPainter* p )
}
QgsRectangle otherExtent = overviewFrameMap->extent();
- QgsRectangle thisExtent = extent();
+ QgsRectangle thisExtent;
+ extentCenteredOnOverview( thisExtent );
QgsRectangle intersectRect = thisExtent.intersect( &otherExtent );
QgsRenderContext context;
View
15 src/core/composer/qgscomposermap.h
@@ -332,6 +332,11 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
/** Sets the overview's inversion mode*/
void setOverviewInverted( bool inverted );
+ /** Returns true if the extent is forced to center on the overview when the overview is outside the extent */
+ bool overviewCentered() const { return mOverviewCentered; }
+ /** Set the overview's centering mode */
+ void setOverviewCentered( bool centered );
+
void setGridLineSymbol( QgsLineSymbolV2* symbol );
QgsLineSymbolV2* gridLineSymbol() { return mGridLineSymbol; }
@@ -408,6 +413,8 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
/**Blend mode for overview*/
QPainter::CompositionMode mOverviewBlendMode;
bool mOverviewInverted;
+ /** Centering mode for overview */
+ bool mOverviewCentered;
/**Establishes signal/slot connection for update in case of layer change*/
void connectUpdateSlot();
@@ -503,6 +510,9 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
@param poly out: the result polygon with the four corner points. The points are clockwise, starting at the top-left point
@return true in case of success*/
void mapPolygon( QPolygonF& poly ) const;
+ /** mapPolygon variant using a given extent */
+ void mapPolygon( const QgsRectangle& extent, QPolygonF& poly ) const;
+
/**Calculates the extent to request and the yShift of the top-left point in case of rotation.*/
void requestedExtent( QgsRectangle& extent ) const;
/**Scales a composer map shift (in MM) and rotates it by mRotation
@@ -525,6 +535,11 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
void createDefaultOverviewFrameSymbol();
void createDefaultGridLineSymbol();
void initGridAnnotationFormatFromProject();
+
+ /**
+ * Returns the extent, centered on the overview frame, if needed (when the overview frame is not visible)
+ */
+ void extentCenteredOnOverview( QgsRectangle& extent ) const;
};
#endif
View
7 src/ui/qgscomposermapwidgetbase.ui
@@ -697,6 +697,13 @@
</property>
</widget>
</item>
+ <item row="4" column="0">
+ <widget class="QCheckBox" name="mOverviewCenterCheckbox">
+ <property name="text">
+ <string>Center on overview when needed</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
Please sign in to comment.
Something went wrong with that request. Please try again.