49#define MAX_GRID_LINES 1000
80 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
86 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
91 QList< QgsLayoutItemMapGrid * > list;
114 const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
115 for (
int i = 0; i < mapGridNodeList.size(); ++i )
117 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
119 mapGrid->
readXml( mapGridElem, doc, context );
133 return std::max( std::max( std::max( top, right ), bottom ), left );
147 double gridTop = 0.0;
148 double gridRight = 0.0;
149 double gridBottom = 0.0;
150 double gridLeft = 0.0;
152 top = std::max( top, gridTop );
153 right = std::max( right, gridRight );
154 bottom = std::max( bottom, gridBottom );
155 left = std::max( left, gridLeft );
171 return QVector2D( 0, 1 );
173 return QVector2D( -1, 0 );
175 return QVector2D( 0, -1 );
177 return QVector2D( 1, 0 );
185 return QVector2D( borderVector.y(), -borderVector.x() );
195 const QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
196 if ( !defaultFontString.isEmpty() )
200 mAnnotationFormat.
setFont( font );
203 createDefaultGridLineSymbol();
204 createDefaultGridMarkerSymbol();
217void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
219 QVariantMap properties;
220 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
221 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
222 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
226void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
228 QVariantMap properties;
229 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
230 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
231 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
237 if ( mGridLineSymbol )
239 mGridLineSymbol->setWidth( width );
245 if ( mGridLineSymbol )
247 mGridLineSymbol->setColor(
c );
258 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
259 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
260 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
261 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
262 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
263 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
264 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
266 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
268 lineStyleElem.appendChild( gridLineStyleElem );
269 mapGridElem.appendChild( lineStyleElem );
271 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
273 markerStyleElem.appendChild( gridMarkerStyleElem );
274 mapGridElem.appendChild( markerStyleElem );
276 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
277 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
278 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
279 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
280 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
284 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
285 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
286 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
287 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
288 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
289 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
292 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
293 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
294 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
295 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
301 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
302 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
303 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
304 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
305 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
306 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
307 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
308 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
309 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
310 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
311 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
312 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
313 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
314 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
315 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
316 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
317 mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
318 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
319 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
320 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
321 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
322 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
325 elem.appendChild( mapGridElem );
332 if ( itemElem.isNull() )
341 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
342 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
343 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
344 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
345 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
346 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
347 mGridFrameSides =
static_cast< QgsLayoutItemMapGrid::FrameSideFlags
>( itemElem.attribute( QStringLiteral(
"gridFrameSideFlags" ), QStringLiteral(
"15" ) ).toInt() );
348 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
349 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
350 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
352 mGridFrameFillColor1 =
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral(
"frameFillColor1" ), QStringLiteral(
"255,255,255,255" ) ) );
353 mGridFrameFillColor2 =
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral(
"frameFillColor2" ), QStringLiteral(
"0,0,0,255" ) ) );
358 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
359 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
360 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
361 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
362 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
363 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
364 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
365 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
367 const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
368 if ( !lineStyleElem.isNull() )
370 const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
371 if ( !symbolElem.isNull() )
373 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
380 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
381 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
382 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
383 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
386 const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
387 if ( !markerStyleElem.isNull() )
389 const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
390 if ( !symbolElem.isNull() )
392 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
396 if ( !mCRS.
readXml( itemElem ) )
399 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
402 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
404 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
405 mGridAnnotationExpression.reset();
410 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
411 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
413 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
419 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
421 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
423 mAnnotationFormat.
readXml( itemElem, context );
430 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
432 mAnnotationFormat.
setFont( font );
433 mAnnotationFormat.
setSize( font.pointSizeF() );
438 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
439 const int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
441 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
442 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
444 refreshDataDefinedProperties();
454 mTransformDirty =
true;
460 return mBlendMode != QPainter::CompositionMode_SourceOver;
463QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
465 const QTransform t = QTransform::fromScale( scale, scale );
466 return t.map( polygon );
469void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
471 if ( !
mMap || !mEvaluatedEnabled )
478 if ( mapPolygon != mPrevMapPolygon )
480 mTransformDirty =
true;
481 mPrevMapPolygon = mapPolygon;
484 if ( mTransformDirty )
486 calculateCrsTransformLines();
490 if ( !calculateLinesOnly )
494 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
495 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
497 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
502 const double maxX =
mMap->rect().width();
503 const double maxY =
mMap->rect().height();
505 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
506 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
508 const double x = intersectionIt->x();
509 const double y = intersectionIt->y();
513 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
514 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
515 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
516 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
517 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
518 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
521 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
522 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
526 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
533void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
537 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
544 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
545 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
552 QList< QgsGeometry > xLines;
553 QList< QgsGeometry > yLines;
554 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
555 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
559 for (
int i = 0; i < gridIt->line.size(); ++i )
561 line.append(
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
570 mTransformedIntersections.clear();
571 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
572 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
574 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
575 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
579 if ( intersects.
isNull() )
587 mTransformedIntersections << vertex;
595 mTransformDirty =
false;
600 if ( !
mMap || !mEvaluatedEnabled )
604 QPaintDevice *paintDevice = p->device();
611 p->setCompositionMode( mBlendMode );
614 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
615 p->setClipRect( thisPaintRect );
616 if ( thisPaintRect != mPrevPaintRect )
619 mTransformDirty =
true;
620 mPrevPaintRect = thisPaintRect;
624 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
625 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
641 drawGridCrsTransform( context, dotsPerMM );
648 drawGridNoTransform( context, dotsPerMM );
653 p->setClipping(
false );
657 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
662 updateGridLinesAnnotationsPositions();
669 if ( mShowGridAnnotation )
675void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
677 QList< GridLine >::iterator it = mGridLines.begin();
678 for ( ; it != mGridLines.end(); ++it )
680 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
681 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
682 it->startAnnotation.position = QVector2D( it->line.first() );
683 it->endAnnotation.position = QVector2D( it->line.last() );
684 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
685 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
687 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() );
689 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() );
693void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
700 if ( calculateLinesOnly )
703 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
704 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
712 for ( ; vIt != mGridLines.constEnd(); ++vIt )
716 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
717 drawGridLine( line, context );
720 for ( ; hIt != mGridLines.constEnd(); ++hIt )
724 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
725 drawGridLine( line, context );
731 QPointF intersectionPoint, crossEnd1, crossEnd2;
732 for ( ; vIt != mGridLines.constEnd(); ++vIt )
737 l1 = QLineF( vIt->line.first(), vIt->line.last() );
740 hIt = mGridLines.constBegin();
741 for ( ; hIt != mGridLines.constEnd(); ++hIt )
746 l2 = QLineF( hIt->line.first(), hIt->line.last() );
748 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
753 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
755 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
758 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
762 drawGridMarker( intersectionPoint * dotsPerMM, context );
774 hIt = mGridLines.constBegin();
775 for ( ; hIt != mGridLines.constEnd(); ++hIt )
780 l1 = QLineF( hIt->line.first(), hIt->line.last() );
782 vIt = mGridLines.constBegin();
783 for ( ; vIt != mGridLines.constEnd(); ++vIt )
788 l2 = QLineF( vIt->line.first(), vIt->line.last() );
790 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
793 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
795 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
798 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
805void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
814 switch ( mGridFrameStyle )
818 drawGridFrameZebra( p, extension );
823 drawGridFrameTicks( p, extension );
828 drawGridFrameLine( p, extension );
839void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
842 poly << line.p1() << line.p2();
843 drawGridLine( poly, context );
846void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
853 mGridLineSymbol->startRender( context );
854 mGridLineSymbol->renderPolyline( line,
nullptr, context );
855 mGridLineSymbol->stopRender( context );
858void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
865 mGridMarkerSymbol->startRender( context );
866 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
867 mGridMarkerSymbol->stopRender( context );
870void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
890void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
899 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
903 double currentCoord = 0.0;
910 bool drawTLBox =
false;
911 bool drawTRBox =
false;
912 bool drawBLBox =
false;
913 bool drawBRBox =
false;
915 QMap< double, double > pos = QMap< double, double >();
916 QList< GridLine >::const_iterator it = mGridLines.constBegin();
917 for ( ; it != mGridLines.constEnd(); ++it )
920 for (
int i = 0 ; i < 2 ; ++i )
922 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
925 if ( annot.border != border )
928 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
932 pos.insert( annot.position.y(), it->coordinate );
934 pos.insert( annot.position.x(), it->coordinate );
941 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
957 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
961 QPen framePen = QPen( mGridFramePenColor );
962 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
963 framePen.setJoinStyle( Qt::MiterJoin );
964 p->setPen( framePen );
966 QMap< double, double >::const_iterator posIt = pos.constBegin();
967 for ( ; posIt != pos.constEnd(); ++posIt )
969 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
972 height = posIt.key() - currentCoord;
973 width = mEvaluatedGridFrameWidth;
974 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
979 height = mEvaluatedGridFrameWidth;
980 width = posIt.key() - currentCoord;
982 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
984 p->drawRect( QRectF( x, y, width, height ) );
985 currentCoord = posIt.key();
992 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
993 p->setBrush( QBrush( mGridFrameFillColor1 ) );
995 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
997 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
999 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1001 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1005void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1015 QPen framePen = QPen( mGridFramePenColor );
1016 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1017 framePen.setCapStyle( Qt::FlatCap );
1018 p->setBrush( Qt::NoBrush );
1019 p->setPen( framePen );
1022 QList< GridLine >::iterator it = mGridLines.begin();
1023 for ( ; it != mGridLines.end(); ++it )
1026 for (
int i = 0 ; i < 2 ; ++i )
1028 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1030 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1034 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1042 facingLeft = ( annot.angle != 0 );
1043 facingRight = ( annot.angle != 0 );
1047 facingLeft = ( annot.angle > 0 );
1048 facingRight = ( annot.angle < 0 );
1052 facingLeft = ( annot.angle < 0 );
1053 facingRight = ( annot.angle > 0 );
1056 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1057 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1059 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1060 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1062 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1063 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1065 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1066 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1070 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1072 double fA = mEvaluatedGridFrameMargin;
1073 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1075 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1077 fA /= QVector2D::dotProduct( vector, normalVector );
1078 fB /= QVector2D::dotProduct( vector, normalVector );
1085 extension->UpdateBorder( annot.border, fB );
1093 pA = annot.position + fA * vector;
1094 pB = annot.position + fB * vector;
1098 pA = annot.position - fA * vector;
1099 pB = annot.position - fB * vector;
1103 pA = annot.position - fB * vector;
1104 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1106 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1112void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1122 QPen framePen = QPen( mGridFramePenColor );
1123 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1124 framePen.setCapStyle( Qt::SquareCap );
1125 p->setBrush( Qt::NoBrush );
1126 p->setPen( framePen );
1136 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1144 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1150 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1152 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1160 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1163 if ( ! extension && drawDiagonals )
1168 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1169 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1170 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1175 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1176 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1177 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1182 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1183 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1184 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1189 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1190 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1191 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1197 GridExtension *extension )
const
1199 QString currentAnnotationString;
1200 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1201 for ( ; it != mGridLines.constEnd(); ++it )
1203 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1204 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1205 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1209void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1216 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1226 : (
QgsTextRenderer::textHeight( context, mAnnotationFormat,
'0', false ) ) ) / context.convertToPainterUnits( 1,
Qgis::RenderUnit::Millimeters );
1228 double xpos = annot.position.x();
1229 double ypos = annot.position.y();
1230 QPointF anchor = QPointF();
1237 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1241 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1244 double f = mEvaluatedAnnotationFrameDistance;
1252 f += mEvaluatedGridFrameWidth;
1253 if ( hasBorderWidth )
1254 f += mEvaluatedGridFrameLineThickness / 2.0;
1259 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1261 f /= QVector2D::dotProduct( vector, normalVector );
1264 const QVector2D pos = annot.position + f * vector;
1277 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1279 if ( rotation <= -90 || rotation > 90 )
1282 anchor.setX( outside ? 0 : textWidth );
1286 anchor.setX( outside ? textWidth : 0 );
1290 anchor.setY( 0.5 * textHeight );
1292 anchor.setY( -1.5 * textHeight );
1294 anchor.setY( -0.5 * textHeight );
1300 anchor.setX( 0.5 * textWidth );
1301 anchor.setY( -0.5 * textHeight );
1303 anchor.setY( outside ? 0 : -textHeight );
1305 anchor.setX( outside ? 0 : textWidth );
1307 anchor.setY( outside ? -textHeight : 0 );
1309 anchor.setX( outside ? textWidth : 0 );
1314 anchor.setX( 0.5 * textWidth );
1315 anchor.setY( -0.5 * textHeight );
1317 anchor.setX( outside ? 0 : textWidth );
1319 anchor.setY( outside ? -textHeight : 0 );
1321 anchor.setX( outside ? textWidth : 0 );
1323 anchor.setY( outside ? 0 : -textHeight );
1328 anchor.setX( 0.5 * textWidth );
1329 anchor.setY( -0.5 * textHeight );
1331 anchor.setX( outside ? textWidth : 0 );
1333 anchor.setY( outside ? 0 : -textHeight );
1335 anchor.setX( outside ? 0 : textWidth );
1337 anchor.setY( outside ? -textHeight : 0 );
1342 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1343 anchor.setX( 0.5 * textWidth );
1345 anchor.setY( -textHeight );
1353 extension->UpdateBorder( frameBorder, -f + textWidth );
1355 extension->UpdateAll( textWidth / 2.0 );
1358 if ( extension || !context.
painter() )
1362 bool facingLeft = ( annot.angle < 0 );
1363 bool facingRight = ( annot.angle > 0 );
1366 facingLeft = !facingLeft;
1367 facingRight = !facingRight;
1369 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1370 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1372 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1373 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1375 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1376 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1378 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1379 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1383 context.
painter()->translate( QPointF( xpos, ypos ) );
1384 context.
painter()->rotate( rotation );
1385 context.
painter()->translate( -anchor );
1393 bool geographic =
false;
1407 const double wrappedX = std::fmod( value, 360.0 );
1408 if ( wrappedX > 180.0 )
1410 value = wrappedX - 360.0;
1412 else if ( wrappedX < -180.0 )
1414 value = wrappedX + 360.0;
1420 return QString::number( value,
'f', mGridAnnotationPrecision );
1426 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1430 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1432 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1438 if ( !geographic || coordRounded != 0.0 )
1440 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1446 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1450 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1457 if ( !mGridAnnotationExpression )
1459 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1460 mGridAnnotationExpression->prepare( &expressionContext );
1462 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1466 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
1467 switch ( mGridAnnotationFormat )
1486 flags = QgsCoordinateFormatter::FormatFlags();
1496 flags = QgsCoordinateFormatter::FormatFlags();
1517int QgsLayoutItemMapGrid::xGridLines()
const
1519 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1526 QRectF mapBoundingRect = mapPolygon.boundingRect();
1527 double gridIntervalY = mEvaluatedIntervalY;
1528 double gridOffsetY = mEvaluatedOffsetY;
1529 double annotationScale = 1.0;
1530 switch ( mGridUnit )
1535 mapBoundingRect =
mMap->rect();
1536 mapPolygon = QPolygonF(
mMap->rect() );
1537 if ( mGridUnit ==
CM )
1539 annotationScale = 0.1;
1540 gridIntervalY *= 10;
1552 const double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1553 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1555 int gridLineCount = 0;
1560 double yCanvasCoord;
1561 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1563 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1565 newLine.coordinate = currentLevel * annotationScale;
1567 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1568 mGridLines.append( newLine );
1569 currentLevel += gridIntervalY;
1576 QVector<QLineF> borderLines;
1577 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1578 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1579 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1580 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1582 QVector<QPointF> intersectionList;
1584 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1586 intersectionList.clear();
1587 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1589 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1590 for ( ; it != borderLines.constEnd(); ++it )
1592 QPointF intersectionPoint;
1593 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1595 intersectionList.push_back( intersectionPoint );
1596 if ( intersectionList.size() >= 2 )
1603 if ( intersectionList.size() >= 2 )
1606 newLine.coordinate = currentLevel;
1609 mGridLines.append( newLine );
1612 currentLevel += gridIntervalY;
1619int QgsLayoutItemMapGrid::yGridLines()
const
1621 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1627 QRectF mapBoundingRect = mapPolygon.boundingRect();
1628 double gridIntervalX = mEvaluatedIntervalX;
1629 double gridOffsetX = mEvaluatedOffsetX;
1630 double annotationScale = 1.0;
1631 switch ( mGridUnit )
1636 mapBoundingRect =
mMap->rect();
1637 mapPolygon = QPolygonF(
mMap->rect() );
1638 if ( mGridUnit ==
CM )
1640 annotationScale = 0.1;
1641 gridIntervalX *= 10;
1653 const double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1654 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1656 int gridLineCount = 0;
1660 double xCanvasCoord;
1661 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1663 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1666 newLine.coordinate = currentLevel * annotationScale;
1668 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1669 mGridLines.append( newLine );
1670 currentLevel += gridIntervalX;
1677 QVector<QLineF> borderLines;
1678 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1679 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1680 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1681 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1683 QVector<QPointF> intersectionList;
1685 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1687 intersectionList.clear();
1688 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1690 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1691 for ( ; it != borderLines.constEnd(); ++it )
1693 QPointF intersectionPoint;
1694 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1696 intersectionList.push_back( intersectionPoint );
1697 if ( intersectionList.size() >= 2 )
1704 if ( intersectionList.size() >= 2 )
1707 newLine.coordinate = currentLevel;
1710 mGridLines.append( newLine );
1713 currentLevel += gridIntervalX;
1721 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1726 const double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1727 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1729 const double minX = bbox.
xMinimum();
1730 const double maxX = bbox.
xMaximum();
1731 double step = ( maxX - minX ) / 20;
1733 bool crosses180 =
false;
1734 bool crossed180 =
false;
1739 step = ( maxX + 360.0 - minX ) / 20;
1745 int gridLineCount = 0;
1749 double currentX = minX;
1753 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1770 if ( crosses180 && currentX > 180.0 )
1778 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1779 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1780 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1782 if ( !( *lineIt ).isEmpty() )
1785 newLine.coordinate = currentLevel;
1787 newLine.line = QPolygonF( *lineIt );
1788 mGridLines.append( newLine );
1792 currentLevel -= mEvaluatedIntervalY;
1800 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1805 const double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1806 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1808 const double minY = bbox.
yMinimum();
1809 const double maxY = bbox.
yMaximum();
1810 const double step = ( maxY - minY ) / 20;
1815 bool crosses180 =
false;
1816 bool crossed180 =
false;
1823 int gridLineCount = 0;
1824 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1827 double currentY = minY;
1831 if ( currentY > maxY )
1851 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1852 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1853 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1855 if ( !( *lineIt ).isEmpty() )
1858 newLine.coordinate = currentLevel;
1860 newLine.line = QPolygonF( *lineIt );
1861 mGridLines.append( newLine );
1865 currentLevel += mEvaluatedIntervalX;
1866 if ( crosses180 && currentLevel > 180.0 )
1868 currentLevel -= 360.0;
1897 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1899 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1901 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1903 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1918 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1920 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1922 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1924 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
1931void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1936 mTransformDirty = mTransformDirty
1943 switch ( mGridUnit )
1956 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1958 mEvaluatedEnabled =
false;
1963 const double mapWidthMapUnits = mapWidth();
1964 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1965 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1967 mEvaluatedIntervalX = interval;
1968 mEvaluatedIntervalY = interval;
1969 mTransformDirty =
true;
1992double QgsLayoutItemMapGrid::mapWidth()
const
2003 return mapExtent.
width();
2020bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2022 return a.first < b.first;
2035 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2036 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2037 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2038 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2044 if ( p.x() <= tolerance )
2055 if ( p.y() <= tolerance )
2067 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2073 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2074 return distanceToSide.at( 0 ).second;
2079 mGridLineSymbol.reset( symbol );
2084 return mGridLineSymbol.get();
2089 return mGridLineSymbol.get();
2094 mGridMarkerSymbol.reset( symbol );
2099 return mGridMarkerSymbol.get();
2104 return mGridMarkerSymbol.get();
2109 mAnnotationFormat.
setFont( font );
2110 if ( font.pointSizeF() > 0 )
2112 mAnnotationFormat.
setSize( font.pointSizeF() );
2115 else if ( font.pixelSize() > 0 )
2117 mAnnotationFormat.
setSize( font.pixelSize() );
2124 return mAnnotationFormat.
toQFont();
2129 mAnnotationFormat.
setColor( color );
2134 return mAnnotationFormat.
color();
2142 mLeftGridAnnotationDisplay = display;
2145 mRightGridAnnotationDisplay = display;
2148 mTopGridAnnotationDisplay = display;
2151 mBottomGridAnnotationDisplay = display;
2155 refreshDataDefinedProperties();
2169 return mLeftGridAnnotationDisplay;
2171 return mRightGridAnnotationDisplay;
2173 return mTopGridAnnotationDisplay;
2175 return mBottomGridAnnotationDisplay;
2177 return mBottomGridAnnotationDisplay;
2184 double bottom = 0.0;
2187 return std::max( std::max( std::max( top, right ), bottom ), left );
2197 if ( !
mMap || !mEvaluatedEnabled )
2207 GridExtension extension;
2210 switch ( mGridUnit )
2217 drawGridCrsTransform( context, 0,
true );
2224 drawGridNoTransform( context, 0,
true );
2229 updateGridLinesAnnotationsPositions();
2233 drawGridFrame(
nullptr, &extension );
2236 if ( mShowGridAnnotation )
2241 top = extension.top;
2242 right = extension.right;
2243 bottom = extension.bottom;
2244 left = extension.left;
2250 refreshDataDefinedProperties();
2255 if ( unit == mGridUnit )
2260 mTransformDirty =
true;
2269 mGridIntervalX = interval;
2270 mTransformDirty =
true;
2271 refreshDataDefinedProperties();
2280 mGridIntervalY = interval;
2281 mTransformDirty =
true;
2282 refreshDataDefinedProperties();
2291 mGridOffsetX = offset;
2292 mTransformDirty =
true;
2293 refreshDataDefinedProperties();
2302 mGridOffsetY = offset;
2303 mTransformDirty =
true;
2304 refreshDataDefinedProperties();
2313 mMinimumIntervalWidth = minWidth;
2314 mTransformDirty =
true;
2315 refreshDataDefinedProperties();
2324 mMaximumIntervalWidth = maxWidth;
2325 mTransformDirty =
true;
2326 refreshDataDefinedProperties();
2331 if (
style == mGridStyle )
2336 mTransformDirty =
true;
2341 mCrossLength = length;
2342 refreshDataDefinedProperties();
2350 mLeftGridAnnotationDirection = direction;
2353 mRightGridAnnotationDirection = direction;
2356 mTopGridAnnotationDirection = direction;
2359 mBottomGridAnnotationDirection = direction;
2372 mGridFrameSides = flags;
2378 mGridFrameSides |= flag;
2380 mGridFrameSides &= ~flag;
2385 return mGridFrameSides;
2394 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2400 if ( mGridLineSymbol )
2406 if ( mGridMarkerSymbol )
2418 mTransformDirty =
true;
2419 refreshDataDefinedProperties();
2426 return mGridFrameSides.testFlag( flag );
2431 mGridFrameWidth = width;
2432 refreshDataDefinedProperties();
2437 mGridFrameMargin = margin;
2438 refreshDataDefinedProperties();
2443 mGridFramePenThickness = width;
2444 refreshDataDefinedProperties();
2449 mLeftGridAnnotationDirection = direction;
2450 mRightGridAnnotationDirection = direction;
2451 mTopGridAnnotationDirection = direction;
2452 mBottomGridAnnotationDirection = direction;
2460 mLeftGridAnnotationPosition = position;
2463 mRightGridAnnotationPosition = position;
2466 mTopGridAnnotationPosition = position;
2469 mBottomGridAnnotationPosition = position;
2485 return mLeftGridAnnotationPosition;
2487 return mRightGridAnnotationPosition;
2489 return mTopGridAnnotationPosition;
2491 return mBottomGridAnnotationPosition;
2493 return mLeftGridAnnotationPosition;
2498 mAnnotationFrameDistance = distance;
2499 refreshDataDefinedProperties();
2506 return mLeftGridAnnotationDirection;
2512 return mLeftGridAnnotationDirection;
2514 return mRightGridAnnotationDirection;
2516 return mTopGridAnnotationDirection;
2518 return mBottomGridAnnotationDirection;
2520 return mLeftGridAnnotationDirection;
2525 mGridAnnotationExpressionString = expression;
2526 mGridAnnotationExpression.reset();
2534 mLeftFrameDivisions = divisions;
2537 mRightFrameDivisions = divisions;
2540 mTopFrameDivisions = divisions;
2543 mBottomFrameDivisions = divisions;
2547 refreshDataDefinedProperties();
2560 return mLeftFrameDivisions;
2562 return mRightFrameDivisions;
2564 return mTopFrameDivisions;
2566 return mBottomFrameDivisions;
2568 return mLeftFrameDivisions;
2584 const QRectF mbr = mapPolygon.boundingRect();
2585 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2591 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2592 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2594 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2595 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2597 if ( lowerLeft.x() > upperRight.x() )
2624QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2632 QList<QPolygonF> trimmedLines;
2633 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2634 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2636 trimmedLines << ( *geomIt ).asQPolygonF();
2638 return trimmedLines;
The Qgis class provides global constants for use throughout the application.
@ Millimeters
Millimeters.
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
@ Forward
Forward transform (from source to destination)
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Qgis::DistanceUnit mapUnits
Custom exception class for Coordinate Reference System related exceptions.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Qgis::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
A geometry is the spatial representation of a feature.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QList< QgsLayoutItemMapGrid * > asList() const
Returns a list of QgsLayoutItemMapGrids contained by the stack.
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void removeGrid(const QString &gridId)
Removes a grid with matching gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid...
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void addGrid(QgsLayoutItemMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
QgsLayoutItemMapGrid * grid(const QString &gridId) const
Returns a reference to a grid with matching gridId within the stack.
bool readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the item stack's state from a DOM document, where element is a DOM node corresponding to a 'Layo...
QgsLayoutItemMapGrid & operator[](int index)
Returns a reference to a grid at the specified index within the stack.
void moveGridUp(const QString &gridId)
Moves a grid with matching gridId up the stack, causing it to be rendered above other grids.
void moveGridDown(const QString &gridId)
Moves a grid with matching gridId down the stack, causing it to be rendered below other grids.
QgsLayoutItemMapGridStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGridStack, attached to the specified map.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
void setFrameSideFlags(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
GridStyle
Grid drawing style.
@ Markers
Draw markers at intersections of grid lines.
@ Cross
Draw line crosses at intersections of grid lines.
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
GridUnit
Unit for grid values.
@ CM
Grid units in centimeters.
@ MM
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnit
Grid units follow map units.
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ FrameTop
Top side of map.
@ FrameBottom
Bottom side of map.
@ FrameLeft
Left side of map.
@ FrameRight
Right side of map.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
void draw(QPainter *painter) override
Draws the item on to a destination painter.
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
AnnotationPosition
Position for grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
AnnotationCoordinate
Annotation coordinate type.
@ Latitude
Coordinate is a latitude value.
@ Longitude
Coordinate is a longitude value.
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
DisplayMode
Display settings for grid annotations and frames.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
void crsChanged()
Emitted whenever the grid's CRS is changed.
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
~QgsLayoutItemMapGrid() override
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
TickLengthMode
Tick length mode (useful for rotated grids)
@ OrthogonalTicks
Align ticks orthogonaly.
AnnotationFormat
Format for displaying grid annotations.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ CustomFormat
Custom expression-based format.
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
AnnotationDirection
Direction of grid annotations.
@ OnTick
Draw annotations parallel to tick (on the line)
@ Horizontal
Draw annotations horizontally.
@ Vertical
Draw annotations vertically, ascending.
@ AboveTick
Draw annotations parallel to tick (above the line)
@ UnderTick
Draw annotations parallel to tick (under the line)
@ VerticalDescending
Draw annotations vertically, descending.
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
FrameStyle
Style for grid frame.
@ Zebra
Black/white pattern.
@ InteriorTicks
Tick markers drawn inside map frame.
@ LineBorder
Simple solid line frame.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ NoFrame
Disable grid frame.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
BorderSide
Border sides for annotations.
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
A collection of map items which are drawn above the map content in a QgsLayoutItemMap.
void addItem(QgsLayoutItemMapItem *item)
Adds a new map item to the stack and takes ownership of the item.
void removeItem(const QString &itemId)
Removes an item which matching itemId from the stack and deletes the corresponding QgsLayoutItemMapIt...
QgsLayoutItemMapItem * item(int index) const
Returns a reference to the item at the specified index within the stack.
void moveItemUp(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
void removeItems()
Clears the item stack and deletes all QgsLayoutItemMapItems contained by the stack.
QList< QgsLayoutItemMapItem * > mItems
void moveItemDown(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
QgsLayoutItemMap * mMap
Associated map.
virtual bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
virtual bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
virtual void setEnabled(bool enabled)
Controls whether the item will be drawn.
bool enabled() const
Returns whether the item will be drawn.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
QgsRectangle extent() const
Returns the current map extent.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
bool frameEnabled() const
Returns true if the item includes a frame.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
QPointer< QgsLayout > mLayout
@ MapGridOffsetY
Map grid offset Y.
@ MapGridFrameDivisionsBottom
Map frame division display bottom.
@ MapGridEnabled
Map grid enabled.
@ MapGridIntervalX
Map grid interval X.
@ MapGridFrameDivisionsTop
Map frame division display top.
@ MapGridAnnotationDisplayLeft
Map annotation display left.
@ MapGridFrameMargin
Map grid frame margin.
@ MapGridCrossSize
Map grid cross size.
@ MapGridAnnotationDisplayRight
Map annotation display right.
@ MapGridOffsetX
Map grid offset X.
@ MapGridAnnotationDisplayTop
Map annotation display top.
@ MapGridAnnotationDisplayBottom
Map annotation display bottom.
@ MapGridFrameDivisionsRight
Map frame division display right.
@ MapGridLabelDistance
Map grid label distance.
@ MapGridIntervalY
Map grid interval Y.
@ MapGridFrameSize
Map grid frame size.
@ MapGridFrameLineThickness
Map grid frame line thickness.
@ MapGridFrameDivisionsLeft
Map frame division display left.
QgsLayoutRenderContext::Flags flags() const
Returns the current combination of flags used for rendering the layout.
@ FlagAntialiasing
Use antialiasing when drawing items.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
A line symbol type, for rendering LineString and MultiLineString geometries.
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
A class to represent a 2D point.
bool isEmpty() const
Returns true if the geometry is empty.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Scoped object for saving and restoring a QPainter object's state.
Scoped object for temporary scaling of a QgsRenderContext for pixel based rendering.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
Handles rendering text using rich formatting options, including drop shadows, buffers and background ...
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
QgsLayoutItemMapGrid::DisplayMode gridAnnotationDisplayModeFromDD(QString ddValue, QgsLayoutItemMapGrid::DisplayMode defValue)
bool sortByDistance(QPair< qreal, QgsLayoutItemMapGrid::BorderSide > a, QPair< qreal, QgsLayoutItemMapGrid::BorderSide > b)
QVector2D borderToNormal2D(QgsLayoutItemMapGrid::BorderSide border)
QVector2D borderToVector2D(QgsLayoutItemMapGrid::BorderSide border)
#define QgsDebugError(str)
const QgsCoordinateReferenceSystem & crs
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to the style entity currently being visited.