19#include "moc_qgslayoutitemmapgrid.cpp" 
   48#define MAX_GRID_LINES 1000  
   79  return qobject_cast<QgsLayoutItemMapGrid *>( 
item );
 
 
   85  return qobject_cast<QgsLayoutItemMapGrid *>( 
item );
 
 
   90  QList< QgsLayoutItemMapGrid * > list;
 
 
  113  const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral( 
"ComposerMapGrid" ) );
 
  114  for ( 
int i = 0; i < mapGridNodeList.size(); ++i )
 
  116    const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
 
  118    mapGrid->
readXml( mapGridElem, doc, context );
 
 
  132  return std::max( std::max( std::max( top, right ), bottom ), left );
 
 
  146      double gridTop = 0.0;
 
  147      double gridRight = 0.0;
 
  148      double gridBottom = 0.0;
 
  149      double gridLeft = 0.0;
 
  151      top = std::max( top, gridTop );
 
  152      right = std::max( right, gridRight );
 
  153      bottom = std::max( bottom, gridBottom );
 
  154      left = std::max( left, gridLeft );
 
 
  170      return QVector2D( 0, 1 );
 
  172      return QVector2D( -1, 0 );
 
  174      return QVector2D( 0, -1 );
 
  176      return QVector2D( 1, 0 );
 
 
  184  return QVector2D( borderVector.y(), -borderVector.x() );
 
 
  194  const QString defaultFontString = settings.
value( QStringLiteral( 
"LayoutDesigner/defaultFont" ), QVariant(), 
QgsSettings::Gui ).toString();
 
  195  if ( !defaultFontString.isEmpty() )
 
  199    mAnnotationFormat.
setFont( font );
 
  202  createDefaultGridLineSymbol();
 
  203  createDefaultGridMarkerSymbol();
 
 
  216void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
 
  218  QVariantMap properties;
 
  219  properties.insert( QStringLiteral( 
"color" ), QStringLiteral( 
"0,0,0,255" ) );
 
  220  properties.insert( QStringLiteral( 
"width" ), QStringLiteral( 
"0.3" ) );
 
  221  properties.insert( QStringLiteral( 
"capstyle" ), QStringLiteral( 
"flat" ) );
 
  225void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
 
  227  QVariantMap properties;
 
  228  properties.insert( QStringLiteral( 
"name" ), QStringLiteral( 
"circle" ) );
 
  229  properties.insert( QStringLiteral( 
"size" ), QStringLiteral( 
"2.0" ) );
 
  230  properties.insert( QStringLiteral( 
"color" ), QStringLiteral( 
"0,0,0,255" ) );
 
  236  if ( mGridLineSymbol )
 
  238    mGridLineSymbol->setWidth( width );
 
 
  244  if ( mGridLineSymbol )
 
  246    mGridLineSymbol->setColor( 
c );
 
 
  257  QDomElement mapGridElem = doc.createElement( QStringLiteral( 
"ComposerMapGrid" ) );
 
  258  mapGridElem.setAttribute( QStringLiteral( 
"gridStyle" ), mGridStyle );
 
  259  mapGridElem.setAttribute( QStringLiteral( 
"intervalX" ), 
qgsDoubleToString( mGridIntervalX ) );
 
  260  mapGridElem.setAttribute( QStringLiteral( 
"intervalY" ), 
qgsDoubleToString( mGridIntervalY ) );
 
  261  mapGridElem.setAttribute( QStringLiteral( 
"offsetX" ), 
qgsDoubleToString( mGridOffsetX ) );
 
  262  mapGridElem.setAttribute( QStringLiteral( 
"offsetY" ), 
qgsDoubleToString( mGridOffsetY ) );
 
  263  mapGridElem.setAttribute( QStringLiteral( 
"crossLength" ), 
qgsDoubleToString( mCrossLength ) );
 
  265  QDomElement lineStyleElem = doc.createElement( QStringLiteral( 
"lineStyle" ) );
 
  267  lineStyleElem.appendChild( gridLineStyleElem );
 
  268  mapGridElem.appendChild( lineStyleElem );
 
  270  QDomElement markerStyleElem = doc.createElement( QStringLiteral( 
"markerStyle" ) );
 
  272  markerStyleElem.appendChild( gridMarkerStyleElem );
 
  273  mapGridElem.appendChild( markerStyleElem );
 
  275  mapGridElem.setAttribute( QStringLiteral( 
"gridFrameStyle" ), mGridFrameStyle );
 
  276  mapGridElem.setAttribute( QStringLiteral( 
"gridFrameSideFlags" ), mGridFrameSides );
 
  277  mapGridElem.setAttribute( QStringLiteral( 
"gridFrameWidth" ), 
qgsDoubleToString( mGridFrameWidth ) );
 
  278  mapGridElem.setAttribute( QStringLiteral( 
"gridFrameMargin" ), 
qgsDoubleToString( mGridFrameMargin ) );
 
  279  mapGridElem.setAttribute( QStringLiteral( 
"gridFramePenThickness" ), 
qgsDoubleToString( mGridFramePenThickness ) );
 
  283  mapGridElem.setAttribute( QStringLiteral( 
"leftFrameDivisions" ), mLeftFrameDivisions );
 
  284  mapGridElem.setAttribute( QStringLiteral( 
"rightFrameDivisions" ), mRightFrameDivisions );
 
  285  mapGridElem.setAttribute( QStringLiteral( 
"topFrameDivisions" ), mTopFrameDivisions );
 
  286  mapGridElem.setAttribute( QStringLiteral( 
"bottomFrameDivisions" ), mBottomFrameDivisions );
 
  287  mapGridElem.setAttribute( QStringLiteral( 
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
 
  288  mapGridElem.setAttribute( QStringLiteral( 
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
 
  289  mapGridElem.setAttribute( QStringLiteral( 
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
 
  290  mapGridElem.setAttribute( QStringLiteral( 
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
 
  291  mapGridElem.setAttribute( QStringLiteral( 
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
 
  292  mapGridElem.setAttribute( QStringLiteral( 
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
 
  293  mapGridElem.setAttribute( QStringLiteral( 
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
 
  294  mapGridElem.setAttribute( QStringLiteral( 
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
 
  300  mapGridElem.setAttribute( QStringLiteral( 
"annotationFormat" ), mGridAnnotationFormat );
 
  301  mapGridElem.setAttribute( QStringLiteral( 
"showAnnotation" ), mShowGridAnnotation );
 
  302  mapGridElem.setAttribute( QStringLiteral( 
"annotationExpression" ), mGridAnnotationExpressionString );
 
  303  mapGridElem.setAttribute( QStringLiteral( 
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
 
  304  mapGridElem.setAttribute( QStringLiteral( 
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
 
  305  mapGridElem.setAttribute( QStringLiteral( 
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
 
  306  mapGridElem.setAttribute( QStringLiteral( 
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
 
  307  mapGridElem.setAttribute( QStringLiteral( 
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
 
  308  mapGridElem.setAttribute( QStringLiteral( 
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
 
  309  mapGridElem.setAttribute( QStringLiteral( 
"topAnnotationPosition" ), mTopGridAnnotationPosition );
 
  310  mapGridElem.setAttribute( QStringLiteral( 
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
 
  311  mapGridElem.setAttribute( QStringLiteral( 
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
 
  312  mapGridElem.setAttribute( QStringLiteral( 
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
 
  313  mapGridElem.setAttribute( QStringLiteral( 
"topAnnotationDirection" ), mTopGridAnnotationDirection );
 
  314  mapGridElem.setAttribute( QStringLiteral( 
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
 
  315  mapGridElem.setAttribute( QStringLiteral( 
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
 
  316  mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
 
  317  mapGridElem.setAttribute( QStringLiteral( 
"annotationPrecision" ), mGridAnnotationPrecision );
 
  318  mapGridElem.setAttribute( QStringLiteral( 
"unit" ), mGridUnit );
 
  319  mapGridElem.setAttribute( QStringLiteral( 
"blendMode" ), mBlendMode );
 
  320  mapGridElem.setAttribute( QStringLiteral( 
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
 
  321  mapGridElem.setAttribute( QStringLiteral( 
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
 
  324  elem.appendChild( mapGridElem );
 
 
  331  if ( itemElem.isNull() )
 
  340  mGridIntervalX = itemElem.attribute( QStringLiteral( 
"intervalX" ), QStringLiteral( 
"0" ) ).toDouble();
 
  341  mGridIntervalY = itemElem.attribute( QStringLiteral( 
"intervalY" ), QStringLiteral( 
"0" ) ).toDouble();
 
  342  mGridOffsetX = itemElem.attribute( QStringLiteral( 
"offsetX" ), QStringLiteral( 
"0" ) ).toDouble();
 
  343  mGridOffsetY = itemElem.attribute( QStringLiteral( 
"offsetY" ), QStringLiteral( 
"0" ) ).toDouble();
 
  344  mCrossLength = itemElem.attribute( QStringLiteral( 
"crossLength" ), QStringLiteral( 
"3" ) ).toDouble();
 
  345  mGridFrameStyle = 
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral( 
"gridFrameStyle" ), QStringLiteral( 
"0" ) ).toInt() );
 
  347  mGridFrameWidth = itemElem.attribute( QStringLiteral( 
"gridFrameWidth" ), QStringLiteral( 
"2.0" ) ).toDouble();
 
  348  mGridFrameMargin = itemElem.attribute( QStringLiteral( 
"gridFrameMargin" ), QStringLiteral( 
"0.0" ) ).toDouble();
 
  349  mGridFramePenThickness = itemElem.attribute( QStringLiteral( 
"gridFramePenThickness" ), QStringLiteral( 
"0.3" ) ).toDouble();
 
  351  mGridFrameFillColor1 = 
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral( 
"frameFillColor1" ), QStringLiteral( 
"255,255,255,255" ) ) );
 
  352  mGridFrameFillColor2 = 
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral( 
"frameFillColor2" ), QStringLiteral( 
"0,0,0,255" ) ) );
 
  357  mRotatedTicksLengthMode = 
TickLengthMode( itemElem.attribute( QStringLiteral( 
"rotatedTicksLengthMode" ), QStringLiteral( 
"0" ) ).toInt() );
 
  358  mRotatedTicksEnabled = itemElem.attribute( QStringLiteral( 
"rotatedTicksEnabled" ), QStringLiteral( 
"0" ) ) != QLatin1String( 
"0" );
 
  359  mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral( 
"rotatedTicksMinimumAngle" ), QStringLiteral( 
"0" ) ).toDouble();
 
  360  mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral( 
"rotatedTicksMarginToCorner" ), QStringLiteral( 
"0" ) ).toDouble();
 
  361  mRotatedAnnotationsLengthMode = 
TickLengthMode( itemElem.attribute( QStringLiteral( 
"rotatedAnnotationsLengthMode" ), QStringLiteral( 
"0" ) ).toInt() );
 
  362  mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral( 
"rotatedAnnotationsEnabled" ), QStringLiteral( 
"0" ) ) != QLatin1String( 
"0" );
 
  363  mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral( 
"rotatedAnnotationsMinimumAngle" ), QStringLiteral( 
"0" ) ).toDouble();
 
  364  mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral( 
"rotatedAnnotationsMarginToCorner" ), QStringLiteral( 
"0" ) ).toDouble();
 
  366  const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral( 
"lineStyle" ) );
 
  367  if ( !lineStyleElem.isNull() )
 
  369    const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral( 
"symbol" ) );
 
  370    if ( !symbolElem.isNull() )
 
  372      mGridLineSymbol = QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context );
 
  379    mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral( 
"penWidth" ), QStringLiteral( 
"0" ) ).toDouble() );
 
  380    mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral( 
"penColorRed" ), QStringLiteral( 
"0" ) ).toInt(),
 
  381                                       itemElem.attribute( QStringLiteral( 
"penColorGreen" ), QStringLiteral( 
"0" ) ).toInt(),
 
  382                                       itemElem.attribute( QStringLiteral( 
"penColorBlue" ), QStringLiteral( 
"0" ) ).toInt() ) );
 
  385  const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral( 
"markerStyle" ) );
 
  386  if ( !markerStyleElem.isNull() )
 
  388    const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral( 
"symbol" ) );
 
  389    if ( !symbolElem.isNull() )
 
  391      mGridMarkerSymbol = QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context );
 
  395  if ( !mCRS.
readXml( itemElem ) )
 
  398  mBlendMode = 
static_cast< QPainter::CompositionMode 
>( itemElem.attribute( QStringLiteral( 
"blendMode" ), QStringLiteral( 
"0" ) ).toUInt() );
 
  401  mShowGridAnnotation = ( itemElem.attribute( QStringLiteral( 
"showAnnotation" ), QStringLiteral( 
"0" ) ) != QLatin1String( 
"0" ) );
 
  403  mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral( 
"annotationExpression" ) );
 
  404  mGridAnnotationExpression.reset();
 
  409  mLeftGridAnnotationDisplay = 
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral( 
"leftAnnotationDisplay" ), QStringLiteral( 
"0" ) ).toInt() );
 
  410  mRightGridAnnotationDisplay = 
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral( 
"rightAnnotationDisplay" ), QStringLiteral( 
"0" ) ).toInt() );
 
  412  mBottomGridAnnotationDisplay = 
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral( 
"bottomAnnotationDisplay" ), QStringLiteral( 
"0" ) ).toInt() );
 
  418  mAnnotationFrameDistance = itemElem.attribute( QStringLiteral( 
"frameAnnotationDistance" ), QStringLiteral( 
"0" ) ).toDouble();
 
  420  if ( !itemElem.firstChildElement( 
"text-style" ).isNull() )
 
  422    mAnnotationFormat.
readXml( itemElem, context );
 
  429      font.fromString( itemElem.attribute( 
"annotationFont", QString() ) );
 
  431    mAnnotationFormat.
setFont( font );
 
  432    mAnnotationFormat.
setSize( font.pointSizeF() );
 
  437  mGridAnnotationPrecision = itemElem.attribute( QStringLiteral( 
"annotationPrecision" ), QStringLiteral( 
"3" ) ).toInt();
 
  438  const int gridUnitInt = itemElem.attribute( QStringLiteral( 
"unit" ), QString::number( 
MapUnit ) ).toInt();
 
  440  mMinimumIntervalWidth = itemElem.attribute( QStringLiteral( 
"minimumIntervalWidth" ), QStringLiteral( 
"50" ) ).toDouble();
 
  441  mMaximumIntervalWidth = itemElem.attribute( QStringLiteral( 
"maximumIntervalWidth" ), QStringLiteral( 
"100" ) ).toDouble();
 
  443  refreshDataDefinedProperties();
 
 
  453  mTransformDirty = 
true;
 
 
  459  return mBlendMode != QPainter::CompositionMode_SourceOver;
 
 
  462QPolygonF QgsLayoutItemMapGrid::scalePolygon( 
const QPolygonF &polygon, 
const double scale )
 const 
  464  const QTransform t = QTransform::fromScale( scale, scale );
 
  465  return t.map( polygon );
 
  468void QgsLayoutItemMapGrid::drawGridCrsTransform( 
QgsRenderContext &context, 
double dotsPerMM, 
bool calculateLinesOnly )
 const 
  470  if ( !
mMap || !mEvaluatedEnabled )
 
  477  if ( mapPolygon != mPrevMapPolygon )
 
  479    mTransformDirty = 
true;
 
  480    mPrevMapPolygon = mapPolygon;
 
  483  if ( mTransformDirty )
 
  485    calculateCrsTransformLines();
 
  489  if ( !calculateLinesOnly )
 
  493      QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
 
  494      for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
 
  498        drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
 
  503      const double maxX = 
mMap->rect().width();
 
  504      const double maxY = 
mMap->rect().height();
 
  506      QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
 
  507      for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
 
  509        const double x = intersectionIt->x();
 
  510        const double y = intersectionIt->y();
 
  514          const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
 
  515          line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
 
  516          line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
 
  517          const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
 
  518          line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
 
  519          line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
 
  522          drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
 
  523          drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
 
  527          drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
 
  534void QgsLayoutItemMapGrid::calculateCrsTransformLines()
 const 
  538  if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
 
  545  xGridLinesCrsTransform( crsBoundingRect, inverseTr );
 
  546  yGridLinesCrsTransform( crsBoundingRect, inverseTr );
 
  553    QList< QgsGeometry > xLines;
 
  554    QList< QgsGeometry > yLines;
 
  555    QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
 
  556    for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
 
  560      for ( 
int i = 0; i < gridIt->line.size(); ++i )
 
  562        line.append( 
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
 
  571    mTransformedIntersections.clear();
 
  572    QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
 
  573    for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
 
  575      QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
 
  576      for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
 
  580        if ( intersects.
isNull() )
 
  588          mTransformedIntersections << vertex;
 
  596  mTransformDirty = 
false;
 
  601  if ( !
mMap || !mEvaluatedEnabled )
 
  605  QPaintDevice *paintDevice = p->device();
 
  612  p->setCompositionMode( mBlendMode );
 
  615  const QRectF thisPaintRect = QRectF( 0, 0, 
mMap->rect().width(), 
mMap->rect().height() );
 
  616  p->setClipRect( thisPaintRect );
 
  617  if ( thisPaintRect != mPrevPaintRect )
 
  620    mTransformDirty = 
true;
 
  621    mPrevPaintRect = thisPaintRect;
 
  625  const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
 
  626  p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); 
 
  643        drawGridCrsTransform( context, dotsPerMM );
 
  650      drawGridNoTransform( context, dotsPerMM );
 
  655  p->setClipping( 
false );
 
  659  p->setClipRect( 
mMap->mapRectFromScene( 
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
 
  664    updateGridLinesAnnotationsPositions();
 
  671  if ( mShowGridAnnotation )
 
 
  677void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
 const 
  679  QList< GridLine >::iterator it = mGridLines.begin();
 
  680  for ( ; it != mGridLines.end(); ++it )
 
  682    it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
 
  683    it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
 
  684    it->startAnnotation.position = QVector2D( it->line.first() );
 
  685    it->endAnnotation.position = QVector2D( it->line.last() );
 
  686    it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
 
  687    it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
 
  689    it->startAnnotation.angle = atan2( it->startAnnotation.vector.x() * normS.y() - it->startAnnotation.vector.y() * normS.x(), it->startAnnotation.vector.x() * normS.x() + it->startAnnotation.vector.y() * normS.y() );
 
  691    it->endAnnotation.angle = atan2( it->endAnnotation.vector.x() * normE.y() - it->endAnnotation.vector.y() * normE.x(), it->endAnnotation.vector.x() * normE.x() + it->endAnnotation.vector.y() * normE.y() );
 
  695void QgsLayoutItemMapGrid::drawGridNoTransform( 
QgsRenderContext &context, 
double dotsPerMM, 
bool calculateLinesOnly )
 const 
  702  if ( calculateLinesOnly )
 
  705  QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
 
  706  QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
 
  714    for ( ; vIt != mGridLines.constEnd(); ++vIt )
 
  718      line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
 
  723      drawGridLine( line, context );
 
  726    for ( ; hIt != mGridLines.constEnd(); ++hIt )
 
  730      line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
 
  735      drawGridLine( line, context );
 
  741    QPointF intersectionPoint, crossEnd1, crossEnd2;
 
  742    for ( ; vIt != mGridLines.constEnd(); ++vIt )
 
  747      l1 = QLineF( vIt->line.first(), vIt->line.last() );
 
  750      hIt = mGridLines.constBegin();
 
  751      for ( ; hIt != mGridLines.constEnd(); ++hIt )
 
  756        l2 = QLineF( hIt->line.first(), hIt->line.last() );
 
  758        if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
 
  763            crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
 
  765            crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
 
  768            drawGridLine( QLineF( crossEnd1  * dotsPerMM, crossEnd2  * dotsPerMM ), context );
 
  772            drawGridMarker( intersectionPoint * dotsPerMM, context );
 
  784    hIt = mGridLines.constBegin();
 
  785    for ( ; hIt != mGridLines.constEnd(); ++hIt )
 
  790      l1 = QLineF( hIt->line.first(), hIt->line.last() );
 
  792      vIt = mGridLines.constBegin();
 
  793      for ( ; vIt != mGridLines.constEnd(); ++vIt )
 
  798        l2 = QLineF( vIt->line.first(), vIt->line.last() );
 
  800        if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
 
  803          crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
 
  805          crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 )  ?
 
  808          drawGridLine( QLineF( crossEnd1  * dotsPerMM, crossEnd2  * dotsPerMM ), context );
 
  815void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
 const 
  824  switch ( mGridFrameStyle )
 
  828      drawGridFrameZebra( p, extension );
 
  833      drawGridFrameTicks( p, extension );
 
  838      drawGridFrameLine( p, extension );
 
  849void QgsLayoutItemMapGrid::drawGridLine( 
const QLineF &line, 
QgsRenderContext &context )
 const 
  852  poly << line.p1() << line.p2();
 
  853  drawGridLine( poly, context );
 
  856void QgsLayoutItemMapGrid::drawGridLine( 
const QPolygonF &line, 
QgsRenderContext &context )
 const 
  863  mGridLineSymbol->startRender( context );
 
  864  mGridLineSymbol->renderPolyline( line, 
nullptr, context );
 
  865  mGridLineSymbol->stopRender( context );
 
  868void QgsLayoutItemMapGrid::drawGridMarker( QPointF point, 
QgsRenderContext &context )
 const 
  875  mGridMarkerSymbol->startRender( context );
 
  876  mGridMarkerSymbol->renderPoint( point, 
nullptr, context );
 
  877  mGridMarkerSymbol->stopRender( context );
 
  880void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
 const 
  900void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border, 
double *extension )
 const 
  909    *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
 
  913  double currentCoord = 0.0;
 
  920  bool drawTLBox = 
false;
 
  921  bool drawTRBox = 
false;
 
  922  bool drawBLBox = 
false;
 
  923  bool drawBRBox = 
false;
 
  925  QMap< double, double > pos = QMap< double, double >();
 
  926  QList< GridLine >::const_iterator it = mGridLines.constBegin();
 
  927  for ( ; it != mGridLines.constEnd(); ++it )
 
  930    for ( 
int i = 0 ; i < 2 ; ++i )
 
  932      const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
 
  935      if ( annot.border != border )
 
  938      if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
 
  942        pos.insert( annot.position.y(), it->coordinate );
 
  944        pos.insert( annot.position.x(), it->coordinate );
 
  951    pos.insert( 
mMap->rect().height(), 
mMap->rect().height() );
 
  967    pos.insert( 
mMap->rect().width(), 
mMap->rect().width() );
 
  971  QPen framePen = QPen( mGridFramePenColor );
 
  972  framePen.setWidthF( mEvaluatedGridFrameLineThickness );
 
  973  framePen.setJoinStyle( Qt::MiterJoin );
 
  974  p->setPen( framePen );
 
  976  QMap< double, double >::const_iterator posIt = pos.constBegin();
 
  977  for ( ; posIt != pos.constEnd(); ++posIt )
 
  979    p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
 
  982      height = posIt.key() - currentCoord;
 
  983      width = mEvaluatedGridFrameWidth;
 
  984      x = ( border == 
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) : 
mMap->rect().width() + mEvaluatedGridFrameMargin;
 
  989      height = mEvaluatedGridFrameWidth;
 
  990      width = posIt.key() - currentCoord;
 
  992      y = ( border == 
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) : 
mMap->rect().height() + mEvaluatedGridFrameMargin;
 
  994    p->drawRect( QRectF( x, y, width, height ) );
 
  995    currentCoord = posIt.key();
 
 1002    width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
 
 1003    p->setBrush( QBrush( mGridFrameFillColor1 ) );
 
 1005      p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
 
 1007      p->drawRect( QRectF( 
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
 
 1009      p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), 
mMap->rect().height(), width, height ) );
 
 1011      p->drawRect( QRectF( 
mMap->rect().width(), 
mMap->rect().height(), width, height ) );
 
 1015void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
 const 
 1025    QPen framePen = QPen( mGridFramePenColor );
 
 1026    framePen.setWidthF( mEvaluatedGridFrameLineThickness );
 
 1027    framePen.setCapStyle( Qt::FlatCap );
 
 1028    p->setBrush( Qt::NoBrush );
 
 1029    p->setPen( framePen );
 
 1032  QList< GridLine >::iterator it = mGridLines.begin();
 
 1033  for ( ; it != mGridLines.end(); ++it )
 
 1036    for ( 
int i = 0 ; i < 2 ; ++i )
 
 1038      const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
 
 1040      if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
 
 1044      if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
 
 1052        facingLeft = ( annot.angle != 0 );
 
 1053        facingRight = ( annot.angle != 0 );
 
 1057        facingLeft = ( annot.angle > 0 );
 
 1058        facingRight = ( annot.angle < 0 );
 
 1062        facingLeft = ( annot.angle < 0 );
 
 1063        facingRight = ( annot.angle > 0 );
 
 1066      if ( annot.border == 
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
 
 1067           ( facingRight && annot.position.x() > 
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
 
 1069      if ( annot.border == 
BorderSide::Bottom && ( ( facingLeft && annot.position.x() > 
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
 
 1070           ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
 
 1072      if ( annot.border == 
BorderSide::Left && ( ( facingLeft && annot.position.y() > 
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
 
 1073           ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
 
 1075      if ( annot.border == 
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
 
 1076           ( facingRight && annot.position.y() > 
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
 
 1080      const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
 
 1082      double fA = mEvaluatedGridFrameMargin; 
 
 1083      double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth; 
 
 1085      if ( mRotatedTicksEnabled && mRotatedTicksLengthMode == 
OrthogonalTicks )
 
 1087        fA /= QVector2D::dotProduct( vector, normalVector );
 
 1088        fB /= QVector2D::dotProduct( vector, normalVector );
 
 1095          extension->UpdateBorder( annot.border, fB );
 
 1103        pA = annot.position + fA * vector;
 
 1104        pB = annot.position + fB * vector;
 
 1108        pA = annot.position - fA * vector;
 
 1109        pB = annot.position - fB * vector;
 
 1113        pA = annot.position - fB * vector;
 
 1114        pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
 
 1116      p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
 
 1122void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
 const 
 1132    QPen framePen = QPen( mGridFramePenColor );
 
 1133    framePen.setWidthF( mEvaluatedGridFrameLineThickness );
 
 1134    framePen.setCapStyle( Qt::SquareCap );
 
 1135    p->setBrush( Qt::NoBrush );
 
 1136    p->setPen( framePen );
 
 1146      p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
 
 1154      p->drawLine( QLineF( 
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 
mMap->rect().width() + mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
 
 1160      extension->UpdateBorder( 
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
 
 1162      p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
 
 1170      p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin, 
mMap->rect().width() + mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
 
 1173  if ( ! extension && drawDiagonals )
 
 1178      const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
 
 1179      const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
 
 1180      p->drawLine( QLineF( 0, 0, X1, Y1 ) );
 
 1185      const double X1 = 
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1186      const double Y1 = 
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1187      p->drawLine( QLineF( 
mMap->rect().width(), 
mMap->rect().height(), X1, Y1 ) );
 
 1192      const double X1 = 
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1193      const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1194      p->drawLine( QLineF( 
mMap->rect().width(), 0, X1, Y1 ) );
 
 1199      const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1200      const double Y1 = 
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1201      p->drawLine( QLineF( 0, 
mMap->rect().height(), X1, Y1 ) );
 
 1207    GridExtension *extension )
 const 
 1209  QString currentAnnotationString;
 
 1210  QList< GridLine >::const_iterator it = mGridLines.constBegin();
 
 1211  for ( ; it != mGridLines.constEnd(); ++it )
 
 1213    currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
 
 1214    drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
 
 1215    drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
 
 1219void QgsLayoutItemMapGrid::drawCoordinateAnnotation( 
QgsRenderContext &context, GridLineAnnotation annot, 
const QString &annotationString, 
const AnnotationCoordinate coordinateType, GridExtension *extension )
 const 
 1226  if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
 
 1236                              : ( 
QgsTextRenderer::textHeight( context, mAnnotationFormat, 
'0', false ) ) ) / context.convertToPainterUnits( 1, 
Qgis::RenderUnit::Millimeters );
 
 1238  double xpos = annot.position.x();
 
 1239  double ypos = annot.position.y();
 
 1240  QPointF anchor = QPointF();
 
 1247  if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
 
 1251  const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
 
 1254  double f = mEvaluatedAnnotationFrameDistance;
 
 1262    f += mEvaluatedGridFrameWidth;
 
 1263  if ( hasBorderWidth )
 
 1264    f += mEvaluatedGridFrameLineThickness / 2.0;
 
 1269  if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode == 
OrthogonalTicks )
 
 1271    f /= QVector2D::dotProduct( vector, normalVector );
 
 1274  const QVector2D pos = annot.position + f * vector;
 
 1287    rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
 
 1289    if ( rotation <= -90 || rotation > 90 )
 
 1292      anchor.setX( outside ? 0 : textWidth ); 
 
 1296      anchor.setX( outside ? textWidth : 0 ); 
 
 1300      anchor.setY( 0.5 * textHeight ); 
 
 1302      anchor.setY( -1.5 * textHeight ); 
 
 1304      anchor.setY( -0.5 * textHeight ); 
 
 1310    anchor.setX( 0.5 * textWidth ); 
 
 1311    anchor.setY( -0.5 * textHeight ); 
 
 1313      anchor.setY( outside ? 0 : -textHeight ); 
 
 1315      anchor.setX( outside ? 0 : textWidth ); 
 
 1317      anchor.setY( outside ? -textHeight : 0 ); 
 
 1319      anchor.setX( outside ? textWidth : 0 ); 
 
 1324    anchor.setX( 0.5 * textWidth ); 
 
 1325    anchor.setY( -0.5 * textHeight ); 
 
 1327      anchor.setX( outside ? 0 : textWidth ); 
 
 1329      anchor.setY( outside ? -textHeight : 0 ); 
 
 1331      anchor.setX( outside ? textWidth : 0 ); 
 
 1333      anchor.setY( outside ? 0 : -textHeight ); 
 
 1338    anchor.setX( 0.5 * textWidth ); 
 
 1339    anchor.setY( -0.5 * textHeight ); 
 
 1341      anchor.setX( outside ? textWidth : 0 ); 
 
 1343      anchor.setY( outside ? 0 : -textHeight ); 
 
 1345      anchor.setX( outside ? 0 : textWidth ); 
 
 1347      anchor.setY( outside ? -textHeight : 0 ); 
 
 1352    rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
 
 1353    anchor.setX( 0.5 * textWidth ); 
 
 1355      anchor.setY( -textHeight ); 
 
 1363    extension->UpdateBorder( frameBorder, -f + textWidth );
 
 1365    extension->UpdateAll( textWidth / 2.0 );
 
 1368  if ( extension || !context.
painter() )
 
 1372  bool facingLeft = ( annot.angle < 0 );
 
 1373  bool facingRight = ( annot.angle > 0 );
 
 1376    facingLeft = !facingLeft;
 
 1377    facingRight = !facingRight;
 
 1379  if ( annot.border == 
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
 
 1380       ( facingRight && annot.position.x() > 
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
 
 1382  if ( annot.border == 
BorderSide::Bottom && ( ( facingLeft && annot.position.x() > 
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
 
 1383       ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
 
 1385  if ( annot.border == 
BorderSide::Left && ( ( facingLeft && annot.position.y() > 
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
 
 1386       ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
 
 1388  if ( annot.border == 
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
 
 1389       ( facingRight && annot.position.y() > 
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
 
 1393  context.
painter()->translate( QPointF( xpos, ypos ) );
 
 1394  context.
painter()->rotate( rotation );
 
 1395  context.
painter()->translate( -anchor );
 
 1403  bool geographic = 
false;
 
 1417    const double wrappedX = std::fmod( value, 360.0 );
 
 1418    if ( wrappedX > 180.0 )
 
 1420      value = wrappedX - 360.0;
 
 1422    else if ( wrappedX < -180.0 )
 
 1424      value = wrappedX + 360.0;
 
 1430    return QString::number( value, 
'f', mGridAnnotationPrecision );
 
 1436    const double coordRounded = 
qgsRound( value, mGridAnnotationPrecision );
 
 1440      if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
 
 1442        hemisphere = value < 0 ? QObject::tr( 
"W" ) : QObject::tr( 
"E" );
 
 1448      if ( !geographic || coordRounded != 0.0 )
 
 1450        hemisphere = value < 0 ? QObject::tr( 
"S" ) : QObject::tr( 
"N" );
 
 1456      return QString::number( std::fabs( value ), 
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
 
 1460      return QString::number( std::fabs( value ), 
'f', mGridAnnotationPrecision ) + hemisphere;
 
 1467    if ( !mGridAnnotationExpression )
 
 1469      mGridAnnotationExpression.reset( 
new QgsExpression( mGridAnnotationExpressionString ) );
 
 1470      mGridAnnotationExpression->prepare( &expressionContext );
 
 1472    return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
 
 1477  switch ( mGridAnnotationFormat )
 
 1527int QgsLayoutItemMapGrid::xGridLines()
 const 
 1529  if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
 
 1536  QRectF mapBoundingRect = mapPolygon.boundingRect();
 
 1537  double gridIntervalY = mEvaluatedIntervalY;
 
 1538  double gridOffsetY = mEvaluatedOffsetY;
 
 1539  double annotationScale = 1.0;
 
 1540  switch ( mGridUnit )
 
 1545      mapBoundingRect = 
mMap->rect();
 
 1546      mapPolygon = QPolygonF( 
mMap->rect() );
 
 1547      if ( mGridUnit == 
CM )
 
 1549        annotationScale = 0.1;
 
 1550        gridIntervalY *= 10;
 
 1562  const double roundCorrection = mapBoundingRect.top() > gridOffsetY ? 1.0 : 0.0;
 
 1563  double currentLevel = 
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
 
 1565  int gridLineCount = 0;
 
 1570    double yCanvasCoord;
 
 1571    while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < 
MAX_GRID_LINES )
 
 1573      yCanvasCoord = 
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
 
 1575      newLine.coordinate = currentLevel * annotationScale;
 
 1577      newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF( 
mMap->rect().width(), yCanvasCoord );
 
 1578      mGridLines.append( newLine );
 
 1579      currentLevel += gridIntervalY;
 
 1586  QVector<QLineF> borderLines;
 
 1587  borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
 
 1588  borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
 
 1589  borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
 
 1590  borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
 
 1592  QVector<QPointF> intersectionList; 
 
 1594  while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < 
MAX_GRID_LINES )
 
 1596    intersectionList.clear();
 
 1597    const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
 
 1599    QVector<QLineF>::const_iterator it = borderLines.constBegin();
 
 1600    for ( ; it != borderLines.constEnd(); ++it )
 
 1602      QPointF intersectionPoint;
 
 1603      if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
 
 1605        intersectionList.push_back( intersectionPoint );
 
 1606        if ( intersectionList.size() >= 2 )
 
 1613    if ( intersectionList.size() >= 2 )
 
 1616      newLine.coordinate = currentLevel;
 
 1619      mGridLines.append( newLine );
 
 1622    currentLevel += gridIntervalY;
 
 1629int QgsLayoutItemMapGrid::yGridLines()
 const 
 1631  if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
 
 1637  QRectF mapBoundingRect = mapPolygon.boundingRect();
 
 1638  double gridIntervalX = mEvaluatedIntervalX;
 
 1639  double gridOffsetX = mEvaluatedOffsetX;
 
 1640  double annotationScale = 1.0;
 
 1641  switch ( mGridUnit )
 
 1646      mapBoundingRect = 
mMap->rect();
 
 1647      mapPolygon = QPolygonF( 
mMap->rect() );
 
 1648      if ( mGridUnit == 
CM )
 
 1650        annotationScale = 0.1;
 
 1651        gridIntervalX *= 10;
 
 1663  const double roundCorrection = mapBoundingRect.left() > gridOffsetX ? 1.0 : 0.0;
 
 1664  double currentLevel = 
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
 
 1666  int gridLineCount = 0;
 
 1670    double xCanvasCoord;
 
 1671    while ( currentLevel <= mapBoundingRect.right() && gridLineCount < 
MAX_GRID_LINES )
 
 1673      xCanvasCoord = 
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
 
 1676      newLine.coordinate = currentLevel * annotationScale;
 
 1678      newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord, 
mMap->rect().height() );
 
 1679      mGridLines.append( newLine );
 
 1680      currentLevel += gridIntervalX;
 
 1687  QVector<QLineF> borderLines;
 
 1688  borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
 
 1689  borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
 
 1690  borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
 
 1691  borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
 
 1693  QVector<QPointF> intersectionList; 
 
 1695  while ( currentLevel <= mapBoundingRect.right() && gridLineCount < 
MAX_GRID_LINES )
 
 1697    intersectionList.clear();
 
 1698    const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
 
 1700    QVector<QLineF>::const_iterator it = borderLines.constBegin();
 
 1701    for ( ; it != borderLines.constEnd(); ++it )
 
 1703      QPointF intersectionPoint;
 
 1704      if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
 
 1706        intersectionList.push_back( intersectionPoint );
 
 1707        if ( intersectionList.size() >= 2 )
 
 1714    if ( intersectionList.size() >= 2 )
 
 1717      newLine.coordinate = currentLevel;
 
 1720      mGridLines.append( newLine );
 
 1723    currentLevel += gridIntervalX;
 
 1731  if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
 
 1736  const double roundCorrection = bbox.
yMaximum() > mEvaluatedOffsetY ? 1.0 : 0.0;
 
 1737  double currentLevel = 
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
 
 1739  const double minX = bbox.
xMinimum();
 
 1740  const double maxX = bbox.
xMaximum();
 
 1741  double step = ( maxX - minX ) / 20;
 
 1743  bool crosses180 = 
false;
 
 1744  bool crossed180 = 
false;
 
 1749    step = ( maxX + 360.0 - minX ) / 20;
 
 1755  int gridLineCount = 0;
 
 1759    double currentX = minX;
 
 1763      if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
 
 1780      if ( crosses180 && currentX > 180.0 )
 
 1788    const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, 
QgsRectangle( 
mMap->rect() ) );
 
 1789    QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
 
 1790    for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
 
 1792      if ( !( *lineIt ).isEmpty() )
 
 1795        newLine.coordinate = currentLevel;
 
 1797        newLine.line = QPolygonF( *lineIt );
 
 1798        mGridLines.append( newLine );
 
 1802    currentLevel -= mEvaluatedIntervalY;
 
 1810  if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
 
 1815  const double roundCorrection = bbox.
xMinimum() > mEvaluatedOffsetX ? 1.0 : 0.0;
 
 1816  double currentLevel = 
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
 
 1818  const double minY = bbox.
yMinimum();
 
 1819  const double maxY = bbox.
yMaximum();
 
 1820  const double step = ( maxY - minY ) / 20;
 
 1825  bool crosses180 = 
false;
 
 1826  bool crossed180 = 
false;
 
 1833  int gridLineCount = 0;
 
 1834  while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount < 
MAX_GRID_LINES )
 
 1837    double currentY = minY;
 
 1841      if ( currentY > maxY )
 
 1861    const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, 
QgsRectangle( 
mMap->rect() ) );
 
 1862    QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
 
 1863    for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
 
 1865      if ( !( *lineIt ).isEmpty() )
 
 1868        newLine.coordinate = currentLevel;
 
 1870        newLine.line = QPolygonF( *lineIt );
 
 1871        mGridLines.append( newLine );
 
 1875    currentLevel += mEvaluatedIntervalX;
 
 1876    if ( crosses180 && currentLevel > 180.0 )
 
 1878      currentLevel -= 360.0;
 
 1907      return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
 
 1909      return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
 
 1911      return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
 
 1913      return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
 
 1927  if ( ddValue.compare( QLatin1String( 
"x_only" ), Qt::CaseInsensitive ) == 0 )
 
 1929  else if ( ddValue.compare( QLatin1String( 
"y_only" ), Qt::CaseInsensitive ) == 0 )
 
 1931  else if ( ddValue.compare( QLatin1String( 
"disabled" ), Qt::CaseInsensitive ) == 0 )
 
 1933  else if ( ddValue.compare( QLatin1String( 
"all" ), Qt::CaseInsensitive ) == 0 )
 
 
 1939void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
 
 1944  mTransformDirty = mTransformDirty
 
 1951  switch ( mGridUnit )
 
 1964      if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
 
 1966        mEvaluatedEnabled = 
false;
 
 1971        const double mapWidthMapUnits = mapWidth();
 
 1972        const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
 
 1973        const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
 
 1975        mEvaluatedIntervalX = interval;
 
 1976        mEvaluatedIntervalY = interval;
 
 1977        mTransformDirty = 
true;
 
 1999double QgsLayoutItemMapGrid::mapWidth()
 const 
 2010    return mapExtent.
width();
 
 2030      QgsDebugError( QStringLiteral( 
"An error occurred while calculating length" ) );
 
 2036bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
 
 2038  return a.first < b.first;
 
 
 2051  if ( ( p.y() <= tolerance && p.x() <= tolerance ) 
 
 2052       || ( p.y() <= tolerance && p.x() >= ( 
mMap->rect().width() - tolerance ) ) 
 
 2053       || ( p.y() >= ( 
mMap->rect().height() - tolerance ) && p.x() <= tolerance ) 
 
 2054       || ( p.y() >= ( 
mMap->rect().height() - tolerance ) && p.x() >= ( 
mMap->rect().width() - tolerance ) ) 
 
 2060      if ( p.x() <= tolerance )
 
 2071      if ( p.y() <= tolerance )
 
 2083  QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
 
 2089  std::sort( distanceToSide.begin(), distanceToSide.end(), 
sortByDistance );
 
 2090  return distanceToSide.at( 0 ).second;
 
 2095  mGridLineSymbol.reset( symbol );
 
 
 2100  return mGridLineSymbol.get();
 
 
 2105  return mGridLineSymbol.get();
 
 
 2110  mGridMarkerSymbol.reset( symbol );
 
 
 2115  return mGridMarkerSymbol.get();
 
 
 2120  return mGridMarkerSymbol.get();
 
 
 2125  mAnnotationFormat.
setFont( font );
 
 2126  if ( font.pointSizeF() > 0 )
 
 2128    mAnnotationFormat.
setSize( font.pointSizeF() );
 
 2131  else if ( font.pixelSize() > 0 )
 
 2133    mAnnotationFormat.
setSize( font.pixelSize() );
 
 
 2140  return mAnnotationFormat.
toQFont();
 
 
 2145  mAnnotationFormat.
setColor( color );
 
 
 2150  return mAnnotationFormat.
color();
 
 
 2158      mLeftGridAnnotationDisplay = display;
 
 2161      mRightGridAnnotationDisplay = display;
 
 2164      mTopGridAnnotationDisplay = display;
 
 2167      mBottomGridAnnotationDisplay = display;
 
 2171  refreshDataDefinedProperties();
 
 
 2185      return mLeftGridAnnotationDisplay;
 
 2187      return mRightGridAnnotationDisplay;
 
 2189      return mTopGridAnnotationDisplay;
 
 2191      return mBottomGridAnnotationDisplay;
 
 2193  return mBottomGridAnnotationDisplay; 
 
 
 2200  double bottom = 0.0;
 
 2203  return std::max( std::max( std::max( top, right ), bottom ), left );
 
 
 2213  if ( !
mMap || !mEvaluatedEnabled )
 
 2223  GridExtension extension;
 
 2226  switch ( mGridUnit )
 
 2233        drawGridCrsTransform( context, 0, 
true );
 
 2240      drawGridNoTransform( context, 0, 
true );
 
 2245    updateGridLinesAnnotationsPositions();
 
 2249    drawGridFrame( 
nullptr, &extension );
 
 2252  if ( mShowGridAnnotation )
 
 2257  top = extension.top;
 
 2258  right = extension.right;
 
 2259  bottom = extension.bottom;
 
 2260  left = extension.left;
 
 
 2266  refreshDataDefinedProperties();
 
 
 2271  if ( unit == mGridUnit )
 
 2276  mTransformDirty = 
true;
 
 
 2285  mGridIntervalX = interval;
 
 2286  mTransformDirty = 
true;
 
 2287  refreshDataDefinedProperties();
 
 
 2296  mGridIntervalY = interval;
 
 2297  mTransformDirty = 
true;
 
 2298  refreshDataDefinedProperties();
 
 
 2307  mGridOffsetX = offset;
 
 2308  mTransformDirty = 
true;
 
 2309  refreshDataDefinedProperties();
 
 
 2318  mGridOffsetY = offset;
 
 2319  mTransformDirty = 
true;
 
 2320  refreshDataDefinedProperties();
 
 
 2329  mMinimumIntervalWidth = minWidth;
 
 2330  mTransformDirty = 
true;
 
 2331  refreshDataDefinedProperties();
 
 
 2340  mMaximumIntervalWidth = maxWidth;
 
 2341  mTransformDirty = 
true;
 
 2342  refreshDataDefinedProperties();
 
 
 2347  if ( 
style == mGridStyle )
 
 2352  mTransformDirty = 
true;
 
 
 2357  mCrossLength = length;
 
 2358  refreshDataDefinedProperties();
 
 
 2366      mLeftGridAnnotationDirection = direction;
 
 2369      mRightGridAnnotationDirection = direction;
 
 2372      mTopGridAnnotationDirection = direction;
 
 2375      mBottomGridAnnotationDirection = direction;
 
 
 2388  mGridFrameSides = flags;
 
 
 2394    mGridFrameSides |= flag;
 
 2396    mGridFrameSides &= ~flag;
 
 
 2401  return mGridFrameSides;
 
 
 2410  context.
setHighlightedVariables( QStringList() << QStringLiteral( 
"grid_number" ) << QStringLiteral( 
"grid_axis" ) );
 
 
 2416  if ( mGridLineSymbol )
 
 2422  if ( mGridMarkerSymbol )
 
 
 2434  mTransformDirty = 
true;
 
 2435  refreshDataDefinedProperties();
 
 
 2442  return mGridFrameSides.testFlag( flag );
 
 
 2447  mGridFrameWidth = width;
 
 2448  refreshDataDefinedProperties();
 
 
 2453  mGridFrameMargin = margin;
 
 2454  refreshDataDefinedProperties();
 
 
 2459  mGridFramePenThickness = width;
 
 2460  refreshDataDefinedProperties();
 
 
 2465  mLeftGridAnnotationDirection = direction;
 
 2466  mRightGridAnnotationDirection = direction;
 
 2467  mTopGridAnnotationDirection = direction;
 
 2468  mBottomGridAnnotationDirection = direction;
 
 
 2476      mLeftGridAnnotationPosition = position;
 
 2479      mRightGridAnnotationPosition = position;
 
 2482      mTopGridAnnotationPosition = position;
 
 2485      mBottomGridAnnotationPosition = position;
 
 
 2501      return mLeftGridAnnotationPosition;
 
 2503      return mRightGridAnnotationPosition;
 
 2505      return mTopGridAnnotationPosition;
 
 2507      return mBottomGridAnnotationPosition;
 
 2509  return mLeftGridAnnotationPosition; 
 
 
 2514  mAnnotationFrameDistance = distance;
 
 2515  refreshDataDefinedProperties();
 
 
 2522    return mLeftGridAnnotationDirection;
 
 2528      return mLeftGridAnnotationDirection;
 
 2530      return mRightGridAnnotationDirection;
 
 2532      return mTopGridAnnotationDirection;
 
 2534      return mBottomGridAnnotationDirection;
 
 2536  return mLeftGridAnnotationDirection; 
 
 
 2541  mGridAnnotationExpressionString = expression;
 
 2542  mGridAnnotationExpression.reset();
 
 
 2550      mLeftFrameDivisions = divisions;
 
 2553      mRightFrameDivisions = divisions;
 
 2556      mTopFrameDivisions = divisions;
 
 2559      mBottomFrameDivisions = divisions;
 
 2563  refreshDataDefinedProperties();
 
 
 2576      return mLeftFrameDivisions;
 
 2578      return mRightFrameDivisions;
 
 2580      return mTopFrameDivisions;
 
 2582      return mBottomFrameDivisions;
 
 2584  return mLeftFrameDivisions; 
 
 
 2600    const QRectF mbr = mapPolygon.boundingRect();
 
 2601    const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
 
 2607      QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
 
 2608      QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
 
 2610      lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
 
 2611      upperRight = tr.transform( upperRight.x(), upperRight.y() );
 
 2613      if ( lowerLeft.x() > upperRight.x() )
 
 2640QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap( 
const QPolygonF &line, 
const QgsRectangle &rect )
 
 2648  QList<QPolygonF> trimmedLines;
 
 2649  QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
 
 2650  for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
 
 2652    trimmedLines << ( *geomIt ).asQPolygonF();
 
 2654  return trimmedLines;
 
 2729  refreshDataDefinedProperties();
 
 
Provides global constants and enumerations for use throughout the application.
 
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
 
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
 
@ Millimeters
Millimeters.
 
DistanceUnit
Units of distance.
 
@ Unknown
Unknown distance unit.
 
@ Millimeters
Millimeters.
 
@ Points
Points (e.g., for font sizes)
 
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
 
@ Forward
Forward transform (from source to destination)
 
@ Antialiasing
Use antialiasing when drawing items.
 
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
 
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
 
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
 
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
 
static QString colorToString(const QColor &color)
Encodes a color into a string value.
 
Represents a coordinate reference system (CRS).
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
 
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
 
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
 
Qgis::DistanceUnit mapUnits
 
Custom exception class for Coordinate Reference System related exceptions.
 
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
 
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
 
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
 
Qgis::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
 
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
 
Single scope for storing variables and functions for use within a QgsExpressionContext.
 
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
 
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
 
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
 
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
 
Handles parsing and evaluation of expressions (formerly called "search strings").
 
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
 
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
 
A geometry is the spatial representation of a feature.
 
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
 
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
 
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
 
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
 
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
 
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
 
QList< QgsLayoutItemMapGrid * > asList() const
Returns a list of QgsLayoutItemMapGrids contained by the stack.
 
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
 
void removeGrid(const QString &gridId)
Removes a grid with matching gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid...
 
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
 
void addGrid(QgsLayoutItemMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
 
QgsLayoutItemMapGrid * grid(const QString &gridId) const
Returns a reference to a grid with matching gridId within the stack.
 
bool readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the item stack's state from a DOM document, where element is a DOM node corresponding to a 'Layo...
 
QgsLayoutItemMapGrid & operator[](int index)
Returns a reference to a grid at the specified index within the stack.
 
void moveGridUp(const QString &gridId)
Moves a grid with matching gridId up the stack, causing it to be rendered above other grids.
 
void moveGridDown(const QString &gridId)
Moves a grid with matching gridId down the stack, causing it to be rendered below other grids.
 
QgsLayoutItemMapGridStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGridStack, attached to the specified map.
 
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
 
void setFrameSideFlags(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
 
bool rotatedAnnotationsEnabled() const
Gets whether annotations rotation for rotated or reprojected grids is enabled.
 
QString annotationExpression() const
Returns the expression used for drawing grid annotations.
 
double rotatedTicksMarginToCorner() const
Gets the margin to corners (in canvas units) below which outwards facing ticks are not drawn.
 
GridStyle
Grid drawing style.
 
@ Markers
Draw markers at intersections of grid lines.
 
@ Cross
Draw line crosses at intersections of grid lines.
 
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
 
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
 
void setFrameFillColor2(const QColor &color)
Sets the second fill color used for the grid frame.
 
GridUnit
Unit for grid values.
 
@ CM
Grid units in centimeters.
 
@ MM
Grid units in millimeters.
 
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
 
@ MapUnit
Grid units follow map units.
 
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
 
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
 
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
 
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
 
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
 
@ FrameTop
Top side of map.
 
@ FrameBottom
Bottom side of map.
 
@ FrameLeft
Left side of map.
 
@ FrameRight
Right side of map.
 
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
 
void setAnnotationFormat(const AnnotationFormat format)
Sets the format for drawing grid annotations.
 
double frameWidth() const
Gets the grid frame width in layout units.
 
void draw(QPainter *painter) override
Draws the item on to a destination painter.
 
double crossLength() const
Retrieves the length (in layout units) of the cross segments drawn for the grid.
 
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
 
void setRotatedTicksMinimumAngle(const double angle)
Sets the minimum angle (in degrees) below which ticks are not drawn.
 
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
 
QPainter::CompositionMode blendMode() const
Retrieves the blending mode used for drawing the grid.
 
void setAnnotationEnabled(const bool enabled)
Sets whether annotations should be shown for the grid.
 
QgsTextFormat annotationTextFormat() const
Returns the text format used when rendering grid annotations.
 
AnnotationFormat annotationFormat() const
Returns the format for drawing grid annotations.
 
double framePenSize() const
Retrieves the width of the stroke drawn in the grid frame.
 
void setFramePenColor(const QColor &color)
Sets the color of the stroke drawn in the grid frame.
 
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
 
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
 
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
 
void setRotatedTicksEnabled(const bool state)
Enable/disable ticks rotation for rotated or reprojected grids.
 
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
 
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
 
AnnotationPosition
Position for grid annotations.
 
@ InsideMapFrame
Draw annotations inside the map frame.
 
@ OutsideMapFrame
Draw annotations outside the map frame.
 
TickLengthMode rotatedAnnotationsLengthMode() const
Returns the annotation length calculation mode.
 
double rotatedTicksMinimumAngle() const
Gets the minimum angle (in degrees) below which ticks are not drawn.
 
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
 
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
 
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
 
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
 
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
 
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
 
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
 
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
 
AnnotationCoordinate
Annotation coordinate type.
 
@ Latitude
Coordinate is a latitude value.
 
@ Longitude
Coordinate is a longitude value.
 
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
 
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
 
void setRotatedTicksLengthMode(const TickLengthMode mode)
Sets the tick length calculation mode.
 
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
 
DisplayMode
Display settings for grid annotations and frames.
 
@ LongitudeOnly
Show longitude/x annotations/divisions only.
 
@ ShowAll
Show both latitude and longitude annotations/divisions.
 
@ LatitudeOnly
Show latitude/y annotations/divisions only.
 
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
 
void crsChanged()
Emitted whenever the grid's CRS is changed.
 
void setRotatedAnnotationsMinimumAngle(const double angle)
Sets the minimum angle (in degrees) below which annotations are not drawn.
 
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
 
double rotatedAnnotationsMinimumAngle() const
Gets the minimum angle (in degrees) below which annotations are not drawn.
 
void setAnnotationTextFormat(const QgsTextFormat &format)
Sets the text format to use when rendering grid annotations.
 
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
 
~QgsLayoutItemMapGrid() override
 
void copyProperties(const QgsLayoutItemMapGrid *other)
Copies properties from specified map grid.
 
void setBlendMode(const QPainter::CompositionMode mode)
Sets the blending mode used for drawing the grid.
 
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
 
bool annotationEnabled() const
Returns whether annotations are shown for the grid.
 
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
 
void setFrameStyle(const FrameStyle style)
Sets the grid frame style.
 
QFlags< FrameSideFlag > FrameSideFlags
 
QColor framePenColor() const
Retrieves the color of the stroke drawn in the grid frame.
 
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
 
FrameStyle frameStyle() const
Returns the grid frame style.
 
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
 
void setRotatedTicksMarginToCorner(const double margin)
Sets the margin to corners (in canvas units) below which outwards facing ticks are not drawn.
 
void setAnnotationPrecision(const int precision)
Sets the coordinate precision for grid annotations.
 
QColor frameFillColor2() const
Retrieves the second fill color for the grid frame.
 
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
 
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
 
void setRotatedAnnotationsMarginToCorner(const double margin)
Sets the margin to corners (in canvas units) below which outwards facing annotations are not drawn.
 
double rotatedAnnotationsMarginToCorner() const
Gets the margin to corners (in canvas units) below which outwards facing annotations are not drawn.
 
void setRotatedAnnotationsLengthMode(const TickLengthMode mode)
Sets the annotation length calculation mode.
 
TickLengthMode
Tick length mode (useful for rotated grids)
 
@ OrthogonalTicks
Align ticks orthogonaly.
 
double offsetX() const
Returns the offset for grid lines in the x-direction.
 
bool rotatedTicksEnabled() const
Gets whether ticks rotation for rotated or reprojected grids is enabled.
 
AnnotationFormat
Format for displaying grid annotations.
 
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
 
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
 
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
 
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
 
@ DegreeMinute
Degree/minutes, use NSEW suffix.
 
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
 
@ Decimal
Decimal degrees, use - for S/W coordinates.
 
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
 
@ CustomFormat
Custom expression-based format.
 
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
 
AnnotationDirection
Direction of grid annotations.
 
@ OnTick
Draw annotations parallel to tick (on the line)
 
@ Horizontal
Draw annotations horizontally.
 
@ Vertical
Draw annotations vertically, ascending.
 
@ AboveTick
Draw annotations parallel to tick (above the line)
 
@ UnderTick
Draw annotations parallel to tick (under the line)
 
@ VerticalDescending
Draw annotations vertically, descending.
 
double annotationFrameDistance() const
Returns the distance between the map frame and annotations.
 
double intervalY() const
Returns the interval between grid lines in the y-direction.
 
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
 
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
 
double minimumIntervalWidth() const
Returns the minimum width (in millimeters) for grid segments.
 
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
 
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
 
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
 
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
 
QColor frameFillColor1() const
Retrieves the first fill color for the grid frame.
 
void setRotatedAnnotationsEnabled(const bool state)
Enable/disable annotations rotation for rotated or reprojected grids.
 
FrameStyle
Style for grid frame.
 
@ Zebra
Black/white pattern.
 
@ InteriorTicks
Tick markers drawn inside map frame.
 
@ LineBorder
Simple solid line frame.
 
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
 
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
 
@ ExteriorTicks
Tick markers drawn outside map frame.
 
@ NoFrame
Disable grid frame.
 
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
 
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
 
void setFrameFillColor1(const QColor &color)
Sets the first fill color used for the grid frame.
 
double frameMargin() const
Sets the grid frame Margin (in layout units).
 
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
 
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
 
BorderSide
Border sides for annotations.
 
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
 
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
 
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
 
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
 
int annotationPrecision() const
Returns the coordinate precision for grid annotations, which is the number of decimal places shown wh...
 
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
 
double maximumIntervalWidth() const
Returns the maximum width (in millimeters) for grid segments.
 
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
 
TickLengthMode rotatedTicksLengthMode() const
Returns the grid frame style.
 
double intervalX() const
Returns the interval between grid lines in the x-direction.
 
A collection of map items which are drawn above the map content in a QgsLayoutItemMap.
 
void addItem(QgsLayoutItemMapItem *item)
Adds a new map item to the stack and takes ownership of the item.
 
void removeItem(const QString &itemId)
Removes an item which matching itemId from the stack and deletes the corresponding QgsLayoutItemMapIt...
 
QgsLayoutItemMapItem * item(int index) const
Returns a reference to the item at the specified index within the stack.
 
void moveItemUp(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
 
void removeItems()
Clears the item stack and deletes all QgsLayoutItemMapItems contained by the stack.
 
QList< QgsLayoutItemMapItem * > mItems
 
void moveItemDown(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
 
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
 
QgsLayoutItemMap * mMap
Associated map.
 
virtual bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
 
virtual bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
 
virtual void setEnabled(bool enabled)
Controls whether the item will be drawn.
 
bool enabled() const
Returns whether the item will be drawn.
 
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
 
Layout graphical items for displaying a map.
 
void extentChanged()
Emitted when the map's extent changes.
 
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
 
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
 
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
 
void crsChanged()
Emitted when the map's coordinate reference system is changed.
 
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
 
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
 
QgsRectangle extent() const
Returns the current map extent.
 
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
 
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
 
bool frameEnabled() const
Returns true if the item includes a frame.
 
QgsPropertyCollection mDataDefinedProperties
 
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
 
const QgsLayout * layout() const
Returns the layout the object is attached to.
 
QPointer< QgsLayout > mLayout
 
@ MapGridOffsetY
Map grid offset Y.
 
@ MapGridFrameDivisionsBottom
Map frame division display bottom.
 
@ MapGridEnabled
Map grid enabled.
 
@ MapGridIntervalX
Map grid interval X.
 
@ MapGridFrameDivisionsTop
Map frame division display top.
 
@ MapGridAnnotationDisplayLeft
Map annotation display left.
 
@ MapGridFrameMargin
Map grid frame margin.
 
@ MapGridCrossSize
Map grid cross size.
 
@ MapGridAnnotationDisplayRight
Map annotation display right.
 
@ MapGridOffsetX
Map grid offset X.
 
@ MapGridAnnotationDisplayTop
Map annotation display top.
 
@ MapGridAnnotationDisplayBottom
Map annotation display bottom.
 
@ MapGridFrameDivisionsRight
Map frame division display right.
 
@ MapGridLabelDistance
Map grid label distance.
 
@ MapGridIntervalY
Map grid interval Y.
 
@ MapGridFrameSize
Map grid frame size.
 
@ MapGridFrameLineThickness
Map grid frame line thickness.
 
@ MapGridFrameDivisionsLeft
Map frame division display left.
 
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the objects's property collection, used for data defined overrides.
 
Qgis::LayoutRenderFlags flags() const
Returns the current combination of flags used for rendering the layout.
 
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
 
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
 
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
 
A line symbol type, for rendering LineString and MultiLineString geometries.
 
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
 
static std::unique_ptr< QgsLineSymbol > createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
 
A marker symbol type, for rendering Point and MultiPoint geometries.
 
static std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
 
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
 
bool isEmpty() const
Returns true if the geometry is empty.
 
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
 
A container for the context for various read/write operations on objects.
 
A rectangle specified with double values.
 
Contains information about the context of a rendering operation.
 
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
 
QPainter * painter()
Returns the destination QPainter for the render operation.
 
QgsExpressionContext & expressionContext()
Gets the expression context.
 
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
 
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
 
Qgis::RasterizedRenderingPolicy rasterizedRenderingPolicy() const
Returns the policy controlling when rasterisation of content during renders is permitted.
 
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
 
Scoped object for saving and restoring a QPainter object's state.
 
Scoped object for temporary scaling of a QgsRenderContext for pixel based rendering.
 
Stores settings for use within QGIS.
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
An interface for classes which can visit style entity (e.g.
 
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
 
A symbol entity for QgsStyle databases.
 
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
 
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
 
void setColor(const QColor &color)
Sets the color that text will be rendered in.
 
void setSize(double size)
Sets the size for rendered text.
 
void setFont(const QFont &font)
Sets the font used for rendering text.
 
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
 
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
 
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
 
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
 
QColor color() const
Returns the color that text will be rendered in.
 
Handles rendering text using rich formatting options, including drop shadows, buffers and background ...
 
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
 
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
 
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
 
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
 
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
 
QgsLayoutItemMapGrid::DisplayMode gridAnnotationDisplayModeFromDD(QString ddValue, QgsLayoutItemMapGrid::DisplayMode defValue)
 
bool sortByDistance(QPair< qreal, QgsLayoutItemMapGrid::BorderSide > a, QPair< qreal, QgsLayoutItemMapGrid::BorderSide > b)
 
QVector2D borderToNormal2D(QgsLayoutItemMapGrid::BorderSide border)
 
QVector2D borderToVector2D(QgsLayoutItemMapGrid::BorderSide border)
 
#define QgsDebugError(str)
 
const QgsCoordinateReferenceSystem & crs
 
Single variable definition for use within a QgsExpressionContextScope.
 
Contains information relating to the style entity currently being visited.