QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
34 {
35 
36 }
37 
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  {
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() );
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.
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 ...
void save()
static double fontAscentMM(const QFont &font)
Calculate font ascent in millimeters, including workarounds for QT font rendering issues...
void setFont(const QFont &font)
QPointF pos() const
virtual ~QgsScaleBarStyle()
QString number(int n, int base)
qreal x() const
qreal y() const
QString firstLabelString() const
Returns string of first label (important for drawing, labeling, size calculation. ...
void setPen(const QColor &color)
double labelBarSpace() const
T & first()
QgsScaleBarStyle(const QgsComposerScaleBar *bar)
void restore()
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
qreal widthF() const
const_iterator constEnd() 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...
const_iterator constBegin() const
virtual void drawLabels(QPainter *p) const