QGIS API Documentation  2.99.0-Master (08c2e66)
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.
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, 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
int numSegmentsLeft() const
double labelBarSpace() const
QString unitLabeling() const
double segmentMillimeters() const
QgsScaleBarStyle(const QgsComposerScaleBar *bar)
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. ...