QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsticksscalebarrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsticksscalebarrenderer.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 
18 #include "qgsscalebarsettings.h"
19 #include "qgslayoututils.h"
20 #include "qgssymbol.h"
21 #include "qgslinesymbol.h"
22 #include "qgstextrenderer.h"
23 #include <QPainter>
24 
26  : mTickPosition( position )
27 {
28 
29 }
30 
32 {
33  switch ( mTickPosition )
34  {
35  case TicksUp:
36  return QStringLiteral( "Line Ticks Up" );
37  case TicksDown:
38  return QStringLiteral( "Line Ticks Down" );
39  case TicksMiddle:
40  return QStringLiteral( "Line Ticks Middle" );
41  }
42  return QString(); // to make gcc happy
43 }
44 
46 {
47  switch ( mTickPosition )
48  {
49  case TicksUp:
50  return QObject::tr( "Line Ticks Up" );
51  case TicksDown:
52  return QObject::tr( "Line Ticks Down" );
53  case TicksMiddle:
54  return QObject::tr( "Line Ticks Middle" );
55  }
56  return QString(); // to make gcc happy
57 
58 }
59 
61 {
62  switch ( mTickPosition )
63  {
64  case TicksUp:
65  return 5;
66  case TicksDown:
67  return 4;
68  case TicksMiddle:
69  return 3;
70  }
71  return 6;
72 }
73 
74 QgsScaleBarRenderer::Flags QgsTicksScaleBarRenderer::flags() const
75 {
88 }
89 
91 {
92  return new QgsTicksScaleBarRenderer( * this );
93 }
94 
95 void QgsTicksScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const
96 {
97  if ( !context.painter() )
98  return;
99 
100  QPainter *painter = context.painter();
101 
102  const double scaledLabelBarSpace = context.convertToPainterUnits( settings.labelBarSpace(), QgsUnitTypes::RenderMillimeters );
103  const double scaledBoxContentSpace = context.convertToPainterUnits( settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters );
104  const QFontMetricsF fontMetrics = QgsTextRenderer::fontMetrics( context, settings.textFormat() );
105  const double barTopPosition = scaledBoxContentSpace + ( settings.labelVerticalPlacement() == QgsScaleBarSettings::LabelAboveSegment ? fontMetrics.ascent() + scaledLabelBarSpace : 0 );
106  const double scaledHeight = context.convertToPainterUnits( settings.height(), QgsUnitTypes::RenderMillimeters );
107  const double scaledSubdivisionsHeight = context.convertToPainterUnits( settings.subdivisionsHeight(), QgsUnitTypes::RenderMillimeters );
108  const double scaledMaxHeight = ( ( settings.numberOfSubdivisions() > 1 ) && ( scaledSubdivisionsHeight > scaledHeight ) ) ? scaledSubdivisionsHeight : scaledHeight;
109  const double middlePosition = barTopPosition + scaledMaxHeight / 2.0;
110  const double bottomPosition = barTopPosition + scaledMaxHeight;
111 
112  const double xOffset = firstLabelXOffset( settings, context, scaleContext );
113 
114  painter->save();
115  context.setPainterFlagsUsingContext( painter );
116 
117  std::unique_ptr< QgsLineSymbol > symbol( settings.lineSymbol()->clone() );
118  symbol->startRender( context );
119 
120  std::unique_ptr< QgsLineSymbol > divisionSymbol( settings.divisionLineSymbol()->clone() );
121  divisionSymbol->startRender( context );
122 
123  std::unique_ptr< QgsLineSymbol > subdivisionSymbol( settings.subdivisionLineSymbol()->clone() );
124  subdivisionSymbol->startRender( context );
125 
126  const QList<double> positions = segmentPositions( context, scaleContext, settings );
127 
128  // vertical positions
129  double verticalPos = 0.0;
130  QList<double> subTickPositionsY;
131  QList<double> tickPositionsY;
132  switch ( mTickPosition )
133  {
134  case TicksDown:
135  verticalPos = barTopPosition;
136  subTickPositionsY << verticalPos;
137  subTickPositionsY << verticalPos + scaledSubdivisionsHeight;
138  tickPositionsY << verticalPos;
139  tickPositionsY << verticalPos + scaledHeight;
140  break;
141  case TicksMiddle:
142  verticalPos = middlePosition;
143  subTickPositionsY << verticalPos + scaledSubdivisionsHeight / 2.0;
144  subTickPositionsY << verticalPos - scaledSubdivisionsHeight / 2.0;
145  tickPositionsY << verticalPos + scaledHeight / 2.0;
146  tickPositionsY << verticalPos - scaledHeight / 2.0;
147  break;
148  case TicksUp:
149  verticalPos = bottomPosition;
150  subTickPositionsY << verticalPos;
151  subTickPositionsY << verticalPos - scaledSubdivisionsHeight;
152  tickPositionsY << verticalPos;
153  tickPositionsY << verticalPos - scaledHeight;
154  break;
155  }
156 
157  int symbolLayerCount = symbol->symbolLayerCount();
158  symbolLayerCount = std::max( symbolLayerCount, divisionSymbol->symbolLayerCount() );
159  symbolLayerCount = std::max( symbolLayerCount, subdivisionSymbol->symbolLayerCount() );
160 
161  // we render the bar symbol-layer-by-symbol-layer, to avoid ugliness where the lines overlap in multi-layer symbols
162  for ( int layer = 0; layer < symbolLayerCount; ++ layer )
163  {
164  const bool drawDivisionsForThisSymbolLayer = layer < divisionSymbol->symbolLayerCount();
165  const bool drawSubdivisionsForThisSymbolLayer = layer < subdivisionSymbol->symbolLayerCount();
166  const bool drawLineForThisSymbolLayer = layer < symbol->symbolLayerCount();
167 
168  if ( drawDivisionsForThisSymbolLayer )
169  {
170  // first draw the vertical lines for segments
171  for ( int i = 0; i < positions.size(); ++i )
172  {
173  const double thisX = context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset;
174  divisionSymbol->renderPolyline( QPolygonF() << QPointF( thisX, tickPositionsY.at( 0 ) )
175  << QPointF( thisX, tickPositionsY.at( 1 ) ), nullptr, context, layer );
176  }
177  }
178 
179  // draw the vertical lines for right subdivisions
180  if ( drawSubdivisionsForThisSymbolLayer )
181  {
182  for ( int i = settings.numberOfSegmentsLeft(); i < positions.size(); ++i )
183  {
184  for ( int j = 1; j < settings.numberOfSubdivisions(); ++j )
185  {
186  const double thisSubX = context.convertToPainterUnits( positions.at( i ) + j * scaleContext.segmentWidth / settings.numberOfSubdivisions(), QgsUnitTypes::RenderMillimeters ) + xOffset;
187  subdivisionSymbol->renderPolyline( QPolygonF() << QPointF( thisSubX, subTickPositionsY.at( 0 ) )
188  << QPointF( thisSubX, subTickPositionsY.at( 1 ) ), nullptr, context, layer );
189  }
190  }
191  }
192 
193  //draw last tick and horizontal line
194  if ( !positions.isEmpty() )
195  {
196  const double lastTickPositionX = context.convertToPainterUnits( positions.at( positions.size() - 1 ) + scaleContext.segmentWidth, QgsUnitTypes::RenderMillimeters ) + xOffset;
197 
198  //last vertical line
199  if ( drawDivisionsForThisSymbolLayer )
200  {
201  divisionSymbol->renderPolyline( QPolygonF() << QPointF( lastTickPositionX, tickPositionsY.at( 0 ) )
202  << QPointF( lastTickPositionX, tickPositionsY.at( 1 ) ),
203  nullptr, context, layer );
204  }
205 
206  //horizontal line
207  if ( drawLineForThisSymbolLayer )
208  {
209  symbol->renderPolyline( QPolygonF() << QPointF( xOffset + context.convertToPainterUnits( positions.at( 0 ), QgsUnitTypes::RenderMillimeters ), verticalPos )
210  << QPointF( lastTickPositionX, verticalPos ), nullptr, context, layer );
211  }
212  }
213  }
214 
215  symbol->stopRender( context );
216  divisionSymbol->stopRender( context );
217  subdivisionSymbol->stopRender( context );
218 
219  painter->restore();
220 
221  //draw labels using the default method
222  drawDefaultLabels( context, settings, scaleContext );
223 }
224 
225 
QgsScaleBarSettings::height
double height() const
Returns the scalebar height (in millimeters).
Definition: qgsscalebarsettings.h:550
QgsTicksScaleBarRenderer::TicksUp
@ TicksUp
Render ticks above line.
Definition: qgsticksscalebarrenderer.h:36
QgsScaleBarSettings::lineSymbol
QgsLineSymbol * lineSymbol() const
Returns the line symbol used to render the scalebar (only used for some scalebar types).
Definition: qgsscalebarsettings.cpp:193
QgsRenderContext::setPainterFlagsUsingContext
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
Definition: qgsrendercontext.cpp:169
QgsScaleBarRenderer::ScaleBarContext
Contains parameters regarding scalebar calculations.
Definition: qgsscalebarrenderer.h:70
QgsScaleBarRenderer::Flag::FlagUsesUnitLabel
@ FlagUsesUnitLabel
Renderer uses the QgsScaleBarSettings::unitLabel() setting.
qgstextrenderer.h
QgsTicksScaleBarRenderer::flags
Flags flags() const override
Returns the scalebar rendering flags, which dictates the renderer's behavior.
Definition: qgsticksscalebarrenderer.cpp:74
QgsTicksScaleBarRenderer::clone
QgsTicksScaleBarRenderer * clone() const override
Returns a clone of the renderer.
Definition: qgsticksscalebarrenderer.cpp:90
QgsLineSymbol::clone
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgslinesymbol.cpp:303
QgsTextRenderer::fontMetrics
static QFontMetricsF fontMetrics(QgsRenderContext &context, const QgsTextFormat &format, double scaleFactor=1.0)
Returns the font metrics for the given text format, when rendered in the specified render context.
Definition: qgstextrenderer.cpp:280
QgsTicksScaleBarRenderer::QgsTicksScaleBarRenderer
QgsTicksScaleBarRenderer(TickPosition position=TicksMiddle)
Constructor for QgsTicksScaleBarRenderer.
Definition: qgsticksscalebarrenderer.cpp:25
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsUnitTypes::RenderMillimeters
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
QgsTicksScaleBarRenderer::TicksMiddle
@ TicksMiddle
Render ticks crossing line.
Definition: qgsticksscalebarrenderer.h:38
QgsScaleBarRenderer::Flag::FlagUsesLabelHorizontalPlacement
@ FlagUsesLabelHorizontalPlacement
Renderer uses the QgsScaleBarSettings::labelHorizontalPlacement() setting.
QgsTicksScaleBarRenderer::TicksDown
@ TicksDown
Render ticks below line.
Definition: qgsticksscalebarrenderer.h:37
qgsscalebarsettings.h
qgslayoututils.h
QgsScaleBarSettings::subdivisionsHeight
double subdivisionsHeight() const
Returns the scalebar subdivisions height (in millimeters) for segments included in the right part of ...
Definition: qgsscalebarsettings.h:150
QgsScaleBarSettings::labelBarSpace
double labelBarSpace() const
Returns the spacing (in millimeters) between labels and the scalebar.
Definition: qgsscalebarsettings.h:562
QgsTicksScaleBarRenderer::visibleName
QString visibleName() const override
Returns the user friendly, translated name for the renderer.
Definition: qgsticksscalebarrenderer.cpp:45
QgsScaleBarRenderer::Flag::FlagUsesLabelVerticalPlacement
@ FlagUsesLabelVerticalPlacement
Renderer uses the QgsScaleBarSettings::labelVerticalPlacement() setting.
QgsScaleBarSettings::boxContentSpace
double boxContentSpace() const
Returns the spacing (margin) between the scalebar box and content in millimeters.
Definition: qgsscalebarsettings.h:602
QgsScaleBarSettings::labelVerticalPlacement
LabelVerticalPlacement labelVerticalPlacement() const
Returns the vertical placement of text labels.
Definition: qgsscalebarsettings.h:575
QgsScaleBarSettings::textFormat
QgsTextFormat & textFormat()
Returns the text format used for drawing text in the scalebar.
Definition: qgsscalebarsettings.h:268
QgsScaleBarRenderer::Flag::FlagUsesLineSymbol
@ FlagUsesLineSymbol
Renderer utilizes the scalebar line symbol (see QgsScaleBarSettings::lineSymbol() )
QgsScaleBarSettings
The QgsScaleBarSettings class stores the appearance and layout settings for scalebar drawing with Qgs...
Definition: qgsscalebarsettings.h:40
QgsScaleBarRenderer::Flag::FlagRespectsMapUnitsPerScaleBarUnit
@ FlagRespectsMapUnitsPerScaleBarUnit
Renderer respects the QgsScaleBarSettings::mapUnitsPerScaleBarUnit() setting.
QgsScaleBarSettings::numberOfSegmentsLeft
int numberOfSegmentsLeft() const
Returns the number of segments included in the left part of the scalebar.
Definition: qgsscalebarsettings.h:114
QgsScaleBarRenderer::firstLabelXOffset
Q_DECL_DEPRECATED double firstLabelXOffset(const QgsScaleBarSettings &settings) const
Returns the x-offset (in millimeters) used for the first label in the scalebar.
Definition: qgsscalebarrenderer.cpp:311
QgsTicksScaleBarRenderer::TickPosition
TickPosition
Tick positions.
Definition: qgsticksscalebarrenderer.h:34
QgsScaleBarRenderer::ScaleBarContext::segmentWidth
double segmentWidth
The width, in millimeters, of each individual segment drawn.
Definition: qgsscalebarrenderer.h:77
QgsRenderContext::convertToPainterUnits
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
Definition: qgsrendercontext.cpp:367
QgsScaleBarSettings::LabelAboveSegment
@ LabelAboveSegment
Labels are drawn above the scalebar.
Definition: qgsscalebarsettings.h:68
QgsScaleBarRenderer::drawDefaultLabels
void drawDefaultLabels(QgsRenderContext &context, const QgsScaleBarSettings &settings, const QgsScaleBarRenderer::ScaleBarContext &scaleContext) const
Draws default scalebar labels using the specified settings and scaleContext to a destination render c...
Definition: qgsscalebarrenderer.cpp:30
QgsScaleBarRenderer::Flag::FlagUsesSubdivisions
@ FlagUsesSubdivisions
Renderer uses the scalebar subdivisions (see QgsScaleBarSettings::numberOfSubdivisions() )
qgsticksscalebarrenderer.h
QgsScaleBarSettings::divisionLineSymbol
QgsLineSymbol * divisionLineSymbol() const
Returns the line symbol used to render the scalebar divisions (only used for some scalebar types).
Definition: qgsscalebarsettings.cpp:203
QgsScaleBarRenderer::Flag::FlagRespectsUnits
@ FlagRespectsUnits
Renderer respects the QgsScaleBarSettings::units() setting.
QgsScaleBarSettings::subdivisionLineSymbol
QgsLineSymbol * subdivisionLineSymbol() const
Returns the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
Definition: qgsscalebarsettings.cpp:213
QgsScaleBarSettings::numberOfSubdivisions
int numberOfSubdivisions() const
Returns the number of subdivisions for segments included in the right part of the scalebar (only used...
Definition: qgsscalebarsettings.h:132
QgsScaleBarRenderer::Flag::FlagUsesSubdivisionsHeight
@ FlagUsesSubdivisionsHeight
Renderer uses the scalebar subdivisions height (see QgsScaleBarSettings::subdivisionsHeight() )
QgsTicksScaleBarRenderer
A scale bar that draws segments using short ticks.
Definition: qgsticksscalebarrenderer.h:29
QgsScaleBarRenderer::Flag::FlagUsesLabelBarSpace
@ FlagUsesLabelBarSpace
Renderer uses the QgsScaleBarSettings::labelBarSpace() setting.
QgsScaleBarRenderer::Flag::FlagUsesSegments
@ FlagUsesSegments
Renderer uses the scalebar segments.
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:112
QgsScaleBarRenderer::Flag::FlagUsesDivisionSymbol
@ FlagUsesDivisionSymbol
Renderer utilizes the scalebar division symbol (see QgsScaleBarSettings::divisionLineSymbol() )
QgsScaleBarRenderer::Flag::FlagUsesSubdivisionSymbol
@ FlagUsesSubdivisionSymbol
Renderer utilizes the scalebar subdivision symbol (see QgsScaleBarSettings::subdivisionLineSymbol() )
qgssymbol.h
QgsTicksScaleBarRenderer::draw
void draw(QgsRenderContext &context, const QgsScaleBarSettings &settings, const QgsScaleBarRenderer::ScaleBarContext &scaleContext) const override
Draws the scalebar using the specified settings and scaleContext to a destination render context.
Definition: qgsticksscalebarrenderer.cpp:95
qgslinesymbol.h
QgsTicksScaleBarRenderer::id
QString id() const override
Returns the unique ID for this renderer.
Definition: qgsticksscalebarrenderer.cpp:31
QgsTicksScaleBarRenderer::sortKey
int sortKey() const override
Returns a sorting key value, where renderers with a lower sort key will be shown earlier in lists.
Definition: qgsticksscalebarrenderer.cpp:60
QgsScaleBarRenderer::segmentPositions
Q_DECL_DEPRECATED QList< double > segmentPositions(const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings) const
Returns a list of positions for each segment within the scalebar.
Definition: qgsscalebarrenderer.cpp:341