Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsdiagram.cpp 3 : : --------------------- 4 : : begin : March 2011 5 : : copyright : (C) 2011 by Marco Hugentobler 6 : : email : marco dot hugentobler at sourcepole dot ch 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : #include "qgsdiagram.h" 16 : : #include "qgsdiagramrenderer.h" 17 : : 18 : : #include <QPainter> 19 : : 20 : 0 : QgsDiagram::QgsDiagram( const QgsDiagram & ): mExpressions{} 21 : 0 : { 22 : : // do not copy the cached expression map - the expressions need to be created and prepared with getExpression(...) call 23 : 0 : } 24 : : 25 : : 26 : 0 : void QgsDiagram::clearCache() 27 : : { 28 : 0 : QMapIterator<QString, QgsExpression *> i( mExpressions ); 29 : 0 : while ( i.hasNext() ) 30 : : { 31 : 0 : i.next(); 32 : 0 : delete i.value(); 33 : : } 34 : 0 : mExpressions.clear(); 35 : 0 : } 36 : : 37 : 0 : QgsExpression *QgsDiagram::getExpression( const QString &expression, const QgsExpressionContext &context ) 38 : : { 39 : 0 : if ( !mExpressions.contains( expression ) ) 40 : : { 41 : 0 : QgsExpression *expr = new QgsExpression( expression ); 42 : 0 : expr->prepare( &context ); 43 : 0 : mExpressions[expression] = expr; 44 : 0 : } 45 : 0 : return mExpressions[expression]; 46 : 0 : } 47 : : 48 : 0 : void QgsDiagram::setPenWidth( QPen &pen, const QgsDiagramSettings &s, const QgsRenderContext &c ) 49 : : { 50 : 0 : pen.setWidthF( c.convertToPainterUnits( s.penWidth, s.lineSizeUnit, s.lineSizeScale ) ); 51 : 0 : } 52 : : 53 : : 54 : 0 : QSizeF QgsDiagram::sizePainterUnits( QSizeF size, const QgsDiagramSettings &s, const QgsRenderContext &c ) 55 : : { 56 : 0 : return QSizeF( c.convertToPainterUnits( size.width(), s.sizeType, s.sizeScale ), c.convertToPainterUnits( size.height(), s.sizeType, s.sizeScale ) ); 57 : : } 58 : : 59 : 0 : double QgsDiagram::sizePainterUnits( double l, const QgsDiagramSettings &s, const QgsRenderContext &c ) 60 : : { 61 : 0 : return c.convertToPainterUnits( l, s.sizeType, s.sizeScale ); 62 : : } 63 : : 64 : 0 : QFont QgsDiagram::scaledFont( const QgsDiagramSettings &s, const QgsRenderContext &c ) 65 : : { 66 : 0 : QFont f = s.font; 67 : 0 : if ( s.sizeType == QgsUnitTypes::RenderMapUnits ) 68 : : { 69 : 0 : int pixelsize = s.font.pointSizeF() / c.mapToPixel().mapUnitsPerPixel(); 70 : 0 : f.setPixelSize( pixelsize > 0 ? pixelsize : 1 ); 71 : 0 : } 72 : : else 73 : : { 74 : 0 : f.setPixelSize( s.font.pointSizeF() * 0.376 * c.scaleFactor() ); 75 : : } 76 : : 77 : 0 : return f; 78 : 0 : } 79 : : 80 : 0 : QSizeF QgsDiagram::sizeForValue( double value, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &is ) const 81 : : { 82 : 0 : double scaledValue = value; 83 : 0 : double scaledLowerValue = is.lowerValue; 84 : 0 : double scaledUpperValue = is.upperValue; 85 : : 86 : : // interpolate the squared value if scale by area 87 : 0 : if ( s.scaleByArea ) 88 : : { 89 : 0 : scaledValue = std::sqrt( scaledValue ); 90 : 0 : scaledLowerValue = std::sqrt( scaledLowerValue ); 91 : 0 : scaledUpperValue = std::sqrt( scaledUpperValue ); 92 : 0 : } 93 : : 94 : : //interpolate size 95 : 0 : double scaledRatio = ( scaledValue - scaledLowerValue ) / ( scaledUpperValue - scaledLowerValue ); 96 : : 97 : 0 : QSizeF size = QSizeF( is.upperSize.width() * scaledRatio + is.lowerSize.width() * ( 1 - scaledRatio ), 98 : 0 : is.upperSize.height() * scaledRatio + is.lowerSize.height() * ( 1 - scaledRatio ) ); 99 : : 100 : : // Scale, if extension is smaller than the specified minimum 101 : 0 : if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize ) 102 : : { 103 : 0 : bool p = false; // preserve height == width 104 : 0 : if ( qgsDoubleNear( size.width(), size.height() ) ) 105 : 0 : p = true; 106 : : 107 : 0 : size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio ); 108 : : 109 : : // If height == width, recover here (overwrite floating point errors) 110 : 0 : if ( p ) 111 : 0 : size.setWidth( size.height() ); 112 : 0 : } 113 : : 114 : 0 : return size; 115 : : }