QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsscalebarstyle.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsscalebarstyle.cpp
3  --------------------
4  begin : June 2008
5  copyright : (C) 2008 by Marco Hugentobler
6  email : marco.hugentobler@karto.baug.ethz.ch
7  ***************************************************************************/
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgsscalebarstyle.h"
18 #include "qgscomposerscalebar.h"
19 #include "qgscomposerutils.h"
20 #include <QFontMetricsF>
21 #include <QPainter>
22 
24 {
25 
26 }
27 
29 {
30 
31 }
32 
34 {
35 
36 }
37 
38 void QgsScaleBarStyle::drawLabels( QPainter* p ) const
39 {
40  if ( !p || !mScaleBar )
41  {
42  return;
43  }
44 
45  p->save();
46 
47  p->setFont( mScaleBar->font() );
48  p->setPen( QPen( mScaleBar->fontColor() ) );
49 
50  QString firstLabel = mScaleBar->firstLabelString();
51  double xOffset = QgsComposerUtils::textWidthMM( mScaleBar->font(), firstLabel ) / 2;
52 
53  //double mCurrentXCoord = mScaleBar->pen().widthF() + mScaleBar->boxContentSpace();
54  QList<QPair<double, double> > segmentInfo;
55  mScaleBar->segmentPositions( segmentInfo );
56 
57  double currentLabelNumber = 0.0;
58 
59  int nSegmentsLeft = mScaleBar->numSegmentsLeft();
60  int segmentCounter = 0;
61  QString currentNumericLabel;
62 
63  QList<QPair<double, double> >::const_iterator segmentIt = segmentInfo.constBegin();
64  for ( ; segmentIt != segmentInfo.constEnd(); ++segmentIt )
65  {
66  if ( segmentCounter == 0 && nSegmentsLeft > 0 )
67  {
68  //label first left segment
69  currentNumericLabel = firstLabel;
70  }
71  else if ( segmentCounter != 0 && segmentCounter == nSegmentsLeft ) //reset label number to 0 if there are left segments
72  {
73  currentLabelNumber = 0;
74  }
75 
76  if ( segmentCounter >= nSegmentsLeft )
77  {
78  currentNumericLabel = QString::number( currentLabelNumber / mScaleBar->numMapUnitsPerScaleBarUnit() );
79  }
80 
81  if ( segmentCounter == 0 || segmentCounter >= nSegmentsLeft ) //don't draw label for intermediate left segments
82  {
83  QgsComposerUtils::drawText( p, QPointF( segmentIt->first - QgsComposerUtils::textWidthMM( mScaleBar->font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->boxContentSpace() ),
84  currentNumericLabel, mScaleBar->font(), mScaleBar->fontColor() );
85  }
86 
87  if ( segmentCounter >= nSegmentsLeft )
88  {
89  currentLabelNumber += mScaleBar->numUnitsPerSegment();
90  }
91  ++segmentCounter;
92  }
93 
94  //also draw the last label
95  if ( !segmentInfo.isEmpty() )
96  {
97  currentNumericLabel = QString::number( currentLabelNumber / mScaleBar->numMapUnitsPerScaleBarUnit() );
98  QgsComposerUtils::drawText( p, QPointF( segmentInfo.last().first + mScaleBar->segmentMillimeters() - QgsComposerUtils::textWidthMM( mScaleBar->font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->boxContentSpace() ),
99  currentNumericLabel + " " + mScaleBar->unitLabeling(), mScaleBar->font(), mScaleBar->fontColor() );
100  }
101 
102  p->restore();
103 }
104 
106 {
107  if ( !mScaleBar )
108  {
109  return QRectF();
110  }
111 
112  //consider centered first label
113  double firstLabelLeft = QgsComposerUtils::textWidthMM( mScaleBar->font(), mScaleBar->firstLabelString() ) / 2;
114 
115  //consider last number and label
116 
118  QString largestNumberLabel = QString::number( largestLabelNumber );
119  QString largestLabel = QString::number( largestLabelNumber ) + " " + mScaleBar->unitLabeling();
120  double largestLabelWidth = QgsComposerUtils::textWidthMM( mScaleBar->font(), largestLabel ) - QgsComposerUtils::textWidthMM( mScaleBar->font(), largestNumberLabel ) / 2;
121 
122  double totalBarLength = 0.0;
123 
124  QList< QPair<double, double> > segmentList;
125  mScaleBar->segmentPositions( segmentList );
126 
127  QList< QPair<double, double> >::const_iterator segmentIt = segmentList.constBegin();
128  for ( ; segmentIt != segmentList.constEnd(); ++segmentIt )
129  {
130  totalBarLength += segmentIt->second;
131  }
132 
133  double width = firstLabelLeft + totalBarLength + 2 * mScaleBar->pen().widthF() + largestLabelWidth + 2 * mScaleBar->boxContentSpace();
135 
136  return QRectF( mScaleBar->pos().x(), mScaleBar->pos().y(), width, height );
137 }
A scale bar item that can be added to a map composition.
virtual void drawLabels(QPainter *p) const
double boxContentSpace() const
void segmentPositions(QList< QPair< double, double > > &posWidthList) const
Returns the x - positions of the segment borders (in item coordinates) and the width of the segment...
virtual QRectF calculateBoxSize() const
static void drawText(QPainter *painter, const QPointF &pos, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of composer specific issues (calculation ...
static double fontAscentMM(const QFont &font)
Calculate font ascent in millimeters, including workarounds for QT font rendering issues...
double numMapUnitsPerScaleBarUnit() const
virtual ~QgsScaleBarStyle()
int numSegmentsLeft() const
double labelBarSpace() const
QString unitLabeling() const
double segmentMillimeters() const
QPen pen() const
Returns the pen used for drawing the scalebar.
QColor fontColor() const
Returns the color used for drawing text in the scalebar.
static double textWidthMM(const QFont &font, const QString &text)
Calculate font width in millimeters for a string, including workarounds for QT font rendering issues...
const QgsComposerScaleBar * mScaleBar
double numUnitsPerSegment() const
QString firstLabelString() const
Returns string of first label (important for drawing, labeling, size calculation. ...