53#include "moc_qgslayoutitemmapgrid.cpp"
55using namespace Qt::StringLiterals;
57#define MAX_GRID_LINES 1000
88 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
94 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
99 QList< QgsLayoutItemMapGrid * > list;
122 const QDomNodeList mapGridNodeList = elem.elementsByTagName( u
"ComposerMapGrid"_s );
123 for (
int i = 0; i < mapGridNodeList.size(); ++i )
125 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
127 mapGrid->
readXml( mapGridElem, doc, context );
141 return std::max( std::max( std::max( top, right ), bottom ), left );
155 double gridTop = 0.0;
156 double gridRight = 0.0;
157 double gridBottom = 0.0;
158 double gridLeft = 0.0;
159 grid->calculateMaxExtension( gridTop, gridRight, gridBottom, gridLeft );
160 top = std::max( top, gridTop );
161 right = std::max( right, gridRight );
162 bottom = std::max( bottom, gridBottom );
163 left = std::max( left, gridLeft );
179 return QVector2D( 0, 1 );
181 return QVector2D( -1, 0 );
183 return QVector2D( 0, -1 );
185 return QVector2D( 1, 0 );
193 return QVector2D( borderVector.y(), -borderVector.x() );
198 , mGridFrameSides(
Qgis::MapGridFrameSideFlag::
Left |
Qgis::MapGridFrameSideFlag::
Right |
199 Qgis::MapGridFrameSideFlag::Top |
Qgis::MapGridFrameSideFlag::Bottom )
203 const QString defaultFontString = settings.
value( u
"LayoutDesigner/defaultFont"_s, QVariant(),
QgsSettings::Gui ).toString();
204 if ( !defaultFontString.isEmpty() )
207 QgsFontUtils::setFontFamily( font, defaultFontString );
208 mAnnotationFormat.setFont( font );
211 createDefaultGridLineSymbol();
212 createDefaultGridMarkerSymbol();
218 if ( !mCRS.isValid() )
225void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
227 QVariantMap properties;
228 properties.insert( u
"color"_s, u
"0,0,0,255"_s );
229 properties.insert( u
"width"_s, u
"0.3"_s );
230 properties.insert( u
"capstyle"_s, u
"flat"_s );
234void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
236 QVariantMap properties;
237 properties.insert( u
"name"_s, u
"circle"_s );
238 properties.insert( u
"size"_s, u
"2.0"_s );
239 properties.insert( u
"color"_s, u
"0,0,0,255"_s );
245 if ( mGridLineSymbol )
247 mGridLineSymbol->setWidth( width );
253 if ( mGridLineSymbol )
255 mGridLineSymbol->setColor(
c );
266 QDomElement mapGridElem = doc.createElement( u
"ComposerMapGrid"_s );
267 mapGridElem.setAttribute( u
"gridStyle"_s,
static_cast< int >( mGridStyle ) );
274 QDomElement lineStyleElem = doc.createElement( u
"lineStyle"_s );
276 lineStyleElem.appendChild( gridLineStyleElem );
277 mapGridElem.appendChild( lineStyleElem );
279 QDomElement markerStyleElem = doc.createElement( u
"markerStyle"_s );
281 markerStyleElem.appendChild( gridMarkerStyleElem );
282 mapGridElem.appendChild( markerStyleElem );
284 mapGridElem.setAttribute( u
"gridFrameStyle"_s,
static_cast< int >( mGridFrameStyle ) );
285 mapGridElem.setAttribute( u
"gridFrameSideFlags"_s, mGridFrameSides );
286 mapGridElem.setAttribute( u
"gridFrameWidth"_s,
qgsDoubleToString( mGridFrameWidth ) );
287 mapGridElem.setAttribute( u
"gridFrameMargin"_s,
qgsDoubleToString( mGridFrameMargin ) );
288 mapGridElem.setAttribute( u
"gridFramePenThickness"_s,
qgsDoubleToString( mGridFramePenThickness ) );
292 mapGridElem.setAttribute( u
"leftFrameDivisions"_s,
static_cast< int >( mLeftFrameDivisions ) );
293 mapGridElem.setAttribute( u
"rightFrameDivisions"_s,
static_cast< int >( mRightFrameDivisions ) );
294 mapGridElem.setAttribute( u
"topFrameDivisions"_s,
static_cast< int >( mTopFrameDivisions ) );
295 mapGridElem.setAttribute( u
"bottomFrameDivisions"_s,
static_cast< int >( mBottomFrameDivisions ) );
296 mapGridElem.setAttribute( u
"rotatedTicksLengthMode"_s,
static_cast< int >( mRotatedTicksLengthMode ) );
297 mapGridElem.setAttribute( u
"rotatedTicksEnabled"_s, mRotatedTicksEnabled );
298 mapGridElem.setAttribute( u
"rotatedTicksMinimumAngle"_s, QString::number( mRotatedTicksMinimumAngle ) );
299 mapGridElem.setAttribute( u
"rotatedTicksMarginToCorner"_s, QString::number( mRotatedTicksMarginToCorner ) );
300 mapGridElem.setAttribute( u
"rotatedAnnotationsLengthMode"_s,
static_cast< int >( mRotatedAnnotationsLengthMode ) );
301 mapGridElem.setAttribute( u
"rotatedAnnotationsEnabled"_s, mRotatedAnnotationsEnabled );
302 mapGridElem.setAttribute( u
"rotatedAnnotationsMinimumAngle"_s, QString::number( mRotatedAnnotationsMinimumAngle ) );
303 mapGridElem.setAttribute( u
"rotatedAnnotationsMarginToCorner"_s, QString::number( mRotatedAnnotationsMarginToCorner ) );
304 if ( mCRS.isValid() )
306 mCRS.writeXml( mapGridElem, doc );
309 mapGridElem.setAttribute( u
"annotationFormat"_s,
static_cast< int >( mGridAnnotationFormat ) );
310 mapGridElem.setAttribute( u
"showAnnotation"_s, mShowGridAnnotation );
311 mapGridElem.setAttribute( u
"annotationExpression"_s, mGridAnnotationExpressionString );
312 mapGridElem.setAttribute( u
"leftAnnotationDisplay"_s,
static_cast< int >( mLeftGridAnnotationDisplay ) );
313 mapGridElem.setAttribute( u
"rightAnnotationDisplay"_s,
static_cast< int >( mRightGridAnnotationDisplay ) );
314 mapGridElem.setAttribute( u
"topAnnotationDisplay"_s,
static_cast< int >( mTopGridAnnotationDisplay ) );
315 mapGridElem.setAttribute( u
"bottomAnnotationDisplay"_s,
static_cast< int >( mBottomGridAnnotationDisplay ) );
316 mapGridElem.setAttribute( u
"leftAnnotationPosition"_s,
static_cast< int >( mLeftGridAnnotationPosition ) );
317 mapGridElem.setAttribute( u
"rightAnnotationPosition"_s,
static_cast< int >( mRightGridAnnotationPosition ) );
318 mapGridElem.setAttribute( u
"topAnnotationPosition"_s,
static_cast< int >( mTopGridAnnotationPosition ) );
319 mapGridElem.setAttribute( u
"bottomAnnotationPosition"_s,
static_cast< int >( mBottomGridAnnotationPosition ) );
320 mapGridElem.setAttribute( u
"leftAnnotationDirection"_s,
static_cast< int >( mLeftGridAnnotationDirection ) );
321 mapGridElem.setAttribute( u
"rightAnnotationDirection"_s,
static_cast< int >( mRightGridAnnotationDirection ) );
322 mapGridElem.setAttribute( u
"topAnnotationDirection"_s,
static_cast< int >( mTopGridAnnotationDirection ) );
323 mapGridElem.setAttribute( u
"bottomAnnotationDirection"_s,
static_cast< int >( mBottomGridAnnotationDirection ) );
324 mapGridElem.setAttribute( u
"frameAnnotationDistance"_s, QString::number( mAnnotationFrameDistance ) );
325 mapGridElem.appendChild( mAnnotationFormat.writeXml( doc, context ) );
326 mapGridElem.setAttribute( u
"annotationPrecision"_s, mGridAnnotationPrecision );
327 mapGridElem.setAttribute( u
"unit"_s,
static_cast< int >( mGridUnit ) );
328 mapGridElem.setAttribute( u
"blendMode"_s, mBlendMode );
329 mapGridElem.setAttribute( u
"minimumIntervalWidth"_s, QString::number( mMinimumIntervalWidth ) );
330 mapGridElem.setAttribute( u
"maximumIntervalWidth"_s, QString::number( mMaximumIntervalWidth ) );
338 elem.appendChild( mapGridElem );
345 if ( itemElem.isNull() )
353 mGridStyle =
static_cast< Qgis::MapGridStyle >( itemElem.attribute( u
"gridStyle"_s, u
"0"_s ).toInt() );
354 mGridIntervalX = itemElem.attribute( u
"intervalX"_s, u
"0"_s ).toDouble();
355 mGridIntervalY = itemElem.attribute( u
"intervalY"_s, u
"0"_s ).toDouble();
356 mGridOffsetX = itemElem.attribute( u
"offsetX"_s, u
"0"_s ).toDouble();
357 mGridOffsetY = itemElem.attribute( u
"offsetY"_s, u
"0"_s ).toDouble();
358 mCrossLength = itemElem.attribute( u
"crossLength"_s, u
"3"_s ).toDouble();
359 mGridFrameStyle =
static_cast< Qgis::MapGridFrameStyle >( itemElem.attribute( u
"gridFrameStyle"_s, u
"0"_s ).toInt() );
361 mGridFrameWidth = itemElem.attribute( u
"gridFrameWidth"_s, u
"2.0"_s ).toDouble();
362 mGridFrameMargin = itemElem.attribute( u
"gridFrameMargin"_s, u
"0.0"_s ).toDouble();
363 mGridFramePenThickness = itemElem.attribute( u
"gridFramePenThickness"_s, u
"0.3"_s ).toDouble();
371 mRotatedTicksLengthMode =
static_cast< Qgis::MapGridTickLengthMode >( itemElem.attribute( u
"rotatedTicksLengthMode"_s, u
"0"_s ).toInt() );
372 mRotatedTicksEnabled = itemElem.attribute( u
"rotatedTicksEnabled"_s, u
"0"_s ) !=
"0"_L1;
373 mRotatedTicksMinimumAngle = itemElem.attribute( u
"rotatedTicksMinimumAngle"_s, u
"0"_s ).toDouble();
374 mRotatedTicksMarginToCorner = itemElem.attribute( u
"rotatedTicksMarginToCorner"_s, u
"0"_s ).toDouble();
375 mRotatedAnnotationsLengthMode =
static_cast< Qgis::MapGridTickLengthMode >( itemElem.attribute( u
"rotatedAnnotationsLengthMode"_s, u
"0"_s ).toInt() );
376 mRotatedAnnotationsEnabled = itemElem.attribute( u
"rotatedAnnotationsEnabled"_s, u
"0"_s ) !=
"0"_L1;
377 mRotatedAnnotationsMinimumAngle = itemElem.attribute( u
"rotatedAnnotationsMinimumAngle"_s, u
"0"_s ).toDouble();
378 mRotatedAnnotationsMarginToCorner = itemElem.attribute( u
"rotatedAnnotationsMarginToCorner"_s, u
"0"_s ).toDouble();
380 const QDomElement lineStyleElem = itemElem.firstChildElement( u
"lineStyle"_s );
381 if ( !lineStyleElem.isNull() )
383 const QDomElement symbolElem = lineStyleElem.firstChildElement( u
"symbol"_s );
384 if ( !symbolElem.isNull() )
393 mGridLineSymbol->setWidth( itemElem.attribute( u
"penWidth"_s, u
"0"_s ).toDouble() );
394 mGridLineSymbol->setColor( QColor( itemElem.attribute( u
"penColorRed"_s, u
"0"_s ).toInt(),
395 itemElem.attribute( u
"penColorGreen"_s, u
"0"_s ).toInt(),
396 itemElem.attribute( u
"penColorBlue"_s, u
"0"_s ).toInt() ) );
399 const QDomElement markerStyleElem = itemElem.firstChildElement( u
"markerStyle"_s );
400 if ( !markerStyleElem.isNull() )
402 const QDomElement symbolElem = markerStyleElem.firstChildElement( u
"symbol"_s );
403 if ( !symbolElem.isNull() )
409 if ( !mCRS.readXml( itemElem ) )
412 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( u
"blendMode"_s, u
"0"_s ).toUInt() );
415 mShowGridAnnotation = ( itemElem.attribute( u
"showAnnotation"_s, u
"0"_s ) !=
"0"_L1 );
417 mGridAnnotationExpressionString = itemElem.attribute( u
"annotationExpression"_s );
418 mGridAnnotationExpression.reset();
432 mAnnotationFrameDistance = itemElem.attribute( u
"frameAnnotationDistance"_s, u
"0"_s ).toDouble();
434 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
436 mAnnotationFormat.readXml( itemElem, context );
443 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
445 mAnnotationFormat.setFont( font );
446 mAnnotationFormat.setSize( font.pointSizeF() );
451 mGridAnnotationPrecision = itemElem.attribute( u
"annotationPrecision"_s, u
"3"_s ).toInt();
452 const int gridUnitInt = itemElem.attribute( u
"unit"_s, QString::number(
static_cast< int >(
Qgis::MapGridUnit::MapUnits ) ) ).toInt();
454 mMinimumIntervalWidth = itemElem.attribute( u
"minimumIntervalWidth"_s, u
"50"_s ).toDouble();
455 mMaximumIntervalWidth = itemElem.attribute( u
"maximumIntervalWidth"_s, u
"100"_s ).toDouble();
459 refreshDataDefinedProperties();
469 mTransformDirty =
true;
475 return mBlendMode != QPainter::CompositionMode_SourceOver;
478QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
480 const QTransform t = QTransform::fromScale( scale, scale );
481 return t.map( polygon );
484void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
486 if ( !
mMap || !mEvaluatedEnabled )
492 const QPolygonF mapPolygon =
mMap->transformedMapPolygon();
493 if ( mapPolygon != mPrevMapPolygon )
495 mTransformDirty =
true;
496 mPrevMapPolygon = mapPolygon;
499 if ( mTransformDirty )
501 calculateCrsTransformLines();
505 if ( !calculateLinesOnly )
507 int countLongitudeLines = 0;
508 int countLatitudeLines = 0;
509 for (
const GridLine &line : mGridLines )
511 switch ( line.coordinateType )
514 countLongitudeLines++;
517 countLatitudeLines++;
522 int latitudeLineIndex = 0;
523 int longitudeLineIndex = 0;
526 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
527 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
529 switch ( gridIt->coordinateType )
532 longitudeLineIndex++;
546 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
551 const double maxX =
mMap->rect().width();
552 const double maxY =
mMap->rect().height();
554 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
555 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
557 const double x = intersectionIt->x();
558 const double y = intersectionIt->y();
562 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
563 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
564 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
565 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
566 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
567 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
570 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
571 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
575 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
582void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
584 QgsRectangle crsBoundingRect;
585 QgsCoordinateTransform inverseTr;
586 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
593 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
594 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
601 QList< QgsGeometry > xLines;
602 QList< QgsGeometry > yLines;
603 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
604 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
608 for (
int i = 0; i < gridIt->line.size(); ++i )
610 line.append( QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
619 mTransformedIntersections.clear();
620 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
621 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
623 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
624 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
627 const QgsGeometry intersects = ( *yLineIt ).intersection( ( *xLineIt ) );
628 if ( intersects.
isNull() )
633 QgsPointXY vertex = intersects.
vertexAt( i );
636 mTransformedIntersections << vertex;
644 mTransformDirty =
false;
649 if ( !
mMap || !mEvaluatedEnabled )
653 QPaintDevice *paintDevice = p->device();
660 p->setCompositionMode( mBlendMode );
663 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
664 p->setClipRect( thisPaintRect );
665 if ( thisPaintRect != mPrevPaintRect )
668 mTransformDirty =
true;
669 mPrevPaintRect = thisPaintRect;
673 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
674 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
689 if ( mCRS.isValid() && mCRS !=
mMap->crs() )
691 drawGridCrsTransform( context, dotsPerMM );
698 drawGridNoTransform( context, dotsPerMM );
703 p->setClipping(
false );
707 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
712 updateGridLinesAnnotationsPositions();
719 if ( mShowGridAnnotation )
725void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
727 QList< GridLine >::iterator it = mGridLines.begin();
728 for ( ; it != mGridLines.end(); ++it )
730 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
731 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
732 it->startAnnotation.position = QVector2D( it->line.first() );
733 it->endAnnotation.position = QVector2D( it->line.last() );
734 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
735 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
737 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() );
739 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() );
743void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
750 if ( calculateLinesOnly || mGridLines.empty() )
753 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
754 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
756 int countLongitudeLines = 0;
757 int countLatitudeLines = 0;
758 for (
const GridLine &line : mGridLines )
760 switch ( line.coordinateType )
763 countLongitudeLines++;
766 countLatitudeLines++;
771 int latitudeLineIndex = 0;
772 int longitudeLineIndex = 0;
780 for ( ; vIt != mGridLines.constEnd(); ++vIt )
784 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
786 longitudeLineIndex++;
792 drawGridLine( line, context );
795 for ( ; hIt != mGridLines.constEnd(); ++hIt )
799 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
807 drawGridLine( line, context );
813 QPointF intersectionPoint, crossEnd1, crossEnd2;
814 for ( ; vIt != mGridLines.constEnd(); ++vIt )
819 l1 = QLineF( vIt->line.first(), vIt->line.last() );
822 hIt = mGridLines.constBegin();
823 for ( ; hIt != mGridLines.constEnd(); ++hIt )
828 l2 = QLineF( hIt->line.first(), hIt->line.last() );
830 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
835 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
837 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
840 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
844 drawGridMarker( intersectionPoint * dotsPerMM, context );
856 hIt = mGridLines.constBegin();
857 for ( ; hIt != mGridLines.constEnd(); ++hIt )
862 l1 = QLineF( hIt->line.first(), hIt->line.last() );
864 vIt = mGridLines.constBegin();
865 for ( ; vIt != mGridLines.constEnd(); ++vIt )
870 l2 = QLineF( vIt->line.first(), vIt->line.last() );
872 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
875 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
877 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
880 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
887void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
896 switch ( mGridFrameStyle )
900 drawGridFrameZebra( p, extension );
905 drawGridFrameTicks( p, extension );
910 drawGridFrameLine( p, extension );
921void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
924 poly << line.p1() << line.p2();
925 drawGridLine( poly, context );
928void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
930 if ( !
mMap || !
mMap->layout() || !mGridLineSymbol )
935 mGridLineSymbol->startRender( context );
936 mGridLineSymbol->renderPolyline( line,
nullptr, context );
937 mGridLineSymbol->stopRender( context );
940void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
942 if ( !
mMap || !
mMap->layout() || !mGridMarkerSymbol )
947 mGridMarkerSymbol->startRender( context );
948 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
949 mGridMarkerSymbol->stopRender( context );
952void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
972void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p,
Qgis::MapGridBorderSide border,
double *extension )
const
981 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
985 double currentCoord = 0.0;
992 bool drawTLBox =
false;
993 bool drawTRBox =
false;
994 bool drawBLBox =
false;
995 bool drawBRBox =
false;
997 QMap< double, double > pos = QMap< double, double >();
998 QList< GridLine >::const_iterator it = mGridLines.constBegin();
999 for ( ; it != mGridLines.constEnd(); ++it )
1002 for (
int i = 0 ; i < 2 ; ++i )
1004 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1007 if ( annot.border != border )
1010 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1014 pos.insert( annot.position.y(), it->coordinate );
1016 pos.insert( annot.position.x(), it->coordinate );
1023 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
1039 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
1043 QPen framePen = QPen( mGridFramePenColor );
1044 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1045 framePen.setJoinStyle( Qt::MiterJoin );
1046 p->setPen( framePen );
1048 QMap< double, double >::const_iterator posIt = pos.constBegin();
1049 for ( ; posIt != pos.constEnd(); ++posIt )
1051 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
1054 height = posIt.key() - currentCoord;
1055 width = mEvaluatedGridFrameWidth;
1061 height = mEvaluatedGridFrameWidth;
1062 width = posIt.key() - currentCoord;
1064 y = ( border ==
Qgis::MapGridBorderSide::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
1066 p->drawRect( QRectF( x, y, width, height ) );
1067 currentCoord = posIt.key();
1074 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
1075 p->setBrush( QBrush( mGridFrameFillColor1 ) );
1077 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1079 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1081 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1083 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1087void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1097 QPen framePen = QPen( mGridFramePenColor );
1098 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1099 framePen.setCapStyle( Qt::FlatCap );
1100 p->setBrush( Qt::NoBrush );
1101 p->setPen( framePen );
1104 QList< GridLine >::iterator it = mGridLines.begin();
1105 for ( ; it != mGridLines.end(); ++it )
1108 for (
int i = 0 ; i < 2 ; ++i )
1110 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1112 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1116 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1124 facingLeft = ( annot.angle != 0 );
1125 facingRight = ( annot.angle != 0 );
1129 facingLeft = ( annot.angle > 0 );
1130 facingRight = ( annot.angle < 0 );
1134 facingLeft = ( annot.angle < 0 );
1135 facingRight = ( annot.angle > 0 );
1139 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1142 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1145 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1148 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1152 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1154 double fA = mEvaluatedGridFrameMargin;
1155 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1159 fA /= QVector2D::dotProduct( vector, normalVector );
1160 fB /= QVector2D::dotProduct( vector, normalVector );
1167 extension->UpdateBorder( annot.border, fB );
1175 pA = annot.position +
static_cast< float >( fA ) * vector;
1176 pB = annot.position +
static_cast< float >( fB ) * vector;
1180 pA = annot.position -
static_cast< float >( fA ) * vector;
1181 pB = annot.position -
static_cast< float >( fB ) * vector;
1185 pA = annot.position -
static_cast< float >( fB ) * vector;
1186 pB = annot.position +
static_cast< float >( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1188 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1194void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1204 QPen framePen = QPen( mGridFramePenColor );
1205 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1206 framePen.setCapStyle( Qt::SquareCap );
1207 p->setBrush( Qt::NoBrush );
1208 p->setPen( framePen );
1218 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1226 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1234 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1242 p->drawLine( 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 ) );
1279 GridExtension *extension )
const
1281 if ( mGridLines.empty() )
1284 QString currentAnnotationString;
1285 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1287 QgsExpressionContextScope *gridScope =
new QgsExpressionContextScope();
1288 QgsExpressionContextScopePopper scopePopper( expressionContext, gridScope );
1290 bool geographic =
false;
1291 if ( mCRS.isValid() )
1293 geographic = mCRS.isGeographic();
1297 geographic =
mMap->crs().isGeographic();
1303 int countLongitudeLines = 0;
1304 int countLatitudeLines = 0;
1305 for (
const GridLine &line : mGridLines )
1307 switch ( line.coordinateType )
1310 countLongitudeLines++;
1313 countLatitudeLines++;
1318 int latitudeLineIndex = 0;
1319 int longitudeLineIndex = 0;
1320 for ( ; it != mGridLines.constEnd(); ++it )
1322 double value = it->coordinate;
1323 switch ( it->coordinateType )
1326 longitudeLineIndex++;
1327 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_count"_s, countLongitudeLines,
true ) );
1328 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_index"_s, longitudeLineIndex,
true ) );
1329 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_axis"_s, u
"x"_s,
true ) );
1333 latitudeLineIndex++;
1334 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_count"_s, countLatitudeLines,
true ) );
1335 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_index"_s, latitudeLineIndex,
true ) );
1336 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_axis"_s, u
"y"_s,
true ) );
1343 const double wrappedX = std::fmod( value, 360.0 );
1344 if ( wrappedX > 180.0 )
1346 value = wrappedX - 360.0;
1348 else if ( wrappedX < -180.0 )
1350 value = wrappedX + 360.0;
1354 gridScope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"grid_number"_s, value,
true ) );
1356 if ( mDrawAnnotationProperty )
1359 const bool display = mDrawAnnotationProperty->valueAsBool( expressionContext,
true, &ok );
1360 if ( ok && !display )
1363 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext, geographic );
1364 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1365 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1369void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const Qgis::MapGridAnnotationType coordinateType, GridExtension *extension )
const
1376 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1380 std::unique_ptr< QgsScopedQPainterState > painterState;
1381 double dotsPerMM = 1;
1385 painterState = std::make_unique< QgsScopedQPainterState >( context.
painter() );
1386 dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
1387 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1398 double textWidthPainterUnits = sizePainterUnits.width();
1400 textWidthPainterUnits *= 1.1;
1402 const double textWidthMM = textWidthPainterUnits * painterUnitsToMM ;
1404 double textHeightPainterUnits = 0;
1405 if ( extension || doc.
size() > 1 )
1407 textHeightPainterUnits = sizePainterUnits.height();
1416 const double textHeightMM = textHeightPainterUnits * painterUnitsToMM;
1422 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1426 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1429 double distanceToFrameMM = mEvaluatedAnnotationFrameDistance;
1437 distanceToFrameMM += mEvaluatedGridFrameWidth;
1438 if ( hasBorderWidth )
1439 distanceToFrameMM += mEvaluatedGridFrameLineThickness / 2.0;
1442 distanceToFrameMM *= -1;
1446 distanceToFrameMM /= QVector2D::dotProduct( vector, normalVector );
1449 QPointF annotationPositionMM = ( annot.position +
static_cast< float >( distanceToFrameMM ) * vector ).toPointF();
1454 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 );
1485 anchorMM.setX( 0.5 * textWidthMM );
1486 anchorMM.setY( -0.5 * textHeightMM );
1488 anchorMM.setY( outside ? 0 : -textHeightMM );
1490 anchorMM.setX( outside ? 0 : textWidthMM );
1492 anchorMM.setY( outside ? -textHeightMM : 0 );
1494 anchorMM.setX( outside ? textWidthMM : 0 );
1499 anchorMM.setX( 0.5 * textWidthMM );
1500 anchorMM.setY( -0.5 * textHeightMM );
1502 anchorMM.setX( outside ? 0 : textWidthMM );
1504 anchorMM.setY( outside ? -textHeightMM : 0 );
1506 anchorMM.setX( outside ? textWidthMM : 0 );
1508 anchorMM.setY( outside ? 0 : -textHeightMM );
1513 anchorMM.setX( 0.5 * textWidthMM );
1514 anchorMM.setY( -0.5 * textHeightMM );
1516 anchorMM.setX( outside ? textWidthMM : 0 );
1518 anchorMM.setY( outside ? 0 : -textHeightMM );
1520 anchorMM.setX( outside ? 0 : textWidthMM );
1522 anchorMM.setY( outside ? -textHeightMM : 0 );
1527 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1528 anchorMM.setX( 0.5 * textWidthMM );
1530 anchorMM.setY( -textHeightMM );
1538 extension->UpdateBorder( frameBorder, -distanceToFrameMM + std::max( textHeightMM, textWidthMM ) );
1540 extension->UpdateAll( std::max( textHeightMM, textWidthMM ) / 2.0 );
1543 if ( extension || !context.
painter() )
1547 bool facingLeft = ( annot.angle < 0 );
1548 bool facingRight = ( annot.angle > 0 );
1551 facingLeft = !facingLeft;
1552 facingRight = !facingRight;
1555 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1558 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1561 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1564 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1571 QPointF textPos( 0, 0 );
1572 switch ( annot.border )
1589 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1592 textPos.setX( textWidthMM / painterUnitsToMM );
1598 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1620 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1623 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1627 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1642 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1667 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1670 textPos.setX( textWidthMM / painterUnitsToMM );
1682 textPos.setX( textWidthMM / ( 2 * painterUnitsToMM ) );
1703 context.
painter()->translate( QPointF( annotationPositionMM.x(), annotationPositionMM.y() ) / painterUnitsToMM );
1704 context.
painter()->rotate( rotation );
1705 context.
painter()->translate( -anchorMM / painterUnitsToMM );
1718 return QString::number( value,
'f', mGridAnnotationPrecision );
1724 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1728 if ( !isGeographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1730 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1736 if ( !isGeographic || coordRounded != 0.0 )
1738 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1744 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1748 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1753 if ( !mGridAnnotationExpression )
1755 mGridAnnotationExpression = std::make_unique<QgsExpression>( mGridAnnotationExpressionString );
1756 mGridAnnotationExpression->prepare( &expressionContext );
1758 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1763 switch ( mGridAnnotationFormat )
1813int QgsLayoutItemMapGrid::xGridLines()
const
1815 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1821 QPolygonF mapPolygon =
mMap->transformedMapPolygon();
1822 QRectF mapBoundingRect = mapPolygon.boundingRect();
1823 double gridIntervalY = mEvaluatedIntervalY;
1824 double gridOffsetY = mEvaluatedOffsetY;
1825 double annotationScale = 1.0;
1826 switch ( mGridUnit )
1831 mapBoundingRect =
mMap->rect();
1832 mapPolygon = QPolygonF(
mMap->rect() );
1835 annotationScale = 0.1;
1836 gridIntervalY *= 10;
1848 const double roundCorrection = mapBoundingRect.top() > gridOffsetY ? 1.0 : 0.0;
1849 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1851 int gridLineCount = 0;
1856 double yCanvasCoord;
1857 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1859 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1861 newLine.coordinate = currentLevel * annotationScale;
1863 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1864 mGridLines.append( newLine );
1865 currentLevel += gridIntervalY;
1872 QVector<QLineF> borderLines;
1873 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1874 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1875 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1876 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1878 QVector<QPointF> intersectionList;
1880 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1882 intersectionList.clear();
1883 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1885 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1886 for ( ; it != borderLines.constEnd(); ++it )
1888 QPointF intersectionPoint;
1889 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1891 intersectionList.push_back( intersectionPoint );
1892 if ( intersectionList.size() >= 2 )
1899 if ( intersectionList.size() >= 2 )
1902 newLine.coordinate = currentLevel;
1904 newLine.line = QPolygonF() <<
mMap->mapToItemCoords( intersectionList.at( 0 ) ) <<
mMap->mapToItemCoords( intersectionList.at( 1 ) );
1905 mGridLines.append( newLine );
1908 currentLevel += gridIntervalY;
1915int QgsLayoutItemMapGrid::yGridLines()
const
1917 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1922 QPolygonF mapPolygon =
mMap->transformedMapPolygon();
1923 QRectF mapBoundingRect = mapPolygon.boundingRect();
1924 double gridIntervalX = mEvaluatedIntervalX;
1925 double gridOffsetX = mEvaluatedOffsetX;
1926 double annotationScale = 1.0;
1927 switch ( mGridUnit )
1932 mapBoundingRect =
mMap->rect();
1933 mapPolygon = QPolygonF(
mMap->rect() );
1936 annotationScale = 0.1;
1937 gridIntervalX *= 10;
1949 const double roundCorrection = mapBoundingRect.left() > gridOffsetX ? 1.0 : 0.0;
1950 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1952 int gridLineCount = 0;
1956 double xCanvasCoord;
1957 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1959 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1962 newLine.coordinate = currentLevel * annotationScale;
1964 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1965 mGridLines.append( newLine );
1966 currentLevel += gridIntervalX;
1973 QVector<QLineF> borderLines;
1974 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1975 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1976 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1977 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1979 QVector<QPointF> intersectionList;
1981 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1983 intersectionList.clear();
1984 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1986 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1987 for ( ; it != borderLines.constEnd(); ++it )
1989 QPointF intersectionPoint;
1990 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1992 intersectionList.push_back( intersectionPoint );
1993 if ( intersectionList.size() >= 2 )
2000 if ( intersectionList.size() >= 2 )
2003 newLine.coordinate = currentLevel;
2005 newLine.line = QPolygonF() <<
mMap->mapToItemCoords( intersectionList.at( 0 ) ) <<
mMap->mapToItemCoords( intersectionList.at( 1 ) );
2006 mGridLines.append( newLine );
2009 currentLevel += gridIntervalX;
2017 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
2022 const double roundCorrection = bbox.
yMaximum() > mEvaluatedOffsetY ? 1.0 : 0.0;
2023 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
2025 const double minX = bbox.
xMinimum();
2026 const double maxX = bbox.
xMaximum();
2027 double step = ( maxX - minX ) / 20;
2029 bool crosses180 =
false;
2030 bool crossed180 =
false;
2031 if ( mCRS.isGeographic() && ( minX > maxX ) )
2035 step = ( maxX + 360.0 - minX ) / 20;
2041 int gridLineCount = 0;
2045 double currentX = minX;
2049 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
2056 const QgsPointXY mapPoint = t.
transform( currentX, currentLevel );
2057 gridLine.append(
mMap->mapToItemCoords( QPointF( mapPoint.
x(), mapPoint.
y() ) ) );
2059 catch ( QgsCsException &cse )
2066 if ( crosses180 && currentX > 180.0 )
2074 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, QgsRectangle(
mMap->rect() ) );
2075 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
2076 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
2078 if ( !( *lineIt ).isEmpty() )
2081 newLine.coordinate = currentLevel;
2083 newLine.line = QPolygonF( *lineIt );
2084 mGridLines.append( newLine );
2088 currentLevel -= mEvaluatedIntervalY;
2096 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
2101 const double roundCorrection = bbox.
xMinimum() > mEvaluatedOffsetX ? 1.0 : 0.0;
2102 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
2104 const double minY = bbox.
yMinimum();
2105 const double maxY = bbox.
yMaximum();
2106 const double step = ( maxY - minY ) / 20;
2111 bool crosses180 =
false;
2112 bool crossed180 =
false;
2119 int gridLineCount = 0;
2120 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
2123 double currentY = minY;
2127 if ( currentY > maxY )
2134 const QgsPointXY mapPoint = t.
transform( currentLevel, currentY );
2136 gridLine.append(
mMap->mapToItemCoords( QPointF( mapPoint.
x(), mapPoint.
y() ) ) );
2138 catch ( QgsCsException &cse )
2147 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, QgsRectangle(
mMap->rect() ) );
2148 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
2149 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
2151 if ( !( *lineIt ).isEmpty() )
2154 newLine.coordinate = currentLevel;
2156 newLine.line = QPolygonF( *lineIt );
2157 mGridLines.append( newLine );
2161 currentLevel += mEvaluatedIntervalX;
2162 if ( crosses180 && currentLevel > 180.0 )
2164 currentLevel -= 360.0;
2193 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
2195 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
2197 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
2199 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
2213 if ( ddValue.compare(
"x_only"_L1, Qt::CaseInsensitive ) == 0 )
2215 else if ( ddValue.compare(
"y_only"_L1, Qt::CaseInsensitive ) == 0 )
2217 else if ( ddValue.compare(
"disabled"_L1, Qt::CaseInsensitive ) == 0 )
2219 else if ( ddValue.compare(
"all"_L1, Qt::CaseInsensitive ) == 0 )
2225void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
2230 mTransformDirty = mTransformDirty
2241 mDrawAnnotationProperty->prepare( context );
2245 mDrawAnnotationProperty.reset();
2248 switch ( mGridUnit )
2261 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
2263 mEvaluatedEnabled =
false;
2268 const double mapWidthMapUnits = mapWidth();
2269 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
2270 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
2272 mEvaluatedIntervalX = interval;
2273 mEvaluatedIntervalY = interval;
2274 mTransformDirty =
true;
2296double QgsLayoutItemMapGrid::mapWidth()
const
2303 const QgsRectangle mapExtent =
mMap->extent();
2307 return mapExtent.
width();
2324 catch ( QgsCsException & )
2327 QgsDebugError( u
"An error occurred while calculating length"_s );
2333bool sortByDistance( QPair<qreal, Qgis::MapGridBorderSide> a, QPair<qreal, Qgis::MapGridBorderSide> b )
2335 return a.first < b.first;
2345 const double tolerance = std::max(
mMap->frameEnabled() ?
mMap->pen().widthF() : 0.0, 1.0 );
2348 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2349 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2350 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2351 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2357 if ( p.x() <= tolerance )
2368 if ( p.y() <= tolerance )
2380 QList< QPair<qreal, Qgis::MapGridBorderSide > > distanceToSide;
2386 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2387 return distanceToSide.at( 0 ).second;
2392 mGridLineSymbol.reset( symbol );
2397 return mGridLineSymbol.get();
2402 return mGridLineSymbol.get();
2407 mGridMarkerSymbol.reset( symbol );
2412 return mGridMarkerSymbol.get();
2417 return mGridMarkerSymbol.get();
2422 mAnnotationFormat.setFont( font );
2423 if ( font.pointSizeF() > 0 )
2425 mAnnotationFormat.setSize( font.pointSizeF() );
2428 else if ( font.pixelSize() > 0 )
2430 mAnnotationFormat.setSize( font.pixelSize() );
2437 return mAnnotationFormat.toQFont();
2442 mAnnotationFormat.
setColor( color );
2447 return mAnnotationFormat.color();
2455 mLeftGridAnnotationDisplay = display;
2458 mRightGridAnnotationDisplay = display;
2461 mTopGridAnnotationDisplay = display;
2464 mBottomGridAnnotationDisplay = display;
2468 refreshDataDefinedProperties();
2472 mMap->updateBoundingRect();
2482 return mLeftGridAnnotationDisplay;
2484 return mRightGridAnnotationDisplay;
2486 return mTopGridAnnotationDisplay;
2488 return mBottomGridAnnotationDisplay;
2490 return mBottomGridAnnotationDisplay;
2497 double bottom = 0.0;
2500 return std::max( std::max( std::max( top, right ), bottom ), left );
2510 if ( !
mMap || !mEvaluatedEnabled )
2520 GridExtension extension;
2523 switch ( mGridUnit )
2528 if ( mCRS.isValid() && mCRS !=
mMap->crs() )
2530 drawGridCrsTransform( context, 0,
true );
2537 drawGridNoTransform( context, 0,
true );
2542 updateGridLinesAnnotationsPositions();
2546 drawGridFrame(
nullptr, &extension );
2549 if ( mShowGridAnnotation )
2554 top = extension.top;
2555 right = extension.right;
2556 bottom = extension.bottom;
2557 left = extension.left;
2563 refreshDataDefinedProperties();
2568 if ( unit == mGridUnit )
2573 mTransformDirty =
true;
2582 mGridIntervalX = interval;
2583 mTransformDirty =
true;
2584 refreshDataDefinedProperties();
2593 mGridIntervalY = interval;
2594 mTransformDirty =
true;
2595 refreshDataDefinedProperties();
2604 mGridOffsetX = offset;
2605 mTransformDirty =
true;
2606 refreshDataDefinedProperties();
2615 mGridOffsetY = offset;
2616 mTransformDirty =
true;
2617 refreshDataDefinedProperties();
2626 mMinimumIntervalWidth = minWidth;
2627 mTransformDirty =
true;
2628 refreshDataDefinedProperties();
2637 mMaximumIntervalWidth = maxWidth;
2638 mTransformDirty =
true;
2639 refreshDataDefinedProperties();
2644 if (
style == mGridStyle )
2649 mTransformDirty =
true;
2654 mCrossLength = length;
2655 refreshDataDefinedProperties();
2663 mLeftGridAnnotationDirection = direction;
2666 mRightGridAnnotationDirection = direction;
2669 mTopGridAnnotationDirection = direction;
2672 mBottomGridAnnotationDirection = direction;
2678 mMap->updateBoundingRect();
2685 mGridFrameSides = flags;
2690 mGridFrameSides.setFlag( flag, on );
2695 return mGridFrameSides;
2710 if ( mGridLineSymbol )
2716 if ( mGridMarkerSymbol )
2728 mTransformDirty =
true;
2729 refreshDataDefinedProperties();
2730 mMap->updateBoundingRect();
2736 return mGridFrameSides.testFlag( flag );
2741 mGridFrameWidth = width;
2742 refreshDataDefinedProperties();
2747 mGridFrameMargin = margin;
2748 refreshDataDefinedProperties();
2753 mGridFramePenThickness = width;
2754 refreshDataDefinedProperties();
2764 mHAlign = alignment;
2769 mLeftGridAnnotationDirection = direction;
2770 mRightGridAnnotationDirection = direction;
2771 mTopGridAnnotationDirection = direction;
2772 mBottomGridAnnotationDirection = direction;
2780 mLeftGridAnnotationPosition = position;
2783 mRightGridAnnotationPosition = position;
2786 mTopGridAnnotationPosition = position;
2789 mBottomGridAnnotationPosition = position;
2795 mMap->updateBoundingRect();
2805 return mLeftGridAnnotationPosition;
2807 return mRightGridAnnotationPosition;
2809 return mTopGridAnnotationPosition;
2811 return mBottomGridAnnotationPosition;
2813 return mLeftGridAnnotationPosition;
2818 mAnnotationFrameDistance = distance;
2819 refreshDataDefinedProperties();
2826 return mLeftGridAnnotationDirection;
2832 return mLeftGridAnnotationDirection;
2834 return mRightGridAnnotationDirection;
2836 return mTopGridAnnotationDirection;
2838 return mBottomGridAnnotationDirection;
2840 return mLeftGridAnnotationDirection;
2845 mGridAnnotationExpressionString = expression;
2846 mGridAnnotationExpression.reset();
2854 mLeftFrameDivisions = divisions;
2857 mRightFrameDivisions = divisions;
2860 mTopFrameDivisions = divisions;
2863 mBottomFrameDivisions = divisions;
2867 refreshDataDefinedProperties();
2880 return mLeftFrameDivisions;
2882 return mRightFrameDivisions;
2884 return mTopFrameDivisions;
2886 return mBottomFrameDivisions;
2888 return mLeftFrameDivisions;
2900 const QgsCoordinateTransform tr(
mMap->crs(), mCRS,
mLayout->project() );
2901 QgsCoordinateTransform extentTransform = tr;
2903 const QPolygonF mapPolygon =
mMap->transformedMapPolygon();
2904 const QRectF mbr = mapPolygon.boundingRect();
2905 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2908 if ( mCRS.isGeographic() )
2911 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2912 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2914 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2915 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2917 if ( lowerLeft.x() > upperRight.x() )
2933 inverseTransform = QgsCoordinateTransform( mCRS,
mMap->crs(),
mLayout->project() );
2935 catch ( QgsCsException &cse )
2944QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2949 const QgsGeometry intersected = lineGeom.
intersection( rectGeom );
2952 QList<QPolygonF> trimmedLines;
2953 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2954 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2956 trimmedLines << ( *geomIt ).asQPolygonF();
2958 return trimmedLines;
3033 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.