QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsdoubleboxscalebarrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdoubleboxscalebarrenderer.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 "qgstextrenderer.h"
22 #include <QList>
23 #include <QPainter>
24 
26 {
27  return QStringLiteral( "Double Box" );
28 }
29 
31 {
32  return QObject::tr( "Double Box" );
33 }
34 
35 QgsScaleBarRenderer::Flags QgsDoubleBoxScaleBarRenderer::flags() const
36 {
47 }
48 
50 {
51  return 2;
52 }
53 
55 {
56  return new QgsDoubleBoxScaleBarRenderer( *this );
57 }
58 
59 void QgsDoubleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const
60 {
61  if ( !context.painter() )
62  {
63  return;
64  }
65  QPainter *painter = context.painter();
66 
67  const double scaledLabelBarSpace = context.convertToPainterUnits( settings.labelBarSpace(), QgsUnitTypes::RenderMillimeters );
68  const double scaledBoxContentSpace = context.convertToPainterUnits( settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters );
69  const QFontMetricsF fontMetrics = QgsTextRenderer::fontMetrics( context, settings.textFormat() );
70  const double barTopPosition = scaledBoxContentSpace + ( settings.labelVerticalPlacement() == QgsScaleBarSettings::LabelAboveSegment ? fontMetrics.ascent() + scaledLabelBarSpace : 0 );
71  const double segmentHeight = context.convertToPainterUnits( settings.height() / 2, QgsUnitTypes::RenderMillimeters );
72 
73  painter->save();
74  context.setPainterFlagsUsingContext( painter );
75 
76  std::unique_ptr< QgsLineSymbol > lineSymbol( settings.lineSymbol()->clone() );
77  lineSymbol->startRender( context );
78 
79  std::unique_ptr< QgsFillSymbol > fillSymbol1( settings.fillSymbol()->clone() );
80  fillSymbol1->startRender( context );
81 
82  std::unique_ptr< QgsFillSymbol > fillSymbol2( settings.alternateFillSymbol()->clone() );
83  fillSymbol2->startRender( context );
84 
85  painter->setPen( Qt::NoPen );
86  painter->setBrush( Qt::NoBrush );
87 
88  bool useColor = true; //alternate brush color/white
89 
90  const double xOffset = firstLabelXOffset( settings, context, scaleContext );
91 
92  const QList<double> positions = segmentPositions( context, scaleContext, settings );
93  const QList<double> widths = segmentWidths( scaleContext, settings );
94 
95  double minX = 0;
96  double maxX = 0;
97  QgsFillSymbol *currentSymbol = nullptr;
98  for ( int i = 0; i < positions.size(); ++i )
99  {
100  //draw top half
101  if ( useColor )
102  {
103  currentSymbol = fillSymbol1.get();
104  }
105  else //secondary symbol
106  {
107  currentSymbol = fillSymbol2.get();
108  }
109 
110  const double thisX = context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset;
111  const double thisWidth = context.convertToPainterUnits( widths.at( i ), QgsUnitTypes::RenderMillimeters );
112 
113  if ( i == 0 )
114  minX = thisX;
115  if ( i == positions.size() - 1 )
116  maxX = thisX + thisWidth;
117 
118  const QRectF segmentRectTop( thisX, barTopPosition, thisWidth, segmentHeight );
119  currentSymbol->renderPolygon( QPolygonF()
120  << segmentRectTop.topLeft()
121  << segmentRectTop.topRight()
122  << segmentRectTop.bottomRight()
123  << segmentRectTop.bottomLeft()
124  << segmentRectTop.topLeft(),
125  nullptr, nullptr, context );
126  painter->drawRect( segmentRectTop );
127 
128  //draw bottom half
129  if ( useColor )
130  {
131  //secondary symbol
132  currentSymbol = fillSymbol2.get();
133  }
134  else //primary symbol
135  {
136  currentSymbol = fillSymbol1.get(); ;
137  }
138 
139  const QRectF segmentRectBottom( thisX, barTopPosition + segmentHeight, thisWidth, segmentHeight );
140 
141  currentSymbol->renderPolygon( QPolygonF()
142  << segmentRectBottom.topLeft()
143  << segmentRectBottom.topRight()
144  << segmentRectBottom.bottomRight()
145  << segmentRectBottom.bottomLeft()
146  << segmentRectBottom.topLeft(),
147  nullptr, nullptr, context );
148  useColor = !useColor;
149  }
150 
151 
152  // and then the lines
153  // note that we do this layer-by-layer, to avoid ugliness where the lines touch the outer rect
154  for ( int layer = 0; layer < lineSymbol->symbolLayerCount(); ++layer )
155  {
156  // vertical lines
157  for ( int i = 1; i < positions.size(); ++i )
158  {
159  const double lineX = context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset;
160  lineSymbol->renderPolyline( QPolygonF()
161  << QPointF( lineX, barTopPosition )
162  << QPointF( lineX, barTopPosition + segmentHeight * 2 ),
163  nullptr, context, layer );
164  }
165 
166  // middle horizontal line
167  lineSymbol->renderPolyline( QPolygonF()
168  << QPointF( minX, barTopPosition + segmentHeight )
169  << QPointF( maxX, barTopPosition + segmentHeight ),
170  nullptr, context, layer );
171 
172 
173  // outside line
174  lineSymbol->renderPolyline( QPolygonF()
175  << QPointF( minX, barTopPosition )
176  << QPointF( maxX, barTopPosition )
177  << QPointF( maxX, barTopPosition + segmentHeight * 2 )
178  << QPointF( minX, barTopPosition + segmentHeight * 2 )
179  << QPointF( minX, barTopPosition ),
180  nullptr, context, layer );
181  }
182 
183  lineSymbol->stopRender( context );
184  fillSymbol1->stopRender( context );
185  fillSymbol2->stopRender( context );
186 
187  painter->restore();
188 
189  //draw labels using the default method
190  drawDefaultLabels( context, settings, scaleContext );
191 }
QgsScaleBarSettings::height
double height() const
Returns the scalebar height (in millimeters).
Definition: qgsscalebarsettings.h:550
QgsScaleBarSettings::lineSymbol
QgsLineSymbol * lineSymbol() const
Returns the line symbol used to render the scalebar (only used for some scalebar types).
Definition: qgsscalebarsettings.cpp:191
QgsDoubleBoxScaleBarRenderer::clone
QgsDoubleBoxScaleBarRenderer * clone() const override
Returns a clone of the renderer.
Definition: qgsdoubleboxscalebarrenderer.cpp:54
QgsRenderContext::convertToPainterUnits
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
Definition: qgsrendercontext.cpp:318
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:143
QgsScaleBarRenderer::ScaleBarContext
Contains parameters regarding scalebar calculations.
Definition: qgsscalebarrenderer.h:71
QgsScaleBarRenderer::Flag::FlagUsesUnitLabel
@ FlagUsesUnitLabel
Renderer uses the QgsScaleBarSettings::unitLabel() setting.
qgstextrenderer.h
QgsDoubleBoxScaleBarRenderer::id
QString id() const override
Returns the unique ID for this renderer.
Definition: qgsdoubleboxscalebarrenderer.cpp:25
QgsScaleBarRenderer::segmentWidths
QList< double > segmentWidths(const QgsScaleBarRenderer::ScaleBarContext &scaleContext, const QgsScaleBarSettings &settings) const
Returns a list of widths of each segment of the scalebar.
Definition: qgsscalebarrenderer.cpp:403
QgsLineSymbol::clone
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2193
QgsScaleBarRenderer::Flag::FlagUsesFillSymbol
@ FlagUsesFillSymbol
Renderer utilizes the scalebar fill symbol (see QgsScaleBarSettings::fillSymbol() )
QgsScaleBarRenderer::Flag::FlagUsesAlternateFillSymbol
@ FlagUsesAlternateFillSymbol
Renderer utilizes the alternate scalebar fill symbol (see QgsScaleBarSettings::alternateFillSymbol() ...
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:261
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsScaleBarSettings::fillSymbol
QgsFillSymbol * fillSymbol() const
Returns the primary fill symbol used to render the scalebar (only used for some scalebar types).
Definition: qgsscalebarsettings.cpp:221
QgsUnitTypes::RenderMillimeters
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
QgsDoubleBoxScaleBarRenderer::flags
Flags flags() const override
Returns the scalebar rendering flags, which dictates the renderer's behavior.
Definition: qgsdoubleboxscalebarrenderer.cpp:35
QgsScaleBarRenderer::Flag::FlagUsesLabelHorizontalPlacement
@ FlagUsesLabelHorizontalPlacement
Renderer uses the QgsScaleBarSettings::labelHorizontalPlacement() setting.
QgsDoubleBoxScaleBarRenderer::sortKey
int sortKey() const override
Returns a sorting key value, where renderers with a lower sort key will be shown earlier in lists.
Definition: qgsdoubleboxscalebarrenderer.cpp:49
qgsscalebarsettings.h
qgslayoututils.h
QgsScaleBarSettings::labelBarSpace
double labelBarSpace() const
Returns the spacing (in millimeters) between labels and the scalebar.
Definition: qgsscalebarsettings.h:562
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() )
QgsDoubleBoxScaleBarRenderer
Double box with alternating colors.
Definition: qgsdoubleboxscalebarrenderer.h:31
QgsScaleBarSettings
The QgsScaleBarSettings class stores the appearance and layout settings for scalebar drawing with Qgs...
Definition: qgsscalebarsettings.h:41
QgsScaleBarRenderer::Flag::FlagRespectsMapUnitsPerScaleBarUnit
@ FlagRespectsMapUnitsPerScaleBarUnit
Renderer respects the QgsScaleBarSettings::mapUnitsPerScaleBarUnit() setting.
qgsdoubleboxscalebarrenderer.h
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:318
QgsFillSymbol::renderPolygon
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Renders the symbol using the given render context.
Definition: qgssymbol.cpp:2215
QgsScaleBarSettings::LabelAboveSegment
@ LabelAboveSegment
Labels are drawn above the scalebar.
Definition: qgsscalebarsettings.h:68
QgsDoubleBoxScaleBarRenderer::QgsDoubleBoxScaleBarRenderer
QgsDoubleBoxScaleBarRenderer()=default
Constructor for QgsDoubleBoxScaleBarRenderer.
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:28
QgsScaleBarRenderer::Flag::FlagRespectsUnits
@ FlagRespectsUnits
Renderer respects the QgsScaleBarSettings::units() setting.
QgsFillSymbol::clone
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2317
QgsFillSymbol
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgssymbol.h:1234
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:179
QgsScaleBarSettings::alternateFillSymbol
QgsFillSymbol * alternateFillSymbol() const
Returns the secondary fill symbol used to render the scalebar (only used for some scalebar types).
Definition: qgsscalebarsettings.cpp:231
qgssymbol.h
QgsDoubleBoxScaleBarRenderer::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: qgsdoubleboxscalebarrenderer.cpp:59
QgsDoubleBoxScaleBarRenderer::visibleName
QString visibleName() const override
Returns the user friendly, translated name for the renderer.
Definition: qgsdoubleboxscalebarrenderer.cpp:30
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:348