QGIS API Documentation  2.99.0-Master (0a63d1f)
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 : [email protected]
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 
33 void QgsScaleBarStyle::drawLabels( QPainter* p ) const
34 {
35  if ( !p || !mScaleBar )
36  {
37  return;
38  }
39 
40  p->save();
41 
42  p->setFont( mScaleBar->font() );
43  p->setPen( QPen( mScaleBar->fontColor() ) );
44 
45  QString firstLabel = mScaleBar->firstLabelString();
46  double xOffset = QgsComposerUtils::textWidthMM( mScaleBar->font(), firstLabel ) / 2;
47 
48  //double mCurrentXCoord = mScaleBar->pen().widthF() + mScaleBar->boxContentSpace();
49  QList<QPair<double, double> > segmentInfo;
50  mScaleBar->segmentPositions( segmentInfo );
51 
52  double currentLabelNumber = 0.0;
53 
54  int nSegmentsLeft = mScaleBar->numSegmentsLeft();
55  int segmentCounter = 0;
56  QString currentNumericLabel;
57 
58  QList<QPair<double, double> >::const_iterator segmentIt = segmentInfo.constBegin();
59  for ( ; segmentIt != segmentInfo.constEnd(); ++segmentIt )
60  {
61  if ( segmentCounter == 0 && nSegmentsLeft > 0 )
62  {
63  //label first left segment
64  currentNumericLabel = firstLabel;
65  }
66  else if ( segmentCounter != 0 && segmentCounter == nSegmentsLeft ) //reset label number to 0 if there are left segments
67  {
68  currentLabelNumber = 0;
69  }
70 
71  if ( segmentCounter >= nSegmentsLeft )
72  {
73  currentNumericLabel = QString::number( currentLabelNumber / mScaleBar->numMapUnitsPerScaleBarUnit() );
74  }
75 
76  if ( segmentCounter == 0 || segmentCounter >= nSegmentsLeft ) //don't draw label for intermediate left segments
77  {
78  QgsComposerUtils::drawText( p, QPointF( segmentIt->first - QgsComposerUtils::textWidthMM( mScaleBar->font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->boxContentSpace() ),
79  currentNumericLabel, mScaleBar->font(), mScaleBar->fontColor() );
80  }
81 
82  if ( segmentCounter >= nSegmentsLeft )
83  {
84  currentLabelNumber += mScaleBar->numUnitsPerSegment();
85  }
86  ++segmentCounter;
87  }
88 
89  //also draw the last label
90  if ( !segmentInfo.isEmpty() )
91  {
92  currentNumericLabel = QString::number( currentLabelNumber / mScaleBar->numMapUnitsPerScaleBarUnit() );
93  QgsComposerUtils::drawText( p, QPointF( segmentInfo.last().first + mScaleBar->segmentMillimeters() - QgsComposerUtils::textWidthMM( mScaleBar->font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( mScaleBar->font() ) + mScaleBar->boxContentSpace() ),
94  currentNumericLabel + ' ' + mScaleBar->unitLabeling(), mScaleBar->font(), mScaleBar->fontColor() );
95  }
96 
97  p->restore();
98 }
99 
101 {
102  if ( !mScaleBar )
103  {
104  return QRectF();
105  }
106 
107  //consider centered first label
108  double firstLabelLeft = QgsComposerUtils::textWidthMM( mScaleBar->font(), mScaleBar->firstLabelString() ) / 2;
109 
110  //consider last number and label
111 
113  QString largestNumberLabel = QString::number( largestLabelNumber );
114  QString largestLabel = QString::number( largestLabelNumber ) + ' ' + mScaleBar->unitLabeling();
115  double largestLabelWidth = QgsComposerUtils::textWidthMM( mScaleBar->font(), largestLabel ) - QgsComposerUtils::textWidthMM( mScaleBar->font(), largestNumberLabel ) / 2;
116 
117  double totalBarLength = 0.0;
118 
119  QList< QPair<double, double> > segmentList;
120  mScaleBar->segmentPositions( segmentList );
121 
122  QList< QPair<double, double> >::const_iterator segmentIt = segmentList.constBegin();
123  for ( ; segmentIt != segmentList.constEnd(); ++segmentIt )
124  {
125  totalBarLength += segmentIt->second;
126  }
127 
128  double width = firstLabelLeft + totalBarLength + 2 * mScaleBar->pen().widthF() + largestLabelWidth + 2 * mScaleBar->boxContentSpace();
130 
131  return QRectF( mScaleBar->pos().x(), mScaleBar->pos().y(), width, height );
132 }
A scale bar item that can be added to a map composition.
double numUnitsPerSegment() const
virtual QRectF calculateBoxSize() const
double numMapUnitsPerScaleBarUnit() 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 void drawText(QPainter *painter, 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...
QString firstLabelString() const
Returns string of first label (important for drawing, labeling, size calculation. ...
double labelBarSpace() const
QgsScaleBarStyle(const QgsComposerScaleBar *bar)
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 segmentMillimeters() const
QString unitLabeling() 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 void drawLabels(QPainter *p) const