From d705642fb3ba729ea79aa23034e57c6bb8d4581a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 30 May 2017 15:49:32 +1000 Subject: [PATCH] Update diagram renderer to use rotation in degrees clockwise --- doc/api_break.dox | 1 + python/core/qgsdiagramrenderer.sip | 7 ++++++- src/app/qgsdiagramproperties.cpp | 10 +++++----- src/core/diagram/qgspiediagram.cpp | 2 +- src/core/qgsdiagramrenderer.cpp | 11 +++++++---- src/core/qgsdiagramrenderer.h | 9 +++++++-- src/core/qgsmapsettings.cpp | 3 ++- src/core/qgsmapsettings.h | 19 ++++++++++++------- tests/src/core/testqgsdiagram.cpp | 22 +++++++++++----------- 9 files changed, 52 insertions(+), 32 deletions(-) diff --git a/doc/api_break.dox b/doc/api_break.dox index 8b60b521977..28f311f0d3e 100644 --- a/doc/api_break.dox +++ b/doc/api_break.dox @@ -1024,6 +1024,7 @@ QgsDiagramSettings {#qgis_api_break_3_0_QgsDiagramSettings} - The SizeType enum was removed. Use QgsUnitTypes.RenderUnit instead. - readXml() and writeXml() do not take QgsVectorLayer as an argument anymore. - transparency was removed. Use opacity instead. +- angleOffset was removed. Use rotationOffset instead. QgsDial {#qgis_api_break_3_0_QgsDial} diff --git a/python/core/qgsdiagramrenderer.sip b/python/core/qgsdiagramrenderer.sip index 07bf4599fde..7a8717d53c1 100644 --- a/python/core/qgsdiagramrenderer.sip +++ b/python/core/qgsdiagramrenderer.sip @@ -365,7 +365,12 @@ Opacity, from 0 (transparent) to 1.0 (opaque) %End bool scaleByArea; - int angleOffset; + + double rotationOffset; +%Docstring + Rotation offset, in degrees clockwise from horizontal. +.. versionadded:: 3.0 +%End bool scaleBasedVisibility; double minScaleDenominator; diff --git a/src/app/qgsdiagramproperties.cpp b/src/app/qgsdiagramproperties.cpp index abaced5ff0b..ee29cd68df9 100644 --- a/src/app/qgsdiagramproperties.cpp +++ b/src/app/qgsdiagramproperties.cpp @@ -147,10 +147,10 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare mScaleDependencyComboBox->addItem( tr( "Area" ), true ); mScaleDependencyComboBox->addItem( tr( "Diameter" ), false ); - mAngleOffsetComboBox->addItem( tr( "Top" ), 90 * 16 ); + mAngleOffsetComboBox->addItem( tr( "Top" ), 270 ); mAngleOffsetComboBox->addItem( tr( "Right" ), 0 ); - mAngleOffsetComboBox->addItem( tr( "Bottom" ), 270 * 16 ); - mAngleOffsetComboBox->addItem( tr( "Left" ), 180 * 16 ); + mAngleOffsetComboBox->addItem( tr( "Bottom" ), 90 ); + mAngleOffsetComboBox->addItem( tr( "Left" ), 180 ); QgsSettings settings; @@ -283,7 +283,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare mLabelPlacementComboBox->setCurrentIndex( 1 ); } - mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).angleOffset ) ); + mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).rotationOffset ) ); mOrientationLeftButton->setProperty( "direction", QgsDiagramSettings::Left ); mOrientationRightButton->setProperty( "direction", QgsDiagramSettings::Right ); @@ -779,7 +779,7 @@ void QgsDiagramProperties::apply() ds.scaleBasedVisibility = mScaleVisibilityGroupBox->isChecked(); // Diagram angle offset (pie) - ds.angleOffset = mAngleOffsetComboBox->currentData().toInt(); + ds.rotationOffset = mAngleOffsetComboBox->currentData().toInt(); // Diagram orientation (histogram) ds.diagramOrientation = static_cast( mOrientationButtonGroup->checkedButton()->property( "direction" ).toInt() ); diff --git a/src/core/diagram/qgspiediagram.cpp b/src/core/diagram/qgspiediagram.cpp index 7f616a9f359..4c9910543a1 100644 --- a/src/core/diagram/qgspiediagram.cpp +++ b/src/core/diagram/qgspiediagram.cpp @@ -138,7 +138,7 @@ void QgsPieDiagram::renderDiagram( const QgsFeature &feature, QgsRenderContext & } else { - p->drawPie( baseX, baseY, w, h, totalAngle + s.angleOffset, currentAngle ); + p->drawPie( baseX, baseY, w, h, totalAngle - s.rotationOffset * 16.0, currentAngle ); } totalAngle += currentAngle; } diff --git a/src/core/qgsdiagramrenderer.cpp b/src/core/qgsdiagramrenderer.cpp index 71c9d56fd77..ee06bde9dc4 100644 --- a/src/core/qgsdiagramrenderer.cpp +++ b/src/core/qgsdiagramrenderer.cpp @@ -255,7 +255,10 @@ void QgsDiagramSettings::readXml( const QDomElement &elem ) barWidth = elem.attribute( QStringLiteral( "barWidth" ) ).toDouble(); - angleOffset = elem.attribute( QStringLiteral( "angleOffset" ) ).toInt(); + if ( elem.hasAttribute( QStringLiteral( "angleOffset" ) ) ) + rotationOffset = fmod( 360.0 - elem.attribute( QStringLiteral( "angleOffset" ) ).toInt() / 16.0, 360.0 ); + else + rotationOffset = elem.attribute( QStringLiteral( "rotationOffset" ) ).toDouble(); minimumSize = elem.attribute( QStringLiteral( "minimumSize" ) ).toDouble(); @@ -374,7 +377,7 @@ void QgsDiagramSettings::writeXml( QDomElement &rendererElem, QDomDocument &doc categoryElem.setAttribute( QStringLiteral( "barWidth" ), QString::number( barWidth ) ); categoryElem.setAttribute( QStringLiteral( "minimumSize" ), QString::number( minimumSize ) ); - categoryElem.setAttribute( QStringLiteral( "angleOffset" ), QString::number( angleOffset ) ); + categoryElem.setAttribute( QStringLiteral( "rotationOffset" ), QString::number( rotationOffset ) ); int nCats = qMin( categoryColors.size(), categoryAttributes.size() ); for ( int i = 0; i < nCats; ++i ) @@ -447,8 +450,8 @@ void QgsDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRenderCont s.penColor = properties.valueAsColor( QgsDiagramLayerSettings::StrokeColor, c.expressionContext(), s.penColor ); c.expressionContext().setOriginalValueVariable( s.penWidth ); s.penWidth = properties.valueAsDouble( QgsDiagramLayerSettings::StrokeWidth, c.expressionContext(), s.penWidth ); - c.expressionContext().setOriginalValueVariable( s.angleOffset / 16.0 ); - s.angleOffset = 16.0 * properties.valueAsDouble( QgsDiagramLayerSettings::StartAngle, c.expressionContext(), s.angleOffset / 16.0 ); + c.expressionContext().setOriginalValueVariable( s.rotationOffset ); + s.rotationOffset = properties.valueAsDouble( QgsDiagramLayerSettings::StartAngle, c.expressionContext(), s.rotationOffset ); } mDiagram->renderDiagram( feature, c, s, pos ); diff --git a/src/core/qgsdiagramrenderer.h b/src/core/qgsdiagramrenderer.h index 33fb00ddff1..51704ab05af 100644 --- a/src/core/qgsdiagramrenderer.h +++ b/src/core/qgsdiagramrenderer.h @@ -374,7 +374,7 @@ class CORE_EXPORT QgsDiagramSettings , barWidth( 5.0 ) , opacity( 1.0 ) , scaleByArea( true ) - , angleOffset( 90 * 16 ) //top + , rotationOffset( 270 ) //top , scaleBasedVisibility( false ) , minScaleDenominator( -1 ) , maxScaleDenominator( -1 ) @@ -418,7 +418,12 @@ class CORE_EXPORT QgsDiagramSettings double opacity; bool scaleByArea; - int angleOffset; + + /** + * Rotation offset, in degrees clockwise from horizontal. + * \since QGIS 3.0 + */ + double rotationOffset; bool scaleBasedVisibility; //scale range (-1 if no lower / upper bound ) diff --git a/src/core/qgsmapsettings.cpp b/src/core/qgsmapsettings.cpp index 05deae8857d..e48b391dda4 100644 --- a/src/core/qgsmapsettings.cpp +++ b/src/core/qgsmapsettings.cpp @@ -106,7 +106,8 @@ double QgsMapSettings::rotation() const void QgsMapSettings::setRotation( double degrees ) { - if ( qgsDoubleNear( mRotation, degrees ) ) return; + if ( qgsDoubleNear( mRotation, degrees ) ) + return; mRotation = degrees; diff --git a/src/core/qgsmapsettings.h b/src/core/qgsmapsettings.h index cee04081bfb..364abe191ae 100644 --- a/src/core/qgsmapsettings.h +++ b/src/core/qgsmapsettings.h @@ -76,14 +76,19 @@ class CORE_EXPORT QgsMapSettings //! Set the size of the resulting map image void setOutputSize( QSize size ); - //! Return the rotation of the resulting map image - //! Units are clockwise degrees - //! \since QGIS 2.8 + /** + * Returns the rotation of the resulting map image, in degrees clockwise. + * \since QGIS 2.8 + * \see setRotation() + */ double rotation() const; - //! Set the rotation of the resulting map image - //! Units are clockwise degrees - //! \since QGIS 2.8 - void setRotation( double degrees ); + + /** + * Sets the \a rotation of the resulting map image, in degrees clockwise. + * \since QGIS 2.8 + * \see rotation() + */ + void setRotation( double rotation ); //! Return DPI used for conversion between real world units (e.g. mm) and pixels //! Default value is 96 diff --git a/tests/src/core/testqgsdiagram.cpp b/tests/src/core/testqgsdiagram.cpp index 2a1b1628b9e..7e62ead7e35 100644 --- a/tests/src/core/testqgsdiagram.cpp +++ b/tests/src/core/testqgsdiagram.cpp @@ -153,7 +153,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 5, 5 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsLinearlyInterpolatedDiagramRenderer *dr = new QgsLinearlyInterpolatedDiagramRenderer(); dr->setLowerValue( 0.0 ); @@ -190,7 +190,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 5, 5 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsLinearlyInterpolatedDiagramRenderer *dr = new QgsLinearlyInterpolatedDiagramRenderer(); dr->setLowerValue( 0.0 ); @@ -232,7 +232,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 15, 15 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -269,7 +269,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 15, 15 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -306,7 +306,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 15, 15 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -342,7 +342,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 15, 15 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -378,7 +378,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 15, 15 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -414,7 +414,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 50, 50 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -448,7 +448,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 50, 50 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -484,7 +484,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 50, 50 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsPieDiagram() ); @@ -525,7 +525,7 @@ class TestQgsDiagram : public QObject ds.scaleByArea = true; ds.sizeType = QgsUnitTypes::RenderMillimeters; ds.size = QSizeF( 15, 15 ); - ds.angleOffset = 0; + ds.rotationOffset = 270; QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer(); dr->setDiagram( new QgsTextDiagram() );