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