1 /***************************************************************************
2                          qgslayoutitemmapgrid.h
3                          ----------------------
4     begin                : October 2017
5     copyright            : (C) 2017 by Marco Hugentobler, Nyall Dawson
6     email                : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef QGSLAYOUTITEMMAPGRID_H
19 #define QGSLAYOUTITEMMAPGRID_H
20 
21 #include "qgis_core.h"
22 #include "qgis_sip.h"
23 #include "qgslayoutitemmapitem.h"
24 #include "qgssymbol.h"
25 #include "qgstextformat.h"
26 #include <QPainter>
27 #include <QVector2D>
28 
29 class QgsCoordinateTransform;
30 class QgsLayoutItemMapGrid;
31 class QgsLayoutItemMap;
32 class QDomDocument;
33 class QDomElement;
34 class QPainter;
35 class QgsRenderContext;
36 
37 /**
38  * \ingroup core
39  * \class QgsLayoutItemMapGridStack
40  * \brief A collection of grids which is drawn above the map content in a
41  * QgsLayoutItemMap. The grid stack controls which grids are drawn and the
42  * order they are drawn in.
43  * \see QgsLayoutItemMapGrid
44  * \since QGIS 3.0
45  */
46 class CORE_EXPORT QgsLayoutItemMapGridStack : public QgsLayoutItemMapItemStack
47 {
48   public:
49 
50     /**
51      * Constructor for QgsLayoutItemMapGridStack, attached to the specified \a map.
52      */
53     QgsLayoutItemMapGridStack( QgsLayoutItemMap *map );
54 
55     /**
56      * Adds a new map \a grid to the stack and takes ownership of the grid.
57      * The grid will be added to the end of the stack, and rendered
58      * above any existing map grids already present in the stack.
59      * \note After adding a grid to the stack, updateBoundingRect() and update()
60      * should be called for the QgsLayoutItemMap to prevent rendering artifacts.
61      * \see removeGrid()
62      */
63     void addGrid( QgsLayoutItemMapGrid *grid SIP_TRANSFER );
64 
65     /**
66      * Removes a grid with matching \a gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid.
67      * \note After removing a grid from the stack, updateBoundingRect() and update()
68      * should be called for the QgsLayoutItemMap to prevent rendering artifacts.
69      * \see addGrid()
70      */
71     void removeGrid( const QString &gridId );
72 
73     /**
74      * Moves a grid with matching \a gridId up the stack, causing it to be rendered above other grids.
75      * \note After moving a grid within the stack, update() should be
76      * called for the QgsLayoutItemMap to redraw the map with the new grid stack order.
77      * \see moveGridDown()
78      */
79     void moveGridUp( const QString &gridId );
80 
81     /**
82      * Moves a grid with matching \a gridId down the stack, causing it to be rendered below other grids.
83      * \note After moving a grid within the stack, update() should be
84      * called for the QgsLayoutItemMap to redraw the map with the new grid stack order.
85      * \see moveGridUp()
86      */
87     void moveGridDown( const QString &gridId );
88 
89     /**
90      * Returns a reference to a grid with matching \a gridId within the stack.
91      */
92     QgsLayoutItemMapGrid *grid( const QString &gridId ) const;
93 
94     /**
95      * Returns a reference to a grid at the specified \a index within the stack.
96      */
97     QgsLayoutItemMapGrid *grid( int index ) const;
98 
99     /**
100      * Returns a reference to a grid at the specified \a index within the stack.
101      * \see grid()
102      */
103     QgsLayoutItemMapGrid &operator[]( int index );
104 
105     /**
106      * Returns a list of QgsLayoutItemMapGrids contained by the stack.
107      */
108     QList< QgsLayoutItemMapGrid * > asList() const;
109 
110     bool readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context ) override;
111 
112     /**
113      * Calculates the maximum distance grids within the stack extend
114      * beyond the QgsLayoutItemMap's item rect.
115      * \see calculateMaxGridExtension()
116      */
117     double maxGridExtension() const;
118 
119     /**
120      * Calculates the maximum distance grids within the stack extend beyond the
121      * QgsLayoutItemMap's item rect. This method calculates the distance for each side of the
122      * map item separately.
123      * \see maxGridExtension()
124      */
125     void calculateMaxGridExtension( double &top, double &right, double &bottom, double &left ) const;
126 };
127 
128 //
129 // QgsLayoutItemMapGrid
130 //
131 
132 /**
133  * \ingroup core
134  * \class QgsLayoutItemMapGrid
135  * \brief An individual grid which is drawn above the map content in a
136  * QgsLayoutItemMap.
137  * \see QgsLayoutItemMapGridStack
138  * \since QGIS 3.0
139  */
140 class CORE_EXPORT QgsLayoutItemMapGrid : public QgsLayoutItemMapItem
141 {
142 
143     Q_OBJECT
144 
145   public:
146 
147     /**
148      * Unit for grid values
149      */
150     enum GridUnit
151     {
152       MapUnit, //!< Grid units follow map units
153       MM, //!< Grid units in millimeters
154       CM, //!< Grid units in centimeters
155       DynamicPageSizeBased, //!< Dynamically sized, based on a on-page size range
156     };
157 
158     /**
159      * Grid drawing style
160      */
161     enum GridStyle
162     {
163       Solid = 0,
164       Cross, //!< Draw line crosses at intersections of grid lines
165       Markers, //!< Draw markers at intersections of grid lines
166       FrameAnnotationsOnly //!< No grid lines over the map, only draw frame and annotations
167     };
168 
169     /**
170      * Display settings for grid annotations and frames
171      */
172     enum DisplayMode
173     {
174       ShowAll = 0, //!< Show both latitude and longitude annotations/divisions
175       LatitudeOnly, //!< Show latitude/y annotations/divisions only
176       LongitudeOnly, //!< Show longitude/x annotations/divisions only
177       HideAll //!< No annotations
178     };
179 
180     /**
181      * Position for grid annotations
182      */
183     enum AnnotationPosition
184     {
185       InsideMapFrame = 0, //!< Draw annotations inside the map frame
186       OutsideMapFrame, //!< Draw annotations outside the map frame
187     };
188 
189     /**
190      * Direction of grid annotations
191      */
192     enum AnnotationDirection
193     {
194       Horizontal = 0, //!< Draw annotations horizontally
195       Vertical, //!< Draw annotations vertically, ascending
196       VerticalDescending, //!< Draw annotations vertically, descending
197       BoundaryDirection, //!< Annotations follow the boundary direction
198       AboveTick, //!< Draw annotations parallel to tick (above the line)
199       OnTick, //!< Draw annotations parallel to tick (on the line)
200       UnderTick, //!< Draw annotations parallel to tick (under the line)
201     };
202 
203     /**
204      * Format for displaying grid annotations
205      */
206     enum AnnotationFormat
207     {
208       Decimal = 0, //!< Decimal degrees, use - for S/W coordinates
209       DegreeMinute, //!< Degree/minutes, use NSEW suffix
210       DegreeMinuteSecond, //!< Degree/minutes/seconds, use NSEW suffix
211       DecimalWithSuffix, //!< Decimal degrees, use NSEW suffix
212       DegreeMinuteNoSuffix, //!< Degree/minutes, use - for S/W coordinates
213       DegreeMinutePadded, //!< Degree/minutes, with minutes using leading zeros where required
214       DegreeMinuteSecondNoSuffix, //!< Degree/minutes/seconds, use - for S/W coordinates
215       DegreeMinuteSecondPadded, //!< Degree/minutes/seconds, with minutes using leading zeros where required
216       CustomFormat //!< Custom expression-based format
217     };
218 
219     /**
220      * Border sides for annotations
221      */
222     enum BorderSide
223     {
224       Left, //!< Left border
225       Right, //!< Right border
226       Bottom, //!< Bottom border
227       Top, //!< Top border
228     };
229 
230     /**
231      * Style for grid frame
232      */
233     enum FrameStyle
234     {
235       NoFrame = 0, //!< Disable grid frame
236       Zebra, //!< Black/white pattern
237       InteriorTicks,  //!< Tick markers drawn inside map frame
238       ExteriorTicks,  //!< Tick markers drawn outside map frame
239       InteriorExteriorTicks, //!< Tick markers drawn both inside and outside the map frame
240       LineBorder, //!< Simple solid line frame
241       LineBorderNautical, //!< Simple solid line frame, with nautical style diagonals on corners
242       ZebraNautical, //!< Black/white pattern, with nautical style diagonals on corners
243     };
244 
245     /**
246      * Tick length mode (useful for rotated grids)
247      */
248     enum TickLengthMode
249     {
250       OrthogonalTicks = 0, //!< Align ticks orthogonaly
251       NormalizedTicks, //!< Constant tick lengths
252     };
253 
254     /**
255      * Flags for controlling which side of the map a frame is drawn on
256      */
257     enum FrameSideFlag
258     {
259       FrameLeft = 0x01, //!< Left side of map
260       FrameRight = 0x02, //!< Right side of map
261       FrameTop = 0x04, //!< Top side of map
262       FrameBottom = 0x08 //!< Bottom side of map
263     };
264     Q_DECLARE_FLAGS( FrameSideFlags, FrameSideFlag )
265 
266     /**
267      * Annotation coordinate type
268      */
269     enum AnnotationCoordinate
270     {
271       Longitude = 0, //!< Coordinate is a longitude value
272       Latitude //!< Coordinate is a latitude value
273     };
274 
275     /**
276      * Constructor for QgsLayoutItemMapGrid.
277      * \param name friendly display name for grid
278      * \param map QgsLayoutItemMap the grid is attached to
279      */
280     QgsLayoutItemMapGrid( const QString &name, QgsLayoutItemMap *map );
281 
282     void draw( QPainter *painter ) override;
283     bool writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
284     bool readXml( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context ) override;
285 
286     /**
287      * Sets the \a crs for the grid.
288      * \see crs()
289      */
290     void setCrs( const QgsCoordinateReferenceSystem &crs );
291 
292     /**
293      * Retrieves the CRS for the grid.
294      * \see setCrs()
295      */
crs()296     QgsCoordinateReferenceSystem crs() const { return mCRS; }
297 
298     /**
299      * Sets the blending \a mode used for drawing the grid.
300      * \see blendMode()
301      */
setBlendMode(const QPainter::CompositionMode mode)302     void setBlendMode( const QPainter::CompositionMode mode ) { mBlendMode = mode; }
303 
304     /**
305      * Retrieves the blending mode used for drawing the grid.
306      * \see setBlendMode()
307      */
blendMode()308     QPainter::CompositionMode blendMode() const { return mBlendMode; }
309 
310     bool usesAdvancedEffects() const override;
311 
312     /**
313      * Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's
314      * item rect (in layout units).
315      */
316     double maxExtension() const;
317 
318     /**
319      * Calculates the maximum distance the grid extends beyond the
320      * QgsLayoutItemMap's item rect. This method calculates the distance for each side of the
321      * map item separately.
322      * \see maxExtension()
323      */
324     void calculateMaxExtension( double &top, double &right, double &bottom, double &left ) const;
325 
326     void setEnabled( bool enabled ) override;
327 
328     //
329     // GRID UNITS
330     //
331 
332     /**
333      * Sets the \a unit to use for grid measurements such as the interval
334      * and offset for grid lines.
335      * \see units
336      */
337     void setUnits( GridUnit unit );
338 
339     /**
340      * Returns the units used for grid measurements such as the interval
341      * and offset for grid lines.
342      * \see setUnits()
343      */
units()344     GridUnit units() const { return mGridUnit; }
345 
346     /**
347      * Sets the \a interval between grid lines in the x-direction. The units
348      * are controlled through the setUnits method
349      * \see setIntervalY()
350      * \see intervalX()
351      */
352     void setIntervalX( double interval );
353 
354     /**
355      * Returns the interval between grid lines in the x-direction. The units
356      * are retrieved through the units() method.
357      * \see setIntervalX()
358      * \see intervalY()
359      */
intervalX()360     double intervalX() const { return mGridIntervalX; }
361 
362     /**
363      * Sets the \a interval between grid lines in the y-direction. The units
364      * are controlled through the setUnits method
365      * \see setIntervalX()
366      * \see intervalY()
367      */
368     void setIntervalY( double interval );
369 
370     /**
371      * Returns the interval between grid lines in the y-direction. The units
372      * are retrieved through the units() method.
373      * \see setIntervalY()
374      * \see intervalX()
375      */
intervalY()376     double intervalY() const { return mGridIntervalY; }
377 
378     /**
379      * Sets the \a offset for grid lines in the x-direction. The units
380      * are controlled through the setUnits method.
381      * \see setOffsetY()
382      * \see offsetX()
383      */
384     void setOffsetX( double offset );
385 
386     /**
387      * Returns the offset for grid lines in the x-direction. The units
388      * are retrieved through the units() method.
389      * \see setOffsetX()
390      * \see offsetY()
391      */
offsetX()392     double offsetX() const { return mGridOffsetX; }
393 
394     /**
395      * Sets the \a offset for grid lines in the y-direction. The units
396      * are controlled through the setUnits method.
397      * \see setOffsetX()
398      * \see offsetY()
399      */
400     void setOffsetY( double offset );
401 
402     /**
403      * Returns the offset for grid lines in the y-direction. The units
404      * are retrieved through the units() method.
405      * \see setOffsetY()
406      * \see offsetX()
407      */
offsetY()408     double offsetY() const { return mGridOffsetY; }
409 
410     /**
411      * Returns the minimum width (in millimeters) for grid segments. This
412      * property is only effective if the units() is set
413      * to DynamicPageSizeBased.
414      * \see units()
415      * \see setMinimumIntervalWidth()
416      * \see maximumIntervalWidth()
417      * \since QGIS 3.10
418      */
minimumIntervalWidth()419     double minimumIntervalWidth() const { return mMinimumIntervalWidth; }
420 
421     /**
422      * Sets the minimum \a width (in millimeters) for grid segments. This
423      * property is only effective if the units() is set
424      * to DynamicPageSizeBased.
425      * \see minimumIntervalWidth()
426      * \see setMaximumIntervalWidth()
427      * \see setUnits()
428      * \since QGIS 3.10
429      */
430     void setMinimumIntervalWidth( double width );
431 
432     /**
433      * Returns the maximum width (in millimeters) for grid segments. This
434      * property is only effective if the units() is set
435      * to DynamicPageSizeBased.
436      * \see units()
437      * \see setMaximumIntervalWidth()
438      * \see minimumIntervalWidth()
439      * \since QGIS 3.10
440      */
maximumIntervalWidth()441     double maximumIntervalWidth() const { return mMaximumIntervalWidth; }
442 
443     /**
444      * Sets the maximum \a width (in millimeters) for grid segments. This
445      * property is only effective if the units() is set
446      * to DynamicPageSizeBased.
447      * \see maximumIntervalWidth()
448      * \see setMinimumIntervalWidth()
449      * \see setUnits()
450      * \since QGIS 3.10
451      */
452     void setMaximumIntervalWidth( double width );
453 
454     //
455     // GRID APPEARANCE
456     //
457 
458     /**
459      * Sets the grid \a style, which controls how the grid is drawn
460      * over the map's contents.
461      * \see style()
462      */
463     void setStyle( GridStyle style );
464 
465     /**
466      * Returns the grid's style, which controls how the grid is drawn
467      * over the map's contents.
468      * \see setStyle()
469      */
style()470     GridStyle style() const { return mGridStyle; }
471 
472     /**
473      * Sets the \a length (in layout units) of the cross segments drawn for the grid. This is only used for grids
474      * with QgsLayoutItemMapGrid::Cross styles.
475      * \see crossLength()
476      */
477     void setCrossLength( const double length );
478 
479     /**
480      * Retrieves the length (in layout units) of the cross segments drawn for the grid. This is only used for grids
481      * with QgsLayoutItemMapGrid::Cross styles.
482      * \see setCrossLength()
483      */
crossLength()484     double crossLength() const { return mCrossLength; }
485 
486     /**
487      * Sets the \a width of grid lines (in layout units). This is only used for grids with QgsLayoutItemMapGrid::Solid
488      * or QgsLayoutItemMapGrid::Cross styles. For more control over grid line appearance, use
489      * setLineSymbol instead.
490      * \see setLineSymbol()
491      * \see setGridLineColor()
492      */
493     void setGridLineWidth( double width );
494 
495     /**
496      * Sets the \a color of grid lines. This is only used for grids with QgsLayoutItemMapGrid::Solid
497      * or QgsLayoutItemMapGrid::Cross styles. For more control over grid line appearance, use
498      * setLineSymbol instead.
499      * \see setLineSymbol()
500      * \see setGridLineWidth()
501      */
502     void setGridLineColor( const QColor &color );
503 
504     /**
505      * Sets the line \a symbol used for drawing grid lines. This is only used for grids with
506      * QgsLayoutItemMapGrid::Solid or QgsLayoutItemMapGrid::Cross styles.
507      * Ownership of \a symbol is transferred to the grid.
508      * \see lineSymbol()
509      * \see setMarkerSymbol()
510      * \see setStyle()
511      */
512     void setLineSymbol( QgsLineSymbol *symbol SIP_TRANSFER );
513 
514     /**
515      * Returns the line symbol used for drawing grid lines. This is only used for grids with
516      * QgsLayoutItemMapGrid::Solid or QgsLayoutItemMapGrid::Cross styles.
517      * \see setLineSymbol()
518      * \see markerSymbol()
519      * \see style()
520      * \note not available in Python bindings
521      */
522     const QgsLineSymbol *lineSymbol() const; SIP_SKIP
523 
524     /**
525      * Returns the line symbol used for drawing grid lines. This is only used for grids with
526      * QgsLayoutItemMapGrid::Solid or QgsLayoutItemMapGrid::Cross styles.
527      * \see setLineSymbol()
528      * \see markerSymbol()
529      * \see style()
530      */
531     QgsLineSymbol *lineSymbol();
532 
533     /**
534      * Sets the marker \a symbol used for drawing grid points. This is only used for grids with a
535      * QgsLayoutItemMapGrid::Markers style.
536      * Ownership of \a symbol is transferred to the grid.
537      * \see markerSymbol()
538      * \see setLineSymbol()
539      * \see setStyle()
540      */
541     void setMarkerSymbol( QgsMarkerSymbol *symbol SIP_TRANSFER );
542 
543     /**
544      * Returns the marker symbol used for drawing grid points. This is only used for grids with a
545      * QgsLayoutItemMapGrid::Markers style.
546      * \see setMarkerSymbol()
547      * \see lineSymbol()
548      * \see style()
549      * \note not available in Python bindings
550      */
551     const QgsMarkerSymbol *markerSymbol() const; SIP_SKIP
552 
553     /**
554      * Returns the marker symbol used for drawing grid points. This is only used for grids with a
555      * QgsLayoutItemMapGrid::Markers style.
556      * \see setMarkerSymbol()
557      * \see lineSymbol()
558      * \see style()
559      */
560     QgsMarkerSymbol *markerSymbol();
561 
562     //
563     // ANNOTATIONS
564     //
565 
566     /**
567      * Sets whether annotations should be shown for the grid.
568      * \see annotationEnabled()
569      */
setAnnotationEnabled(const bool enabled)570     void setAnnotationEnabled( const bool enabled ) { mShowGridAnnotation = enabled; }
571 
572     /**
573      * Returns whether annotations are shown for the grid.
574      * \see setAnnotationEnabled()
575      */
annotationEnabled()576     bool annotationEnabled() const { return mShowGridAnnotation; }
577 
578     /**
579      * Sets the text \a format to use when rendering grid annotations.
580      *
581      * \see annotationTextFormat()
582      * \since QGIS 3.16
583      */
setAnnotationTextFormat(const QgsTextFormat & format)584     void setAnnotationTextFormat( const QgsTextFormat &format ) { mAnnotationFormat = format; }
585 
586     /**
587      * Returns the text format used when rendering grid annotations.
588      *
589      * \see setAnnotationTextFormat()
590      * \since QGIS 3.16
591      */
annotationTextFormat()592     QgsTextFormat annotationTextFormat() const { return mAnnotationFormat; }
593 
594     /**
595      * Sets the \a font used for drawing grid annotations.
596      * Shortcut for annotationTextFormat().setFont().
597      * \see annotationFont()
598      * \deprecated use setAnnotationTextFormat() instead
599      */
600     Q_DECL_DEPRECATED void setAnnotationFont( const QFont &font ) SIP_DEPRECATED;
601 
602     /**
603      * Returns the font used for drawing grid annotations.
604      * Shortcut for annotationTextFormat().font().
605      * \see setAnnotationFont()
606      * \deprecated use annotationTextFormat() instead
607      */
608     Q_DECL_DEPRECATED QFont annotationFont() const SIP_DEPRECATED;
609 
610     /**
611      * Sets the font \a color used for drawing grid annotations.
612      * Shortcut for annotationTextFormat().setColor() and annotationTextFormat().setOpacity().
613      * \see annotationFontColor()
614      * \deprecated use setAnnotationTextFormat() instead
615      */
616     Q_DECL_DEPRECATED void setAnnotationFontColor( const QColor &color ) SIP_DEPRECATED;
617 
618     /**
619      * Returns the font color used for drawing grid annotations.
620      * Shortcut for annotationTextFormat().color() and annotationTextFormat().opacity().
621      * \see setAnnotationFontColor()
622      * \deprecated use annotationTextFormat() instead
623      */
624     Q_DECL_DEPRECATED QColor annotationFontColor() const SIP_DEPRECATED;
625 
626     /**
627      * Sets the coordinate \a precision for grid annotations.
628      * The \a precision indicates the number of decimal places to show when drawing grid annotations.
629      * \see annotationPrecision()
630      */
setAnnotationPrecision(const int precision)631     void setAnnotationPrecision( const int precision ) { mGridAnnotationPrecision = precision; }
632 
633     /**
634      * Returns the coordinate precision for grid annotations, which is the
635      * number of decimal places shown when drawing grid annotations.
636      * \see setAnnotationPrecision()
637      */
annotationPrecision()638     int annotationPrecision() const { return mGridAnnotationPrecision; }
639 
640     /**
641      * Sets what types of grid annotations should be drawn for a specified side of the map frame,
642      * or whether grid annotations should be disabled for the side.
643      * \param display display mode for annotations
644      * \param border side of map for annotations
645      * \see annotationDisplay()
646      */
647     void setAnnotationDisplay( DisplayMode display, BorderSide border );
648 
649     /**
650      * Returns the display mode for the grid annotations on a specified side of the map
651      * frame. This property also specifies whether annotations have been disabled
652      * from a side of the map frame.
653      * \param border side of map for annotations
654      * \returns display mode for grid annotations
655      * \see setAnnotationDisplay()
656      */
657     DisplayMode annotationDisplay( BorderSide border ) const;
658 
659     /**
660      * Sets the \a position for the grid annotations on a specified \a side of the map
661      * frame.
662      * \see annotationPosition()
663      */
664     void setAnnotationPosition( AnnotationPosition position, BorderSide side );
665 
666     /**
667      * Returns the position for the grid annotations on a specified \a side of the map
668      * frame.
669      * \see setAnnotationPosition()
670      */
671     AnnotationPosition annotationPosition( BorderSide side ) const;
672 
673     /**
674      * Sets the \a distance between the map frame and annotations. Units are layout units.
675      * \see annotationFrameDistance()
676      */
677     void setAnnotationFrameDistance( const double distance );
678 
679     /**
680      * Returns the distance between the map frame and annotations. Units are in layout units.
681      * \see setAnnotationFrameDistance()
682      */
annotationFrameDistance()683     double annotationFrameDistance() const { return mAnnotationFrameDistance; }
684 
685     /**
686      * Sets the \a direction for drawing frame annotations for the specified map \a side.
687      * \see annotationDirection()
688      */
689     void setAnnotationDirection( AnnotationDirection direction, BorderSide side );
690 
691     /**
692      * Sets the \a direction for drawing all frame annotations.
693      * \see annotationDirection()
694      */
695     void setAnnotationDirection( AnnotationDirection direction );
696 
697     /**
698      * Returns the direction for drawing frame annotations, on the specified \a side
699      * of the map.
700      * \see setAnnotationDirection()
701      */
702     AnnotationDirection annotationDirection( BorderSide border ) const;
703 
704     /**
705      * Sets the \a format for drawing grid annotations.
706      * \see annotationFormat()
707      */
setAnnotationFormat(const AnnotationFormat format)708     void setAnnotationFormat( const AnnotationFormat format ) { mGridAnnotationFormat = format; }
709 
710     /**
711      * Returns the format for drawing grid annotations.
712      * \see setAnnotationFormat()
713      */
annotationFormat()714     AnnotationFormat annotationFormat() const { return mGridAnnotationFormat; }
715 
716     /**
717      * Sets the \a expression used for drawing grid annotations. This is only used when annotationFormat()
718      * is QgsLayoutItemMapGrid::CustomFormat.
719      * \see annotationExpression()
720      */
setAnnotationExpression(const QString & expression)721     void setAnnotationExpression( const QString &expression ) { mGridAnnotationExpressionString = expression; mGridAnnotationExpression.reset(); }
722 
723     /**
724      * Returns the expression used for drawing grid annotations. This is only used when annotationFormat()
725      * is QgsLayoutItemMapGrid::CustomFormat.
726      * \see setAnnotationExpression()
727      */
annotationExpression()728     QString annotationExpression() const { return mGridAnnotationExpressionString; }
729 
730     //
731     // GRID FRAME
732     //
733 
734     /**
735      * Sets the grid frame \a style.
736      * \see frameStyle()
737      */
setFrameStyle(const FrameStyle style)738     void setFrameStyle( const FrameStyle style ) { mGridFrameStyle = style; }
739 
740     /**
741      * Returns the grid frame style.
742      * \see setFrameStyle()
743      */
frameStyle()744     FrameStyle frameStyle() const { return mGridFrameStyle; }
745 
746     /**
747      * Sets what type of grid \a divisions should be used for frames on a specified \a side of the map.
748      * \see frameDivisions()
749      */
750     void setFrameDivisions( DisplayMode divisions, BorderSide side );
751 
752     /**
753      * Returns the type of grid divisions which are used for frames on a specified \a side of the map.
754      * \see setFrameDivisions()
755      */
756     DisplayMode frameDivisions( BorderSide side ) const;
757 
758     /**
759      * Sets \a flags for grid frame sides. Setting these flags controls which sides
760      * of the map item the grid frame is drawn on.
761      * \see setFrameSideFlag()
762      * \see frameSideFlags()
763      * \see testFrameSideFlag()
764      */
765     void setFrameSideFlags( QgsLayoutItemMapGrid::FrameSideFlags flags );
766 
767     /**
768      * Sets whether the grid frame is drawn for a certain side of the map item.
769      * \param flag flag for grid frame side
770      * \param on set to TRUE to draw grid frame on that side of the map
771      * \see setFrameSideFlags()
772      * \see frameSideFlags()
773      * \see testFrameSideFlag()
774      */
775     void setFrameSideFlag( QgsLayoutItemMapGrid::FrameSideFlag flag, bool on = true );
776 
777     /**
778      * Returns the flags which control which sides of the map item the grid frame
779      * is drawn on.
780      * \see setFrameSideFlags()
781      * \see setFrameSideFlag()
782      * \see testFrameSideFlag()
783      */
784     QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const;
785 
786     /**
787      * Tests whether the grid frame should be drawn on a specified side of the map
788      * item.
789      * \param flag flag for grid frame side
790      * \returns TRUE if grid frame should be drawn for that side of the map
791      * \see setFrameSideFlags()
792      * \see setFrameSideFlag()
793      * \see frameSideFlags()
794      */
795     bool testFrameSideFlag( FrameSideFlag flag ) const;
796 
797     /**
798      * Sets the grid frame \a width (in layout units). This property controls how wide the grid frame is.
799      * The size of the line outlines drawn in the frame is controlled through the
800      * setFramePenSize method.
801      * \see frameWidth()
802      */
803     void setFrameWidth( const double width );
804 
805     /**
806      * Gets the grid frame width in layout units. This property controls how wide the grid frame is.
807      * The size of the line outlines drawn in the frame can be retrieved via the
808      * framePenSize method.
809      * \see setFrameWidth()
810      */
frameWidth()811     double frameWidth() const { return mGridFrameWidth; }
812 
813     /**
814      * Enable/disable ticks rotation for rotated or reprojected grids.
815      * \see rotatedTicksEnabled()
816      * \since QGIS 3.16
817      */
setRotatedTicksEnabled(const bool state)818     void setRotatedTicksEnabled( const bool state ) { mRotatedTicksEnabled = state; }
819 
820     /**
821      * Gets whether ticks rotation for rotated or reprojected grids is enabled.
822      * \see setRotatedTicksEnabled()
823      * \since QGIS 3.16
824      */
rotatedTicksEnabled()825     double rotatedTicksEnabled() const { return mRotatedTicksEnabled; }
826 
827     /**
828      * Sets the tick length calculation mode.
829      * \see rotatedTicksLengthMode()
830      * \since QGIS 3.16
831      */
setRotatedTicksLengthMode(const TickLengthMode mode)832     void setRotatedTicksLengthMode( const TickLengthMode mode ) { mRotatedTicksLengthMode = mode; }
833 
834     /**
835      * Returns the grid frame style.
836      * \see setRotatedTicksLengthMode()
837      * \since QGIS 3.16
838      */
rotatedTicksLengthMode()839     TickLengthMode rotatedTicksLengthMode() const { return mRotatedTicksLengthMode; }
840 
841     /**
842      * Sets the \a minimum angle (in degrees) below which ticks are not drawn.
843      * \see rotatedTicksMinimumAngle()
844      * \since QGIS 3.16
845      */
setRotatedTicksMinimumAngle(const double angle)846     void setRotatedTicksMinimumAngle( const double angle ) { mRotatedTicksMinimumAngle = angle; }
847 
848     /**
849      * Gets the \a minimum angle (in degrees) below which ticks are not drawn.
850      * \see setRotatedTicksMinimumAngle()
851      * \since QGIS 3.16
852      */
rotatedTicksMinimumAngle()853     double rotatedTicksMinimumAngle() const { return mRotatedTicksMinimumAngle; }
854 
855     /**
856      * Sets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
857      * \see rotatedTicksMarginToCorner()
858      * \since QGIS 3.16
859      */
setRotatedTicksMarginToCorner(const double margin)860     void setRotatedTicksMarginToCorner( const double margin ) { mRotatedTicksMarginToCorner = margin; }
861 
862     /**
863      * Gets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
864      * \see setRotatedTicksMarginToCorner()
865      * \since QGIS 3.16
866      */
rotatedTicksMarginToCorner()867     double rotatedTicksMarginToCorner() const { return mRotatedTicksMarginToCorner; }
868 
869     /**
870      * Enable/disable annotations rotation for rotated or reprojected grids.
871      * \see rotatedAnnotationsEnabled()
872      * \since QGIS 3.16
873      */
setRotatedAnnotationsEnabled(const bool state)874     void setRotatedAnnotationsEnabled( const bool state ) { mRotatedAnnotationsEnabled = state; }
875 
876     /**
877      * Gets whether annotations rotation for rotated or reprojected grids is enabled.
878      * \see setRotatedAnnotationsEnabled()
879      * \since QGIS 3.16
880      */
rotatedAnnotationsEnabled()881     double rotatedAnnotationsEnabled() const { return mRotatedAnnotationsEnabled; }
882 
883     /**
884      * Sets the annotation length calculation mode.
885      * \see rotatedAnnotationsLengthMode()
886      * \since QGIS 3.16
887     */
setRotatedAnnotationsLengthMode(const TickLengthMode mode)888     void setRotatedAnnotationsLengthMode( const TickLengthMode mode ) { mRotatedAnnotationsLengthMode = mode; }
889 
890     /**
891      * Returns the grid frame style.
892      * \see setRotatedAnnotationsLengthMode()
893      * \since QGIS 3.16
894      */
rotatedAnnotationsLengthMode()895     TickLengthMode rotatedAnnotationsLengthMode() const { return mRotatedAnnotationsLengthMode; }
896 
897     /**
898      * Sets the \a minimum angle (in degrees) below which annotated are not drawn.
899      * \see rotatedAnnotationsMinimumAngle()
900      * \since QGIS 3.16
901      */
setRotatedAnnotationsMinimumAngle(const double angle)902     void setRotatedAnnotationsMinimumAngle( const double angle ) { mRotatedAnnotationsMinimumAngle = angle; }
903 
904     /**
905      * Gets the \a minimum angle (in degrees) below which annotated are not drawn.
906      * \see setRotatedAnnotationsMinimumAngle()
907      * \since QGIS 3.16
908      */
rotatedAnnotationsMinimumAngle()909     double rotatedAnnotationsMinimumAngle() const { return mRotatedAnnotationsMinimumAngle; }
910 
911     /**
912      * Sets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
913      * \see rotatedAnnotationsMarginToCorner()
914      * \since QGIS 3.16
915      */
setRotatedAnnotationsMarginToCorner(const double margin)916     void setRotatedAnnotationsMarginToCorner( const double margin ) { mRotatedAnnotationsMarginToCorner = margin; }
917 
918     /**
919      * Gets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
920      * \see setRotatedAnnotationsMarginToCorner()
921      * \since QGIS 3.16
922      */
rotatedAnnotationsMarginToCorner()923     double rotatedAnnotationsMarginToCorner() const { return mRotatedAnnotationsMarginToCorner; }
924 
925     /**
926      * Sets the grid frame margin (in layout units).
927      * This property controls distance between the map frame and the grid frame.
928      * \see frameMargin()
929      * \since QGIS 3.6
930      */
931     void setFrameMargin( const double margin );
932 
933     /**
934      * Sets the grid frame Margin (in layout units).
935      * This property controls distance between the map frame and the grid frame.
936      * \see setFrameMargin()
937      * \since QGIS 3.6
938      */
frameMargin()939     double frameMargin() const { return mGridFrameMargin; }
940 
941     /**
942      * Sets the \a width of the stroke drawn in the grid frame.
943      * \see framePenSize()
944      * \see setFramePenColor()
945      */
946     void setFramePenSize( const double width );
947 
948     /**
949      * Retrieves the width of the stroke drawn in the grid frame.
950      * \see setFramePenSize()
951      * \see framePenColor()
952      */
framePenSize()953     double framePenSize() const { return mGridFramePenThickness; }
954 
955     /**
956      * Sets the \a color of the stroke drawn in the grid frame.
957      * \see framePenColor()
958      * \see setFramePenSize()
959      * \see setFrameFillColor1()
960      * \see setFrameFillColor2()
961      */
setFramePenColor(const QColor & color)962     void setFramePenColor( const QColor &color ) { mGridFramePenColor = color; }
963 
964     /**
965      * Retrieves the color of the stroke drawn in the grid frame.
966      * \see setFramePenColor()
967      * \see framePenSize()
968      * \see frameFillColor1()
969      * \see frameFillColor2()
970      */
framePenColor()971     QColor framePenColor() const {return mGridFramePenColor;}
972 
973     /**
974      * Sets the first fill \a color used for the grid frame.
975      * \see frameFillColor1()
976      * \see setFramePenColor()
977      * \see setFrameFillColor2()
978      */
setFrameFillColor1(const QColor & color)979     void setFrameFillColor1( const QColor &color ) { mGridFrameFillColor1 = color; }
980 
981     /**
982      * Retrieves the first fill color for the grid frame.
983      * \see setFrameFillColor1()
984      * \see framePenColor()
985      * \see frameFillColor2()
986      */
frameFillColor1()987     QColor frameFillColor1() const { return mGridFrameFillColor1; }
988 
989     /**
990      * Sets the second fill \a color used for the grid frame.
991      * \see frameFillColor2()
992      * \see setFramePenColor()
993      * \see setFrameFillColor1()
994      */
setFrameFillColor2(const QColor & color)995     void setFrameFillColor2( const QColor &color ) { mGridFrameFillColor2 = color; }
996 
997     /**
998      * Retrieves the second fill color for the grid frame.
999      * \see setFrameFillColor2()
1000      * \see framePenColor(
1001      * \see frameFillColor1()
1002      */
frameFillColor2()1003     QColor frameFillColor2() const { return mGridFrameFillColor2; }
1004 
1005     QgsExpressionContext createExpressionContext() const override;
1006     bool accept( QgsStyleEntityVisitorInterface *visitor ) const override;
1007     void refresh() override;
1008 
1009   signals:
1010 
1011     /**
1012      * Emitted whenever the grid's CRS is changed.
1013      *
1014      * \since QGIS 3.18
1015      */
1016     void crsChanged();
1017 
1018   private:
1019 
1020     QgsLayoutItemMapGrid() = delete;
1021 
1022     struct GridExtension
1023     {
1024       GridExtension() = default;
1025       double top = 0.0;
1026       double right = 0.0;
1027       double bottom = 0.0;
1028       double left = 0.0;
1029 
1030       /**
1031        * Updates the specified border of the extension
1032        */
UpdateBorderGridExtension1033       void UpdateBorder( BorderSide border, double value )
1034       {
1035         switch ( border )
1036         {
1037           case QgsLayoutItemMapGrid::Left:
1038             left = std::max( left, value );
1039             break;
1040           case QgsLayoutItemMapGrid::Right:
1041             right = std::max( right, value );
1042             break;
1043           case QgsLayoutItemMapGrid::Top:
1044             top = std::max( top, value );
1045             break;
1046           case QgsLayoutItemMapGrid::Bottom:
1047             bottom = std::max( bottom, value );
1048             break;
1049         }
1050       }
1051 
1052       /**
1053        * Updates all borders of the extension
1054        */
UpdateAllGridExtension1055       void UpdateAll( double value )
1056       {
1057         left = std::max( left, value );
1058         right = std::max( right, value );
1059         top = std::max( top, value );
1060         bottom = std::max( bottom, value );
1061       }
1062     };
1063 
1064     struct GridLineAnnotation
1065     {
1066       BorderSide border; // border on which the annotation is
1067       QVector2D position; // position on the frame
1068       QVector2D vector; // vector towards map center
1069       double angle; // the (acute) angle formed between the vector and the border
1070     };
1071 
1072     /**
1073      * Helper that represents a grid line, for drawing the line itself an the
1074      * anotations on the frame.
1075      */
1076     struct GridLine
1077     {
1078       QPolygonF line; // the actual line, can be straight with two points or curved if transformed
1079       double coordinate; // the coordinate value
1080       QgsLayoutItemMapGrid::AnnotationCoordinate coordinateType; // whether it's a latitude or longitude line
1081       GridLineAnnotation startAnnotation; // the annotation on the start point
1082       GridLineAnnotation endAnnotation; // the annotation on the end point
1083     };
1084     mutable QList< GridLine > mGridLines;
1085 
1086     //! True if a re-transformation of grid lines is required
1087     mutable bool mTransformDirty = true;
1088 
1089     //! Solid or crosses
1090     GridStyle mGridStyle = QgsLayoutItemMapGrid::Solid;
1091     //! Grid line interval in x-direction (map units)
1092     double mGridIntervalX = 0.0;
1093     //! Grid line interval in y-direction (map units)
1094     double mGridIntervalY = 0.0;
1095     //! Grid line offset in x-direction
1096     double mGridOffsetX = 0.0;
1097     //! Grid line offset in y-direction
1098     double mGridOffsetY = 0.0;
1099 
1100     //! Text format for grid annotations
1101     QgsTextFormat mAnnotationFormat;
1102 
1103     //! Digits after the dot
1104     int mGridAnnotationPrecision = 3;
1105     //! True if coordinate values should be drawn
1106     bool mShowGridAnnotation = false;
1107 
1108     //! Annotation display mode for left map side
1109     DisplayMode mLeftGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1110     //! Annotation display mode for right map side
1111     DisplayMode mRightGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1112     //! Annotation display mode for top map side
1113     DisplayMode mTopGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1114     //! Annotation display mode for bottom map side
1115     DisplayMode mBottomGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1116 
1117     //! Annotation position for left map side (inside / outside)
1118     AnnotationPosition mLeftGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1119     //! Annotation position for right map side (inside / outside)
1120     AnnotationPosition mRightGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1121     //! Annotation position for top map side (inside / outside)
1122     AnnotationPosition mTopGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1123     //! Annotation position for bottom map side (inside / outside)
1124     AnnotationPosition mBottomGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1125 
1126     //! Distance between map frame and annotation
1127     double mAnnotationFrameDistance = 1.0;
1128 
1129     //! Annotation direction on left side ( horizontal or vertical )
1130     AnnotationDirection mLeftGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1131     //! Annotation direction on right side ( horizontal or vertical )
1132     AnnotationDirection mRightGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1133     //! Annotation direction on top side ( horizontal or vertical )
1134     AnnotationDirection mTopGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1135     //! Annotation direction on bottom side ( horizontal or vertical )
1136     AnnotationDirection mBottomGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1137     AnnotationFormat mGridAnnotationFormat = QgsLayoutItemMapGrid::Decimal;
1138 
1139     QString mGridAnnotationExpressionString;
1140     mutable std::unique_ptr< QgsExpression > mGridAnnotationExpression;
1141 
1142     FrameStyle mGridFrameStyle = QgsLayoutItemMapGrid::NoFrame;
1143 
1144     FrameSideFlags mGridFrameSides;
1145     double mGridFrameWidth = 2.0;
1146     double mGridFramePenThickness = 0.3;
1147     QColor mGridFramePenColor = QColor( 0, 0, 0 );
1148     QColor mGridFrameFillColor1 = Qt::white;
1149     QColor mGridFrameFillColor2 = Qt::black;
1150     double mCrossLength = 3.0;
1151     double mGridFrameMargin = 0.0;
1152     bool mRotatedTicksEnabled = false;
1153     TickLengthMode mRotatedTicksLengthMode = QgsLayoutItemMapGrid::OrthogonalTicks;
1154     double mRotatedTicksMinimumAngle = 0.0;
1155     double mRotatedTicksMarginToCorner = 0.0;
1156     bool mRotatedAnnotationsEnabled = false;
1157     TickLengthMode mRotatedAnnotationsLengthMode = QgsLayoutItemMapGrid::OrthogonalTicks;
1158     double mRotatedAnnotationsMinimumAngle = 0.0;
1159     double mRotatedAnnotationsMarginToCorner = 0.0;
1160 
1161     double mMinimumIntervalWidth = 50;
1162     double mMaximumIntervalWidth = 100;
1163 
1164     //! Divisions for frame on left map side
1165     DisplayMode mLeftFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1166     //! Divisions for frame on right map side
1167     DisplayMode mRightFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1168     //! Divisions for frame on top map side
1169     DisplayMode mTopFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1170     //! Divisions for frame on bottom map side
1171     DisplayMode mBottomFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1172 
1173     std::unique_ptr< QgsLineSymbol > mGridLineSymbol;
1174     std::unique_ptr< QgsMarkerSymbol > mGridMarkerSymbol;
1175 
1176     QgsCoordinateReferenceSystem mCRS;
1177 
1178     GridUnit mGridUnit = MapUnit;
1179 
1180     QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;
1181 
1182     mutable QList< QPair< double, QPolygonF > > mTransformedXLines;
1183     mutable QList< QPair< double, QPolygonF > > mTransformedYLines;
1184     mutable QList< QgsPointXY > mTransformedIntersections;
1185     QRectF mPrevPaintRect;
1186     mutable QPolygonF mPrevMapPolygon;
1187 
1188     bool mEvaluatedEnabled = true;
1189     double mEvaluatedIntervalX = 0;
1190     double mEvaluatedIntervalY = 0;
1191     double mEvaluatedOffsetX = 0;
1192     double mEvaluatedOffsetY = 0;
1193     double mEvaluatedGridFrameWidth = 0;
1194     double mEvaluatedGridFrameMargin = 0;
1195     double mEvaluatedAnnotationFrameDistance = 0;
1196     double mEvaluatedCrossLength = 0;
1197     double mEvaluatedGridFrameLineThickness = 0;
1198     DisplayMode mEvaluatedLeftGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1199     DisplayMode mEvaluatedRightGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1200     DisplayMode mEvaluatedTopGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1201     DisplayMode mEvaluatedBottomGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1202     DisplayMode mEvaluatedLeftFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1203     DisplayMode mEvaluatedRightFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1204     DisplayMode mEvaluatedTopFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1205     DisplayMode mEvaluatedBottomFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1206 
1207     /**
1208      * Updates the grid lines annotation positions
1209      */
1210     void updateGridLinesAnnotationsPositions() const;
1211 
1212     /**
1213      * Draws the map grid. If extension is specified, then no grid will be drawn and instead the maximum extension
1214      * for the grid outside of the map frame will be calculated.
1215      */
1216     void drawGridFrame( QPainter *p, GridExtension *extension = nullptr ) const;
1217 
1218     /**
1219      * Draw coordinates for mGridAnnotationType Coordinate
1220      * \param context destination render context
1221      * \param expressionContext expression context for evaluating custom annotation formats
1222      * \param extension optional. If specified, nothing will be drawn and instead the maximum extension for the grid
1223      * annotations will be stored in this variable.
1224      */
1225     void drawCoordinateAnnotations( QgsRenderContext &context, QgsExpressionContext &expressionContext, GridExtension *extension = nullptr ) const;
1226 
1227     /**
1228      * Draw an annotation. If optional extension argument is specified, nothing will be drawn and instead
1229      * the extension of the annotation outside of the map frame will be stored in this variable.
1230      */
1231     void drawCoordinateAnnotation( QgsRenderContext &context, GridLineAnnotation annot, const QString &annotationString, AnnotationCoordinate coordinateType, GridExtension *extension = nullptr ) const;
1232 
1233     QString gridAnnotationString( double value, AnnotationCoordinate coord, QgsExpressionContext &expressionContext ) const;
1234 
1235     /**
1236      * Computes the grid lines with associated coordinate value
1237      * \returns 0 in case of success
1238     */
1239     int xGridLines() const;
1240 
1241     /**
1242      * Computes the grid lines for the y-coordinates. Not vertical in case of rotation
1243      * \returns 0 in case of success
1244     */
1245     int yGridLines() const;
1246 
1247     int xGridLinesCrsTransform( const QgsRectangle &bbox, const QgsCoordinateTransform &t ) const;
1248 
1249     int yGridLinesCrsTransform( const QgsRectangle &bbox, const QgsCoordinateTransform &t ) const;
1250 
1251     void drawGridLine( const QLineF &line, QgsRenderContext &context ) const;
1252 
1253     void drawGridLine( const QPolygonF &line, QgsRenderContext &context ) const;
1254 
1255     /**
1256      * Draw the grid frame's border. If optional extension argument is specified, nothing will be drawn and instead
1257      * the maximum extension of the frame border outside of the map frame will be stored in this variable.
1258      */
1259     void drawGridFrameBorder( QPainter *p, BorderSide border, double *extension = nullptr ) const;
1260 
1261     /**
1262      * Returns the item border of a point (in item coordinates)
1263      * \param p point
1264      * \param coordinateType coordinate type
1265      */
1266     BorderSide borderForLineCoord( QPointF p, AnnotationCoordinate coordinateType ) const;
1267 
1268     //! Gets parameters for drawing grid in CRS different to map CRS
1269     int crsGridParams( QgsRectangle &crsRect, QgsCoordinateTransform &inverseTransform ) const;
1270 
1271     static QList<QPolygonF> trimLinesToMap( const QPolygonF &line, const QgsRectangle &rect );
1272 
1273     QPolygonF scalePolygon( const QPolygonF &polygon, double scale ) const;
1274 
1275     //! Draws grid if CRS is different to map CRS
1276     void drawGridCrsTransform( QgsRenderContext &context, double dotsPerMM, bool calculateLinesOnly = false ) const;
1277 
1278     void drawGridNoTransform( QgsRenderContext &context, double dotsPerMM, bool calculateLinesOnly = false ) const;
1279 
1280     void createDefaultGridLineSymbol();
1281 
1282     void createDefaultGridMarkerSymbol();
1283 
1284     void drawGridMarker( QPointF point, QgsRenderContext &context ) const;
1285 
1286     void drawGridFrameZebra( QPainter *p, GridExtension *extension = nullptr ) const;
1287 
1288     void drawGridFrameZebraBorder( QPainter *p, BorderSide border, double *extension = nullptr ) const;
1289 
1290     void drawGridFrameTicks( QPainter *p, GridExtension *extension = nullptr ) const;
1291 
1292     void drawGridFrameLine( QPainter *p, GridExtension *extension = nullptr ) const;
1293 
1294     void calculateCrsTransformLines() const;
1295 
1296     bool shouldShowDivisionForSide( AnnotationCoordinate coordinate, BorderSide side ) const;
1297     bool shouldShowAnnotationForSide( AnnotationCoordinate coordinate, BorderSide side ) const;
1298     bool shouldShowForDisplayMode( AnnotationCoordinate coordinate, DisplayMode mode ) const;
1299     void refreshDataDefinedProperties();
1300 
1301     //! Returns diagonal of map in CRS units
1302     double mapWidth() const;
1303 
1304     friend class TestQgsLayoutMapGrid;
1305 
1306 };
1307 
1308 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayoutItemMapGrid::FrameSideFlags )
1309 
1310 #endif // QGSLAYOUTITEMMAPGRID_H
1311