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 "qgstextformat.h"
25 #include <QPainter>
26 #include <QVector2D>
27 
28 class QgsCoordinateTransform;
29 class QgsLayoutItemMapGrid;
30 class QgsLayoutItemMap;
31 class QDomDocument;
32 class QDomElement;
33 class QPainter;
34 class QgsRenderContext;
35 class QgsLineSymbol;
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     ~QgsLayoutItemMapGrid() override;
282 
283     void draw( QPainter *painter ) override;
284     bool writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
285     bool readXml( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context ) override;
286 
287     /**
288      * Sets the \a crs for the grid.
289      * \see crs()
290      */
291     void setCrs( const QgsCoordinateReferenceSystem &crs );
292 
293     /**
294      * Retrieves the CRS for the grid.
295      * \see setCrs()
296      */
crs()297     QgsCoordinateReferenceSystem crs() const { return mCRS; }
298 
299     /**
300      * Sets the blending \a mode used for drawing the grid.
301      * \see blendMode()
302      */
setBlendMode(const QPainter::CompositionMode mode)303     void setBlendMode( const QPainter::CompositionMode mode ) { mBlendMode = mode; }
304 
305     /**
306      * Retrieves the blending mode used for drawing the grid.
307      * \see setBlendMode()
308      */
blendMode()309     QPainter::CompositionMode blendMode() const { return mBlendMode; }
310 
311     bool usesAdvancedEffects() const override;
312 
313     /**
314      * Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's
315      * item rect (in layout units).
316      */
317     double maxExtension() const;
318 
319     /**
320      * Calculates the maximum distance the grid extends beyond the
321      * QgsLayoutItemMap's item rect. This method calculates the distance for each side of the
322      * map item separately.
323      * \see maxExtension()
324      */
325     void calculateMaxExtension( double &top, double &right, double &bottom, double &left ) const;
326 
327     void setEnabled( bool enabled ) override;
328 
329     //
330     // GRID UNITS
331     //
332 
333     /**
334      * Sets the \a unit to use for grid measurements such as the interval
335      * and offset for grid lines.
336      * \see units
337      */
338     void setUnits( GridUnit unit );
339 
340     /**
341      * Returns the units used for grid measurements such as the interval
342      * and offset for grid lines.
343      * \see setUnits()
344      */
units()345     GridUnit units() const { return mGridUnit; }
346 
347     /**
348      * Sets the \a interval between grid lines in the x-direction. The units
349      * are controlled through the setUnits method
350      * \see setIntervalY()
351      * \see intervalX()
352      */
353     void setIntervalX( double interval );
354 
355     /**
356      * Returns the interval between grid lines in the x-direction. The units
357      * are retrieved through the units() method.
358      * \see setIntervalX()
359      * \see intervalY()
360      */
intervalX()361     double intervalX() const { return mGridIntervalX; }
362 
363     /**
364      * Sets the \a interval between grid lines in the y-direction. The units
365      * are controlled through the setUnits method
366      * \see setIntervalX()
367      * \see intervalY()
368      */
369     void setIntervalY( double interval );
370 
371     /**
372      * Returns the interval between grid lines in the y-direction. The units
373      * are retrieved through the units() method.
374      * \see setIntervalY()
375      * \see intervalX()
376      */
intervalY()377     double intervalY() const { return mGridIntervalY; }
378 
379     /**
380      * Sets the \a offset for grid lines in the x-direction. The units
381      * are controlled through the setUnits method.
382      * \see setOffsetY()
383      * \see offsetX()
384      */
385     void setOffsetX( double offset );
386 
387     /**
388      * Returns the offset for grid lines in the x-direction. The units
389      * are retrieved through the units() method.
390      * \see setOffsetX()
391      * \see offsetY()
392      */
offsetX()393     double offsetX() const { return mGridOffsetX; }
394 
395     /**
396      * Sets the \a offset for grid lines in the y-direction. The units
397      * are controlled through the setUnits method.
398      * \see setOffsetX()
399      * \see offsetY()
400      */
401     void setOffsetY( double offset );
402 
403     /**
404      * Returns the offset for grid lines in the y-direction. The units
405      * are retrieved through the units() method.
406      * \see setOffsetY()
407      * \see offsetX()
408      */
offsetY()409     double offsetY() const { return mGridOffsetY; }
410 
411     /**
412      * Returns the minimum width (in millimeters) for grid segments. This
413      * property is only effective if the units() is set
414      * to DynamicPageSizeBased.
415      * \see units()
416      * \see setMinimumIntervalWidth()
417      * \see maximumIntervalWidth()
418      * \since QGIS 3.10
419      */
minimumIntervalWidth()420     double minimumIntervalWidth() const { return mMinimumIntervalWidth; }
421 
422     /**
423      * Sets the minimum \a width (in millimeters) for grid segments. This
424      * property is only effective if the units() is set
425      * to DynamicPageSizeBased.
426      * \see minimumIntervalWidth()
427      * \see setMaximumIntervalWidth()
428      * \see setUnits()
429      * \since QGIS 3.10
430      */
431     void setMinimumIntervalWidth( double width );
432 
433     /**
434      * Returns the maximum width (in millimeters) for grid segments. This
435      * property is only effective if the units() is set
436      * to DynamicPageSizeBased.
437      * \see units()
438      * \see setMaximumIntervalWidth()
439      * \see minimumIntervalWidth()
440      * \since QGIS 3.10
441      */
maximumIntervalWidth()442     double maximumIntervalWidth() const { return mMaximumIntervalWidth; }
443 
444     /**
445      * Sets the maximum \a width (in millimeters) for grid segments. This
446      * property is only effective if the units() is set
447      * to DynamicPageSizeBased.
448      * \see maximumIntervalWidth()
449      * \see setMinimumIntervalWidth()
450      * \see setUnits()
451      * \since QGIS 3.10
452      */
453     void setMaximumIntervalWidth( double width );
454 
455     //
456     // GRID APPEARANCE
457     //
458 
459     /**
460      * Sets the grid \a style, which controls how the grid is drawn
461      * over the map's contents.
462      * \see style()
463      */
464     void setStyle( GridStyle style );
465 
466     /**
467      * Returns the grid's style, which controls how the grid is drawn
468      * over the map's contents.
469      * \see setStyle()
470      */
style()471     GridStyle style() const { return mGridStyle; }
472 
473     /**
474      * Sets the \a length (in layout units) of the cross segments drawn for the grid. This is only used for grids
475      * with QgsLayoutItemMapGrid::Cross styles.
476      * \see crossLength()
477      */
478     void setCrossLength( const double length );
479 
480     /**
481      * Retrieves the length (in layout units) of the cross segments drawn for the grid. This is only used for grids
482      * with QgsLayoutItemMapGrid::Cross styles.
483      * \see setCrossLength()
484      */
crossLength()485     double crossLength() const { return mCrossLength; }
486 
487     /**
488      * Sets the \a width of grid lines (in layout units). This is only used for grids with QgsLayoutItemMapGrid::Solid
489      * or QgsLayoutItemMapGrid::Cross styles. For more control over grid line appearance, use
490      * setLineSymbol instead.
491      * \see setLineSymbol()
492      * \see setGridLineColor()
493      */
494     void setGridLineWidth( double width );
495 
496     /**
497      * Sets the \a color of grid lines. This is only used for grids with QgsLayoutItemMapGrid::Solid
498      * or QgsLayoutItemMapGrid::Cross styles. For more control over grid line appearance, use
499      * setLineSymbol instead.
500      * \see setLineSymbol()
501      * \see setGridLineWidth()
502      */
503     void setGridLineColor( const QColor &color );
504 
505     /**
506      * Sets the line \a symbol used for drawing grid lines. This is only used for grids with
507      * QgsLayoutItemMapGrid::Solid or QgsLayoutItemMapGrid::Cross styles.
508      * Ownership of \a symbol is transferred to the grid.
509      * \see lineSymbol()
510      * \see setMarkerSymbol()
511      * \see setStyle()
512      */
513     void setLineSymbol( QgsLineSymbol *symbol SIP_TRANSFER );
514 
515     /**
516      * Returns the line symbol used for drawing grid lines. This is only used for grids with
517      * QgsLayoutItemMapGrid::Solid or QgsLayoutItemMapGrid::Cross styles.
518      * \see setLineSymbol()
519      * \see markerSymbol()
520      * \see style()
521      * \note not available in Python bindings
522      */
523     const QgsLineSymbol *lineSymbol() const; SIP_SKIP
524 
525     /**
526      * Returns the line symbol used for drawing grid lines. This is only used for grids with
527      * QgsLayoutItemMapGrid::Solid or QgsLayoutItemMapGrid::Cross styles.
528      * \see setLineSymbol()
529      * \see markerSymbol()
530      * \see style()
531      */
532     QgsLineSymbol *lineSymbol();
533 
534     /**
535      * Sets the marker \a symbol used for drawing grid points. This is only used for grids with a
536      * QgsLayoutItemMapGrid::Markers style.
537      * Ownership of \a symbol is transferred to the grid.
538      * \see markerSymbol()
539      * \see setLineSymbol()
540      * \see setStyle()
541      */
542     void setMarkerSymbol( QgsMarkerSymbol *symbol SIP_TRANSFER );
543 
544     /**
545      * Returns the marker symbol used for drawing grid points. This is only used for grids with a
546      * QgsLayoutItemMapGrid::Markers style.
547      * \see setMarkerSymbol()
548      * \see lineSymbol()
549      * \see style()
550      * \note not available in Python bindings
551      */
552     const QgsMarkerSymbol *markerSymbol() const; SIP_SKIP
553 
554     /**
555      * Returns the marker symbol used for drawing grid points. This is only used for grids with a
556      * QgsLayoutItemMapGrid::Markers style.
557      * \see setMarkerSymbol()
558      * \see lineSymbol()
559      * \see style()
560      */
561     QgsMarkerSymbol *markerSymbol();
562 
563     //
564     // ANNOTATIONS
565     //
566 
567     /**
568      * Sets whether annotations should be shown for the grid.
569      * \see annotationEnabled()
570      */
setAnnotationEnabled(const bool enabled)571     void setAnnotationEnabled( const bool enabled ) { mShowGridAnnotation = enabled; }
572 
573     /**
574      * Returns whether annotations are shown for the grid.
575      * \see setAnnotationEnabled()
576      */
annotationEnabled()577     bool annotationEnabled() const { return mShowGridAnnotation; }
578 
579     /**
580      * Sets the text \a format to use when rendering grid annotations.
581      *
582      * \see annotationTextFormat()
583      * \since QGIS 3.16
584      */
setAnnotationTextFormat(const QgsTextFormat & format)585     void setAnnotationTextFormat( const QgsTextFormat &format ) { mAnnotationFormat = format; }
586 
587     /**
588      * Returns the text format used when rendering grid annotations.
589      *
590      * \see setAnnotationTextFormat()
591      * \since QGIS 3.16
592      */
annotationTextFormat()593     QgsTextFormat annotationTextFormat() const { return mAnnotationFormat; }
594 
595     /**
596      * Sets the \a font used for drawing grid annotations.
597      * Shortcut for annotationTextFormat().setFont().
598      * \see annotationFont()
599      * \deprecated use setAnnotationTextFormat() instead
600      */
601     Q_DECL_DEPRECATED void setAnnotationFont( const QFont &font ) SIP_DEPRECATED;
602 
603     /**
604      * Returns the font used for drawing grid annotations.
605      * Shortcut for annotationTextFormat().font().
606      * \see setAnnotationFont()
607      * \deprecated use annotationTextFormat() instead
608      */
609     Q_DECL_DEPRECATED QFont annotationFont() const SIP_DEPRECATED;
610 
611     /**
612      * Sets the font \a color used for drawing grid annotations.
613      * Shortcut for annotationTextFormat().setColor() and annotationTextFormat().setOpacity().
614      * \see annotationFontColor()
615      * \deprecated use setAnnotationTextFormat() instead
616      */
617     Q_DECL_DEPRECATED void setAnnotationFontColor( const QColor &color ) SIP_DEPRECATED;
618 
619     /**
620      * Returns the font color used for drawing grid annotations.
621      * Shortcut for annotationTextFormat().color() and annotationTextFormat().opacity().
622      * \see setAnnotationFontColor()
623      * \deprecated use annotationTextFormat() instead
624      */
625     Q_DECL_DEPRECATED QColor annotationFontColor() const SIP_DEPRECATED;
626 
627     /**
628      * Sets the coordinate \a precision for grid annotations.
629      * The \a precision indicates the number of decimal places to show when drawing grid annotations.
630      * \see annotationPrecision()
631      */
setAnnotationPrecision(const int precision)632     void setAnnotationPrecision( const int precision ) { mGridAnnotationPrecision = precision; }
633 
634     /**
635      * Returns the coordinate precision for grid annotations, which is the
636      * number of decimal places shown when drawing grid annotations.
637      * \see setAnnotationPrecision()
638      */
annotationPrecision()639     int annotationPrecision() const { return mGridAnnotationPrecision; }
640 
641     /**
642      * Sets what types of grid annotations should be drawn for a specified side of the map frame,
643      * or whether grid annotations should be disabled for the side.
644      * \param display display mode for annotations
645      * \param border side of map for annotations
646      * \see annotationDisplay()
647      */
648     void setAnnotationDisplay( DisplayMode display, BorderSide border );
649 
650     /**
651      * Returns the display mode for the grid annotations on a specified side of the map
652      * frame. This property also specifies whether annotations have been disabled
653      * from a side of the map frame.
654      * \param border side of map for annotations
655      * \returns display mode for grid annotations
656      * \see setAnnotationDisplay()
657      */
658     DisplayMode annotationDisplay( BorderSide border ) const;
659 
660     /**
661      * Sets the \a position for the grid annotations on a specified \a side of the map
662      * frame.
663      * \see annotationPosition()
664      */
665     void setAnnotationPosition( AnnotationPosition position, BorderSide side );
666 
667     /**
668      * Returns the position for the grid annotations on a specified \a side of the map
669      * frame.
670      * \see setAnnotationPosition()
671      */
672     AnnotationPosition annotationPosition( BorderSide side ) const;
673 
674     /**
675      * Sets the \a distance between the map frame and annotations. Units are layout units.
676      * \see annotationFrameDistance()
677      */
678     void setAnnotationFrameDistance( const double distance );
679 
680     /**
681      * Returns the distance between the map frame and annotations. Units are in layout units.
682      * \see setAnnotationFrameDistance()
683      */
annotationFrameDistance()684     double annotationFrameDistance() const { return mAnnotationFrameDistance; }
685 
686     /**
687      * Sets the \a direction for drawing frame annotations for the specified map \a side.
688      * \see annotationDirection()
689      */
690     void setAnnotationDirection( AnnotationDirection direction, BorderSide side );
691 
692     /**
693      * Sets the \a direction for drawing all frame annotations.
694      * \see annotationDirection()
695      */
696     void setAnnotationDirection( AnnotationDirection direction );
697 
698     /**
699      * Returns the direction for drawing frame annotations, on the specified \a side
700      * of the map.
701      * \see setAnnotationDirection()
702      */
703     AnnotationDirection annotationDirection( BorderSide border ) const;
704 
705     /**
706      * Sets the \a format for drawing grid annotations.
707      * \see annotationFormat()
708      */
setAnnotationFormat(const AnnotationFormat format)709     void setAnnotationFormat( const AnnotationFormat format ) { mGridAnnotationFormat = format; }
710 
711     /**
712      * Returns the format for drawing grid annotations.
713      * \see setAnnotationFormat()
714      */
annotationFormat()715     AnnotationFormat annotationFormat() const { return mGridAnnotationFormat; }
716 
717     /**
718      * Sets the \a expression used for drawing grid annotations. This is only used when annotationFormat()
719      * is QgsLayoutItemMapGrid::CustomFormat.
720      * \see annotationExpression()
721      */
setAnnotationExpression(const QString & expression)722     void setAnnotationExpression( const QString &expression ) { mGridAnnotationExpressionString = expression; mGridAnnotationExpression.reset(); }
723 
724     /**
725      * Returns the expression used for drawing grid annotations. This is only used when annotationFormat()
726      * is QgsLayoutItemMapGrid::CustomFormat.
727      * \see setAnnotationExpression()
728      */
annotationExpression()729     QString annotationExpression() const { return mGridAnnotationExpressionString; }
730 
731     //
732     // GRID FRAME
733     //
734 
735     /**
736      * Sets the grid frame \a style.
737      * \see frameStyle()
738      */
setFrameStyle(const FrameStyle style)739     void setFrameStyle( const FrameStyle style ) { mGridFrameStyle = style; }
740 
741     /**
742      * Returns the grid frame style.
743      * \see setFrameStyle()
744      */
frameStyle()745     FrameStyle frameStyle() const { return mGridFrameStyle; }
746 
747     /**
748      * Sets what type of grid \a divisions should be used for frames on a specified \a side of the map.
749      * \see frameDivisions()
750      */
751     void setFrameDivisions( DisplayMode divisions, BorderSide side );
752 
753     /**
754      * Returns the type of grid divisions which are used for frames on a specified \a side of the map.
755      * \see setFrameDivisions()
756      */
757     DisplayMode frameDivisions( BorderSide side ) const;
758 
759     /**
760      * Sets \a flags for grid frame sides. Setting these flags controls which sides
761      * of the map item the grid frame is drawn on.
762      * \see setFrameSideFlag()
763      * \see frameSideFlags()
764      * \see testFrameSideFlag()
765      */
766     void setFrameSideFlags( QgsLayoutItemMapGrid::FrameSideFlags flags );
767 
768     /**
769      * Sets whether the grid frame is drawn for a certain side of the map item.
770      * \param flag flag for grid frame side
771      * \param on set to TRUE to draw grid frame on that side of the map
772      * \see setFrameSideFlags()
773      * \see frameSideFlags()
774      * \see testFrameSideFlag()
775      */
776     void setFrameSideFlag( QgsLayoutItemMapGrid::FrameSideFlag flag, bool on = true );
777 
778     /**
779      * Returns the flags which control which sides of the map item the grid frame
780      * is drawn on.
781      * \see setFrameSideFlags()
782      * \see setFrameSideFlag()
783      * \see testFrameSideFlag()
784      */
785     QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const;
786 
787     /**
788      * Tests whether the grid frame should be drawn on a specified side of the map
789      * item.
790      * \param flag flag for grid frame side
791      * \returns TRUE if grid frame should be drawn for that side of the map
792      * \see setFrameSideFlags()
793      * \see setFrameSideFlag()
794      * \see frameSideFlags()
795      */
796     bool testFrameSideFlag( FrameSideFlag flag ) const;
797 
798     /**
799      * Sets the grid frame \a width (in layout units). This property controls how wide the grid frame is.
800      * The size of the line outlines drawn in the frame is controlled through the
801      * setFramePenSize method.
802      * \see frameWidth()
803      */
804     void setFrameWidth( const double width );
805 
806     /**
807      * Gets the grid frame width in layout units. This property controls how wide the grid frame is.
808      * The size of the line outlines drawn in the frame can be retrieved via the
809      * framePenSize method.
810      * \see setFrameWidth()
811      */
frameWidth()812     double frameWidth() const { return mGridFrameWidth; }
813 
814     /**
815      * Enable/disable ticks rotation for rotated or reprojected grids.
816      * \see rotatedTicksEnabled()
817      * \since QGIS 3.16
818      */
setRotatedTicksEnabled(const bool state)819     void setRotatedTicksEnabled( const bool state ) { mRotatedTicksEnabled = state; }
820 
821     /**
822      * Gets whether ticks rotation for rotated or reprojected grids is enabled.
823      * \see setRotatedTicksEnabled()
824      * \since QGIS 3.16
825      */
rotatedTicksEnabled()826     double rotatedTicksEnabled() const { return mRotatedTicksEnabled; }
827 
828     /**
829      * Sets the tick length calculation mode.
830      * \see rotatedTicksLengthMode()
831      * \since QGIS 3.16
832      */
setRotatedTicksLengthMode(const TickLengthMode mode)833     void setRotatedTicksLengthMode( const TickLengthMode mode ) { mRotatedTicksLengthMode = mode; }
834 
835     /**
836      * Returns the grid frame style.
837      * \see setRotatedTicksLengthMode()
838      * \since QGIS 3.16
839      */
rotatedTicksLengthMode()840     TickLengthMode rotatedTicksLengthMode() const { return mRotatedTicksLengthMode; }
841 
842     /**
843      * Sets the \a minimum angle (in degrees) below which ticks are not drawn.
844      * \see rotatedTicksMinimumAngle()
845      * \since QGIS 3.16
846      */
setRotatedTicksMinimumAngle(const double angle)847     void setRotatedTicksMinimumAngle( const double angle ) { mRotatedTicksMinimumAngle = angle; }
848 
849     /**
850      * Gets the \a minimum angle (in degrees) below which ticks are not drawn.
851      * \see setRotatedTicksMinimumAngle()
852      * \since QGIS 3.16
853      */
rotatedTicksMinimumAngle()854     double rotatedTicksMinimumAngle() const { return mRotatedTicksMinimumAngle; }
855 
856     /**
857      * Sets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
858      * \see rotatedTicksMarginToCorner()
859      * \since QGIS 3.16
860      */
setRotatedTicksMarginToCorner(const double margin)861     void setRotatedTicksMarginToCorner( const double margin ) { mRotatedTicksMarginToCorner = margin; }
862 
863     /**
864      * Gets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
865      * \see setRotatedTicksMarginToCorner()
866      * \since QGIS 3.16
867      */
rotatedTicksMarginToCorner()868     double rotatedTicksMarginToCorner() const { return mRotatedTicksMarginToCorner; }
869 
870     /**
871      * Enable/disable annotations rotation for rotated or reprojected grids.
872      * \see rotatedAnnotationsEnabled()
873      * \since QGIS 3.16
874      */
setRotatedAnnotationsEnabled(const bool state)875     void setRotatedAnnotationsEnabled( const bool state ) { mRotatedAnnotationsEnabled = state; }
876 
877     /**
878      * Gets whether annotations rotation for rotated or reprojected grids is enabled.
879      * \see setRotatedAnnotationsEnabled()
880      * \since QGIS 3.16
881      */
rotatedAnnotationsEnabled()882     double rotatedAnnotationsEnabled() const { return mRotatedAnnotationsEnabled; }
883 
884     /**
885      * Sets the annotation length calculation mode.
886      * \see rotatedAnnotationsLengthMode()
887      * \since QGIS 3.16
888     */
setRotatedAnnotationsLengthMode(const TickLengthMode mode)889     void setRotatedAnnotationsLengthMode( const TickLengthMode mode ) { mRotatedAnnotationsLengthMode = mode; }
890 
891     /**
892      * Returns the grid frame style.
893      * \see setRotatedAnnotationsLengthMode()
894      * \since QGIS 3.16
895      */
rotatedAnnotationsLengthMode()896     TickLengthMode rotatedAnnotationsLengthMode() const { return mRotatedAnnotationsLengthMode; }
897 
898     /**
899      * Sets the \a minimum angle (in degrees) below which annotated are not drawn.
900      * \see rotatedAnnotationsMinimumAngle()
901      * \since QGIS 3.16
902      */
setRotatedAnnotationsMinimumAngle(const double angle)903     void setRotatedAnnotationsMinimumAngle( const double angle ) { mRotatedAnnotationsMinimumAngle = angle; }
904 
905     /**
906      * Gets the \a minimum angle (in degrees) below which annotated are not drawn.
907      * \see setRotatedAnnotationsMinimumAngle()
908      * \since QGIS 3.16
909      */
rotatedAnnotationsMinimumAngle()910     double rotatedAnnotationsMinimumAngle() const { return mRotatedAnnotationsMinimumAngle; }
911 
912     /**
913      * Sets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
914      * \see rotatedAnnotationsMarginToCorner()
915      * \since QGIS 3.16
916      */
setRotatedAnnotationsMarginToCorner(const double margin)917     void setRotatedAnnotationsMarginToCorner( const double margin ) { mRotatedAnnotationsMarginToCorner = margin; }
918 
919     /**
920      * Gets the \a margin to corners (in canvas units) below which outwards facing ticks are not drawn.
921      * \see setRotatedAnnotationsMarginToCorner()
922      * \since QGIS 3.16
923      */
rotatedAnnotationsMarginToCorner()924     double rotatedAnnotationsMarginToCorner() const { return mRotatedAnnotationsMarginToCorner; }
925 
926     /**
927      * Sets the grid frame margin (in layout units).
928      * This property controls distance between the map frame and the grid frame.
929      * \see frameMargin()
930      * \since QGIS 3.6
931      */
932     void setFrameMargin( const double margin );
933 
934     /**
935      * Sets the grid frame Margin (in layout units).
936      * This property controls distance between the map frame and the grid frame.
937      * \see setFrameMargin()
938      * \since QGIS 3.6
939      */
frameMargin()940     double frameMargin() const { return mGridFrameMargin; }
941 
942     /**
943      * Sets the \a width of the stroke drawn in the grid frame.
944      * \see framePenSize()
945      * \see setFramePenColor()
946      */
947     void setFramePenSize( const double width );
948 
949     /**
950      * Retrieves the width of the stroke drawn in the grid frame.
951      * \see setFramePenSize()
952      * \see framePenColor()
953      */
framePenSize()954     double framePenSize() const { return mGridFramePenThickness; }
955 
956     /**
957      * Sets the \a color of the stroke drawn in the grid frame.
958      * \see framePenColor()
959      * \see setFramePenSize()
960      * \see setFrameFillColor1()
961      * \see setFrameFillColor2()
962      */
setFramePenColor(const QColor & color)963     void setFramePenColor( const QColor &color ) { mGridFramePenColor = color; }
964 
965     /**
966      * Retrieves the color of the stroke drawn in the grid frame.
967      * \see setFramePenColor()
968      * \see framePenSize()
969      * \see frameFillColor1()
970      * \see frameFillColor2()
971      */
framePenColor()972     QColor framePenColor() const {return mGridFramePenColor;}
973 
974     /**
975      * Sets the first fill \a color used for the grid frame.
976      * \see frameFillColor1()
977      * \see setFramePenColor()
978      * \see setFrameFillColor2()
979      */
setFrameFillColor1(const QColor & color)980     void setFrameFillColor1( const QColor &color ) { mGridFrameFillColor1 = color; }
981 
982     /**
983      * Retrieves the first fill color for the grid frame.
984      * \see setFrameFillColor1()
985      * \see framePenColor()
986      * \see frameFillColor2()
987      */
frameFillColor1()988     QColor frameFillColor1() const { return mGridFrameFillColor1; }
989 
990     /**
991      * Sets the second fill \a color used for the grid frame.
992      * \see frameFillColor2()
993      * \see setFramePenColor()
994      * \see setFrameFillColor1()
995      */
setFrameFillColor2(const QColor & color)996     void setFrameFillColor2( const QColor &color ) { mGridFrameFillColor2 = color; }
997 
998     /**
999      * Retrieves the second fill color for the grid frame.
1000      * \see setFrameFillColor2()
1001      * \see framePenColor(
1002      * \see frameFillColor1()
1003      */
frameFillColor2()1004     QColor frameFillColor2() const { return mGridFrameFillColor2; }
1005 
1006     QgsExpressionContext createExpressionContext() const override;
1007     bool accept( QgsStyleEntityVisitorInterface *visitor ) const override;
1008     void refresh() override;
1009 
1010   signals:
1011 
1012     /**
1013      * Emitted whenever the grid's CRS is changed.
1014      *
1015      * \since QGIS 3.18
1016      */
1017     void crsChanged();
1018 
1019   private:
1020 
1021     QgsLayoutItemMapGrid() = delete;
1022 
1023     struct GridExtension
1024     {
1025       GridExtension() = default;
1026       double top = 0.0;
1027       double right = 0.0;
1028       double bottom = 0.0;
1029       double left = 0.0;
1030 
1031       /**
1032        * Updates the specified border of the extension
1033        */
UpdateBorderGridExtension1034       void UpdateBorder( BorderSide border, double value )
1035       {
1036         switch ( border )
1037         {
1038           case QgsLayoutItemMapGrid::Left:
1039             left = std::max( left, value );
1040             break;
1041           case QgsLayoutItemMapGrid::Right:
1042             right = std::max( right, value );
1043             break;
1044           case QgsLayoutItemMapGrid::Top:
1045             top = std::max( top, value );
1046             break;
1047           case QgsLayoutItemMapGrid::Bottom:
1048             bottom = std::max( bottom, value );
1049             break;
1050         }
1051       }
1052 
1053       /**
1054        * Updates all borders of the extension
1055        */
UpdateAllGridExtension1056       void UpdateAll( double value )
1057       {
1058         left = std::max( left, value );
1059         right = std::max( right, value );
1060         top = std::max( top, value );
1061         bottom = std::max( bottom, value );
1062       }
1063     };
1064 
1065     struct GridLineAnnotation
1066     {
1067       BorderSide border = Left; // border on which the annotation is
1068       QVector2D position; // position on the frame
1069       QVector2D vector; // vector towards map center
1070       double angle = 0; // the (acute) angle formed between the vector and the border
1071     };
1072 
1073     /**
1074      * Helper that represents a grid line, for drawing the line itself an the
1075      * anotations on the frame.
1076      */
1077     struct GridLine
1078     {
1079       QPolygonF line; // the actual line, can be straight with two points or curved if transformed
1080       double coordinate; // the coordinate value
1081       QgsLayoutItemMapGrid::AnnotationCoordinate coordinateType; // whether it's a latitude or longitude line
1082       GridLineAnnotation startAnnotation; // the annotation on the start point
1083       GridLineAnnotation endAnnotation; // the annotation on the end point
1084     };
1085     mutable QList< GridLine > mGridLines;
1086 
1087     //! True if a re-transformation of grid lines is required
1088     mutable bool mTransformDirty = true;
1089 
1090     //! Solid or crosses
1091     GridStyle mGridStyle = QgsLayoutItemMapGrid::Solid;
1092     //! Grid line interval in x-direction (map units)
1093     double mGridIntervalX = 0.0;
1094     //! Grid line interval in y-direction (map units)
1095     double mGridIntervalY = 0.0;
1096     //! Grid line offset in x-direction
1097     double mGridOffsetX = 0.0;
1098     //! Grid line offset in y-direction
1099     double mGridOffsetY = 0.0;
1100 
1101     //! Text format for grid annotations
1102     QgsTextFormat mAnnotationFormat;
1103 
1104     //! Digits after the dot
1105     int mGridAnnotationPrecision = 3;
1106     //! True if coordinate values should be drawn
1107     bool mShowGridAnnotation = false;
1108 
1109     //! Annotation display mode for left map side
1110     DisplayMode mLeftGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1111     //! Annotation display mode for right map side
1112     DisplayMode mRightGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1113     //! Annotation display mode for top map side
1114     DisplayMode mTopGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1115     //! Annotation display mode for bottom map side
1116     DisplayMode mBottomGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1117 
1118     //! Annotation position for left map side (inside / outside)
1119     AnnotationPosition mLeftGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1120     //! Annotation position for right map side (inside / outside)
1121     AnnotationPosition mRightGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1122     //! Annotation position for top map side (inside / outside)
1123     AnnotationPosition mTopGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1124     //! Annotation position for bottom map side (inside / outside)
1125     AnnotationPosition mBottomGridAnnotationPosition = QgsLayoutItemMapGrid::OutsideMapFrame;
1126 
1127     //! Distance between map frame and annotation
1128     double mAnnotationFrameDistance = 1.0;
1129 
1130     //! Annotation direction on left side ( horizontal or vertical )
1131     AnnotationDirection mLeftGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1132     //! Annotation direction on right side ( horizontal or vertical )
1133     AnnotationDirection mRightGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1134     //! Annotation direction on top side ( horizontal or vertical )
1135     AnnotationDirection mTopGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1136     //! Annotation direction on bottom side ( horizontal or vertical )
1137     AnnotationDirection mBottomGridAnnotationDirection = QgsLayoutItemMapGrid::Horizontal;
1138     AnnotationFormat mGridAnnotationFormat = QgsLayoutItemMapGrid::Decimal;
1139 
1140     QString mGridAnnotationExpressionString;
1141     mutable std::unique_ptr< QgsExpression > mGridAnnotationExpression;
1142 
1143     FrameStyle mGridFrameStyle = QgsLayoutItemMapGrid::NoFrame;
1144 
1145     FrameSideFlags mGridFrameSides;
1146     double mGridFrameWidth = 2.0;
1147     double mGridFramePenThickness = 0.3;
1148     QColor mGridFramePenColor = QColor( 0, 0, 0 );
1149     QColor mGridFrameFillColor1 = Qt::white;
1150     QColor mGridFrameFillColor2 = Qt::black;
1151     double mCrossLength = 3.0;
1152     double mGridFrameMargin = 0.0;
1153     bool mRotatedTicksEnabled = false;
1154     TickLengthMode mRotatedTicksLengthMode = QgsLayoutItemMapGrid::OrthogonalTicks;
1155     double mRotatedTicksMinimumAngle = 0.0;
1156     double mRotatedTicksMarginToCorner = 0.0;
1157     bool mRotatedAnnotationsEnabled = false;
1158     TickLengthMode mRotatedAnnotationsLengthMode = QgsLayoutItemMapGrid::OrthogonalTicks;
1159     double mRotatedAnnotationsMinimumAngle = 0.0;
1160     double mRotatedAnnotationsMarginToCorner = 0.0;
1161 
1162     double mMinimumIntervalWidth = 50;
1163     double mMaximumIntervalWidth = 100;
1164 
1165     //! Divisions for frame on left map side
1166     DisplayMode mLeftFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1167     //! Divisions for frame on right map side
1168     DisplayMode mRightFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1169     //! Divisions for frame on top map side
1170     DisplayMode mTopFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1171     //! Divisions for frame on bottom map side
1172     DisplayMode mBottomFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1173 
1174     std::unique_ptr< QgsLineSymbol > mGridLineSymbol;
1175     std::unique_ptr< QgsMarkerSymbol > mGridMarkerSymbol;
1176 
1177     QgsCoordinateReferenceSystem mCRS;
1178 
1179     GridUnit mGridUnit = MapUnit;
1180 
1181     QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;
1182 
1183     mutable QList< QPair< double, QPolygonF > > mTransformedXLines;
1184     mutable QList< QPair< double, QPolygonF > > mTransformedYLines;
1185     mutable QList< QgsPointXY > mTransformedIntersections;
1186     QRectF mPrevPaintRect;
1187     mutable QPolygonF mPrevMapPolygon;
1188 
1189     bool mEvaluatedEnabled = true;
1190     double mEvaluatedIntervalX = 0;
1191     double mEvaluatedIntervalY = 0;
1192     double mEvaluatedOffsetX = 0;
1193     double mEvaluatedOffsetY = 0;
1194     double mEvaluatedGridFrameWidth = 0;
1195     double mEvaluatedGridFrameMargin = 0;
1196     double mEvaluatedAnnotationFrameDistance = 0;
1197     double mEvaluatedCrossLength = 0;
1198     double mEvaluatedGridFrameLineThickness = 0;
1199     DisplayMode mEvaluatedLeftGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1200     DisplayMode mEvaluatedRightGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1201     DisplayMode mEvaluatedTopGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1202     DisplayMode mEvaluatedBottomGridAnnotationDisplay = QgsLayoutItemMapGrid::ShowAll;
1203     DisplayMode mEvaluatedLeftFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1204     DisplayMode mEvaluatedRightFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1205     DisplayMode mEvaluatedTopFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1206     DisplayMode mEvaluatedBottomFrameDivisions = QgsLayoutItemMapGrid::ShowAll;
1207 
1208     /**
1209      * Updates the grid lines annotation positions
1210      */
1211     void updateGridLinesAnnotationsPositions() const;
1212 
1213     /**
1214      * Draws the map grid. If extension is specified, then no grid will be drawn and instead the maximum extension
1215      * for the grid outside of the map frame will be calculated.
1216      */
1217     void drawGridFrame( QPainter *p, GridExtension *extension = nullptr ) const;
1218 
1219     /**
1220      * Draw coordinates for mGridAnnotationType Coordinate
1221      * \param context destination render context
1222      * \param expressionContext expression context for evaluating custom annotation formats
1223      * \param extension optional. If specified, nothing will be drawn and instead the maximum extension for the grid
1224      * annotations will be stored in this variable.
1225      */
1226     void drawCoordinateAnnotations( QgsRenderContext &context, QgsExpressionContext &expressionContext, GridExtension *extension = nullptr ) const;
1227 
1228     /**
1229      * Draw an annotation. If optional extension argument is specified, nothing will be drawn and instead
1230      * the extension of the annotation outside of the map frame will be stored in this variable.
1231      */
1232     void drawCoordinateAnnotation( QgsRenderContext &context, GridLineAnnotation annot, const QString &annotationString, AnnotationCoordinate coordinateType, GridExtension *extension = nullptr ) const;
1233 
1234     QString gridAnnotationString( double value, AnnotationCoordinate coord, QgsExpressionContext &expressionContext ) const;
1235 
1236     /**
1237      * Computes the grid lines with associated coordinate value
1238      * \returns 0 in case of success
1239     */
1240     int xGridLines() const;
1241 
1242     /**
1243      * Computes the grid lines for the y-coordinates. Not vertical in case of rotation
1244      * \returns 0 in case of success
1245     */
1246     int yGridLines() const;
1247 
1248     int xGridLinesCrsTransform( const QgsRectangle &bbox, const QgsCoordinateTransform &t ) const;
1249 
1250     int yGridLinesCrsTransform( const QgsRectangle &bbox, const QgsCoordinateTransform &t ) const;
1251 
1252     void drawGridLine( const QLineF &line, QgsRenderContext &context ) const;
1253 
1254     void drawGridLine( const QPolygonF &line, QgsRenderContext &context ) const;
1255 
1256     /**
1257      * Draw the grid frame's border. If optional extension argument is specified, nothing will be drawn and instead
1258      * the maximum extension of the frame border outside of the map frame will be stored in this variable.
1259      */
1260     void drawGridFrameBorder( QPainter *p, BorderSide border, double *extension = nullptr ) const;
1261 
1262     /**
1263      * Returns the item border of a point (in item coordinates)
1264      * \param p point
1265      * \param coordinateType coordinate type
1266      */
1267     BorderSide borderForLineCoord( QPointF p, AnnotationCoordinate coordinateType ) const;
1268 
1269     //! Gets parameters for drawing grid in CRS different to map CRS
1270     int crsGridParams( QgsRectangle &crsRect, QgsCoordinateTransform &inverseTransform ) const;
1271 
1272     static QList<QPolygonF> trimLinesToMap( const QPolygonF &line, const QgsRectangle &rect );
1273 
1274     QPolygonF scalePolygon( const QPolygonF &polygon, double scale ) const;
1275 
1276     //! Draws grid if CRS is different to map CRS
1277     void drawGridCrsTransform( QgsRenderContext &context, double dotsPerMM, bool calculateLinesOnly = false ) const;
1278 
1279     void drawGridNoTransform( QgsRenderContext &context, double dotsPerMM, bool calculateLinesOnly = false ) const;
1280 
1281     void createDefaultGridLineSymbol();
1282 
1283     void createDefaultGridMarkerSymbol();
1284 
1285     void drawGridMarker( QPointF point, QgsRenderContext &context ) const;
1286 
1287     void drawGridFrameZebra( QPainter *p, GridExtension *extension = nullptr ) const;
1288 
1289     void drawGridFrameZebraBorder( QPainter *p, BorderSide border, double *extension = nullptr ) const;
1290 
1291     void drawGridFrameTicks( QPainter *p, GridExtension *extension = nullptr ) const;
1292 
1293     void drawGridFrameLine( QPainter *p, GridExtension *extension = nullptr ) const;
1294 
1295     void calculateCrsTransformLines() const;
1296 
1297     bool shouldShowDivisionForSide( AnnotationCoordinate coordinate, BorderSide side ) const;
1298     bool shouldShowAnnotationForSide( AnnotationCoordinate coordinate, BorderSide side ) const;
1299     bool shouldShowForDisplayMode( AnnotationCoordinate coordinate, DisplayMode mode ) const;
1300     void refreshDataDefinedProperties();
1301 
1302     //! Returns diagonal of map in CRS units
1303     double mapWidth() const;
1304 
1305     friend class TestQgsLayoutMapGrid;
1306 
1307 };
1308 
1309 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayoutItemMapGrid::FrameSideFlags )
1310 
1311 #endif // QGSLAYOUTITEMMAPGRID_H
1312