QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 
28 QgsScaleBarStyle::QgsScaleBarStyle(): mScaleBar( 0 )
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
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. ...