Branch data Line data Source code
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 : 0 : 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 : 0 : 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 : : */
296 : : QgsCoordinateReferenceSystem crs() const { return mCRS; }
297 : :
298 : : /**
299 : : * Sets the blending \a mode used for drawing the grid.
300 : : * \see blendMode()
301 : : */
302 : 0 : void setBlendMode( const QPainter::CompositionMode mode ) { mBlendMode = mode; }
303 : :
304 : : /**
305 : : * Retrieves the blending mode used for drawing the grid.
306 : : * \see setBlendMode()
307 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
570 : 0 : void setAnnotationEnabled( const bool enabled ) { mShowGridAnnotation = enabled; }
571 : :
572 : : /**
573 : : * Returns whether annotations are shown for the grid.
574 : : * \see setAnnotationEnabled()
575 : : */
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 : : */
584 : 0 : 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 : : */
592 : 0 : 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 : : */
631 : 0 : 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 : : */
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 : : */
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 : : */
708 : 0 : void setAnnotationFormat( const AnnotationFormat format ) { mGridAnnotationFormat = format; }
709 : :
710 : : /**
711 : : * Returns the format for drawing grid annotations.
712 : : * \see setAnnotationFormat()
713 : : */
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 : : */
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 : : */
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 : : */
738 : 0 : void setFrameStyle( const FrameStyle style ) { mGridFrameStyle = style; }
739 : :
740 : : /**
741 : : * Returns the grid frame style.
742 : : * \see setFrameStyle()
743 : : */
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 : : */
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 : : */
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 : : */
825 : : double rotatedTicksEnabled() const { return mRotatedTicksEnabled; }
826 : :
827 : : /**
828 : : * Sets the tick length calculation mode.
829 : : * \see rotatedTicksLengthMode()
830 : : * \since QGIS 3.16
831 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
881 : : double rotatedAnnotationsEnabled() const { return mRotatedAnnotationsEnabled; }
882 : :
883 : : /**
884 : : * Sets the annotation length calculation mode.
885 : : * \see rotatedAnnotationsLengthMode()
886 : : * \since QGIS 3.16
887 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
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 : : */
962 : 0 : 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 : : */
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 : : */
979 : 0 : 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 : : */
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 : : */
995 : 0 : 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 : : */
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 : 0 : GridExtension() = default;
1025 : 0 : double top = 0.0;
1026 : 0 : double right = 0.0;
1027 : 0 : double bottom = 0.0;
1028 : 0 : double left = 0.0;
1029 : :
1030 : : /**
1031 : : * Updates the specified border of the extension
1032 : : */
1033 : 0 : void UpdateBorder( BorderSide border, double value )
1034 : : {
1035 : 0 : switch ( border )
1036 : : {
1037 : : case QgsLayoutItemMapGrid::Left:
1038 : 0 : left = std::max( left, value );
1039 : 0 : break;
1040 : : case QgsLayoutItemMapGrid::Right:
1041 : 0 : right = std::max( right, value );
1042 : 0 : break;
1043 : : case QgsLayoutItemMapGrid::Top:
1044 : 0 : top = std::max( top, value );
1045 : 0 : break;
1046 : : case QgsLayoutItemMapGrid::Bottom:
1047 : 0 : bottom = std::max( bottom, value );
1048 : 0 : break;
1049 : : }
1050 : 0 : }
1051 : :
1052 : : /**
1053 : : * Updates all borders of the extension
1054 : : */
1055 : 0 : void UpdateAll( double value )
1056 : : {
1057 : 0 : left = std::max( left, value );
1058 : 0 : right = std::max( right, value );
1059 : 0 : top = std::max( top, value );
1060 : 0 : bottom = std::max( bottom, value );
1061 : 0 : }
1062 : : };
1063 : :
1064 : 0 : struct GridLineAnnotation
1065 : : {
1066 : 0 : BorderSide border = Left; // border on which the annotation is
1067 : : QVector2D position; // position on the frame
1068 : : QVector2D vector; // vector towards map center
1069 : 0 : double angle = 0; // 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 : 0 : 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 : 0 : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayoutItemMapGrid::FrameSideFlags )
1309 : :
1310 : : #endif // QGSLAYOUTITEMMAPGRID_H
|