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