Quantum GIS API Documentation  1.7.5-Wroclaw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
qgsdiagramrendererv2.cpp
Go to the documentation of this file.
1 #include "qgsdiagramrendererv2.h"
2 #include "qgsdiagram.h"
3 #include "qgsrendercontext.h"
4 #include <QDomElement>
5 #include <QPainter>
6 
7 
8 void QgsDiagramLayerSettings::readXML( const QDomElement& elem )
9 {
10  placement = ( Placement )elem.attribute( "placement" ).toInt();
11  placementFlags = ( LinePlacementFlags )elem.attribute( "linePlacementFlags" ).toInt();
12  priority = elem.attribute( "priority" ).toInt();
13  obstacle = elem.attribute( "obstacle" ).toInt();
14  dist = elem.attribute( "dist" ).toDouble();
15  xPosColumn = elem.attribute( "xPosColumn" ).toInt();
16  yPosColumn = elem.attribute( "yPosColumn" ).toInt();
17 }
18 
19 void QgsDiagramLayerSettings::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
20 {
21  QDomElement diagramLayerElem = doc.createElement( "DiagramLayerSettings" );
22  diagramLayerElem.setAttribute( "placement", placement );
23  diagramLayerElem.setAttribute( "linePlacementFlags", placementFlags );
24  diagramLayerElem.setAttribute( "priority", priority );
25  diagramLayerElem.setAttribute( "obstacle", obstacle );
26  diagramLayerElem.setAttribute( "dist", dist );
27  diagramLayerElem.setAttribute( "xPosColumn", xPosColumn );
28  diagramLayerElem.setAttribute( "yPosColumn", yPosColumn );
29  layerElem.appendChild( diagramLayerElem );
30 }
31 
32 void QgsDiagramSettings::readXML( const QDomElement& elem )
33 {
34  font.fromString( elem.attribute( "font" ) );
35  backgroundColor.setNamedColor( elem.attribute( "backgroundColor" ) );
36  backgroundColor.setAlpha( elem.attribute( "backgroundAlpha" ).toInt() );
37  size.setWidth( elem.attribute( "width" ).toDouble() );
38  size.setHeight( elem.attribute( "height" ).toDouble() );
39  penColor.setNamedColor( elem.attribute( "penColor" ) );
40  penWidth = elem.attribute( "penWidth" ).toDouble();
41  minScaleDenominator = elem.attribute( "minScaleDenominator", "-1" ).toDouble();
42  maxScaleDenominator = elem.attribute( "maxScaleDenominator", "-1" ).toDouble();
43 
44  //mm vs map units
45  if ( elem.attribute( "sizeType" ) == "MM" )
46  {
47  sizeType = MM;
48  }
49  else
50  {
52  }
53 
54  //colors
55  categoryColors.clear();
56  QStringList colorList = elem.attribute( "colors" ).split( "/" );
57  QStringList::const_iterator colorIt = colorList.constBegin();
58  for ( ; colorIt != colorList.constEnd(); ++colorIt )
59  {
60  categoryColors.append( QColor( *colorIt ) );
61  }
62 
63  //attribute indices
64  categoryIndices.clear();
65  QStringList catList = elem.attribute( "categories" ).split( "/" );
66  QStringList::const_iterator catIt = catList.constBegin();
67  for ( ; catIt != catList.constEnd(); ++catIt )
68  {
69  categoryIndices.append( catIt->toInt() );
70  }
71 }
72 
73 void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc ) const
74 {
75  QDomElement categoryElem = doc.createElement( "DiagramCategory" );
76  categoryElem.setAttribute( "font", font.toString() );
77  categoryElem.setAttribute( "backgroundColor", backgroundColor.name() );
78  categoryElem.setAttribute( "backgroundAlpha", backgroundColor.alpha() );
79  categoryElem.setAttribute( "width", size.width() );
80  categoryElem.setAttribute( "height", size.height() );
81  categoryElem.setAttribute( "penColor", penColor.name() );
82  categoryElem.setAttribute( "penWidth", penWidth );
83  categoryElem.setAttribute( "minScaleDenominator", minScaleDenominator );
84  categoryElem.setAttribute( "maxScaleDenominator", maxScaleDenominator );
85  if ( sizeType == MM )
86  {
87  categoryElem.setAttribute( "sizeType", "MM" );
88  }
89  else
90  {
91  categoryElem.setAttribute( "sizeType", "MapUnits" );
92  }
93 
94  QString colors;
95  for ( int i = 0; i < categoryColors.size(); ++i )
96  {
97  if ( i > 0 )
98  {
99  colors.append( "/" );
100  }
101  colors.append( categoryColors.at( i ).name() );
102  }
103  categoryElem.setAttribute( "colors", colors );
104 
105  QString categories;
106  for ( int i = 0; i < categoryIndices.size(); ++i )
107  {
108  if ( i > 0 )
109  {
110  categories.append( "/" );
111  }
112  categories.append( QString::number( categoryIndices.at( i ) ) );
113  }
114  categoryElem.setAttribute( "categories", categories );
115 
116  rendererElem.appendChild( categoryElem );
117 }
118 
120 {
121 }
122 
124 {
125  delete mDiagram;
126 }
127 
129 {
130  delete mDiagram;
131  mDiagram = d;
132 }
133 
134 void QgsDiagramRendererV2::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QPointF& pos )
135 {
136  if ( !mDiagram )
137  {
138  return;
139  }
140 
142  if ( !diagramSettings( att, c, s ) )
143  {
144  return;
145  }
146 
147  mDiagram->renderDiagram( att, c, s, pos );
148 }
149 
151 {
153  if ( !diagramSettings( attributes, c, s ) )
154  {
155  return QSizeF();
156  }
157 
158  QSizeF size = diagramSize( attributes, c );
159  if ( s.sizeType == QgsDiagramSettings::MM )
160  {
161  convertSizeToMapUnits( size, c );
162  }
163  return size;
164 }
165 
166 void QgsDiagramRendererV2::convertSizeToMapUnits( QSizeF& size, const QgsRenderContext& context ) const
167 {
168  if ( !size.isValid() )
169  {
170  return;
171  }
172 
173  int dpi = dpiPaintDevice( context.constPainter() );
174  if ( dpi < 0 )
175  {
176  return;
177  }
178 
179  double pixelToMap = dpi / 25.4 * context.mapToPixel().mapUnitsPerPixel();
180  size.rwidth() *= pixelToMap;
181  size.rheight() *= pixelToMap;
182 }
183 
184 int QgsDiagramRendererV2::dpiPaintDevice( const QPainter* painter )
185 {
186  if ( painter )
187  {
188  QPaintDevice* device = painter->device();
189  if ( device )
190  {
191  return device->logicalDpiX();
192  }
193  }
194  return -1;
195 }
196 
197 void QgsDiagramRendererV2::_readXML( const QDomElement& elem )
198 {
199  delete mDiagram;
200  QString diagramType = elem.attribute( "diagramType" );
201  if ( diagramType == "Pie" )
202  {
203  mDiagram = new QgsPieDiagram();
204  }
205  else if ( diagramType == "Text" )
206  {
207  mDiagram = new QgsTextDiagram();
208  }
209  else
210  {
211  mDiagram = 0;
212  }
213 }
214 
215 void QgsDiagramRendererV2::_writeXML( QDomElement& rendererElem, QDomDocument& doc ) const
216 {
217  if ( mDiagram )
218  {
219  rendererElem.setAttribute( "diagramType", mDiagram->diagramName() );
220  }
221 }
222 
224 {
225 }
226 
228 {
229 }
230 
232 {
233  s = mSettings;
234  return true;
235 }
236 
237 QList<QgsDiagramSettings> QgsSingleCategoryDiagramRenderer::diagramSettings() const
238 {
239  QList<QgsDiagramSettings> settingsList;
240  settingsList.push_back( mSettings );
241  return settingsList;
242 }
243 
244 void QgsSingleCategoryDiagramRenderer::readXML( const QDomElement& elem )
245 {
246  QDomElement categoryElem = elem.firstChildElement( "DiagramCategory" );
247  if ( categoryElem.isNull() )
248  {
249  return;
250  }
251 
252  mSettings.readXML( categoryElem );
253  _readXML( elem );
254 }
255 
256 void QgsSingleCategoryDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
257 {
258  QDomElement rendererElem = doc.createElement( "SingleCategoryDiagramRenderer" );
259  mSettings.writeXML( rendererElem, doc );
260  _writeXML( rendererElem, doc );
261  layerElem.appendChild( rendererElem );
262 }
263 
264 
266 {
267 }
268 
270 {
271 }
272 
274 {
275  QList<QgsDiagramSettings> settingsList;
276  settingsList.push_back( mSettings );
277  return settingsList;
278 }
279 
281 {
282  s = mSettings;
283  s.size = diagramSize( attributes, c );
284  return true;
285 }
286 
288 {
289  QList<int> attributes = mSettings.categoryIndices;
290  if ( !attributes.contains( mClassificationAttribute ) )
291  {
292  attributes.push_back( mClassificationAttribute );
293  }
294  return attributes;
295 }
296 
298 {
299  QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute );
300  if ( attIt == attributes.constEnd() )
301  {
302  return QSizeF(); //zero size if attribute is missing
303  }
304  double value = attIt.value().toDouble();
305 
306  //interpolate size
307  double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue );
308  return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ),
309  mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) );
310 }
311 
312 void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem )
313 {
314  mLowerValue = elem.attribute( "lowerValue" ).toDouble();
315  mUpperValue = elem.attribute( "upperValue" ).toDouble();
316  mLowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() );
317  mLowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() );
318  mUpperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() );
319  mUpperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() );
320  mClassificationAttribute = elem.attribute( "classificationAttribute" ).toInt();
321  QDomElement settingsElem = elem.firstChildElement( "DiagramCategory" );
322  if ( !settingsElem.isNull() )
323  {
324  mSettings.readXML( settingsElem );
325  }
326  _readXML( elem );
327 }
328 
329 void QgsLinearlyInterpolatedDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
330 {
331  QDomElement rendererElem = doc.createElement( "LinearlyInterpolatedDiagramRenderer" );
332  rendererElem.setAttribute( "lowerValue", mLowerValue );
333  rendererElem.setAttribute( "upperValue", mUpperValue );
334  rendererElem.setAttribute( "lowerWidth", mLowerSize.width() );
335  rendererElem.setAttribute( "lowerHeight", mLowerSize.height() );
336  rendererElem.setAttribute( "upperWidth", mUpperSize.width() );
337  rendererElem.setAttribute( "upperHeight", mUpperSize.height() );
338  rendererElem.setAttribute( "classificationAttribute", mClassificationAttribute );
339  mSettings.writeXML( rendererElem, doc );
340  _writeXML( rendererElem, doc );
341  layerElem.appendChild( rendererElem );
342 }