53#include "moc_qgslayoutitemmapgrid.cpp"
55using namespace Qt::StringLiterals;
57#define MAX_GRID_LINES 1000
86 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
92 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
97 QList< QgsLayoutItemMapGrid * > list;
120 const QDomNodeList mapGridNodeList = elem.elementsByTagName( u
"ComposerMapGrid"_s );
121 for (
int i = 0; i < mapGridNodeList.size(); ++i )
123 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
125 mapGrid->
readXml( mapGridElem, doc, context );
139 return std::max( std::max( std::max( top, right ), bottom ), left );
153 double gridTop = 0.0;
154 double gridRight = 0.0;
155 double gridBottom = 0.0;
156 double gridLeft = 0.0;
157 grid->calculateMaxExtension( gridTop, gridRight, gridBottom, gridLeft );
158 top = std::max( top, gridTop );
159 right = std::max( right, gridRight );
160 bottom = std::max( bottom, gridBottom );
161 left = std::max( left, gridLeft );
177 return QVector2D( 0, 1 );
179 return QVector2D( -1, 0 );
181 return QVector2D( 0, -1 );
183 return QVector2D( 1, 0 );
191 return QVector2D( borderVector.y(), -borderVector.x() );
196 , mGridFrameSides(
Qgis::MapGridFrameSideFlag::
Left |
Qgis::MapGridFrameSideFlag::
Right |
Qgis::MapGridFrameSideFlag::Top |
Qgis::MapGridFrameSideFlag::Bottom )
200 const QString defaultFontString = settings.
value( u
"LayoutDesigner/defaultFont"_s, QVariant(),
QgsSettings::Gui ).toString();
201 if ( !defaultFontString.isEmpty() )
204 QgsFontUtils::setFontFamily( font, defaultFontString );
205 mAnnotationFormat.setFont( font );
208 createDefaultGridLineSymbol();
209 createDefaultGridMarkerSymbol();
214 if ( !mCRS.isValid() )
221void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
223 QVariantMap properties;
224 properties.insert( u
"color"_s, u
"0,0,0,255"_s );
225 properties.insert( u
"width"_s, u
"0.3"_s );
226 properties.insert( u
"capstyle"_s, u
"flat"_s );
230void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
232 QVariantMap properties;
233 properties.insert( u
"name"_s, u
"circle"_s );
234 properties.insert( u
"size"_s, u
"2.0"_s );
235 properties.insert( u
"color"_s, u
"0,0,0,255"_s );
241 if ( mGridLineSymbol )
243 mGridLineSymbol->setWidth( width );
249 if ( mGridLineSymbol )
251 mGridLineSymbol->setColor(
c );
262 QDomElement mapGridElem = doc.createElement( u
"ComposerMapGrid"_s );
263 mapGridElem.setAttribute( u
"gridStyle"_s,
static_cast< int >( mGridStyle ) );
270 QDomElement lineStyleElem = doc.createElement( u
"lineStyle"_s );
272 lineStyleElem.appendChild( gridLineStyleElem );
273 mapGridElem.appendChild( lineStyleElem );
275 QDomElement markerStyleElem = doc.createElement( u
"markerStyle"_s );
277 markerStyleElem.appendChild( gridMarkerStyleElem );
278 mapGridElem.appendChild( markerStyleElem );
280 mapGridElem.setAttribute( u
"gridFrameStyle"_s,
static_cast< int >( mGridFrameStyle ) );
281 mapGridElem.setAttribute( u
"gridFrameSideFlags"_s, mGridFrameSides );
282 mapGridElem.setAttribute( u
"gridFrameWidth"_s,
qgsDoubleToString( mGridFrameWidth ) );
283 mapGridElem.setAttribute( u
"gridFrameMargin"_s,
qgsDoubleToString( mGridFrameMargin ) );
284 mapGridElem.setAttribute( u
"gridFramePenThickness"_s,
qgsDoubleToString( mGridFramePenThickness ) );
288 mapGridElem.setAttribute( u
"leftFrameDivisions"_s,
static_cast< int >( mLeftFrameDivisions ) );
289 mapGridElem.setAttribute( u
"rightFrameDivisions"_s,
static_cast< int >( mRightFrameDivisions ) );
290 mapGridElem.setAttribute( u
"topFrameDivisions"_s,
static_cast< int >( mTopFrameDivisions ) );
291 mapGridElem.setAttribute( u
"bottomFrameDivisions"_s,
static_cast< int >( mBottomFrameDivisions ) );
292 mapGridElem.setAttribute( u
"rotatedTicksLengthMode"_s,
static_cast< int >( mRotatedTicksLengthMode ) );
293 mapGridElem.setAttribute( u
"rotatedTicksEnabled"_s, mRotatedTicksEnabled );
294 mapGridElem.setAttribute( u
"rotatedTicksMinimumAngle"_s, QString::number( mRotatedTicksMinimumAngle ) );
295 mapGridElem.setAttribute( u
"rotatedTicksMarginToCorner"_s, QString::number( mRotatedTicksMarginToCorner ) );
296 mapGridElem.setAttribute( u
"rotatedAnnotationsLengthMode"_s,
static_cast< int >( mRotatedAnnotationsLengthMode ) );
297 mapGridElem.setAttribute( u
"rotatedAnnotationsEnabled"_s, mRotatedAnnotationsEnabled );
298 mapGridElem.setAttribute( u
"rotatedAnnotationsMinimumAngle"_s, QString::number( mRotatedAnnotationsMinimumAngle ) );
299 mapGridElem.setAttribute( u
"rotatedAnnotationsMarginToCorner"_s, QString::number( mRotatedAnnotationsMarginToCorner ) );
300 if ( mCRS.isValid() )
302 mCRS.writeXml( mapGridElem, doc );
305 mapGridElem.setAttribute( u
"annotationFormat"_s,
static_cast< int >( mGridAnnotationFormat ) );
306 mapGridElem.setAttribute( u
"showAnnotation"_s, mShowGridAnnotation );
307 mapGridElem.setAttribute( u
"annotationExpression"_s, mGridAnnotationExpressionString );
308 mapGridElem.setAttribute( u
"leftAnnotationDisplay"_s,
static_cast< int >( mLeftGridAnnotationDisplay ) );
309 mapGridElem.setAttribute( u
"rightAnnotationDisplay"_s,
static_cast< int >( mRightGridAnnotationDisplay ) );
310 mapGridElem.setAttribute( u
"topAnnotationDisplay"_s,
static_cast< int >( mTopGridAnnotationDisplay ) );
311 mapGridElem.setAttribute( u
"bottomAnnotationDisplay"_s,
static_cast< int >( mBottomGridAnnotationDisplay ) );
312 mapGridElem.setAttribute( u
"leftAnnotationPosition"_s,
static_cast< int >( mLeftGridAnnotationPosition ) );
313 mapGridElem.setAttribute( u
"rightAnnotationPosition"_s,
static_cast< int >( mRightGridAnnotationPosition ) );
314 mapGridElem.setAttribute( u
"topAnnotationPosition"_s,
static_cast< int >( mTopGridAnnotationPosition ) );
315 mapGridElem.setAttribute( u
"bottomAnnotationPosition"_s,
static_cast< int >( mBottomGridAnnotationPosition ) );
316 mapGridElem.setAttribute( u
"leftAnnotationDirection"_s,
static_cast< int >( mLeftGridAnnotationDirection ) );
317 mapGridElem.setAttribute( u
"rightAnnotationDirection"_s,
static_cast< int >( mRightGridAnnotationDirection ) );
318 mapGridElem.setAttribute( u
"topAnnotationDirection"_s,
static_cast< int >( mTopGridAnnotationDirection ) );
319 mapGridElem.setAttribute( u
"bottomAnnotationDirection"_s,
static_cast< int >( mBottomGridAnnotationDirection ) );
320 mapGridElem.setAttribute( u
"frameAnnotationDistance"_s, QString::number( mAnnotationFrameDistance ) );
321 mapGridElem.appendChild( mAnnotationFormat.writeXml( doc, context ) );
322 mapGridElem.setAttribute( u
"annotationPrecision"_s, mGridAnnotationPrecision );
323 mapGridElem.setAttribute( u
"unit"_s,
static_cast< int >( mGridUnit ) );
324 mapGridElem.setAttribute( u
"blendMode"_s, mBlendMode );
325 mapGridElem.setAttribute( u
"minimumIntervalWidth"_s, QString::number( mMinimumIntervalWidth ) );
326 mapGridElem.setAttribute( u
"maximumIntervalWidth"_s, QString::number( mMaximumIntervalWidth ) );
334 elem.appendChild( mapGridElem );
341 if ( itemElem.isNull() )
349 mGridStyle =
static_cast< Qgis::MapGridStyle >( itemElem.attribute( u
"gridStyle"_s, u
"0"_s ).toInt() );
350 mGridIntervalX = itemElem.attribute( u
"intervalX"_s, u
"0"_s ).toDouble();
351 mGridIntervalY = itemElem.attribute( u
"intervalY"_s, u
"0"_s ).toDouble();
352 mGridOffsetX = itemElem.attribute( u
"offsetX"_s, u
"0"_s ).toDouble();
353 mGridOffsetY = itemElem.attribute( u
"offsetY"_s, u
"0"_s ).toDouble();
354 mCrossLength = itemElem.attribute( u
"crossLength"_s, u
"3"_s ).toDouble();
355 mGridFrameStyle =
static_cast< Qgis::MapGridFrameStyle >( itemElem.attribute( u
"gridFrameStyle"_s, u
"0"_s ).toInt() );
357 mGridFrameWidth = itemElem.attribute( u
"gridFrameWidth"_s, u
"2.0"_s ).toDouble();
358 mGridFrameMargin = itemElem.attribute( u
"gridFrameMargin"_s, u
"0.0"_s ).toDouble();
359 mGridFramePenThickness = itemElem.attribute( u
"gridFramePenThickness"_s, u
"0.3"_s ).toDouble();
367 mRotatedTicksLengthMode =
static_cast< Qgis::MapGridTickLengthMode >( itemElem.attribute( u
"rotatedTicksLengthMode"_s, u
"0"_s ).toInt() );
368 mRotatedTicksEnabled = itemElem.attribute( u
"rotatedTicksEnabled"_s, u
"0"_s ) !=
"0"_L1;
369 mRotatedTicksMinimumAngle = itemElem.attribute( u
"rotatedTicksMinimumAngle"_s, u
"0"_s ).toDouble();
370 mRotatedTicksMarginToCorner = itemElem.attribute( u
"rotatedTicksMarginToCorner"_s, u
"0"_s ).toDouble();
371 mRotatedAnnotationsLengthMode =
static_cast< Qgis::MapGridTickLengthMode >( itemElem.attribute( u
"rotatedAnnotationsLengthMode"_s, u
"0"_s ).toInt() );
372 mRotatedAnnotationsEnabled = itemElem.attribute( u
"rotatedAnnotationsEnabled"_s, u
"0"_s ) !=
"0"_L1;
373 mRotatedAnnotationsMinimumAngle = itemElem.attribute( u
"rotatedAnnotationsMinimumAngle"_s, u
"0"_s ).toDouble();
374 mRotatedAnnotationsMarginToCorner = itemElem.attribute( u
"rotatedAnnotationsMarginToCorner"_s, u
"0"_s ).toDouble();
376 const QDomElement lineStyleElem = itemElem.firstChildElement( u
"lineStyle"_s );
377 if ( !lineStyleElem.isNull() )
379 const QDomElement symbolElem = lineStyleElem.firstChildElement( u
"symbol"_s );
380 if ( !symbolElem.isNull() )
389 mGridLineSymbol->setWidth( itemElem.attribute( u
"penWidth"_s, u
"0"_s ).toDouble() );
390 mGridLineSymbol->setColor(
391 QColor( itemElem.attribute( u
"penColorRed"_s, u
"0"_s ).toInt(), itemElem.attribute( u
"penColorGreen"_s, u
"0"_s ).toInt(), itemElem.attribute( u
"penColorBlue"_s, u
"0"_s ).toInt() )
395 const QDomElement markerStyleElem = itemElem.firstChildElement( u
"markerStyle"_s );
396 if ( !markerStyleElem.isNull() )
398 const QDomElement symbolElem = markerStyleElem.firstChildElement( u
"symbol"_s );
399 if ( !symbolElem.isNull() )
405 if ( !mCRS.readXml( itemElem ) )
408 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( u
"blendMode"_s, u
"0"_s ).toUInt() );
411 mShowGridAnnotation = ( itemElem.attribute( u
"showAnnotation"_s, u
"0"_s ) !=
"0"_L1 );
413 mGridAnnotationExpressionString = itemElem.attribute( u
"annotationExpression"_s );
414 mGridAnnotationExpression.reset();
428 mAnnotationFrameDistance = itemElem.attribute( u
"frameAnnotationDistance"_s, u
"0"_s ).toDouble();
430 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
432 mAnnotationFormat.readXml( itemElem, context );
439 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
441 mAnnotationFormat.setFont( font );
442 mAnnotationFormat.setSize( font.pointSizeF() );
447 mGridAnnotationPrecision = itemElem.attribute( u
"annotationPrecision"_s, u
"3"_s ).toInt();
448 const int gridUnitInt = itemElem.attribute( u
"unit"_s, QString::number(
static_cast< int >(
Qgis::MapGridUnit::MapUnits ) ) ).toInt();
450 mMinimumIntervalWidth = itemElem.attribute( u
"minimumIntervalWidth"_s, u
"50"_s ).toDouble();
451 mMaximumIntervalWidth = itemElem.attribute( u
"maximumIntervalWidth"_s, u
"100"_s ).toDouble();
455 refreshDataDefinedProperties();
465 mTransformDirty =
true;
471 return mBlendMode != QPainter::CompositionMode_SourceOver;
474QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
476 const QTransform t = QTransform::fromScale( scale, scale );
477 return t.map( polygon );
480void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
482 if ( !
mMap || !mEvaluatedEnabled )
488 const QPolygonF mapPolygon =
mMap->transformedMapPolygon();
489 if ( mapPolygon != mPrevMapPolygon )
491 mTransformDirty =
true;
492 mPrevMapPolygon = mapPolygon;
495 if ( mTransformDirty )
497 calculateCrsTransformLines();
501 if ( !calculateLinesOnly )
503 int countLongitudeLines = 0;
504 int countLatitudeLines = 0;
505 for (
const GridLine &line : mGridLines )
507 switch ( line.coordinateType )
510 countLongitudeLines++;
513 countLatitudeLines++;
518 int latitudeLineIndex = 0;
519 int longitudeLineIndex = 0;
522 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
523 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
525 switch ( gridIt->coordinateType )
528 longitudeLineIndex++;
542 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
547 const double maxX =
mMap->rect().width();
548 const double maxY =
mMap->rect().height();
550 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
551 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
553 const double x = intersectionIt->x();
554 const double y = intersectionIt->y();
558 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
559 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
560 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
561 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
562 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
563 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
566 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
567 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
571 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
578void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
580 QgsRectangle crsBoundingRect;
581 QgsCoordinateTransform inverseTr;
582 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
589 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
590 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
597 QList< QgsGeometry > xLines;
598 QList< QgsGeometry > yLines;
599 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
600 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
603 for (
int i = 0; i < gridIt->line.size(); ++i )
605 line.append( QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
614 mTransformedIntersections.clear();
615 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
616 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
618 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
619 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
622 const QgsGeometry intersects = ( *yLineIt ).intersection( ( *xLineIt ) );
623 if ( intersects.
isNull() )
628 QgsPointXY vertex = intersects.
vertexAt( i );
631 mTransformedIntersections << vertex;
639 mTransformDirty =
false;
644 if ( !
mMap || !mEvaluatedEnabled )
648 QPaintDevice *paintDevice = p->device();
655 p->setCompositionMode( mBlendMode );
658 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
659 p->setClipRect( thisPaintRect );
660 if ( thisPaintRect != mPrevPaintRect )
663 mTransformDirty =
true;
664 mPrevPaintRect = thisPaintRect;
668 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
669 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
684 if ( mCRS.isValid() && mCRS !=
mMap->crs() )
686 drawGridCrsTransform( context, dotsPerMM );
693 drawGridNoTransform( context, dotsPerMM );
698 p->setClipping(
false );
702 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
707 updateGridLinesAnnotationsPositions();
714 if ( mShowGridAnnotation )
720void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
722 QList< GridLine >::iterator it = mGridLines.begin();
723 for ( ; it != mGridLines.end(); ++it )
725 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
726 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
727 it->startAnnotation.position = QVector2D( it->line.first() );
728 it->endAnnotation.position = QVector2D( it->line.last() );
729 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
730 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
732 it->startAnnotation.angle
733 = 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() );
735 it->endAnnotation.angle
736 = 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() );
740void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
747 if ( calculateLinesOnly || mGridLines.empty() )
750 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
751 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
753 int countLongitudeLines = 0;
754 int countLatitudeLines = 0;
755 for (
const GridLine &line : mGridLines )
757 switch ( line.coordinateType )
760 countLongitudeLines++;
763 countLatitudeLines++;
768 int latitudeLineIndex = 0;
769 int longitudeLineIndex = 0;
777 for ( ; vIt != mGridLines.constEnd(); ++vIt )
781 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
783 longitudeLineIndex++;
789 drawGridLine( line, context );
792 for ( ; hIt != mGridLines.constEnd(); ++hIt )
796 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
804 drawGridLine( line, context );
810 QPointF intersectionPoint, crossEnd1, crossEnd2;
811 for ( ; vIt != mGridLines.constEnd(); ++vIt )
816 l1 = QLineF( vIt->line.first(), vIt->line.last() );
819 hIt = mGridLines.constBegin();
820 for ( ; hIt != mGridLines.constEnd(); ++hIt )
825 l2 = QLineF( hIt->line.first(), hIt->line.last() );
827 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
837 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
841 drawGridMarker( intersectionPoint * dotsPerMM, context );
853 hIt = mGridLines.constBegin();
854 for ( ; hIt != mGridLines.constEnd(); ++hIt )
859 l1 = QLineF( hIt->line.first(), hIt->line.last() );
861 vIt = mGridLines.constBegin();
862 for ( ; vIt != mGridLines.constEnd(); ++vIt )
867 l2 = QLineF( vIt->line.first(), vIt->line.last() );
869 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
877 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
884void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
893 switch ( mGridFrameStyle )
897 drawGridFrameZebra( p, extension );
902 drawGridFrameTicks( p, extension );
907 drawGridFrameLine( p, extension );
918void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
921 poly << line.p1() << line.p2();
922 drawGridLine( poly, context );
925void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
927 if ( !
mMap || !
mMap->layout() || !mGridLineSymbol )
932 mGridLineSymbol->startRender( context );
933 mGridLineSymbol->renderPolyline( line,
nullptr, context );
934 mGridLineSymbol->stopRender( context );
937void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
939 if ( !
mMap || !
mMap->layout() || !mGridMarkerSymbol )
944 mGridMarkerSymbol->startRender( context );
945 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
946 mGridMarkerSymbol->stopRender( context );
949void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
969void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p,
Qgis::MapGridBorderSide border,
double *extension )
const
978 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
982 double currentCoord = 0.0;
989 bool drawTLBox =
false;
990 bool drawTRBox =
false;
991 bool drawBLBox =
false;
992 bool drawBRBox =
false;
994 QMap< double, double > pos = QMap< double, double >();
995 QList< GridLine >::const_iterator it = mGridLines.constBegin();
996 for ( ; it != mGridLines.constEnd(); ++it )
999 for (
int i = 0; i < 2; ++i )
1001 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1004 if ( annot.border != border )
1007 if ( !shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1011 pos.insert( annot.position.y(), it->coordinate );
1013 pos.insert( annot.position.x(), it->coordinate );
1020 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
1036 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
1040 QPen framePen = QPen( mGridFramePenColor );
1041 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1042 framePen.setJoinStyle( Qt::MiterJoin );
1043 p->setPen( framePen );
1045 QMap< double, double >::const_iterator posIt = pos.constBegin();
1046 for ( ; posIt != pos.constEnd(); ++posIt )
1048 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
1051 height = posIt.key() - currentCoord;
1052 width = mEvaluatedGridFrameWidth;
1058 height = mEvaluatedGridFrameWidth;
1059 width = posIt.key() - currentCoord;
1061 y = ( border ==
Qgis::MapGridBorderSide::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
1063 p->drawRect( QRectF( x, y, width, height ) );
1064 currentCoord = posIt.key();
1071 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin );
1072 p->setBrush( QBrush( mGridFrameFillColor1 ) );
1074 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1076 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1078 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1080 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1084void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1094 QPen framePen = QPen( mGridFramePenColor );
1095 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1096 framePen.setCapStyle( Qt::FlatCap );
1097 p->setBrush( Qt::NoBrush );
1098 p->setPen( framePen );
1101 QList< GridLine >::iterator it = mGridLines.begin();
1102 for ( ; it != mGridLines.end(); ++it )
1105 for (
int i = 0; i < 2; ++i )
1107 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1109 if ( !shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1113 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1121 facingLeft = ( annot.angle != 0 );
1122 facingRight = ( annot.angle != 0 );
1126 facingLeft = ( annot.angle > 0 );
1127 facingRight = ( annot.angle < 0 );
1131 facingLeft = ( annot.angle < 0 );
1132 facingRight = ( annot.angle > 0 );
1136 && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) || ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1139 && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) || ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1142 && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) || ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1145 && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) || ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1149 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1151 double fA = mEvaluatedGridFrameMargin;
1152 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1156 fA /= QVector2D::dotProduct( vector, normalVector );
1157 fB /= QVector2D::dotProduct( vector, normalVector );
1164 extension->UpdateBorder( annot.border, fB );
1172 pA = annot.position +
static_cast< float >( fA ) * vector;
1173 pB = annot.position +
static_cast< float >( fB ) * vector;
1177 pA = annot.position -
static_cast< float >( fA ) * vector;
1178 pB = annot.position -
static_cast< float >( fB ) * vector;
1182 pA = annot.position -
static_cast< float >( fB ) * vector;
1183 pB = annot.position +
static_cast< float >( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1185 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1190void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1200 QPen framePen = QPen( mGridFramePenColor );
1201 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1202 framePen.setCapStyle( Qt::SquareCap );
1203 p->setBrush( Qt::NoBrush );
1204 p->setPen( framePen );
1214 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1223 QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin )
1232 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1241 QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin )
1245 if ( !extension && drawDiagonals )
1250 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1251 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1252 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1257 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0;
1258 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0;
1259 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1264 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0;
1265 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1266 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1271 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1272 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0;
1273 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1280 if ( mGridLines.empty() )
1283 QString currentAnnotationString;
1284 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1286 QgsExpressionContextScope *gridScope =
new QgsExpressionContextScope();
1287 QgsExpressionContextScopePopper scopePopper( expressionContext, gridScope );
1289 bool geographic =
false;
1290 if ( mCRS.isValid() )
1292 geographic = mCRS.isGeographic();
1296 geographic =
mMap->crs().isGeographic();
1299 const bool forceWrap
1302 int countLongitudeLines = 0;
1303 int countLatitudeLines = 0;
1304 for (
const GridLine &line : mGridLines )
1306 switch ( line.coordinateType )
1309 countLongitudeLines++;
1312 countLatitudeLines++;
1317 int latitudeLineIndex = 0;
1318 int longitudeLineIndex = 0;
1319 for ( ; it != mGridLines.constEnd(); ++it )
1321 double value = it->coordinate;
1322 switch ( it->coordinateType )
1325 longitudeLineIndex++;
1326 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_count"_s, countLongitudeLines,
true ) );
1327 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_index"_s, longitudeLineIndex,
true ) );
1328 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_axis"_s, u
"x"_s,
true ) );
1332 latitudeLineIndex++;
1333 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_count"_s, countLatitudeLines,
true ) );
1334 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_index"_s, latitudeLineIndex,
true ) );
1335 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_axis"_s, u
"y"_s,
true ) );
1342 const double wrappedX = std::fmod( value, 360.0 );
1343 if ( wrappedX > 180.0 )
1345 value = wrappedX - 360.0;
1347 else if ( wrappedX < -180.0 )
1349 value = wrappedX + 360.0;
1353 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_number"_s, value,
true ) );
1355 if ( mDrawAnnotationProperty )
1358 const bool display = mDrawAnnotationProperty->valueAsBool( expressionContext,
true, &ok );
1359 if ( ok && !display )
1362 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext, geographic );
1363 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1364 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1368void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
1377 if ( !shouldShowAnnotationForSide( coordinateType, annot.border ) )
1381 std::unique_ptr< QgsScopedQPainterState > painterState;
1382 double dotsPerMM = 1;
1386 painterState = std::make_unique< QgsScopedQPainterState >( context.
painter() );
1387 dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
1388 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1399 double textWidthPainterUnits = sizePainterUnits.width();
1401 textWidthPainterUnits *= 1.1;
1403 const double textWidthMM = textWidthPainterUnits * painterUnitsToMM;
1405 double textHeightPainterUnits = 0;
1406 if ( extension || doc.
size() > 1 )
1408 textHeightPainterUnits = sizePainterUnits.height();
1417 const double textHeightMM = textHeightPainterUnits * painterUnitsToMM;
1423 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1427 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1430 double distanceToFrameMM = mEvaluatedAnnotationFrameDistance;
1435 const bool hasExteriorMargin
1438 const bool hasBorderWidth
1441 distanceToFrameMM += mEvaluatedGridFrameWidth;
1442 if ( hasBorderWidth )
1443 distanceToFrameMM += mEvaluatedGridFrameLineThickness / 2.0;
1446 distanceToFrameMM *= -1;
1450 distanceToFrameMM /= QVector2D::dotProduct( vector, normalVector );
1453 QPointF annotationPositionMM = ( annot.position +
static_cast< float >( distanceToFrameMM ) * vector ).toPointF();
1458 double rotation = 0;
1462 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1464 if ( rotation <= -90 || rotation > 90 )
1467 anchorMM.setX( outside ? 0 : textWidthMM );
1471 anchorMM.setX( outside ? textWidthMM : 0 );
1475 anchorMM.setY( 0.5 * textHeightMM );
1477 anchorMM.setY( -1.5 * textHeightMM );
1479 anchorMM.setY( -0.5 * textHeightMM );
1484 anchorMM.setX( 0.5 * textWidthMM );
1485 anchorMM.setY( -0.5 * textHeightMM );
1487 anchorMM.setY( outside ? 0 : -textHeightMM );
1489 anchorMM.setX( outside ? 0 : textWidthMM );
1491 anchorMM.setY( outside ? -textHeightMM : 0 );
1493 anchorMM.setX( outside ? textWidthMM : 0 );
1498 anchorMM.setX( 0.5 * textWidthMM );
1499 anchorMM.setY( -0.5 * textHeightMM );
1501 anchorMM.setX( outside ? 0 : textWidthMM );
1503 anchorMM.setY( outside ? -textHeightMM : 0 );
1505 anchorMM.setX( outside ? textWidthMM : 0 );
1507 anchorMM.setY( outside ? 0 : -textHeightMM );
1512 anchorMM.setX( 0.5 * textWidthMM );
1513 anchorMM.setY( -0.5 * textHeightMM );
1515 anchorMM.setX( outside ? textWidthMM : 0 );
1517 anchorMM.setY( outside ? 0 : -textHeightMM );
1519 anchorMM.setX( outside ? 0 : textWidthMM );
1521 anchorMM.setY( outside ? -textHeightMM : 0 );
1526 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1527 anchorMM.setX( 0.5 * textWidthMM );
1529 anchorMM.setY( -textHeightMM );
1537 extension->UpdateBorder( frameBorder, -distanceToFrameMM + std::max( textHeightMM, textWidthMM ) );
1539 extension->UpdateAll( std::max( textHeightMM, textWidthMM ) / 2.0 );
1542 if ( extension || !context.
painter() )
1546 bool facingLeft = ( annot.angle < 0 );
1547 bool facingRight = ( annot.angle > 0 );
1550 facingLeft = !facingLeft;
1551 facingRight = !facingRight;
1554 && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1557 && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1560 && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1563 && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1570 QPointF textPos( 0, 0 );
1571 switch ( annot.border )
1588 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1591 textPos.setX( textWidthMM / painterUnitsToMM );
1597 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1619 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1622 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1626 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1641 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1666 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1669 textPos.setX( textWidthMM / painterUnitsToMM );
1681 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1702 context.
painter()->translate( QPointF( annotationPositionMM.x(), annotationPositionMM.y() ) / painterUnitsToMM );
1703 context.
painter()->rotate( rotation );
1704 context.
painter()->translate( -anchorMM / painterUnitsToMM );
1715 return QString::number( value,
'f', mGridAnnotationPrecision );
1721 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1725 if ( !isGeographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1727 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1733 if ( !isGeographic || coordRounded != 0.0 )
1735 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1741 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1745 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1750 if ( !mGridAnnotationExpression )
1752 mGridAnnotationExpression = std::make_unique<QgsExpression>( mGridAnnotationExpressionString );
1753 mGridAnnotationExpression->prepare( &expressionContext );
1755 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1760 switch ( mGridAnnotationFormat )
1810int QgsLayoutItemMapGrid::xGridLines()
const
1812 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1818 QPolygonF mapPolygon =
mMap->transformedMapPolygon();
1819 QRectF mapBoundingRect = mapPolygon.boundingRect();
1820 double gridIntervalY = mEvaluatedIntervalY;
1821 double gridOffsetY = mEvaluatedOffsetY;
1822 double annotationScale = 1.0;
1823 switch ( mGridUnit )
1828 mapBoundingRect =
mMap->rect();
1829 mapPolygon = QPolygonF(
mMap->rect() );
1832 annotationScale = 0.1;
1833 gridIntervalY *= 10;
1845 const double roundCorrection = mapBoundingRect.top() > gridOffsetY ? 1.0 : 0.0;
1846 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1848 int gridLineCount = 0;
1853 double yCanvasCoord;
1854 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1856 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1858 newLine.coordinate = currentLevel * annotationScale;
1860 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1861 mGridLines.append( newLine );
1862 currentLevel += gridIntervalY;
1869 QVector<QLineF> borderLines;
1870 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1871 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1872 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1873 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1875 QVector<QPointF> intersectionList;
1877 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1879 intersectionList.clear();
1880 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1882 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1883 for ( ; it != borderLines.constEnd(); ++it )
1885 QPointF intersectionPoint;
1886 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1888 intersectionList.push_back( intersectionPoint );
1889 if ( intersectionList.size() >= 2 )
1896 if ( intersectionList.size() >= 2 )
1899 newLine.coordinate = currentLevel;
1901 newLine.line = QPolygonF() <<
mMap->mapToItemCoords( intersectionList.at( 0 ) ) <<
mMap->mapToItemCoords( intersectionList.at( 1 ) );
1902 mGridLines.append( newLine );
1905 currentLevel += gridIntervalY;
1912int QgsLayoutItemMapGrid::yGridLines()
const
1914 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1919 QPolygonF mapPolygon =
mMap->transformedMapPolygon();
1920 QRectF mapBoundingRect = mapPolygon.boundingRect();
1921 double gridIntervalX = mEvaluatedIntervalX;
1922 double gridOffsetX = mEvaluatedOffsetX;
1923 double annotationScale = 1.0;
1924 switch ( mGridUnit )
1929 mapBoundingRect =
mMap->rect();
1930 mapPolygon = QPolygonF(
mMap->rect() );
1933 annotationScale = 0.1;
1934 gridIntervalX *= 10;
1946 const double roundCorrection = mapBoundingRect.left() > gridOffsetX ? 1.0 : 0.0;
1947 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1949 int gridLineCount = 0;
1953 double xCanvasCoord;
1954 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1956 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1959 newLine.coordinate = currentLevel * annotationScale;
1961 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1962 mGridLines.append( newLine );
1963 currentLevel += gridIntervalX;
1970 QVector<QLineF> borderLines;
1971 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1972 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1973 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1974 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1976 QVector<QPointF> intersectionList;
1978 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1980 intersectionList.clear();
1981 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1983 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1984 for ( ; it != borderLines.constEnd(); ++it )
1986 QPointF intersectionPoint;
1987 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1989 intersectionList.push_back( intersectionPoint );
1990 if ( intersectionList.size() >= 2 )
1997 if ( intersectionList.size() >= 2 )
2000 newLine.coordinate = currentLevel;
2002 newLine.line = QPolygonF() <<
mMap->mapToItemCoords( intersectionList.at( 0 ) ) <<
mMap->mapToItemCoords( intersectionList.at( 1 ) );
2003 mGridLines.append( newLine );
2006 currentLevel += gridIntervalX;
2014 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
2019 const double roundCorrection = bbox.
yMaximum() > mEvaluatedOffsetY ? 1.0 : 0.0;
2020 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
2022 const double minX = bbox.
xMinimum();
2023 const double maxX = bbox.
xMaximum();
2024 double step = ( maxX - minX ) / 20;
2026 bool crosses180 =
false;
2027 bool crossed180 =
false;
2028 if ( mCRS.isGeographic() && ( minX > maxX ) )
2032 step = ( maxX + 360.0 - minX ) / 20;
2038 int gridLineCount = 0;
2042 double currentX = minX;
2046 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
2053 const QgsPointXY mapPoint = t.
transform( currentX, currentLevel );
2054 gridLine.append(
mMap->mapToItemCoords( QPointF( mapPoint.
x(), mapPoint.
y() ) ) );
2056 catch ( QgsCsException &cse )
2063 if ( crosses180 && currentX > 180.0 )
2071 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, QgsRectangle(
mMap->rect() ) );
2072 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
2073 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
2075 if ( !( *lineIt ).isEmpty() )
2078 newLine.coordinate = currentLevel;
2080 newLine.line = QPolygonF( *lineIt );
2081 mGridLines.append( newLine );
2085 currentLevel -= mEvaluatedIntervalY;
2093 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
2098 const double roundCorrection = bbox.
xMinimum() > mEvaluatedOffsetX ? 1.0 : 0.0;
2099 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
2101 const double minY = bbox.
yMinimum();
2102 const double maxY = bbox.
yMaximum();
2103 const double step = ( maxY - minY ) / 20;
2108 bool crosses180 =
false;
2109 bool crossed180 =
false;
2116 int gridLineCount = 0;
2117 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
2120 double currentY = minY;
2124 if ( currentY > maxY )
2131 const QgsPointXY mapPoint = t.
transform( currentLevel, currentY );
2133 gridLine.append(
mMap->mapToItemCoords( QPointF( mapPoint.
x(), mapPoint.
y() ) ) );
2135 catch ( QgsCsException &cse )
2144 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, QgsRectangle(
mMap->rect() ) );
2145 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
2146 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
2148 if ( !( *lineIt ).isEmpty() )
2151 newLine.coordinate = currentLevel;
2153 newLine.line = QPolygonF( *lineIt );
2154 mGridLines.append( newLine );
2158 currentLevel += mEvaluatedIntervalX;
2159 if ( crosses180 && currentLevel > 180.0 )
2161 currentLevel -= 360.0;
2190 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
2192 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
2194 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
2196 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
2210 if ( ddValue.compare(
"x_only"_L1, Qt::CaseInsensitive ) == 0 )
2212 else if ( ddValue.compare(
"y_only"_L1, Qt::CaseInsensitive ) == 0 )
2214 else if ( ddValue.compare(
"disabled"_L1, Qt::CaseInsensitive ) == 0 )
2216 else if ( ddValue.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
2222void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
2227 mTransformDirty = mTransformDirty
2238 mDrawAnnotationProperty->prepare( context );
2242 mDrawAnnotationProperty.reset();
2245 switch ( mGridUnit )
2258 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
2260 mEvaluatedEnabled =
false;
2265 const double mapWidthMapUnits = mapWidth();
2266 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
2267 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
2269 mEvaluatedIntervalX = interval;
2270 mEvaluatedIntervalY = interval;
2271 mTransformDirty =
true;
2283 mEvaluatedLeftGridAnnotationDisplay
2285 mEvaluatedRightGridAnnotationDisplay
2287 mEvaluatedTopGridAnnotationDisplay
2289 mEvaluatedBottomGridAnnotationDisplay
2294 mEvaluatedBottomFrameDivisions
2298double QgsLayoutItemMapGrid::mapWidth()
const
2305 const QgsRectangle mapExtent =
mMap->extent();
2309 return mapExtent.
width();
2325 catch ( QgsCsException & )
2328 QgsDebugError( u
"An error occurred while calculating length"_s );
2334bool sortByDistance( QPair<qreal, Qgis::MapGridBorderSide> a, QPair<qreal, Qgis::MapGridBorderSide> b )
2336 return a.first < b.first;
2346 const double tolerance = std::max(
mMap->frameEnabled() ?
mMap->pen().widthF() : 0.0, 1.0 );
2350 ( p.y() <= tolerance && p.x() <= tolerance )
2351 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2352 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2353 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2359 if ( p.x() <= tolerance )
2370 if ( p.y() <= tolerance )
2382 QList< QPair<qreal, Qgis::MapGridBorderSide > > distanceToSide;
2388 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2389 return distanceToSide.at( 0 ).second;
2394 mGridLineSymbol.reset( symbol );
2399 return mGridLineSymbol.get();
2404 return mGridLineSymbol.get();
2409 mGridMarkerSymbol.reset( symbol );
2414 return mGridMarkerSymbol.get();
2419 return mGridMarkerSymbol.get();
2424 mAnnotationFormat.setFont( font );
2425 if ( font.pointSizeF() > 0 )
2427 mAnnotationFormat.setSize( font.pointSizeF() );
2430 else if ( font.pixelSize() > 0 )
2432 mAnnotationFormat.setSize( font.pixelSize() );
2439 return mAnnotationFormat.toQFont();
2444 mAnnotationFormat.
setColor( color );
2449 return mAnnotationFormat.color();
2457 mLeftGridAnnotationDisplay = display;
2460 mRightGridAnnotationDisplay = display;
2463 mTopGridAnnotationDisplay = display;
2466 mBottomGridAnnotationDisplay = display;
2470 refreshDataDefinedProperties();
2474 mMap->updateBoundingRect();
2484 return mLeftGridAnnotationDisplay;
2486 return mRightGridAnnotationDisplay;
2488 return mTopGridAnnotationDisplay;
2490 return mBottomGridAnnotationDisplay;
2492 return mBottomGridAnnotationDisplay;
2499 double bottom = 0.0;
2502 return std::max( std::max( std::max( top, right ), bottom ), left );
2512 if ( !
mMap || !mEvaluatedEnabled )
2522 GridExtension extension;
2525 switch ( mGridUnit )
2530 if ( mCRS.isValid() && mCRS !=
mMap->crs() )
2532 drawGridCrsTransform( context, 0,
true );
2539 drawGridNoTransform( context, 0,
true );
2544 updateGridLinesAnnotationsPositions();
2548 drawGridFrame(
nullptr, &extension );
2551 if ( mShowGridAnnotation )
2556 top = extension.top;
2557 right = extension.right;
2558 bottom = extension.bottom;
2559 left = extension.left;
2565 refreshDataDefinedProperties();
2570 if ( unit == mGridUnit )
2575 mTransformDirty =
true;
2584 mGridIntervalX = interval;
2585 mTransformDirty =
true;
2586 refreshDataDefinedProperties();
2595 mGridIntervalY = interval;
2596 mTransformDirty =
true;
2597 refreshDataDefinedProperties();
2606 mGridOffsetX = offset;
2607 mTransformDirty =
true;
2608 refreshDataDefinedProperties();
2617 mGridOffsetY = offset;
2618 mTransformDirty =
true;
2619 refreshDataDefinedProperties();
2628 mMinimumIntervalWidth = minWidth;
2629 mTransformDirty =
true;
2630 refreshDataDefinedProperties();
2639 mMaximumIntervalWidth = maxWidth;
2640 mTransformDirty =
true;
2641 refreshDataDefinedProperties();
2646 if (
style == mGridStyle )
2651 mTransformDirty =
true;
2656 mCrossLength = length;
2657 refreshDataDefinedProperties();
2665 mLeftGridAnnotationDirection = direction;
2668 mRightGridAnnotationDirection = direction;
2671 mTopGridAnnotationDirection = direction;
2674 mBottomGridAnnotationDirection = direction;
2680 mMap->updateBoundingRect();
2687 mGridFrameSides = flags;
2692 mGridFrameSides.setFlag( flag, on );
2697 return mGridFrameSides;
2712 if ( mGridLineSymbol )
2718 if ( mGridMarkerSymbol )
2730 mTransformDirty =
true;
2731 refreshDataDefinedProperties();
2732 mMap->updateBoundingRect();
2738 return mGridFrameSides.testFlag( flag );
2743 mGridFrameWidth = width;
2744 refreshDataDefinedProperties();
2749 mGridFrameMargin = margin;
2750 refreshDataDefinedProperties();
2755 mGridFramePenThickness = width;
2756 refreshDataDefinedProperties();
2766 mHAlign = alignment;
2771 mLeftGridAnnotationDirection = direction;
2772 mRightGridAnnotationDirection = direction;
2773 mTopGridAnnotationDirection = direction;
2774 mBottomGridAnnotationDirection = direction;
2782 mLeftGridAnnotationPosition = position;
2785 mRightGridAnnotationPosition = position;
2788 mTopGridAnnotationPosition = position;
2791 mBottomGridAnnotationPosition = position;
2797 mMap->updateBoundingRect();
2807 return mLeftGridAnnotationPosition;
2809 return mRightGridAnnotationPosition;
2811 return mTopGridAnnotationPosition;
2813 return mBottomGridAnnotationPosition;
2815 return mLeftGridAnnotationPosition;
2820 mAnnotationFrameDistance = distance;
2821 refreshDataDefinedProperties();
2828 return mLeftGridAnnotationDirection;
2834 return mLeftGridAnnotationDirection;
2836 return mRightGridAnnotationDirection;
2838 return mTopGridAnnotationDirection;
2840 return mBottomGridAnnotationDirection;
2842 return mLeftGridAnnotationDirection;
2847 mGridAnnotationExpressionString = expression;
2848 mGridAnnotationExpression.reset();
2856 mLeftFrameDivisions = divisions;
2859 mRightFrameDivisions = divisions;
2862 mTopFrameDivisions = divisions;
2865 mBottomFrameDivisions = divisions;
2869 refreshDataDefinedProperties();
2882 return mLeftFrameDivisions;
2884 return mRightFrameDivisions;
2886 return mTopFrameDivisions;
2888 return mBottomFrameDivisions;
2890 return mLeftFrameDivisions;
2902 const QgsCoordinateTransform tr(
mMap->crs(), mCRS,
mLayout->project() );
2903 QgsCoordinateTransform extentTransform = tr;
2905 const QPolygonF mapPolygon =
mMap->transformedMapPolygon();
2906 const QRectF mbr = mapPolygon.boundingRect();
2907 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2910 if ( mCRS.isGeographic() )
2913 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2914 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2916 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2917 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2919 if ( lowerLeft.x() > upperRight.x() )
2935 inverseTransform = QgsCoordinateTransform( mCRS,
mMap->crs(),
mLayout->project() );
2937 catch ( QgsCsException &cse )
2946QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2951 const QgsGeometry intersected = lineGeom.
intersection( rectGeom );
2954 QList<QPolygonF> trimmedLines;
2955 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2956 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2958 trimmedLines << ( *geomIt ).asQPolygonF();
2960 return trimmedLines;
3035 refreshDataDefinedProperties();
Provides global constants and enumerations for use throughout the application.
MapGridTickLengthMode
Map grid tick length mode (useful for rotated grids).
@ OrthogonalTicks
Align ticks orthogonaly.
QFlags< MapGridFrameSideFlag > MapGridFrameSideFlags
Flags for controlling which side of the map a frame is drawn on.
@ 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.
MapGridAnnotationPosition
Position for map grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
MapGridUnit
Units for map grid values.
@ Centimeters
Grid units in centimeters.
@ Millimeters
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnits
Grid units follow map units.
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
MapGridBorderSide
Border sides for map grid annotations.
MapGridFrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ Bottom
Bottom side of map.
@ Right
Right side of map.
@ Point
Text at point of origin layout mode.
MapGridComponentVisibility
Visibility display settings for map grid annotations and frames.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
@ Horizontal
Horizontally oriented text.
MapGridStyle
Map grid drawing styles.
@ LineCrosses
Draw line crosses at intersections of grid lines.
@ Markers
Draw markers at intersections of grid lines.
@ Lines
Draw lines for grid.
@ FrameAndAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
@ 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 ...
MapGridAnnotationType
Annotation coordinate type.
@ Latitude
Coordinate is a latitude value.
@ Longitude
Coordinate is a longitude value.
MapGridFrameStyle
Style for map grid frames.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ NoFrame
Disable grid frame.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ Zebra
Black/white pattern.
@ LineBorder
Simple solid line frame.
@ InteriorTicks
Tick markers drawn inside map frame.
MapGridAnnotationDirection
Direction of grid annotations.
@ Vertical
Draw annotations vertically, ascending.
@ UnderTick
Draw annotations parallel to tick (under the line).
@ VerticalDescending
Draw annotations vertically, descending.
@ BoundaryDirection
Annotations follow the boundary direction.
@ AboveTick
Draw annotations parallel to tick (above the line).
@ OnTick
Draw annotations parallel to tick (on the line).
@ Horizontal
Draw annotations horizontally.
TextHorizontalAlignment
Text horizontal alignment.
MapGridAnnotationFormat
Format for displaying map grid annotations.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ CustomFormat
Custom expression-based format.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ Forward
Forward transform (from source to destination).
@ Antialiasing
Use antialiasing when drawing items.
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).
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.
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 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(Qgis::MapGridFrameSideFlags flags)
Sets flags for grid frame sides.
void setRotatedTicksLengthMode(const Qgis::MapGridTickLengthMode mode)
Sets the tick length calculation mode.
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.
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.
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.
void setAnnotationDisplay(Qgis::MapGridComponentVisibility display, Qgis::MapGridBorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
void setFrameStyle(const Qgis::MapGridFrameStyle style)
Sets the grid frame style.
void setUnits(Qgis::MapGridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used 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.
void setStyle(Qgis::MapGridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
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 setRotatedTicksEnabled(const bool state)
Enable/disable ticks rotation for rotated or reprojected grids.
Qgis::MapGridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
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...
void setFrameDivisions(Qgis::MapGridComponentVisibility divisions, Qgis::MapGridBorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
Qgis::MapGridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
double rotatedTicksMinimumAngle() const
Gets the minimum angle (in degrees) below which ticks are not drawn.
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...
Qgis::MapGridTickLengthMode rotatedAnnotationsLengthMode() const
Returns the annotation length calculation mode.
Qgis::MapGridFrameStyle frameStyle() const
Returns the grid frame style.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
friend class QgsLayoutItemMap
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 setAnnotationDirection(Qgis::MapGridAnnotationDirection direction, Qgis::MapGridBorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
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.
Qgis::MapGridTickLengthMode rotatedTicksLengthMode() const
Returns the grid frame style.
~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.
Qgis::MapGridComponentVisibility frameDivisions(Qgis::MapGridBorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
Qgis::MapGridFrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
void setAnnotationPosition(Qgis::MapGridAnnotationPosition position, Qgis::MapGridBorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
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.
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 setRotatedAnnotationsLengthMode(const Qgis::MapGridTickLengthMode mode)
Sets the annotation length calculation mode.
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.
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.
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.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
bool testFrameSideFlag(Qgis::MapGridFrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
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.
void setAnnotationFormat(const Qgis::MapGridAnnotationFormat format)
Sets the format for drawing grid annotations.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
Qgis::MapGridComponentVisibility annotationDisplay(Qgis::MapGridBorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
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).
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
Qgis::MapGridAnnotationFormat annotationFormat() const
Returns the format for drawing grid annotations.
void setFrameSideFlag(Qgis::MapGridFrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
Qgis::MapGridAnnotationDirection annotationDirection(Qgis::MapGridBorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
Qgis::MapGridAnnotationPosition annotationPosition(Qgis::MapGridBorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
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...
double maximumIntervalWidth() const
Returns the maximum width (in millimeters) for grid segments.
Qgis::TextHorizontalAlignment horizontalAlignment() const
Returns the horizontal alignment for annotation text.
void setHorizontalAlignment(Qgis::TextHorizontalAlignment alignment)
Sets the horizontal alignment for annotation text.
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
double intervalX() const
Returns the interval between grid lines in the x-direction.
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.
QgsLayoutItemMapItemStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapItemStack, attached to the specified map.
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.
QString name() const
Returns the friendly display name for the item.
QgsLayoutItemMapItem(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapItem, attached to the specified map.
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...
const QgsLayoutItemMap * map() const
Returns the layout item map for the item.
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
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.
@ MapGridDrawAnnotation
Map annotation visibility (for individual annotations).
@ 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.
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].
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.
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.
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 std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
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) const
Sets the color for the symbol.
QSizeF documentSize(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the overall size of the document.
static QgsTextDocumentMetrics calculateMetrics(const QgsTextDocument &document, const QgsTextFormat &format, const QgsRenderContext &context, double scaleFactor=1.0, const QgsTextDocumentRenderContext &documentContext=QgsTextDocumentRenderContext())
Returns precalculated text metrics for a text document, when rendered using the given base format and...
int size() const
Returns the number of blocks in the document.
static QgsTextDocument fromTextAndFormat(const QStringList &lines, const QgsTextFormat &format)
Constructor for QgsTextDocument consisting of a set of lines, respecting settings from a text format.
static void drawDocument(const QRectF &rect, const QgsTextFormat &format, const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics, QgsRenderContext &context, Qgis::TextHorizontalAlignment horizontalAlignment=Qgis::TextHorizontalAlignment::Left, Qgis::TextVerticalAlignment verticalAlignment=Qgis::TextVerticalAlignment::Top, double rotation=0, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws a text document within a rectangle using the specified settings.
static double calculateScaleFactorForFormat(const QgsRenderContext &context, const QgsTextFormat &format)
Returns the scale factor used for upscaling font sizes and downscaling destination painter devices.
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
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
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.
QVector2D borderToVector2D(Qgis::MapGridBorderSide border)
bool sortByDistance(QPair< qreal, Qgis::MapGridBorderSide > a, QPair< qreal, Qgis::MapGridBorderSide > b)
Qgis::MapGridComponentVisibility gridAnnotationDisplayModeFromDD(QString ddValue, Qgis::MapGridComponentVisibility defValue)
QVector2D borderToNormal2D(Qgis::MapGridBorderSide border)
#define QgsDebugError(str)
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to the style entity currently being visited.