Quantum GIS API Documentation  1.7.4
src/core/qgsdiagramrendererv2.cpp
Go to the documentation of this file.
00001 #include "qgsdiagramrendererv2.h"
00002 #include "qgsdiagram.h"
00003 #include "qgsrendercontext.h"
00004 #include <QDomElement>
00005 #include <QPainter>
00006 
00007 
00008 void QgsDiagramLayerSettings::readXML( const QDomElement& elem )
00009 {
00010   placement = ( Placement )elem.attribute( "placement" ).toInt();
00011   placementFlags = ( LinePlacementFlags )elem.attribute( "linePlacementFlags" ).toInt();
00012   priority = elem.attribute( "priority" ).toInt();
00013   obstacle = elem.attribute( "obstacle" ).toInt();
00014   dist = elem.attribute( "dist" ).toDouble();
00015   xPosColumn = elem.attribute( "xPosColumn" ).toInt();
00016   yPosColumn = elem.attribute( "yPosColumn" ).toInt();
00017 }
00018 
00019 void QgsDiagramLayerSettings::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
00020 {
00021   QDomElement diagramLayerElem = doc.createElement( "DiagramLayerSettings" );
00022   diagramLayerElem.setAttribute( "placement", placement );
00023   diagramLayerElem.setAttribute( "linePlacementFlags", placementFlags );
00024   diagramLayerElem.setAttribute( "priority", priority );
00025   diagramLayerElem.setAttribute( "obstacle", obstacle );
00026   diagramLayerElem.setAttribute( "dist", dist );
00027   diagramLayerElem.setAttribute( "xPosColumn", xPosColumn );
00028   diagramLayerElem.setAttribute( "yPosColumn", yPosColumn );
00029   layerElem.appendChild( diagramLayerElem );
00030 }
00031 
00032 void QgsDiagramSettings::readXML( const QDomElement& elem )
00033 {
00034   font.fromString( elem.attribute( "font" ) );
00035   backgroundColor.setNamedColor( elem.attribute( "backgroundColor" ) );
00036   backgroundColor.setAlpha( elem.attribute( "backgroundAlpha" ).toInt() );
00037   size.setWidth( elem.attribute( "width" ).toDouble() );
00038   size.setHeight( elem.attribute( "height" ).toDouble() );
00039   penColor.setNamedColor( elem.attribute( "penColor" ) );
00040   penWidth = elem.attribute( "penWidth" ).toDouble();
00041   minScaleDenominator = elem.attribute( "minScaleDenominator", "-1" ).toDouble();
00042   maxScaleDenominator = elem.attribute( "maxScaleDenominator", "-1" ).toDouble();
00043 
00044   //mm vs map units
00045   if ( elem.attribute( "sizeType" ) == "MM" )
00046   {
00047     sizeType = MM;
00048   }
00049   else
00050   {
00051     sizeType = MapUnits;
00052   }
00053 
00054   //colors
00055   categoryColors.clear();
00056   QStringList colorList = elem.attribute( "colors" ).split( "/" );
00057   QStringList::const_iterator colorIt = colorList.constBegin();
00058   for ( ; colorIt != colorList.constEnd(); ++colorIt )
00059   {
00060     categoryColors.append( QColor( *colorIt ) );
00061   }
00062 
00063   //attribute indices
00064   categoryIndices.clear();
00065   QStringList catList = elem.attribute( "categories" ).split( "/" );
00066   QStringList::const_iterator catIt = catList.constBegin();
00067   for ( ; catIt != catList.constEnd(); ++catIt )
00068   {
00069     categoryIndices.append( catIt->toInt() );
00070   }
00071 }
00072 
00073 void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc ) const
00074 {
00075   QDomElement categoryElem = doc.createElement( "DiagramCategory" );
00076   categoryElem.setAttribute( "font", font.toString() );
00077   categoryElem.setAttribute( "backgroundColor", backgroundColor.name() );
00078   categoryElem.setAttribute( "backgroundAlpha", backgroundColor.alpha() );
00079   categoryElem.setAttribute( "width", size.width() );
00080   categoryElem.setAttribute( "height", size.height() );
00081   categoryElem.setAttribute( "penColor", penColor.name() );
00082   categoryElem.setAttribute( "penWidth", penWidth );
00083   categoryElem.setAttribute( "minScaleDenominator", minScaleDenominator );
00084   categoryElem.setAttribute( "maxScaleDenominator", maxScaleDenominator );
00085   if ( sizeType == MM )
00086   {
00087     categoryElem.setAttribute( "sizeType", "MM" );
00088   }
00089   else
00090   {
00091     categoryElem.setAttribute( "sizeType", "MapUnits" );
00092   }
00093 
00094   QString colors;
00095   for ( int i = 0; i < categoryColors.size(); ++i )
00096   {
00097     if ( i > 0 )
00098     {
00099       colors.append( "/" );
00100     }
00101     colors.append( categoryColors.at( i ).name() );
00102   }
00103   categoryElem.setAttribute( "colors", colors );
00104 
00105   QString categories;
00106   for ( int i = 0; i < categoryIndices.size(); ++i )
00107   {
00108     if ( i > 0 )
00109     {
00110       categories.append( "/" );
00111     }
00112     categories.append( QString::number( categoryIndices.at( i ) ) );
00113   }
00114   categoryElem.setAttribute( "categories", categories );
00115 
00116   rendererElem.appendChild( categoryElem );
00117 }
00118 
00119 QgsDiagramRendererV2::QgsDiagramRendererV2(): mDiagram( 0 )
00120 {
00121 }
00122 
00123 QgsDiagramRendererV2::~QgsDiagramRendererV2()
00124 {
00125   delete mDiagram;
00126 }
00127 
00128 void QgsDiagramRendererV2::setDiagram( QgsDiagram* d )
00129 {
00130   delete mDiagram;
00131   mDiagram = d;
00132 }
00133 
00134 void QgsDiagramRendererV2::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos )
00135 {
00136   if ( !mDiagram )
00137   {
00138     return;
00139   }
00140 
00141   QgsDiagramSettings s;
00142   if ( !diagramSettings( att, c, s ) )
00143   {
00144     return;
00145   }
00146 
00147   mDiagram->renderDiagram( att, c, s, pos );
00148 }
00149 
00150 QSizeF QgsDiagramRendererV2::sizeMapUnits( const QgsAttributeMap& attributes, const QgsRenderContext& c )
00151 {
00152   QgsDiagramSettings s;
00153   if ( !diagramSettings( attributes, c, s ) )
00154   {
00155     return QSizeF();
00156   }
00157 
00158   QSizeF size = diagramSize( attributes, c );
00159   if ( s.sizeType == QgsDiagramSettings::MM )
00160   {
00161     convertSizeToMapUnits( size, c );
00162   }
00163   return size;
00164 }
00165 
00166 void QgsDiagramRendererV2::convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const
00167 {
00168   if ( !size.isValid() )
00169   {
00170     return;
00171   }
00172 
00173   int dpi = dpiPaintDevice( context.constPainter() );
00174   if ( dpi < 0 )
00175   {
00176     return;
00177   }
00178 
00179   double pixelToMap = dpi / 25.4 * context.mapToPixel().mapUnitsPerPixel();
00180   size.rwidth() *= pixelToMap;
00181   size.rheight() *= pixelToMap;
00182 }
00183 
00184 int QgsDiagramRendererV2::dpiPaintDevice( const QPainter* painter )
00185 {
00186   if ( painter )
00187   {
00188     QPaintDevice* device = painter->device();
00189     if ( device )
00190     {
00191       return device->logicalDpiX();
00192     }
00193   }
00194   return -1;
00195 }
00196 
00197 void QgsDiagramRendererV2::_readXML( const QDomElement& elem )
00198 {
00199   delete mDiagram;
00200   QString diagramType = elem.attribute( "diagramType" );
00201   if ( diagramType == "Pie" )
00202   {
00203     mDiagram = new QgsPieDiagram();
00204   }
00205   else if ( diagramType == "Text" )
00206   {
00207     mDiagram = new QgsTextDiagram();
00208   }
00209   else
00210   {
00211     mDiagram = 0;
00212   }
00213 }
00214 
00215 void QgsDiagramRendererV2::_writeXML( QDomElement& rendererElem, QDomDocument& doc ) const
00216 {
00217   if ( mDiagram )
00218   {
00219     rendererElem.setAttribute( "diagramType", mDiagram->diagramName() );
00220   }
00221 }
00222 
00223 QgsSingleCategoryDiagramRenderer::QgsSingleCategoryDiagramRenderer(): QgsDiagramRendererV2()
00224 {
00225 }
00226 
00227 QgsSingleCategoryDiagramRenderer::~QgsSingleCategoryDiagramRenderer()
00228 {
00229 }
00230 
00231 bool QgsSingleCategoryDiagramRenderer::diagramSettings( const QgsAttributeMap&, const QgsRenderContext& c, QgsDiagramSettings& s )
00232 {
00233   s = mSettings;
00234   return true;
00235 }
00236 
00237 QList<QgsDiagramSettings> QgsSingleCategoryDiagramRenderer::diagramSettings() const
00238 {
00239   QList<QgsDiagramSettings> settingsList;
00240   settingsList.push_back( mSettings );
00241   return settingsList;
00242 }
00243 
00244 void QgsSingleCategoryDiagramRenderer::readXML( const QDomElement& elem )
00245 {
00246   QDomElement categoryElem = elem.firstChildElement( "DiagramCategory" );
00247   if ( categoryElem.isNull() )
00248   {
00249     return;
00250   }
00251 
00252   mSettings.readXML( categoryElem );
00253   _readXML( elem );
00254 }
00255 
00256 void QgsSingleCategoryDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
00257 {
00258   QDomElement rendererElem = doc.createElement( "SingleCategoryDiagramRenderer" );
00259   mSettings.writeXML( rendererElem, doc );
00260   _writeXML( rendererElem, doc );
00261   layerElem.appendChild( rendererElem );
00262 }
00263 
00264 
00265 QgsLinearlyInterpolatedDiagramRenderer::QgsLinearlyInterpolatedDiagramRenderer(): QgsDiagramRendererV2()
00266 {
00267 }
00268 
00269 QgsLinearlyInterpolatedDiagramRenderer::~QgsLinearlyInterpolatedDiagramRenderer()
00270 {
00271 }
00272 
00273 QList<QgsDiagramSettings> QgsLinearlyInterpolatedDiagramRenderer::diagramSettings() const
00274 {
00275   QList<QgsDiagramSettings> settingsList;
00276   settingsList.push_back( mSettings );
00277   return settingsList;
00278 }
00279 
00280 bool QgsLinearlyInterpolatedDiagramRenderer::diagramSettings( const QgsAttributeMap& attributes, const QgsRenderContext& c, QgsDiagramSettings& s )
00281 {
00282   s = mSettings;
00283   s.size = diagramSize( attributes, c );
00284   return true;
00285 }
00286 
00287 QList<int> QgsLinearlyInterpolatedDiagramRenderer::diagramAttributes() const
00288 {
00289   QList<int> attributes = mSettings.categoryIndices;
00290   if ( !attributes.contains( mClassificationAttribute ) )
00291   {
00292     attributes.push_back( mClassificationAttribute );
00293   }
00294   return attributes;
00295 }
00296 
00297 QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c )
00298 {
00299   QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute );
00300   if ( attIt == attributes.constEnd() )
00301   {
00302     return QSizeF(); //zero size if attribute is missing
00303   }
00304   double value = attIt.value().toDouble();
00305 
00306   //interpolate size
00307   double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue );
00308   return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ),
00309                  mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) );
00310 }
00311 
00312 void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem )
00313 {
00314   mLowerValue = elem.attribute( "lowerValue" ).toDouble();
00315   mUpperValue = elem.attribute( "upperValue" ).toDouble();
00316   mLowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() );
00317   mLowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() );
00318   mUpperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() );
00319   mUpperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() );
00320   mClassificationAttribute = elem.attribute( "classificationAttribute" ).toInt();
00321   QDomElement settingsElem = elem.firstChildElement( "DiagramCategory" );
00322   if ( !settingsElem.isNull() )
00323   {
00324     mSettings.readXML( settingsElem );
00325   }
00326   _readXML( elem );
00327 }
00328 
00329 void QgsLinearlyInterpolatedDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
00330 {
00331   QDomElement rendererElem = doc.createElement( "LinearlyInterpolatedDiagramRenderer" );
00332   rendererElem.setAttribute( "lowerValue", mLowerValue );
00333   rendererElem.setAttribute( "upperValue", mUpperValue );
00334   rendererElem.setAttribute( "lowerWidth", mLowerSize.width() );
00335   rendererElem.setAttribute( "lowerHeight", mLowerSize.height() );
00336   rendererElem.setAttribute( "upperWidth", mUpperSize.width() );
00337   rendererElem.setAttribute( "upperHeight", mUpperSize.height() );
00338   rendererElem.setAttribute( "classificationAttribute", mClassificationAttribute );
00339   mSettings.writeXML( rendererElem, doc );
00340   _writeXML( rendererElem, doc );
00341   layerElem.appendChild( rendererElem );
00342 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines