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() )
 
  198    font.setFamily( defaultFontString );
 
  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() );
 
  346  mGridFrameSides = 
static_cast< QgsLayoutItemMapGrid::FrameSideFlags 
>( itemElem.attribute( QStringLiteral( 
"gridFrameSideFlags" ), QStringLiteral( 
"15" ) ).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();
 
  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.reset( 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.reset( 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() );
 
  433    mAnnotationFormat.
setSizeUnit( Qgis::RenderUnit::Points );
 
  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 )
 
  496        drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
 
  501      const double maxX = 
mMap->rect().width();
 
  502      const double maxY = 
mMap->rect().height();
 
  504      QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
 
  505      for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
 
  507        const double x = intersectionIt->x();
 
  508        const double y = intersectionIt->y();
 
  512          const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
 
  513          line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
 
  514          line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
 
  515          const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
 
  516          line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
 
  517          line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
 
  520          drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
 
  521          drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
 
  525          drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
 
  532void QgsLayoutItemMapGrid::calculateCrsTransformLines()
 const 
  536  if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
 
  543  xGridLinesCrsTransform( crsBoundingRect, inverseTr );
 
  544  yGridLinesCrsTransform( crsBoundingRect, inverseTr );
 
  551    QList< QgsGeometry > xLines;
 
  552    QList< QgsGeometry > yLines;
 
  553    QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
 
  554    for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
 
  558      for ( 
int i = 0; i < gridIt->line.size(); ++i )
 
  560        line.append( 
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
 
  562      if ( gridIt->coordinateType == AnnotationCoordinate::Longitude )
 
  564      else if ( gridIt->coordinateType == AnnotationCoordinate::Latitude )
 
  569    mTransformedIntersections.clear();
 
  570    QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
 
  571    for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
 
  573      QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
 
  574      for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
 
  578        if ( intersects.
isNull() )
 
  586          mTransformedIntersections << vertex;
 
  594  mTransformDirty = 
false;
 
  599  if ( !
mMap || !mEvaluatedEnabled )
 
  603  QPaintDevice *paintDevice = p->device();
 
  610  p->setCompositionMode( mBlendMode );
 
  613  const QRectF thisPaintRect = QRectF( 0, 0, 
mMap->rect().width(), 
mMap->rect().height() );
 
  614  p->setClipRect( thisPaintRect );
 
  615  if ( thisPaintRect != mPrevPaintRect )
 
  618    mTransformDirty = 
true;
 
  619    mPrevPaintRect = thisPaintRect;
 
  623  const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
 
  624  p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); 
 
  640        drawGridCrsTransform( context, dotsPerMM );
 
  647      drawGridNoTransform( context, dotsPerMM );
 
  652  p->setClipping( 
false );
 
  656  p->setClipRect( 
mMap->mapRectFromScene( 
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
 
  661    updateGridLinesAnnotationsPositions();
 
  668  if ( mShowGridAnnotation )
 
  674void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
 const 
  676  QList< GridLine >::iterator it = mGridLines.begin();
 
  677  for ( ; it != mGridLines.end(); ++it )
 
  679    it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
 
  680    it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
 
  681    it->startAnnotation.position = QVector2D( it->line.first() );
 
  682    it->endAnnotation.position = QVector2D( it->line.last() );
 
  683    it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
 
  684    it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
 
  686    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() );
 
  688    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() );
 
  692void QgsLayoutItemMapGrid::drawGridNoTransform( 
QgsRenderContext &context, 
double dotsPerMM, 
bool calculateLinesOnly )
 const 
  699  if ( calculateLinesOnly )
 
  702  QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
 
  703  QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
 
  711    for ( ; vIt != mGridLines.constEnd(); ++vIt )
 
  713      if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
 
  715      line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
 
  716      drawGridLine( line, context );
 
  719    for ( ; hIt != mGridLines.constEnd(); ++hIt )
 
  721      if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
 
  723      line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
 
  724      drawGridLine( line, context );
 
  730    QPointF intersectionPoint, crossEnd1, crossEnd2;
 
  731    for ( ; vIt != mGridLines.constEnd(); ++vIt )
 
  733      if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
 
  736      l1 = QLineF( vIt->line.first(), vIt->line.last() );
 
  739      hIt = mGridLines.constBegin();
 
  740      for ( ; hIt != mGridLines.constEnd(); ++hIt )
 
  742        if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
 
  745        l2 = QLineF( hIt->line.first(), hIt->line.last() );
 
  747        if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
 
  752            crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
 
  754            crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
 
  757            drawGridLine( QLineF( crossEnd1  * dotsPerMM, crossEnd2  * dotsPerMM ), context );
 
  761            drawGridMarker( intersectionPoint * dotsPerMM, context );
 
  773    hIt = mGridLines.constBegin();
 
  774    for ( ; hIt != mGridLines.constEnd(); ++hIt )
 
  776      if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
 
  779      l1 = QLineF( hIt->line.first(), hIt->line.last() );
 
  781      vIt = mGridLines.constBegin();
 
  782      for ( ; vIt != mGridLines.constEnd(); ++vIt )
 
  784        if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
 
  787        l2 = QLineF( vIt->line.first(), vIt->line.last() );
 
  789        if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
 
  792          crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
 
  794          crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 )  ?
 
  797          drawGridLine( QLineF( crossEnd1  * dotsPerMM, crossEnd2  * dotsPerMM ), context );
 
  804void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
 const 
  813  switch ( mGridFrameStyle )
 
  817      drawGridFrameZebra( p, extension );
 
  822      drawGridFrameTicks( p, extension );
 
  827      drawGridFrameLine( p, extension );
 
  838void QgsLayoutItemMapGrid::drawGridLine( 
const QLineF &line, 
QgsRenderContext &context )
 const 
  841  poly << line.p1() << line.p2();
 
  842  drawGridLine( poly, context );
 
  845void QgsLayoutItemMapGrid::drawGridLine( 
const QPolygonF &line, 
QgsRenderContext &context )
 const 
  852  mGridLineSymbol->startRender( context );
 
  853  mGridLineSymbol->renderPolyline( line, 
nullptr, context );
 
  854  mGridLineSymbol->stopRender( context );
 
  857void QgsLayoutItemMapGrid::drawGridMarker( QPointF point, 
QgsRenderContext &context )
 const 
  864  mGridMarkerSymbol->startRender( context );
 
  865  mGridMarkerSymbol->renderPoint( point, 
nullptr, context );
 
  866  mGridMarkerSymbol->stopRender( context );
 
  869void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
 const 
  889void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border, 
double *extension )
 const 
  898    *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
 
  902  double currentCoord = 0.0;
 
  909  bool drawTLBox = 
false;
 
  910  bool drawTRBox = 
false;
 
  911  bool drawBLBox = 
false;
 
  912  bool drawBRBox = 
false;
 
  914  QMap< double, double > pos = QMap< double, double >();
 
  915  QList< GridLine >::const_iterator it = mGridLines.constBegin();
 
  916  for ( ; it != mGridLines.constEnd(); ++it )
 
  919    for ( 
int i = 0 ; i < 2 ; ++i )
 
  921      const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
 
  924      if ( annot.border != border )
 
  927      if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
 
  931        pos.insert( annot.position.y(), it->coordinate );
 
  933        pos.insert( annot.position.x(), it->coordinate );
 
  940    pos.insert( 
mMap->rect().height(), 
mMap->rect().height() );
 
  956    pos.insert( 
mMap->rect().width(), 
mMap->rect().width() );
 
  960  QPen framePen = QPen( mGridFramePenColor );
 
  961  framePen.setWidthF( mEvaluatedGridFrameLineThickness );
 
  962  framePen.setJoinStyle( Qt::MiterJoin );
 
  963  p->setPen( framePen );
 
  965  QMap< double, double >::const_iterator posIt = pos.constBegin();
 
  966  for ( ; posIt != pos.constEnd(); ++posIt )
 
  968    p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
 
  971      height = posIt.key() - currentCoord;
 
  972      width = mEvaluatedGridFrameWidth;
 
  973      x = ( border == 
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) : 
mMap->rect().width() + mEvaluatedGridFrameMargin;
 
  978      height = mEvaluatedGridFrameWidth;
 
  979      width = posIt.key() - currentCoord;
 
  981      y = ( border == 
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) : 
mMap->rect().height() + mEvaluatedGridFrameMargin;
 
  983    p->drawRect( QRectF( x, y, width, height ) );
 
  984    currentCoord = posIt.key();
 
  991    width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
 
  992    p->setBrush( QBrush( mGridFrameFillColor1 ) );
 
  994      p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
 
  996      p->drawRect( QRectF( 
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
 
  998      p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), 
mMap->rect().height(), width, height ) );
 
 1000      p->drawRect( QRectF( 
mMap->rect().width(), 
mMap->rect().height(), width, height ) );
 
 1004void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
 const 
 1014    QPen framePen = QPen( mGridFramePenColor );
 
 1015    framePen.setWidthF( mEvaluatedGridFrameLineThickness );
 
 1016    framePen.setCapStyle( Qt::FlatCap );
 
 1017    p->setBrush( Qt::NoBrush );
 
 1018    p->setPen( framePen );
 
 1021  QList< GridLine >::iterator it = mGridLines.begin();
 
 1022  for ( ; it != mGridLines.end(); ++it )
 
 1025    for ( 
int i = 0 ; i < 2 ; ++i )
 
 1027      const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
 
 1029      if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
 
 1033      if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
 
 1041        facingLeft = ( annot.angle != 0 );
 
 1042        facingRight = ( annot.angle != 0 );
 
 1046        facingLeft = ( annot.angle > 0 );
 
 1047        facingRight = ( annot.angle < 0 );
 
 1051        facingLeft = ( annot.angle < 0 );
 
 1052        facingRight = ( annot.angle > 0 );
 
 1055      if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
 
 1056           ( facingRight && annot.position.x() > 
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
 
 1058      if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() > 
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
 
 1059           ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
 
 1061      if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() > 
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
 
 1062           ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
 
 1064      if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
 
 1065           ( facingRight && annot.position.y() > 
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
 
 1069      const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
 
 1071      double fA = mEvaluatedGridFrameMargin; 
 
 1072      double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth; 
 
 1074      if ( mRotatedTicksEnabled && mRotatedTicksLengthMode == 
OrthogonalTicks )
 
 1076        fA /= QVector2D::dotProduct( vector, normalVector );
 
 1077        fB /= QVector2D::dotProduct( vector, normalVector );
 
 1084          extension->UpdateBorder( annot.border, fB );
 
 1092        pA = annot.position + fA * vector;
 
 1093        pB = annot.position + fB * vector;
 
 1097        pA = annot.position - fA * vector;
 
 1098        pB = annot.position - fB * vector;
 
 1102        pA = annot.position - fB * vector;
 
 1103        pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
 
 1105      p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
 
 1111void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
 const 
 1121    QPen framePen = QPen( mGridFramePenColor );
 
 1122    framePen.setWidthF( mEvaluatedGridFrameLineThickness );
 
 1123    framePen.setCapStyle( Qt::SquareCap );
 
 1124    p->setBrush( Qt::NoBrush );
 
 1125    p->setPen( framePen );
 
 1135      p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
 
 1143      p->drawLine( QLineF( 
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 
mMap->rect().width() + mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
 
 1149      extension->UpdateBorder( 
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
 
 1151      p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
 
 1159      p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin, 
mMap->rect().width() + mEvaluatedGridFrameMargin, 
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
 
 1162  if ( ! extension && drawDiagonals )
 
 1167      const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
 
 1168      const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
 
 1169      p->drawLine( QLineF( 0, 0, X1, Y1 ) );
 
 1174      const double X1 = 
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1175      const double Y1 = 
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1176      p->drawLine( QLineF( 
mMap->rect().width(), 
mMap->rect().height(), X1, Y1 ) );
 
 1181      const double X1 = 
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1182      const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1183      p->drawLine( QLineF( 
mMap->rect().width(), 0, X1, Y1 ) );
 
 1188      const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1189      const double Y1 = 
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
 
 1190      p->drawLine( QLineF( 0, 
mMap->rect().height(), X1, Y1 ) );
 
 1196    GridExtension *extension )
 const 
 1198  QString currentAnnotationString;
 
 1199  QList< GridLine >::const_iterator it = mGridLines.constBegin();
 
 1200  for ( ; it != mGridLines.constEnd(); ++it )
 
 1202    currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
 
 1203    drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
 
 1204    drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
 
 1208void QgsLayoutItemMapGrid::drawCoordinateAnnotation( 
QgsRenderContext &context, GridLineAnnotation annot, 
const QString &annotationString, 
const AnnotationCoordinate coordinateType, GridExtension *extension )
 const 
 1215  if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
 
 1227  double xpos = annot.position.x();
 
 1228  double ypos = annot.position.y();
 
 1229  QPointF anchor = QPointF();
 
 1236  if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
 
 1240  const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
 
 1243  double f = mEvaluatedAnnotationFrameDistance;
 
 1251    f += mEvaluatedGridFrameWidth;
 
 1252  if ( hasBorderWidth )
 
 1253    f += mEvaluatedGridFrameLineThickness / 2.0;
 
 1258  if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode == 
OrthogonalTicks )
 
 1260    f /= QVector2D::dotProduct( vector, normalVector );
 
 1263  const QVector2D pos = annot.position + f * vector;
 
 1276    rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
 
 1278    if ( rotation <= -90 || rotation > 90 )
 
 1281      anchor.setX( outside ? 0 : textWidth ); 
 
 1285      anchor.setX( outside ? textWidth : 0 ); 
 
 1289      anchor.setY( 0.5 * textHeight ); 
 
 1291      anchor.setY( -1.5 * textHeight ); 
 
 1293      anchor.setY( -0.5 * textHeight ); 
 
 1299    anchor.setX( 0.5 * textWidth ); 
 
 1300    anchor.setY( -0.5 * textHeight ); 
 
 1302      anchor.setY( outside ? 0 : -textHeight ); 
 
 1304      anchor.setX( outside ? 0 : textWidth ); 
 
 1306      anchor.setY( outside ? -textHeight : 0 ); 
 
 1308      anchor.setX( outside ? textWidth : 0 ); 
 
 1313    anchor.setX( 0.5 * textWidth ); 
 
 1314    anchor.setY( -0.5 * textHeight ); 
 
 1316      anchor.setX( outside ? 0 : textWidth ); 
 
 1318      anchor.setY( outside ? -textHeight : 0 ); 
 
 1320      anchor.setX( outside ? textWidth : 0 ); 
 
 1322      anchor.setY( outside ? 0 : -textHeight ); 
 
 1327    anchor.setX( 0.5 * textWidth ); 
 
 1328    anchor.setY( -0.5 * textHeight ); 
 
 1330      anchor.setX( outside ? textWidth : 0 ); 
 
 1332      anchor.setY( outside ? 0 : -textHeight ); 
 
 1334      anchor.setX( outside ? 0 : textWidth ); 
 
 1336      anchor.setY( outside ? -textHeight : 0 ); 
 
 1341    rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
 
 1342    anchor.setX( 0.5 * textWidth ); 
 
 1344      anchor.setY( -textHeight ); 
 
 1352    extension->UpdateBorder( frameBorder, -f + textWidth );
 
 1354    extension->UpdateAll( textWidth / 2.0 );
 
 1357  if ( extension || !context.
painter() )
 
 1361  bool facingLeft = ( annot.angle < 0 );
 
 1362  bool facingRight = ( annot.angle > 0 );
 
 1365    facingLeft = !facingLeft;
 
 1366    facingRight = !facingRight;
 
 1368  if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
 
 1369       ( facingRight && annot.position.x() > 
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
 
 1371  if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() > 
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
 
 1372       ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
 
 1374  if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() > 
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
 
 1375       ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
 
 1377  if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
 
 1378       ( facingRight && annot.position.y() > 
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
 
 1382  context.
painter()->translate( QPointF( xpos, ypos ) );
 
 1383  context.
painter()->rotate( rotation );
 
 1384  context.
painter()->translate( -anchor );
 
 1386  QgsTextRenderer::drawText( QPointF( 0, 0 ), 0, Qgis::TextHorizontalAlignment::Left, annotationString.split( 
'\n' ), context, mAnnotationFormat );
 
 1392  bool geographic = 
false;
 
 1406    const double wrappedX = std::fmod( value, 360.0 );
 
 1407    if ( wrappedX > 180.0 )
 
 1409      value = wrappedX - 360.0;
 
 1411    else if ( wrappedX < -180.0 )
 
 1413      value = wrappedX + 360.0;
 
 1419    return QString::number( value, 
'f', mGridAnnotationPrecision );
 
 1425    const double coordRounded = 
qgsRound( value, mGridAnnotationPrecision );
 
 1429      if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
 
 1431        hemisphere = value < 0 ? QObject::tr( 
"W" ) : QObject::tr( 
"E" );
 
 1437      if ( !geographic || coordRounded != 0.0 )
 
 1439        hemisphere = value < 0 ? QObject::tr( 
"S" ) : QObject::tr( 
"N" );
 
 1445      return QString::number( std::fabs( value ), 
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
 
 1449      return QString::number( std::fabs( value ), 
'f', mGridAnnotationPrecision ) + hemisphere;
 
 1456    if ( !mGridAnnotationExpression )
 
 1458      mGridAnnotationExpression.reset( 
new QgsExpression( mGridAnnotationExpressionString ) );
 
 1459      mGridAnnotationExpression->prepare( &expressionContext );
 
 1461    return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
 
 1465  QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
 
 1466  switch ( mGridAnnotationFormat )
 
 1485      flags = QgsCoordinateFormatter::FormatFlags();
 
 1495      flags = QgsCoordinateFormatter::FormatFlags();
 
 1516int QgsLayoutItemMapGrid::xGridLines()
 const 
 1518  if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
 
 1525  QRectF mapBoundingRect = mapPolygon.boundingRect();
 
 1526  double gridIntervalY = mEvaluatedIntervalY;
 
 1527  double gridOffsetY = mEvaluatedOffsetY;
 
 1528  double annotationScale = 1.0;
 
 1529  switch ( mGridUnit )
 
 1534      mapBoundingRect = 
mMap->rect();
 
 1535      mapPolygon = QPolygonF( 
mMap->rect() );
 
 1536      if ( mGridUnit == 
CM )
 
 1538        annotationScale = 0.1;
 
 1539        gridIntervalY *= 10;
 
 1551  const double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
 
 1552  double currentLevel = 
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
 
 1554  int gridLineCount = 0;
 
 1559    double yCanvasCoord;
 
 1560    while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < 
MAX_GRID_LINES )
 
 1562      yCanvasCoord = 
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
 
 1564      newLine.coordinate = currentLevel * annotationScale;
 
 1565      newLine.coordinateType = AnnotationCoordinate::Latitude;
 
 1566      newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF( 
mMap->rect().width(), yCanvasCoord );
 
 1567      mGridLines.append( newLine );
 
 1568      currentLevel += gridIntervalY;
 
 1575  QVector<QLineF> borderLines;
 
 1576  borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
 
 1577  borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
 
 1578  borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
 
 1579  borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
 
 1581  QVector<QPointF> intersectionList; 
 
 1583  while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < 
MAX_GRID_LINES )
 
 1585    intersectionList.clear();
 
 1586    const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
 
 1588    QVector<QLineF>::const_iterator it = borderLines.constBegin();
 
 1589    for ( ; it != borderLines.constEnd(); ++it )
 
 1591      QPointF intersectionPoint;
 
 1592      if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
 
 1594        intersectionList.push_back( intersectionPoint );
 
 1595        if ( intersectionList.size() >= 2 )
 
 1602    if ( intersectionList.size() >= 2 )
 
 1605      newLine.coordinate = currentLevel;
 
 1606      newLine.coordinateType = AnnotationCoordinate::Latitude;
 
 1608      mGridLines.append( newLine );
 
 1611    currentLevel += gridIntervalY;
 
 1618int QgsLayoutItemMapGrid::yGridLines()
 const 
 1620  if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
 
 1626  QRectF mapBoundingRect = mapPolygon.boundingRect();
 
 1627  double gridIntervalX = mEvaluatedIntervalX;
 
 1628  double gridOffsetX = mEvaluatedOffsetX;
 
 1629  double annotationScale = 1.0;
 
 1630  switch ( mGridUnit )
 
 1635      mapBoundingRect = 
mMap->rect();
 
 1636      mapPolygon = QPolygonF( 
mMap->rect() );
 
 1637      if ( mGridUnit == 
CM )
 
 1639        annotationScale = 0.1;
 
 1640        gridIntervalX *= 10;
 
 1652  const double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
 
 1653  double currentLevel = 
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
 
 1655  int gridLineCount = 0;
 
 1659    double xCanvasCoord;
 
 1660    while ( currentLevel <= mapBoundingRect.right() && gridLineCount < 
MAX_GRID_LINES )
 
 1662      xCanvasCoord = 
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
 
 1665      newLine.coordinate = currentLevel * annotationScale;
 
 1666      newLine.coordinateType = AnnotationCoordinate::Longitude;
 
 1667      newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord, 
mMap->rect().height() );
 
 1668      mGridLines.append( newLine );
 
 1669      currentLevel += gridIntervalX;
 
 1676  QVector<QLineF> borderLines;
 
 1677  borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
 
 1678  borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
 
 1679  borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
 
 1680  borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
 
 1682  QVector<QPointF> intersectionList; 
 
 1684  while ( currentLevel <= mapBoundingRect.right() && gridLineCount < 
MAX_GRID_LINES )
 
 1686    intersectionList.clear();
 
 1687    const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
 
 1689    QVector<QLineF>::const_iterator it = borderLines.constBegin();
 
 1690    for ( ; it != borderLines.constEnd(); ++it )
 
 1692      QPointF intersectionPoint;
 
 1693      if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
 
 1695        intersectionList.push_back( intersectionPoint );
 
 1696        if ( intersectionList.size() >= 2 )
 
 1703    if ( intersectionList.size() >= 2 )
 
 1706      newLine.coordinate = currentLevel;
 
 1707      newLine.coordinateType = AnnotationCoordinate::Longitude;
 
 1709      mGridLines.append( newLine );
 
 1712    currentLevel += gridIntervalX;
 
 1720  if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
 
 1725  const double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
 
 1726  double currentLevel = 
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
 
 1728  const double minX = bbox.
xMinimum();
 
 1729  const double maxX = bbox.
xMaximum();
 
 1730  double step = ( maxX - minX ) / 20;
 
 1732  bool crosses180 = 
false;
 
 1733  bool crossed180 = 
false;
 
 1738    step = ( maxX + 360.0 - minX ) / 20;
 
 1744  int gridLineCount = 0;
 
 1748    double currentX = minX;
 
 1752      if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
 
 1769      if ( crosses180 && currentX > 180.0 )
 
 1777    const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, 
QgsRectangle( 
mMap->rect() ) );
 
 1778    QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
 
 1779    for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
 
 1781      if ( !( *lineIt ).isEmpty() )
 
 1784        newLine.coordinate = currentLevel;
 
 1785        newLine.coordinateType = AnnotationCoordinate::Latitude;
 
 1786        newLine.line = QPolygonF( *lineIt );
 
 1787        mGridLines.append( newLine );
 
 1791    currentLevel -= mEvaluatedIntervalY;
 
 1799  if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
 
 1804  const double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
 
 1805  double currentLevel = 
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
 
 1807  const double minY = bbox.
yMinimum();
 
 1808  const double maxY = bbox.
yMaximum();
 
 1809  const double step = ( maxY - minY ) / 20;
 
 1814  bool crosses180 = 
false;
 
 1815  bool crossed180 = 
false;
 
 1822  int gridLineCount = 0;
 
 1823  while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount < 
MAX_GRID_LINES )
 
 1826    double currentY = minY;
 
 1830      if ( currentY > maxY )
 
 1850    const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, 
QgsRectangle( 
mMap->rect() ) );
 
 1851    QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
 
 1852    for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
 
 1854      if ( !( *lineIt ).isEmpty() )
 
 1857        newLine.coordinate = currentLevel;
 
 1858        newLine.coordinateType = AnnotationCoordinate::Longitude;
 
 1859        newLine.line = QPolygonF( *lineIt );
 
 1860        mGridLines.append( newLine );
 
 1864    currentLevel += mEvaluatedIntervalX;
 
 1865    if ( crosses180 && currentLevel > 180.0 )
 
 1867      currentLevel -= 360.0;
 
 1896      return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
 
 1898      return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
 
 1900      return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
 
 1902      return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
 
 1917  if ( ddValue.compare( QLatin1String( 
"x_only" ), Qt::CaseInsensitive ) == 0 )
 
 1919  else if ( ddValue.compare( QLatin1String( 
"y_only" ), Qt::CaseInsensitive ) == 0 )
 
 1921  else if ( ddValue.compare( QLatin1String( 
"disabled" ), Qt::CaseInsensitive ) == 0 )
 
 1923  else if ( ddValue.compare( QLatin1String( 
"all" ), Qt::CaseInsensitive ) == 0 )
 
 1930void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
 
 1935  mTransformDirty = mTransformDirty
 
 1942  switch ( mGridUnit )
 
 1955      if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
 
 1957        mEvaluatedEnabled = 
false;
 
 1961        const double mapWidthMm = 
mLayout->renderContext().measurementConverter().convert( 
mMap->
sizeWithUnits(), Qgis::LayoutUnit::Millimeters ).width();
 
 1962        const double mapWidthMapUnits = mapWidth();
 
 1963        const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
 
 1964        const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
 
 1966        mEvaluatedIntervalX = interval;
 
 1967        mEvaluatedIntervalY = interval;
 
 1968        mTransformDirty = 
true;
 
 1991double QgsLayoutItemMapGrid::mapWidth()
 const 
 2000  if ( distanceUnit == Qgis::DistanceUnit::Unknown )
 
 2002    return mapExtent.
width();
 
 2019bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
 
 2021  return a.first < b.first;
 
 2034  if ( ( p.y() <= tolerance && p.x() <= tolerance ) 
 
 2035       || ( p.y() <= tolerance && p.x() >= ( 
mMap->rect().width() - tolerance ) ) 
 
 2036       || ( p.y() >= ( 
mMap->rect().height() - tolerance ) && p.x() <= tolerance ) 
 
 2037       || ( p.y() >= ( 
mMap->rect().height() - tolerance ) && p.x() >= ( 
mMap->rect().width() - tolerance ) ) 
 
 2043      if ( p.x() <= tolerance )
 
 2054      if ( p.y() <= tolerance )
 
 2066  QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
 
 2072  std::sort( distanceToSide.begin(), distanceToSide.end(), 
sortByDistance );
 
 2073  return distanceToSide.at( 0 ).second;
 
 2078  mGridLineSymbol.reset( symbol );
 
 2083  return mGridLineSymbol.get();
 
 2088  return mGridLineSymbol.get();
 
 2093  mGridMarkerSymbol.reset( symbol );
 
 2098  return mGridMarkerSymbol.get();
 
 2103  return mGridMarkerSymbol.get();
 
 2108  mAnnotationFormat.
setFont( font );
 
 2109  if ( font.pointSizeF() > 0 )
 
 2111    mAnnotationFormat.
setSize( font.pointSizeF() );
 
 2112    mAnnotationFormat.
setSizeUnit( Qgis::RenderUnit::Points );
 
 2114  else if ( font.pixelSize() > 0 )
 
 2116    mAnnotationFormat.
setSize( font.pixelSize() );
 
 2117    mAnnotationFormat.
setSizeUnit( Qgis::RenderUnit::Pixels );
 
 2123  return mAnnotationFormat.
toQFont();
 
 2128  mAnnotationFormat.
setColor( color );
 
 2133  return mAnnotationFormat.
color();
 
 2141      mLeftGridAnnotationDisplay = display;
 
 2144      mRightGridAnnotationDisplay = display;
 
 2147      mTopGridAnnotationDisplay = display;
 
 2150      mBottomGridAnnotationDisplay = display;
 
 2154  refreshDataDefinedProperties();
 
 2168      return mLeftGridAnnotationDisplay;
 
 2170      return mRightGridAnnotationDisplay;
 
 2172      return mTopGridAnnotationDisplay;
 
 2174      return mBottomGridAnnotationDisplay;
 
 2176  return mBottomGridAnnotationDisplay; 
 
 2183  double bottom = 0.0;
 
 2186  return std::max( std::max( std::max( top, right ), bottom ), left );
 
 2196  if ( !
mMap || !mEvaluatedEnabled )
 
 2206  GridExtension extension;
 
 2209  switch ( mGridUnit )
 
 2216        drawGridCrsTransform( context, 0, 
true );
 
 2223      drawGridNoTransform( context, 0, 
true );
 
 2228    updateGridLinesAnnotationsPositions();
 
 2232    drawGridFrame( 
nullptr, &extension );
 
 2235  if ( mShowGridAnnotation )
 
 2240  top = extension.top;
 
 2241  right = extension.right;
 
 2242  bottom = extension.bottom;
 
 2243  left = extension.left;
 
 2249  refreshDataDefinedProperties();
 
 2254  if ( unit == mGridUnit )
 
 2259  mTransformDirty = 
true;
 
 2268  mGridIntervalX = interval;
 
 2269  mTransformDirty = 
true;
 
 2270  refreshDataDefinedProperties();
 
 2279  mGridIntervalY = interval;
 
 2280  mTransformDirty = 
true;
 
 2281  refreshDataDefinedProperties();
 
 2290  mGridOffsetX = offset;
 
 2291  mTransformDirty = 
true;
 
 2292  refreshDataDefinedProperties();
 
 2301  mGridOffsetY = offset;
 
 2302  mTransformDirty = 
true;
 
 2303  refreshDataDefinedProperties();
 
 2312  mMinimumIntervalWidth = minWidth;
 
 2313  mTransformDirty = 
true;
 
 2314  refreshDataDefinedProperties();
 
 2323  mMaximumIntervalWidth = maxWidth;
 
 2324  mTransformDirty = 
true;
 
 2325  refreshDataDefinedProperties();
 
 2330  if ( 
style == mGridStyle )
 
 2335  mTransformDirty = 
true;
 
 2340  mCrossLength = length;
 
 2341  refreshDataDefinedProperties();
 
 2349      mLeftGridAnnotationDirection = direction;
 
 2352      mRightGridAnnotationDirection = direction;
 
 2355      mTopGridAnnotationDirection = direction;
 
 2358      mBottomGridAnnotationDirection = direction;
 
 2371  mGridFrameSides = flags;
 
 2377    mGridFrameSides |= flag;
 
 2379    mGridFrameSides &= ~flag;
 
 2384  return mGridFrameSides;
 
 2393  context.
setHighlightedVariables( QStringList() << QStringLiteral( 
"grid_number" ) << QStringLiteral( 
"grid_axis" ) );
 
 2399  if ( mGridLineSymbol )
 
 2405  if ( mGridMarkerSymbol )
 
 2417  mTransformDirty = 
true;
 
 2418  refreshDataDefinedProperties();
 
 2425  return mGridFrameSides.testFlag( flag );
 
 2430  mGridFrameWidth = width;
 
 2431  refreshDataDefinedProperties();
 
 2436  mGridFrameMargin = margin;
 
 2437  refreshDataDefinedProperties();
 
 2442  mGridFramePenThickness = width;
 
 2443  refreshDataDefinedProperties();
 
 2448  mLeftGridAnnotationDirection = direction;
 
 2449  mRightGridAnnotationDirection = direction;
 
 2450  mTopGridAnnotationDirection = direction;
 
 2451  mBottomGridAnnotationDirection = direction;
 
 2459      mLeftGridAnnotationPosition = position;
 
 2462      mRightGridAnnotationPosition = position;
 
 2465      mTopGridAnnotationPosition = position;
 
 2468      mBottomGridAnnotationPosition = position;
 
 2484      return mLeftGridAnnotationPosition;
 
 2486      return mRightGridAnnotationPosition;
 
 2488      return mTopGridAnnotationPosition;
 
 2490      return mBottomGridAnnotationPosition;
 
 2492  return mLeftGridAnnotationPosition; 
 
 2497  mAnnotationFrameDistance = distance;
 
 2498  refreshDataDefinedProperties();
 
 2505    return mLeftGridAnnotationDirection;
 
 2511      return mLeftGridAnnotationDirection;
 
 2513      return mRightGridAnnotationDirection;
 
 2515      return mTopGridAnnotationDirection;
 
 2517      return mBottomGridAnnotationDirection;
 
 2519  return mLeftGridAnnotationDirection; 
 
 2524  mGridAnnotationExpressionString = expression;
 
 2525  mGridAnnotationExpression.reset();
 
 2533      mLeftFrameDivisions = divisions;
 
 2536      mRightFrameDivisions = divisions;
 
 2539      mTopFrameDivisions = divisions;
 
 2542      mBottomFrameDivisions = divisions;
 
 2546  refreshDataDefinedProperties();
 
 2559      return mLeftFrameDivisions;
 
 2561      return mRightFrameDivisions;
 
 2563      return mTopFrameDivisions;
 
 2565      return mBottomFrameDivisions;
 
 2567  return mLeftFrameDivisions; 
 
 2583    const QRectF mbr = mapPolygon.boundingRect();
 
 2584    const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
 
 2590      QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
 
 2591      QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
 
 2593      lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
 
 2594      upperRight = tr.transform( upperRight.x(), upperRight.y() );
 
 2596      if ( lowerLeft.x() > upperRight.x() )
 
 2599        crsRect = extentTransform.
transformBoundingBox( mapBoundingRect, Qgis::TransformDirection::Forward, 
true );
 
 2623QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap( 
const QPolygonF &line, 
const QgsRectangle &rect )
 
 2631  QList<QPolygonF> trimmedLines;
 
 2632  QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
 
 2633  for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
 
 2635    trimmedLines << ( *geomIt ).asQPolygonF();
 
 2637  return trimmedLines;
 
DistanceUnit
Units of distance.
 
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
 
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.
 
This class represents a coordinate reference system (CRS).
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
 
Q_GADGET Qgis::DistanceUnit mapUnits
 
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.
 
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.
 
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.
 
Class for 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.
 
A geometry is the spatial representation of a feature.
 
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.
 
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
 
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.
 
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.
 
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 draw(QPainter *painter) override
Draws the item on to a destination painter.
 
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
 
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
 
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,...
 
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.
 
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 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 setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
 
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
 
~QgsLayoutItemMapGrid() override
 
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
 
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
 
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
 
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
 
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
 
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
 
TickLengthMode
Tick length mode (useful for rotated grids)
 
@ OrthogonalTicks
Align ticks orthogonaly.
 
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.
 
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.
 
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...
 
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).
 
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).
 
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
 
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
 
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
 
const QgsLayout * layout() const
Returns the layout the object is attached to.
 
QPointer< QgsLayout > mLayout
 
@ MapGridIntervalX
Map grid interval X.
 
@ MapGridAnnotationDisplayBottom
Map annotation display bottom.
 
@ MapGridIntervalY
Map grid interval Y.
 
@ MapGridFrameSize
Map grid frame size.
 
@ MapGridFrameDivisionsBottom
Map frame division display bottom.
 
@ MapGridAnnotationDisplayRight
Map annotation display right.
 
@ MapGridFrameMargin
Map grid frame margin.
 
@ MapGridOffsetX
Map grid offset X.
 
@ MapGridLabelDistance
Map grid label distance.
 
@ MapGridAnnotationDisplayLeft
Map annotation display left.
 
@ MapGridFrameDivisionsLeft
Map frame division display left.
 
@ MapGridEnabled
Map grid enabled.
 
@ MapGridFrameLineThickness
Map grid frame line thickness.
 
@ MapGridFrameDivisionsRight
Map frame division display right.
 
@ MapGridFrameDivisionsTop
Map frame division display top.
 
@ MapGridCrossSize
Map grid cross size.
 
@ MapGridOffsetY
Map grid offset Y.
 
@ MapGridAnnotationDisplayTop
Map annotation display top.
 
QgsLayoutRenderContext::Flags flags() const
Returns the current combination of flags used for rendering the layout.
 
@ FlagAntialiasing
Use antialiasing when drawing items.
 
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.
 
static 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 QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
 
A class to represent a 2D point.
 
bool isEmpty() const SIP_HOLDGIL
Returns true if the geometry is empty.
 
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
 
The class is used as a container of context for various read/write operations on other objects.
 
A rectangle specified with double values.
 
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
 
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
 
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
 
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
 
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
 
Contains information about the context of a rendering operation.
 
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
 
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 setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
 
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.
 
This class is a composition of two QSettings instances:
 
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 QColor decodeColor(const QString &str)
 
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 QString encodeColor(const QColor &color)
 
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.
 
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.