mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[FEATURE][composer] Data defined map scale, rotation and extents. Funded by Canton of Neuchâtel, Switzerland
This commit is contained in:
parent
0fd99d2820
commit
6d7c5f885d
@ -127,7 +127,7 @@ class QgsComposerMap : QgsComposerItem
|
||||
double scale() const;
|
||||
|
||||
/**Sets new scale and changes only mExtent*/
|
||||
void setNewScale( double scaleDenominator );
|
||||
void setNewScale( double scaleDenominator, bool forceUpdate = true );
|
||||
|
||||
/**Sets new Extent and changes width, height (and implicitely also scale)*/
|
||||
void setNewExtent( const QgsRectangle& extent );
|
||||
@ -341,8 +341,14 @@ class QgsComposerMap : QgsComposerItem
|
||||
way the map is drawn within the item
|
||||
@note this function was added in version 2.1*/
|
||||
void setMapRotation( double r );
|
||||
/**Returns the rotation used for drawing the map within the composer item*/
|
||||
double mapRotation() const;
|
||||
|
||||
/**Returns the rotation used for drawing the map within the composer item
|
||||
* @returns rotation for map
|
||||
* @param valueType controls whether the returned value is the user specified rotation,
|
||||
* or the current evaluated rotation (which may be affected by data driven rotation
|
||||
* settings).
|
||||
*/
|
||||
double mapRotation( PropertyValueType valueType = EvaluatedValue ) const;
|
||||
|
||||
void updateItem();
|
||||
|
||||
@ -506,4 +512,6 @@ class QgsComposerMap : QgsComposerItem
|
||||
void renderModeUpdateCachedImage();
|
||||
|
||||
void overviewExtentChanged();
|
||||
|
||||
virtual void refreshDataDefinedProperty( DataDefinedProperty property = AllProperties );
|
||||
};
|
||||
|
@ -103,9 +103,39 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap ): QgsCo
|
||||
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
|
||||
this, SLOT( atlasLayerChanged( QgsVectorLayer* ) ) );
|
||||
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( compositionAtlasToggled( bool ) ) );
|
||||
|
||||
// repopulate data defined buttons if atlas layer changes
|
||||
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
|
||||
this, SLOT( populateDataDefinedButtons() ) );
|
||||
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( populateDataDefinedButtons() ) );
|
||||
}
|
||||
}
|
||||
|
||||
//connections for data defined buttons
|
||||
connect( mScaleDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mScaleDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mScaleDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mScaleLineEdit, SLOT( setDisabled( bool ) ) );
|
||||
|
||||
connect( mMapRotationDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mMapRotationDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mMapRotationDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mMapRotationSpinBox, SLOT( setDisabled( bool ) ) );
|
||||
|
||||
connect( mXMinDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mXMinDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mXMinDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mXMinLineEdit, SLOT( setDisabled( bool ) ) );
|
||||
|
||||
connect( mYMinDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mYMinDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mYMinDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mYMinLineEdit, SLOT( setDisabled( bool ) ) );
|
||||
|
||||
connect( mXMaxDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mXMaxDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mXMaxDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mXMaxLineEdit, SLOT( setDisabled( bool ) ) );
|
||||
|
||||
connect( mYMaxDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mYMaxDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
|
||||
connect( mYMaxDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mYMaxLineEdit, SLOT( setDisabled( bool ) ) );
|
||||
|
||||
updateOverviewSymbolMarker();
|
||||
updateLineSymbolMarker();
|
||||
|
||||
@ -117,6 +147,79 @@ QgsComposerMapWidget::~QgsComposerMapWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void QgsComposerMapWidget::populateDataDefinedButtons()
|
||||
{
|
||||
QgsVectorLayer* vl = atlasCoverageLayer();
|
||||
|
||||
//block signals from data defined buttons
|
||||
mScaleDDBtn->blockSignals( true );
|
||||
mMapRotationDDBtn->blockSignals( true );
|
||||
mXMinDDBtn->blockSignals( true );
|
||||
mYMinDDBtn->blockSignals( true );
|
||||
mXMaxDDBtn->blockSignals( true );
|
||||
mYMaxDDBtn->blockSignals( true );
|
||||
|
||||
//initialise buttons to use atlas coverage layer
|
||||
mScaleDDBtn->init( vl, mItem->dataDefinedProperty( QgsComposerItem::MapScale ),
|
||||
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
|
||||
mMapRotationDDBtn->init( vl, mItem->dataDefinedProperty( QgsComposerItem::MapRotation ),
|
||||
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
|
||||
mXMinDDBtn->init( vl, mItem->dataDefinedProperty( QgsComposerItem::MapXMin ),
|
||||
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
|
||||
mYMinDDBtn->init( vl, mItem->dataDefinedProperty( QgsComposerItem::MapYMin ),
|
||||
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
|
||||
mXMaxDDBtn->init( vl, mItem->dataDefinedProperty( QgsComposerItem::MapXMax ),
|
||||
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
|
||||
mYMaxDDBtn->init( vl, mItem->dataDefinedProperty( QgsComposerItem::MapYMax ),
|
||||
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
|
||||
|
||||
//initial state of controls - disable related controls when dd buttons are active
|
||||
mScaleLineEdit->setEnabled( !mScaleDDBtn->isActive() );
|
||||
mMapRotationSpinBox->setEnabled( !mMapRotationDDBtn->isActive() );
|
||||
mXMinLineEdit->setEnabled( !mXMinDDBtn->isActive() );
|
||||
mYMinLineEdit->setEnabled( !mYMinDDBtn->isActive() );
|
||||
mXMaxLineEdit->setEnabled( !mXMaxDDBtn->isActive() );
|
||||
mYMaxLineEdit->setEnabled( !mYMaxDDBtn->isActive() );
|
||||
|
||||
//unblock signals from data defined buttons
|
||||
mScaleDDBtn->blockSignals( false );
|
||||
mMapRotationDDBtn->blockSignals( false );
|
||||
mXMinDDBtn->blockSignals( false );
|
||||
mYMinDDBtn->blockSignals( false );
|
||||
mXMaxDDBtn->blockSignals( false );
|
||||
mYMaxDDBtn->blockSignals( false );
|
||||
}
|
||||
|
||||
QgsComposerItem::DataDefinedProperty QgsComposerMapWidget::ddPropertyForWidget( QgsDataDefinedButton* widget )
|
||||
{
|
||||
if ( widget == mScaleDDBtn )
|
||||
{
|
||||
return QgsComposerItem::MapScale;
|
||||
}
|
||||
else if ( widget == mMapRotationDDBtn )
|
||||
{
|
||||
return QgsComposerItem::MapRotation;
|
||||
}
|
||||
else if ( widget == mXMinDDBtn )
|
||||
{
|
||||
return QgsComposerItem::MapXMin;
|
||||
}
|
||||
else if ( widget == mYMinDDBtn )
|
||||
{
|
||||
return QgsComposerItem::MapYMin;
|
||||
}
|
||||
else if ( widget == mXMaxDDBtn )
|
||||
{
|
||||
return QgsComposerItem::MapXMax;
|
||||
}
|
||||
else if ( widget == mYMaxDDBtn )
|
||||
{
|
||||
return QgsComposerItem::MapYMax;
|
||||
}
|
||||
|
||||
return QgsComposerItem::NoProperty;
|
||||
}
|
||||
|
||||
void QgsComposerMapWidget::compositionAtlasToggled( bool atlasEnabled )
|
||||
{
|
||||
if ( atlasEnabled )
|
||||
@ -328,43 +431,45 @@ void QgsComposerMapWidget::on_mMapRotationSpinBox_valueChanged( double value )
|
||||
|
||||
void QgsComposerMapWidget::on_mSetToMapCanvasExtentButton_clicked()
|
||||
{
|
||||
if ( mComposerMap )
|
||||
if ( !mComposerMap )
|
||||
{
|
||||
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->endCommand();
|
||||
return;
|
||||
}
|
||||
|
||||
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->endCommand();
|
||||
}
|
||||
|
||||
void QgsComposerMapWidget::on_mViewExtentInCanvasButton_clicked()
|
||||
@ -473,7 +578,7 @@ void QgsComposerMapWidget::updateGuiElements()
|
||||
mYMinLineEdit->setText( QString::number( composerMapExtent.yMinimum(), 'f', 3 ) );
|
||||
mYMaxLineEdit->setText( QString::number( composerMapExtent.yMaximum(), 'f', 3 ) );
|
||||
|
||||
mMapRotationSpinBox->setValue( mComposerMap->mapRotation() );
|
||||
mMapRotationSpinBox->setValue( mComposerMap->mapRotation( QgsComposerItem::OriginalValue ) );
|
||||
|
||||
//keep layer list check box
|
||||
if ( mComposerMap->keepLayerSet() )
|
||||
@ -606,8 +711,9 @@ void QgsComposerMapWidget::updateGuiElements()
|
||||
mAtlasPredefinedScaleRadio->setEnabled( false );
|
||||
}
|
||||
|
||||
blockAllSignals( false );
|
||||
populateDataDefinedButtons();
|
||||
|
||||
blockAllSignals( false );
|
||||
}
|
||||
|
||||
void QgsComposerMapWidget::toggleAtlasScalingOptionsByLayerType()
|
||||
|
@ -108,6 +108,12 @@ class QgsComposerMapWidget: public QgsComposerItemBaseWidget, private Ui::QgsCom
|
||||
/**Sets the current composer map values to the GUI elements*/
|
||||
virtual void updateGuiElements();
|
||||
|
||||
QgsComposerItem::DataDefinedProperty ddPropertyForWidget( QgsDataDefinedButton *widget );
|
||||
|
||||
protected slots:
|
||||
/**Initializes data defined buttons to current atlas coverage layer*/
|
||||
void populateDataDefinedButtons();
|
||||
|
||||
private slots:
|
||||
|
||||
/**Sets the GUI elements to the values of mPicture*/
|
||||
|
@ -42,17 +42,46 @@
|
||||
#include <cmath>
|
||||
|
||||
QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int width, int height )
|
||||
: QgsComposerItem( x, y, width, height, composition ), mMapRotation( 0 ), mKeepLayerSet( false )
|
||||
, mOverviewFrameMapId( -1 ), mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mOverviewCentered( false )
|
||||
, mUpdatesEnabled( true ), 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 )
|
||||
, mTopGridAnnotationPosition( OutsideMapFrame ), mBottomGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 )
|
||||
, mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal )
|
||||
, mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 )
|
||||
, mGridFramePenThickness( 0.5 ), mGridFramePenColor( QColor( 0, 0, 0 ) ), mGridFrameFillColor1( Qt::white ), mGridFrameFillColor2( Qt::black )
|
||||
, mCrossLength( 3 ), mMapCanvas( 0 ), mDrawCanvasItems( true ), mAtlasDriven( false ), mAtlasScalingMode( Auto ), mAtlasMargin( 0.10 )
|
||||
: QgsComposerItem( x, y, width, height, composition )
|
||||
, mMapRotation( 0 )
|
||||
, mEvaluatedMapRotation( 0 )
|
||||
, mKeepLayerSet( false )
|
||||
, mOverviewFrameMapId( -1 )
|
||||
, mOverviewBlendMode( QPainter::CompositionMode_SourceOver )
|
||||
, mOverviewInverted( false )
|
||||
, mOverviewCentered( false )
|
||||
, mUpdatesEnabled( true )
|
||||
, 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 )
|
||||
, mTopGridAnnotationPosition( OutsideMapFrame )
|
||||
, mBottomGridAnnotationPosition( OutsideMapFrame )
|
||||
, mAnnotationFrameDistance( 1.0 )
|
||||
, mLeftGridAnnotationDirection( Horizontal )
|
||||
, mRightGridAnnotationDirection( Horizontal )
|
||||
, mTopGridAnnotationDirection( Horizontal )
|
||||
, mBottomGridAnnotationDirection( Horizontal )
|
||||
, mGridFrameStyle( NoGridFrame )
|
||||
, mGridFrameWidth( 2.0 )
|
||||
, mGridFramePenThickness( 0.5 )
|
||||
, mGridFramePenColor( QColor( 0, 0, 0 ) )
|
||||
, mGridFrameFillColor1( Qt::white )
|
||||
, mGridFrameFillColor2( Qt::black )
|
||||
, mCrossLength( 3 )
|
||||
, mMapCanvas( 0 )
|
||||
, mDrawCanvasItems( true )
|
||||
, mAtlasDriven( false )
|
||||
, mAtlasScalingMode( Auto )
|
||||
, mAtlasMargin( 0.10 )
|
||||
{
|
||||
mComposition = composition;
|
||||
mOverviewFrameMapSymbol = 0;
|
||||
@ -88,29 +117,54 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
|
||||
int bgBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 );
|
||||
setBackgroundColor( QColor( bgRedInt, bgGreenInt, bgBlueInt ) );
|
||||
|
||||
connectUpdateSlot();
|
||||
|
||||
//calculate mExtent based on width/height ratio and map canvas extent
|
||||
mExtent = mComposition->mapSettings().visibleExtent();
|
||||
|
||||
setSceneRect( QRectF( x, y, width, height ) );
|
||||
setToolTip( tr( "Map %1" ).arg( mId ) );
|
||||
|
||||
initGridAnnotationFormatFromProject();
|
||||
init();
|
||||
}
|
||||
|
||||
QgsComposerMap::QgsComposerMap( QgsComposition *composition )
|
||||
: QgsComposerItem( 0, 0, 10, 10, composition ), mMapRotation( 0 ), mKeepLayerSet( false ), mOverviewFrameMapId( -1 )
|
||||
, mOverviewBlendMode( QPainter::CompositionMode_SourceOver ), mOverviewInverted( false ), mOverviewCentered( false )
|
||||
, mUpdatesEnabled( true ), 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 )
|
||||
, mTopGridAnnotationPosition( OutsideMapFrame ), mBottomGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 )
|
||||
, mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal )
|
||||
, mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ), mGridFramePenThickness( 0.5 )
|
||||
, mGridFramePenColor( QColor( 0, 0, 0 ) ), mGridFrameFillColor1( Qt::white ), mGridFrameFillColor2( Qt::black )
|
||||
, mCrossLength( 3 ), mMapCanvas( 0 ), mDrawCanvasItems( true ), mAtlasDriven( false ), mAtlasScalingMode( Auto ), mAtlasMargin( 0.10 )
|
||||
: QgsComposerItem( 0, 0, 10, 10, composition )
|
||||
, mMapRotation( 0 )
|
||||
, mEvaluatedMapRotation( 0 )
|
||||
, mKeepLayerSet( false )
|
||||
, mOverviewFrameMapId( -1 )
|
||||
, mOverviewBlendMode( QPainter::CompositionMode_SourceOver )
|
||||
, mOverviewInverted( false )
|
||||
, mOverviewCentered( false )
|
||||
, mUpdatesEnabled( true )
|
||||
, 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 )
|
||||
, mTopGridAnnotationPosition( OutsideMapFrame )
|
||||
, mBottomGridAnnotationPosition( OutsideMapFrame )
|
||||
, mAnnotationFrameDistance( 1.0 )
|
||||
, mLeftGridAnnotationDirection( Horizontal )
|
||||
, mRightGridAnnotationDirection( Horizontal )
|
||||
, mTopGridAnnotationDirection( Horizontal )
|
||||
, mBottomGridAnnotationDirection( Horizontal )
|
||||
, mGridFrameStyle( NoGridFrame )
|
||||
, mGridFrameWidth( 2.0 )
|
||||
, mGridFramePenThickness( 0.5 )
|
||||
, mGridFramePenColor( QColor( 0, 0, 0 ) )
|
||||
, mGridFrameFillColor1( Qt::white )
|
||||
, mGridFrameFillColor2( Qt::black )
|
||||
, mCrossLength( 3 )
|
||||
, mMapCanvas( 0 )
|
||||
, mDrawCanvasItems( true )
|
||||
, mAtlasDriven( false )
|
||||
, mAtlasScalingMode( Auto )
|
||||
, mAtlasMargin( 0.10 )
|
||||
{
|
||||
mOverviewFrameMapSymbol = 0;
|
||||
mGridLineSymbol = 0;
|
||||
@ -120,16 +174,29 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition )
|
||||
mXOffset = 0.0;
|
||||
mYOffset = 0.0;
|
||||
|
||||
connectUpdateSlot();
|
||||
|
||||
mComposition = composition;
|
||||
mId = mComposition->composerMapItems().size();
|
||||
mPreviewMode = QgsComposerMap::Rectangle;
|
||||
mCurrentRectangle = rect();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
void QgsComposerMap::init()
|
||||
{
|
||||
connectUpdateSlot();
|
||||
|
||||
setToolTip( tr( "Map %1" ).arg( mId ) );
|
||||
|
||||
initGridAnnotationFormatFromProject();
|
||||
|
||||
// data defined strings
|
||||
mDataDefinedNames.insert( QgsComposerItem::MapRotation, QString( "dataDefinedMapRotation" ) );
|
||||
mDataDefinedNames.insert( QgsComposerItem::MapScale, QString( "dataDefinedMapScale" ) );
|
||||
mDataDefinedNames.insert( QgsComposerItem::MapXMin, QString( "dataDefinedMapXMin" ) );
|
||||
mDataDefinedNames.insert( QgsComposerItem::MapYMin, QString( "dataDefinedMapYMin" ) );
|
||||
mDataDefinedNames.insert( QgsComposerItem::MapXMax, QString( "dataDefinedMapXMax" ) );
|
||||
mDataDefinedNames.insert( QgsComposerItem::MapYMax, QString( "dataDefinedMapYMax" ) );
|
||||
}
|
||||
|
||||
void QgsComposerMap::adjustExtentToItemShape( double itemWidth, double itemHeight, QgsRectangle& extent ) const
|
||||
@ -347,7 +414,7 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
|
||||
|
||||
painter->translate( mXOffset, mYOffset );
|
||||
painter->translate( xTopLeftShift, yTopLeftShift );
|
||||
painter->rotate( mMapRotation );
|
||||
painter->rotate( mEvaluatedMapRotation );
|
||||
painter->translate( xShiftMM, -yShiftMM );
|
||||
painter->scale( scale, scale );
|
||||
painter->drawImage( 0, 0, mCacheImage );
|
||||
@ -398,7 +465,7 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
|
||||
painter->save();
|
||||
painter->translate( mXOffset, mYOffset );
|
||||
painter->translate( xTopLeftShift, yTopLeftShift );
|
||||
painter->rotate( mMapRotation );
|
||||
painter->rotate( mEvaluatedMapRotation );
|
||||
painter->translate( xShiftMM, -yShiftMM );
|
||||
|
||||
double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
|
||||
@ -502,7 +569,6 @@ bool QgsComposerMap::shouldDrawPart( PartType part ) const
|
||||
return true; // for Layer
|
||||
}
|
||||
|
||||
|
||||
void QgsComposerMap::updateCachedImage( void )
|
||||
{
|
||||
syncLayerSet(); //layer list may have changed
|
||||
@ -588,6 +654,10 @@ void QgsComposerMap::moveContent( double dx, double dy )
|
||||
currentMapExtent()->setXMaximum( currentMapExtent()->xMaximum() + dx );
|
||||
currentMapExtent()->setYMinimum( currentMapExtent()->yMinimum() + dy );
|
||||
currentMapExtent()->setYMaximum( currentMapExtent()->yMaximum() + dy );
|
||||
|
||||
//in case data defined extents are set, these override the calculated values
|
||||
refreshMapExtents();
|
||||
|
||||
cache();
|
||||
update();
|
||||
emit itemChanged();
|
||||
@ -669,6 +739,9 @@ void QgsComposerMap::zoomContent( int delta, double x, double y )
|
||||
mExtent.scale( scaleRatio );
|
||||
}
|
||||
|
||||
//recalculate data defined scale and extents, since that may override zoom
|
||||
refreshMapExtents();
|
||||
|
||||
cache();
|
||||
update();
|
||||
emit itemChanged();
|
||||
@ -686,6 +759,9 @@ void QgsComposerMap::setSceneRect( const QRectF& rectangle )
|
||||
//QGraphicsRectItem::update();
|
||||
double newHeight = mExtent.width() * h / w ;
|
||||
mExtent = QgsRectangle( mExtent.xMinimum(), mExtent.yMinimum(), mExtent.xMaximum(), mExtent.yMinimum() + newHeight );
|
||||
|
||||
//recalculate data defined scale and extents
|
||||
refreshMapExtents();
|
||||
mCacheUpdated = false;
|
||||
|
||||
updateBoundingRect();
|
||||
@ -696,16 +772,19 @@ void QgsComposerMap::setSceneRect( const QRectF& rectangle )
|
||||
|
||||
void QgsComposerMap::setNewExtent( const QgsRectangle& extent )
|
||||
{
|
||||
if ( mExtent == extent )
|
||||
if ( *currentMapExtent() == extent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
mExtent = extent;
|
||||
*currentMapExtent() = extent;
|
||||
|
||||
//recalculate data defined scale and extents, since that may override extent
|
||||
refreshMapExtents();
|
||||
|
||||
//adjust height
|
||||
QRectF currentRect = rect();
|
||||
|
||||
double newHeight = currentRect.width() * extent.height() / extent.width();
|
||||
double newHeight = currentRect.width() * currentMapExtent()->height() / currentMapExtent()->width();
|
||||
|
||||
setSceneRect( QRectF( pos().x(), pos().y(), currentRect.width(), newHeight ) );
|
||||
updateItem();
|
||||
@ -713,37 +792,35 @@ void QgsComposerMap::setNewExtent( const QgsRectangle& extent )
|
||||
|
||||
void QgsComposerMap::setNewAtlasFeatureExtent( const QgsRectangle& extent )
|
||||
{
|
||||
if ( mAtlasFeatureExtent == extent )
|
||||
if ( mAtlasFeatureExtent != extent )
|
||||
{
|
||||
emit preparedForAtlas();
|
||||
return;
|
||||
//don't adjust size of item, instead adjust size of bounds to fit
|
||||
QgsRectangle newExtent = extent;
|
||||
|
||||
//Make sure the width/height ratio is the same as the map item size
|
||||
double currentWidthHeightRatio = rect().width() / rect().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( extent.yMinimum() - deltaHeight / 2 );
|
||||
newExtent.setYMaximum( extent.yMaximum() + deltaHeight / 2 );
|
||||
}
|
||||
else if ( currentWidthHeightRatio >= newWidthHeightRatio )
|
||||
{
|
||||
//enlarge width of new extent, ensuring the map center stays the same
|
||||
double newWidth = currentWidthHeightRatio * newExtent.height();
|
||||
double deltaWidth = newWidth - newExtent.width();
|
||||
newExtent.setXMinimum( extent.xMinimum() - deltaWidth / 2 );
|
||||
newExtent.setXMaximum( extent.xMaximum() + deltaWidth / 2 );
|
||||
}
|
||||
|
||||
mAtlasFeatureExtent = newExtent;
|
||||
}
|
||||
|
||||
//don't adjust size of item, instead adjust size of bounds to fit
|
||||
QgsRectangle newExtent = extent;
|
||||
|
||||
//Make sure the width/height ratio is the same as the map item size
|
||||
double currentWidthHeightRatio = rect().width() / rect().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( extent.yMinimum() - deltaHeight / 2 );
|
||||
newExtent.setYMaximum( extent.yMaximum() + deltaHeight / 2 );
|
||||
}
|
||||
else if ( currentWidthHeightRatio >= newWidthHeightRatio )
|
||||
{
|
||||
//enlarge width of new extent, ensuring the map center stays the same
|
||||
double newWidth = currentWidthHeightRatio * newExtent.height();
|
||||
double deltaWidth = newWidth - newExtent.width();
|
||||
newExtent.setXMinimum( extent.xMinimum() - deltaWidth / 2 );
|
||||
newExtent.setXMaximum( extent.xMaximum() + deltaWidth / 2 );
|
||||
}
|
||||
|
||||
mAtlasFeatureExtent = newExtent;
|
||||
mCacheUpdated = false;
|
||||
emit preparedForAtlas();
|
||||
updateItem();
|
||||
@ -792,7 +869,7 @@ const QgsRectangle* QgsComposerMap::currentMapExtent() const
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerMap::setNewScale( double scaleDenominator )
|
||||
void QgsComposerMap::setNewScale( double scaleDenominator, bool forceUpdate )
|
||||
{
|
||||
double currentScaleDenominator = scale();
|
||||
|
||||
@ -817,9 +894,12 @@ void QgsComposerMap::setNewScale( double scaleDenominator )
|
||||
}
|
||||
|
||||
mCacheUpdated = false;
|
||||
cache();
|
||||
update();
|
||||
emit itemChanged();
|
||||
if ( forceUpdate )
|
||||
{
|
||||
cache();
|
||||
update();
|
||||
emit itemChanged();
|
||||
}
|
||||
emit extentChanged();
|
||||
}
|
||||
|
||||
@ -844,11 +924,131 @@ void QgsComposerMap::setRotation( double r )
|
||||
void QgsComposerMap::setMapRotation( double r )
|
||||
{
|
||||
mMapRotation = r;
|
||||
mEvaluatedMapRotation = mMapRotation;
|
||||
emit mapRotationChanged( r );
|
||||
emit itemChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
double QgsComposerMap::mapRotation( PropertyValueType valueType ) const
|
||||
{
|
||||
return valueType == EvaluatedValue ? mEvaluatedMapRotation : mMapRotation;
|
||||
}
|
||||
|
||||
void QgsComposerMap::refreshMapExtents()
|
||||
{
|
||||
//data defined map extents set?
|
||||
QVariant exprVal;
|
||||
|
||||
QgsRectangle newExtent = *currentMapExtent();
|
||||
|
||||
if ( dataDefinedEvaluate( QgsComposerItem::MapXMin, exprVal ) )
|
||||
{
|
||||
bool ok;
|
||||
double minXD = exprVal.toDouble( &ok );
|
||||
QgsDebugMsg( QString( "exprVal Map XMin:%1" ).arg( minXD ) );
|
||||
if ( ok )
|
||||
{
|
||||
newExtent.setXMinimum( minXD );
|
||||
}
|
||||
}
|
||||
if ( dataDefinedEvaluate( QgsComposerItem::MapYMin, exprVal ) )
|
||||
{
|
||||
bool ok;
|
||||
double minYD = exprVal.toDouble( &ok );
|
||||
QgsDebugMsg( QString( "exprVal Map YMin:%1" ).arg( minYD ) );
|
||||
if ( ok )
|
||||
{
|
||||
newExtent.setYMinimum( minYD );
|
||||
}
|
||||
}
|
||||
if ( dataDefinedEvaluate( QgsComposerItem::MapXMax, exprVal ) )
|
||||
{
|
||||
bool ok;
|
||||
double maxXD = exprVal.toDouble( &ok );
|
||||
QgsDebugMsg( QString( "exprVal Map XMax:%1" ).arg( maxXD ) );
|
||||
if ( ok )
|
||||
{
|
||||
newExtent.setXMaximum( maxXD );
|
||||
}
|
||||
}
|
||||
if ( dataDefinedEvaluate( QgsComposerItem::MapYMax, exprVal ) )
|
||||
{
|
||||
bool ok;
|
||||
double maxYD = exprVal.toDouble( &ok );
|
||||
QgsDebugMsg( QString( "exprVal Map YMax:%1" ).arg( maxYD ) );
|
||||
if ( ok )
|
||||
{
|
||||
newExtent.setYMaximum( maxYD );
|
||||
}
|
||||
}
|
||||
|
||||
if ( newExtent != *currentMapExtent() )
|
||||
{
|
||||
//calculate new extents to fit data defined extents
|
||||
|
||||
//Make sure the width/height ratio is the same as in current map extent.
|
||||
//This is to keep the map item frame and the page layout 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 );
|
||||
}
|
||||
|
||||
*currentMapExtent() = newExtent;
|
||||
}
|
||||
|
||||
//now refresh scale, as this potentially overrides extents
|
||||
|
||||
//data defined map scale set?
|
||||
if ( dataDefinedEvaluate( QgsComposerItem::MapScale, exprVal ) )
|
||||
{
|
||||
bool ok;
|
||||
double scaleD = exprVal.toDouble( &ok );
|
||||
QgsDebugMsg( QString( "exprVal Map Scale:%1" ).arg( scaleD ) );
|
||||
if ( ok )
|
||||
{
|
||||
setNewScale( scaleD, false );
|
||||
}
|
||||
}
|
||||
|
||||
//lastly, map rotation overrides all
|
||||
double mapRotation = mMapRotation;
|
||||
|
||||
//data defined map rotation set?
|
||||
if ( dataDefinedEvaluate( QgsComposerItem::MapRotation, exprVal ) )
|
||||
{
|
||||
bool ok;
|
||||
double rotationD = exprVal.toDouble( &ok );
|
||||
QgsDebugMsg( QString( "exprVal Map Rotation:%1" ).arg( rotationD ) );
|
||||
if ( ok )
|
||||
{
|
||||
mapRotation = rotationD;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mEvaluatedMapRotation != mapRotation )
|
||||
{
|
||||
mEvaluatedMapRotation = mapRotation;
|
||||
emit mapRotationChanged( mapRotation );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QgsComposerMap::updateItem()
|
||||
{
|
||||
if ( !mUpdatesEnabled )
|
||||
@ -1879,7 +2079,7 @@ int QgsComposerMap::xGridLines( QList< QPair< double, QLineF > >& lines ) const
|
||||
double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
|
||||
double currentLevel = ( int )(( mapBoundingRect.top() - mGridOffsetY ) / mGridIntervalY + roundCorrection ) * mGridIntervalY + mGridOffsetY;
|
||||
|
||||
if ( qgsDoubleNear( mMapRotation, 0.0 ) )
|
||||
if ( qgsDoubleNear( mEvaluatedMapRotation, 0.0 ) )
|
||||
{
|
||||
//no rotation. Do it 'the easy way'
|
||||
|
||||
@ -1947,7 +2147,7 @@ int QgsComposerMap::yGridLines( QList< QPair< double, QLineF > >& lines ) const
|
||||
double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
|
||||
double currentLevel = ( int )(( mapBoundingRect.left() - mGridOffsetX ) / mGridIntervalX + roundCorrection ) * mGridIntervalX + mGridOffsetX;
|
||||
|
||||
if ( qgsDoubleNear( mMapRotation, 0.0 ) )
|
||||
if ( qgsDoubleNear( mEvaluatedMapRotation, 0.0 ) )
|
||||
{
|
||||
//no rotation. Do it 'the easy way'
|
||||
double xCanvasCoord;
|
||||
@ -2136,7 +2336,7 @@ double QgsComposerMap::maxExtension() const
|
||||
void QgsComposerMap::mapPolygon( const QgsRectangle& extent, QPolygonF& poly ) const
|
||||
{
|
||||
poly.clear();
|
||||
if ( mMapRotation == 0 )
|
||||
if ( mEvaluatedMapRotation == 0 )
|
||||
{
|
||||
poly << QPointF( extent.xMinimum(), extent.yMaximum() );
|
||||
poly << QPointF( extent.xMaximum(), extent.yMaximum() );
|
||||
@ -2152,25 +2352,25 @@ void QgsComposerMap::mapPolygon( const QgsRectangle& extent, QPolygonF& poly ) c
|
||||
//top left point
|
||||
dx = rotationPoint.x() - extent.xMinimum();
|
||||
dy = rotationPoint.y() - extent.yMaximum();
|
||||
rotate( mMapRotation, dx, dy );
|
||||
rotate( mEvaluatedMapRotation, dx, dy );
|
||||
poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
|
||||
|
||||
//top right point
|
||||
dx = rotationPoint.x() - extent.xMaximum();
|
||||
dy = rotationPoint.y() - extent.yMaximum();
|
||||
rotate( mMapRotation, dx, dy );
|
||||
rotate( mEvaluatedMapRotation, dx, dy );
|
||||
poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
|
||||
|
||||
//bottom right point
|
||||
dx = rotationPoint.x() - extent.xMaximum();
|
||||
dy = rotationPoint.y() - extent.yMinimum();
|
||||
rotate( mMapRotation, dx, dy );
|
||||
rotate( mEvaluatedMapRotation, dx, dy );
|
||||
poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
|
||||
|
||||
//bottom left point
|
||||
dx = rotationPoint.x() - extent.xMinimum();
|
||||
dy = rotationPoint.y() - extent.yMinimum();
|
||||
rotate( mMapRotation, dx, dy );
|
||||
rotate( mEvaluatedMapRotation, dx, dy );
|
||||
poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
|
||||
}
|
||||
|
||||
@ -2181,10 +2381,10 @@ QPolygonF QgsComposerMap::visibleExtentPolygon() const
|
||||
return poly;
|
||||
}
|
||||
|
||||
void QgsComposerMap::requestedExtent( QgsRectangle& extent ) const
|
||||
void QgsComposerMap::requestedExtent( QgsRectangle& extent )
|
||||
{
|
||||
QgsRectangle newExtent = *currentMapExtent();
|
||||
if ( mMapRotation == 0 )
|
||||
if ( mEvaluatedMapRotation == 0 )
|
||||
{
|
||||
extent = newExtent;
|
||||
}
|
||||
@ -2258,6 +2458,24 @@ void QgsComposerMap::overviewExtentChanged()
|
||||
update();
|
||||
}
|
||||
|
||||
void QgsComposerMap::refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property )
|
||||
{
|
||||
//updates data defined properties and redraws item to match
|
||||
if ( property == QgsComposerItem::MapRotation || property == QgsComposerItem::MapScale ||
|
||||
property == QgsComposerItem::MapXMin || property == QgsComposerItem::MapYMin ||
|
||||
property == QgsComposerItem::MapXMax || property == QgsComposerItem::MapYMax ||
|
||||
property == QgsComposerItem::AllProperties )
|
||||
{
|
||||
refreshMapExtents();
|
||||
emit itemChanged();
|
||||
emit extentChanged();
|
||||
}
|
||||
|
||||
//force redraw
|
||||
cache();
|
||||
|
||||
QgsComposerItem::refreshDataDefinedProperty( property );
|
||||
}
|
||||
|
||||
void QgsComposerMap::setOverviewFrameMapSymbol( QgsFillSymbolV2* symbol )
|
||||
{
|
||||
@ -2295,7 +2513,7 @@ void QgsComposerMap::transformShift( double& xShift, double& yShift ) const
|
||||
double dxScaled = xShift * mmToMapUnits;
|
||||
double dyScaled = - yShift * mmToMapUnits;
|
||||
|
||||
rotate( mMapRotation, dxScaled, dyScaled );
|
||||
rotate( mEvaluatedMapRotation, dxScaled, dyScaled );
|
||||
|
||||
xShift = dxScaled;
|
||||
yShift = dyScaled;
|
||||
@ -2313,7 +2531,7 @@ QPointF QgsComposerMap::mapToItemCoords( const QPointF& mapCoords ) const
|
||||
QgsPoint rotationPoint(( tExtent.xMaximum() + tExtent.xMinimum() ) / 2.0, ( tExtent.yMaximum() + tExtent.yMinimum() ) / 2.0 );
|
||||
double dx = mapCoords.x() - rotationPoint.x();
|
||||
double dy = mapCoords.y() - rotationPoint.y();
|
||||
rotate( -mMapRotation, dx, dy );
|
||||
rotate( -mEvaluatedMapRotation, dx, dy );
|
||||
QgsPoint backRotatedCoords( rotationPoint.x() + dx, rotationPoint.y() + dy );
|
||||
|
||||
QgsRectangle unrotatedExtent = transformedExtent();
|
||||
@ -2711,19 +2929,31 @@ void QgsComposerMap::assignFreeId()
|
||||
bool QgsComposerMap::imageSizeConsideringRotation( double& width, double& height ) const
|
||||
{
|
||||
//kept for api compatibility with QGIS 2.0 - use mMapRotation
|
||||
return QgsComposerItem::imageSizeConsideringRotation( width, height, mMapRotation );
|
||||
return QgsComposerItem::imageSizeConsideringRotation( width, height, mEvaluatedMapRotation );
|
||||
}
|
||||
|
||||
bool QgsComposerMap::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
|
||||
{
|
||||
//kept for api compatibility with QGIS 2.0 - use mMapRotation
|
||||
return QgsComposerItem::cornerPointOnRotatedAndScaledRect( x, y, width, height, mMapRotation );
|
||||
return QgsComposerItem::cornerPointOnRotatedAndScaledRect( x, y, width, height, mEvaluatedMapRotation );
|
||||
}
|
||||
|
||||
void QgsComposerMap::sizeChangedByRotation( double& width, double& height )
|
||||
{
|
||||
//kept for api compatibility with QGIS 2.0 - use mMapRotation
|
||||
return QgsComposerItem::sizeChangedByRotation( width, height, mMapRotation );
|
||||
return QgsComposerItem::sizeChangedByRotation( width, height, mEvaluatedMapRotation );
|
||||
}
|
||||
|
||||
void QgsComposerMap::setAtlasDriven( bool enabled )
|
||||
{
|
||||
mAtlasDriven = enabled;
|
||||
|
||||
if ( !enabled )
|
||||
{
|
||||
//if not enabling the atlas, we still need to refresh the map extents
|
||||
//so that data defined extents and scale are recalculated
|
||||
refreshMapExtents();
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsComposerMap::atlasFixedScale() const
|
||||
|
@ -161,7 +161,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
double scale() const;
|
||||
|
||||
/**Sets new scale and changes only mExtent*/
|
||||
void setNewScale( double scaleDenominator );
|
||||
void setNewScale( double scaleDenominator, bool forceUpdate = true );
|
||||
|
||||
/**Sets new Extent and changes width, height (and implicitely also scale)*/
|
||||
void setNewExtent( const QgsRectangle& extent );
|
||||
@ -376,8 +376,14 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
way the map is drawn within the item
|
||||
@note this function was added in version 2.1*/
|
||||
void setMapRotation( double r );
|
||||
/**Returns the rotation used for drawing the map within the composer item*/
|
||||
double mapRotation() const { return mMapRotation;};
|
||||
|
||||
/**Returns the rotation used for drawing the map within the composer item
|
||||
* @returns rotation for map
|
||||
* @param valueType controls whether the returned value is the user specified rotation,
|
||||
* or the current evaluated rotation (which may be affected by data driven rotation
|
||||
* settings).
|
||||
*/
|
||||
double mapRotation( PropertyValueType valueType = EvaluatedValue ) const;
|
||||
|
||||
void updateItem();
|
||||
|
||||
@ -455,7 +461,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
* @see atlasDriven
|
||||
* @see setAtlasScalingMode
|
||||
*/
|
||||
void setAtlasDriven( bool enabled ) { mAtlasDriven = enabled; }
|
||||
void setAtlasDriven( bool enabled );
|
||||
|
||||
/**Returns true if the map uses a fixed scale when in atlas mode
|
||||
* @deprecated since 2.4 Use atlasScalingMode() instead
|
||||
@ -542,6 +548,8 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
|
||||
void overviewExtentChanged();
|
||||
|
||||
virtual void refreshDataDefinedProperty( DataDefinedProperty property = AllProperties );
|
||||
|
||||
private:
|
||||
|
||||
enum AnnotationCoordinate
|
||||
@ -585,6 +593,9 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
|
||||
/**Map rotation*/
|
||||
double mMapRotation;
|
||||
/**Temporary evaluated map rotation. Data defined rotation may mean this value
|
||||
* differs from mMapRotation*/
|
||||
double mEvaluatedMapRotation;
|
||||
|
||||
/**Flag if layers to be displayed should be read from qgis canvas (true) or from stored list in mLayerSet (false)*/
|
||||
bool mKeepLayerSet;
|
||||
@ -684,6 +695,8 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
/**Margin size for atlas driven extents (percentage of feature size) - when in auto scaling mode*/
|
||||
double mAtlasMargin;
|
||||
|
||||
void init();
|
||||
|
||||
/**Returns a list of the layers to render for this map item*/
|
||||
QStringList layersToRender() const;
|
||||
|
||||
@ -719,7 +732,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
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;
|
||||
void requestedExtent( QgsRectangle& extent );
|
||||
/**Scales a composer map shift (in MM) and rotates it by mRotation
|
||||
@param xShift in: shift in x direction (in item units), out: xShift in map units
|
||||
@param yShift in: shift in y direction (in item units), out: yShift in map units*/
|
||||
@ -753,6 +766,11 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
|
||||
/**Test if a part of the copmosermap needs to be drawn, considering mCurrentExportLayer*/
|
||||
bool shouldDrawPart( PartType part ) const;
|
||||
|
||||
/**Refresh the map's extents, considering data defined extent, scale and rotation
|
||||
* @note this method was added in version 2.5
|
||||
*/
|
||||
void refreshMapExtents();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,16 +23,7 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@ -63,9 +54,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-348</y>
|
||||
<width>438</width>
|
||||
<height>1415</height>
|
||||
<y>0</y>
|
||||
<width>439</width>
|
||||
<height>1711</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -87,12 +78,6 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@ -125,11 +110,22 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="mScaleLineEdit">
|
||||
<property name="inputMask">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="mScaleLineEdit">
|
||||
<property name="inputMask">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDataDefinedButton" name="mScaleDDBtn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mMapRotationLabel">
|
||||
@ -139,14 +135,25 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mMapRotationSpinBox">
|
||||
<property name="suffix">
|
||||
<string> °</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mMapRotationSpinBox">
|
||||
<property name="suffix">
|
||||
<string> °</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDataDefinedButton" name="mMapRotationDDBtn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mDrawCanvasItemsCheckBox">
|
||||
@ -200,7 +207,18 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="mXMinLineEdit"/>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="mXMinLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDataDefinedButton" name="mXMinDDBtn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="mYMinLabel">
|
||||
@ -216,7 +234,18 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="mYMinLineEdit"/>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="mYMinLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDataDefinedButton" name="mYMinDDBtn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mXMaxLabel">
|
||||
@ -232,7 +261,18 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="mXMaxLineEdit"/>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="mXMaxLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDataDefinedButton" name="mXMaxDDBtn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="mYMaxLabel">
|
||||
@ -248,7 +288,18 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="mYMaxLineEdit"/>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="mYMaxLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDataDefinedButton" name="mYMaxDDBtn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="mSetToMapCanvasExtentButton">
|
||||
@ -875,7 +926,7 @@
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBoxBasic</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>qgscollapsiblegroupbox.h</header>
|
||||
<header location="global">qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
@ -883,6 +934,11 @@
|
||||
<extends>QPushButton</extends>
|
||||
<header>qgscolorbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsDataDefinedButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>qgsdatadefinedbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsBlendModeComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
|
Loading…
x
Reference in New Issue
Block a user