49#include "moc_qgslayoutitemmapgrid.cpp"
51#define MAX_GRID_LINES 1000
82 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
88 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
93 QList< QgsLayoutItemMapGrid * > list;
116 const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
117 for (
int i = 0; i < mapGridNodeList.size(); ++i )
119 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
121 mapGrid->
readXml( mapGridElem, doc, context );
135 return std::max( std::max( std::max( top, right ), bottom ), left );
149 double gridTop = 0.0;
150 double gridRight = 0.0;
151 double gridBottom = 0.0;
152 double gridLeft = 0.0;
153 grid->calculateMaxExtension( gridTop, gridRight, gridBottom, gridLeft );
154 top = std::max( top, gridTop );
155 right = std::max( right, gridRight );
156 bottom = std::max( bottom, gridBottom );
157 left = std::max( left, gridLeft );
173 return QVector2D( 0, 1 );
175 return QVector2D( -1, 0 );
177 return QVector2D( 0, -1 );
179 return QVector2D( 1, 0 );
187 return QVector2D( borderVector.y(), -borderVector.x() );
197 const QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
198 if ( !defaultFontString.isEmpty() )
201 QgsFontUtils::setFontFamily( font, defaultFontString );
202 mAnnotationFormat.setFont( font );
205 createDefaultGridLineSymbol();
206 createDefaultGridMarkerSymbol();
212 if ( !mCRS.isValid() )
219void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
221 QVariantMap properties;
222 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
223 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
224 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
228void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
230 QVariantMap properties;
231 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
232 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
233 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
239 if ( mGridLineSymbol )
241 mGridLineSymbol->setWidth( width );
247 if ( mGridLineSymbol )
249 mGridLineSymbol->setColor(
c );
260 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
261 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
262 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
263 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
264 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
265 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
266 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
268 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
270 lineStyleElem.appendChild( gridLineStyleElem );
271 mapGridElem.appendChild( lineStyleElem );
273 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
275 markerStyleElem.appendChild( gridMarkerStyleElem );
276 mapGridElem.appendChild( markerStyleElem );
278 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
279 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
280 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
281 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
282 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
286 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
287 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
288 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
289 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
292 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
293 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
294 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
295 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
296 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
297 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
298 if ( mCRS.isValid() )
300 mCRS.writeXml( mapGridElem, doc );
303 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
304 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
305 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
306 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
307 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
308 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
309 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
310 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
311 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
312 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
313 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
314 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
315 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
316 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
317 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
318 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
319 mapGridElem.appendChild( mAnnotationFormat.writeXml( doc, context ) );
320 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
321 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
322 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
323 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
324 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
327 elem.appendChild( mapGridElem );
334 if ( itemElem.isNull() )
343 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
344 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
345 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
346 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
347 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
348 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
350 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
351 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
352 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
354 mGridFrameFillColor1 =
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral(
"frameFillColor1" ), QStringLiteral(
"255,255,255,255" ) ) );
355 mGridFrameFillColor2 =
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral(
"frameFillColor2" ), QStringLiteral(
"0,0,0,255" ) ) );
360 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
361 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
362 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
363 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
364 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
365 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
366 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
367 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
369 const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
370 if ( !lineStyleElem.isNull() )
372 const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
373 if ( !symbolElem.isNull() )
382 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
383 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
384 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
385 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
388 const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
389 if ( !markerStyleElem.isNull() )
391 const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
392 if ( !symbolElem.isNull() )
398 if ( !mCRS.readXml( itemElem ) )
401 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
404 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
406 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
407 mGridAnnotationExpression.reset();
412 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
413 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
415 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
421 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
423 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
425 mAnnotationFormat.readXml( itemElem, context );
432 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
434 mAnnotationFormat.setFont( font );
435 mAnnotationFormat.setSize( font.pointSizeF() );
440 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
441 const int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
443 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
444 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
446 refreshDataDefinedProperties();
456 mTransformDirty =
true;
462 return mBlendMode != QPainter::CompositionMode_SourceOver;
465QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
467 const QTransform t = QTransform::fromScale( scale, scale );
468 return t.map( polygon );
471void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
473 if ( !
mMap || !mEvaluatedEnabled )
479 const QPolygonF mapPolygon =
mMap->transformedMapPolygon();
480 if ( mapPolygon != mPrevMapPolygon )
482 mTransformDirty =
true;
483 mPrevMapPolygon = mapPolygon;
486 if ( mTransformDirty )
488 calculateCrsTransformLines();
492 if ( !calculateLinesOnly )
496 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
497 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
501 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
506 const double maxX =
mMap->rect().width();
507 const double maxY =
mMap->rect().height();
509 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
510 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
512 const double x = intersectionIt->x();
513 const double y = intersectionIt->y();
517 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
518 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
519 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
520 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
521 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
522 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
525 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
526 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
530 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
537void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
539 QgsRectangle crsBoundingRect;
540 QgsCoordinateTransform inverseTr;
541 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
548 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
549 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
556 QList< QgsGeometry > xLines;
557 QList< QgsGeometry > yLines;
558 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
559 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
563 for (
int i = 0; i < gridIt->line.size(); ++i )
565 line.append( QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
574 mTransformedIntersections.clear();
575 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
576 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
578 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
579 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
582 const QgsGeometry intersects = ( *yLineIt ).intersection( ( *xLineIt ) );
583 if ( intersects.
isNull() )
588 QgsPointXY vertex = intersects.
vertexAt( i );
591 mTransformedIntersections << vertex;
599 mTransformDirty =
false;
604 if ( !
mMap || !mEvaluatedEnabled )
608 QPaintDevice *paintDevice = p->device();
615 p->setCompositionMode( mBlendMode );
618 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
619 p->setClipRect( thisPaintRect );
620 if ( thisPaintRect != mPrevPaintRect )
623 mTransformDirty =
true;
624 mPrevPaintRect = thisPaintRect;
628 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
629 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
644 if ( mCRS.isValid() && mCRS !=
mMap->crs() )
646 drawGridCrsTransform( context, dotsPerMM );
653 drawGridNoTransform( context, dotsPerMM );
658 p->setClipping(
false );
662 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
667 updateGridLinesAnnotationsPositions();
674 if ( mShowGridAnnotation )
680void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
682 QList< GridLine >::iterator it = mGridLines.begin();
683 for ( ; it != mGridLines.end(); ++it )
685 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
686 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
687 it->startAnnotation.position = QVector2D( it->line.first() );
688 it->endAnnotation.position = QVector2D( it->line.last() );
689 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
690 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
692 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() );
694 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() );
698void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
705 if ( calculateLinesOnly )
708 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
709 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
717 for ( ; vIt != mGridLines.constEnd(); ++vIt )
721 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
726 drawGridLine( line, context );
729 for ( ; hIt != mGridLines.constEnd(); ++hIt )
733 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
738 drawGridLine( line, context );
744 QPointF intersectionPoint, crossEnd1, crossEnd2;
745 for ( ; vIt != mGridLines.constEnd(); ++vIt )
750 l1 = QLineF( vIt->line.first(), vIt->line.last() );
753 hIt = mGridLines.constBegin();
754 for ( ; hIt != mGridLines.constEnd(); ++hIt )
759 l2 = QLineF( hIt->line.first(), hIt->line.last() );
761 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
766 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
768 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
771 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
775 drawGridMarker( intersectionPoint * dotsPerMM, context );
787 hIt = mGridLines.constBegin();
788 for ( ; hIt != mGridLines.constEnd(); ++hIt )
793 l1 = QLineF( hIt->line.first(), hIt->line.last() );
795 vIt = mGridLines.constBegin();
796 for ( ; vIt != mGridLines.constEnd(); ++vIt )
801 l2 = QLineF( vIt->line.first(), vIt->line.last() );
803 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
806 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
808 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
811 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
818void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
827 switch ( mGridFrameStyle )
831 drawGridFrameZebra( p, extension );
836 drawGridFrameTicks( p, extension );
841 drawGridFrameLine( p, extension );
852void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
855 poly << line.p1() << line.p2();
856 drawGridLine( poly, context );
859void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
861 if ( !
mMap || !
mMap->layout() || !mGridLineSymbol )
866 mGridLineSymbol->startRender( context );
867 mGridLineSymbol->renderPolyline( line,
nullptr, context );
868 mGridLineSymbol->stopRender( context );
871void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
873 if ( !
mMap || !
mMap->layout() || !mGridMarkerSymbol )
878 mGridMarkerSymbol->startRender( context );
879 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
880 mGridMarkerSymbol->stopRender( context );
883void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
903void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
912 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
916 double currentCoord = 0.0;
923 bool drawTLBox =
false;
924 bool drawTRBox =
false;
925 bool drawBLBox =
false;
926 bool drawBRBox =
false;
928 QMap< double, double > pos = QMap< double, double >();
929 QList< GridLine >::const_iterator it = mGridLines.constBegin();
930 for ( ; it != mGridLines.constEnd(); ++it )
933 for (
int i = 0 ; i < 2 ; ++i )
935 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
938 if ( annot.border != border )
941 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
945 pos.insert( annot.position.y(), it->coordinate );
947 pos.insert( annot.position.x(), it->coordinate );
954 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
970 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
974 QPen framePen = QPen( mGridFramePenColor );
975 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
976 framePen.setJoinStyle( Qt::MiterJoin );
977 p->setPen( framePen );
979 QMap< double, double >::const_iterator posIt = pos.constBegin();
980 for ( ; posIt != pos.constEnd(); ++posIt )
982 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
985 height = posIt.key() - currentCoord;
986 width = mEvaluatedGridFrameWidth;
987 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
992 height = mEvaluatedGridFrameWidth;
993 width = posIt.key() - currentCoord;
995 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
997 p->drawRect( QRectF( x, y, width, height ) );
998 currentCoord = posIt.key();
1005 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
1006 p->setBrush( QBrush( mGridFrameFillColor1 ) );
1008 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1010 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1012 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1014 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1018void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1028 QPen framePen = QPen( mGridFramePenColor );
1029 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1030 framePen.setCapStyle( Qt::FlatCap );
1031 p->setBrush( Qt::NoBrush );
1032 p->setPen( framePen );
1035 QList< GridLine >::iterator it = mGridLines.begin();
1036 for ( ; it != mGridLines.end(); ++it )
1039 for (
int i = 0 ; i < 2 ; ++i )
1041 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1043 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1047 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1055 facingLeft = ( annot.angle != 0 );
1056 facingRight = ( annot.angle != 0 );
1060 facingLeft = ( annot.angle > 0 );
1061 facingRight = ( annot.angle < 0 );
1065 facingLeft = ( annot.angle < 0 );
1066 facingRight = ( annot.angle > 0 );
1069 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1070 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1072 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1073 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1075 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1076 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1078 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1079 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1083 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1085 double fA = mEvaluatedGridFrameMargin;
1086 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1088 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1090 fA /= QVector2D::dotProduct( vector, normalVector );
1091 fB /= QVector2D::dotProduct( vector, normalVector );
1098 extension->UpdateBorder( annot.border, fB );
1106 pA = annot.position + fA * vector;
1107 pB = annot.position + fB * vector;
1111 pA = annot.position - fA * vector;
1112 pB = annot.position - fB * vector;
1116 pA = annot.position - fB * vector;
1117 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1119 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1125void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1135 QPen framePen = QPen( mGridFramePenColor );
1136 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1137 framePen.setCapStyle( Qt::SquareCap );
1138 p->setBrush( Qt::NoBrush );
1139 p->setPen( framePen );
1149 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1157 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1163 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1165 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1173 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1176 if ( ! extension && drawDiagonals )
1181 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1182 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1183 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1188 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1189 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1190 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1195 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1196 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1197 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1202 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1203 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1204 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1210 GridExtension *extension )
const
1212 QString currentAnnotationString;
1213 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1214 for ( ; it != mGridLines.constEnd(); ++it )
1216 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1217 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1218 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1222void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1229 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1241 double xpos = annot.position.x();
1242 double ypos = annot.position.y();
1243 QPointF anchor = QPointF();
1250 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1254 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1257 double f = mEvaluatedAnnotationFrameDistance;
1265 f += mEvaluatedGridFrameWidth;
1266 if ( hasBorderWidth )
1267 f += mEvaluatedGridFrameLineThickness / 2.0;
1272 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1274 f /= QVector2D::dotProduct( vector, normalVector );
1277 const QVector2D pos = annot.position + f * vector;
1290 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1292 if ( rotation <= -90 || rotation > 90 )
1295 anchor.setX( outside ? 0 : textWidth );
1299 anchor.setX( outside ? textWidth : 0 );
1303 anchor.setY( 0.5 * textHeight );
1305 anchor.setY( -1.5 * textHeight );
1307 anchor.setY( -0.5 * textHeight );
1313 anchor.setX( 0.5 * textWidth );
1314 anchor.setY( -0.5 * textHeight );
1316 anchor.setY( outside ? 0 : -textHeight );
1318 anchor.setX( outside ? 0 : textWidth );
1320 anchor.setY( outside ? -textHeight : 0 );
1322 anchor.setX( outside ? textWidth : 0 );
1327 anchor.setX( 0.5 * textWidth );
1328 anchor.setY( -0.5 * textHeight );
1330 anchor.setX( outside ? 0 : textWidth );
1332 anchor.setY( outside ? -textHeight : 0 );
1334 anchor.setX( outside ? textWidth : 0 );
1336 anchor.setY( outside ? 0 : -textHeight );
1341 anchor.setX( 0.5 * textWidth );
1342 anchor.setY( -0.5 * textHeight );
1344 anchor.setX( outside ? textWidth : 0 );
1346 anchor.setY( outside ? 0 : -textHeight );
1348 anchor.setX( outside ? 0 : textWidth );
1350 anchor.setY( outside ? -textHeight : 0 );
1355 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1356 anchor.setX( 0.5 * textWidth );
1358 anchor.setY( -textHeight );
1366 extension->UpdateBorder( frameBorder, -f + textWidth );
1368 extension->UpdateAll( textWidth / 2.0 );
1371 if ( extension || !context.
painter() )
1375 bool facingLeft = ( annot.angle < 0 );
1376 bool facingRight = ( annot.angle > 0 );
1379 facingLeft = !facingLeft;
1380 facingRight = !facingRight;
1382 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1383 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1385 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1386 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1388 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1389 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1391 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1392 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1395 const QgsScopedQPainterState painterState( context.
painter() );
1396 context.
painter()->translate( QPointF( xpos, ypos ) );
1397 context.
painter()->rotate( rotation );
1398 context.
painter()->translate( -anchor );
1399 const QgsScopedRenderContextScaleToPixels scale( context );
1406 bool geographic =
false;
1407 if ( mCRS.isValid() )
1409 geographic = mCRS.isGeographic();
1413 geographic =
mMap->crs().isGeographic();
1420 const double wrappedX = std::fmod( value, 360.0 );
1421 if ( wrappedX > 180.0 )
1423 value = wrappedX - 360.0;
1425 else if ( wrappedX < -180.0 )
1427 value = wrappedX + 360.0;
1433 return QString::number( value,
'f', mGridAnnotationPrecision );
1439 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1443 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1445 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1451 if ( !geographic || coordRounded != 0.0 )
1453 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1459 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1463 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1468 expressionContext.
lastScope()->
addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral(
"grid_number" ), value,
true ) );
1470 if ( !mGridAnnotationExpression )
1472 mGridAnnotationExpression = std::make_unique<QgsExpression>( mGridAnnotationExpressionString );
1473 mGridAnnotationExpression->prepare( &expressionContext );
1475 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1480 switch ( mGridAnnotationFormat )
1530int QgsLayoutItemMapGrid::xGridLines()
const
1532 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1538 QPolygonF mapPolygon =
mMap->transformedMapPolygon();
1539 QRectF mapBoundingRect = mapPolygon.boundingRect();
1540 double gridIntervalY = mEvaluatedIntervalY;
1541 double gridOffsetY = mEvaluatedOffsetY;
1542 double annotationScale = 1.0;
1543 switch ( mGridUnit )
1548 mapBoundingRect =
mMap->rect();
1549 mapPolygon = QPolygonF(
mMap->rect() );
1550 if ( mGridUnit ==
CM )
1552 annotationScale = 0.1;
1553 gridIntervalY *= 10;
1565 const double roundCorrection = mapBoundingRect.top() > gridOffsetY ? 1.0 : 0.0;
1566 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1568 int gridLineCount = 0;
1573 double yCanvasCoord;
1574 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1576 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1578 newLine.coordinate = currentLevel * annotationScale;
1580 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1581 mGridLines.append( newLine );
1582 currentLevel += gridIntervalY;
1589 QVector<QLineF> borderLines;
1590 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1591 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1592 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1593 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1595 QVector<QPointF> intersectionList;
1597 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1599 intersectionList.clear();
1600 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1602 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1603 for ( ; it != borderLines.constEnd(); ++it )
1605 QPointF intersectionPoint;
1606 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1608 intersectionList.push_back( intersectionPoint );
1609 if ( intersectionList.size() >= 2 )
1616 if ( intersectionList.size() >= 2 )
1619 newLine.coordinate = currentLevel;
1621 newLine.line = QPolygonF() <<
mMap->mapToItemCoords( intersectionList.at( 0 ) ) <<
mMap->mapToItemCoords( intersectionList.at( 1 ) );
1622 mGridLines.append( newLine );
1625 currentLevel += gridIntervalY;
1632int QgsLayoutItemMapGrid::yGridLines()
const
1634 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1639 QPolygonF mapPolygon =
mMap->transformedMapPolygon();
1640 QRectF mapBoundingRect = mapPolygon.boundingRect();
1641 double gridIntervalX = mEvaluatedIntervalX;
1642 double gridOffsetX = mEvaluatedOffsetX;
1643 double annotationScale = 1.0;
1644 switch ( mGridUnit )
1649 mapBoundingRect =
mMap->rect();
1650 mapPolygon = QPolygonF(
mMap->rect() );
1651 if ( mGridUnit ==
CM )
1653 annotationScale = 0.1;
1654 gridIntervalX *= 10;
1666 const double roundCorrection = mapBoundingRect.left() > gridOffsetX ? 1.0 : 0.0;
1667 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1669 int gridLineCount = 0;
1673 double xCanvasCoord;
1674 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1676 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1679 newLine.coordinate = currentLevel * annotationScale;
1681 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1682 mGridLines.append( newLine );
1683 currentLevel += gridIntervalX;
1690 QVector<QLineF> borderLines;
1691 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1692 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1693 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1694 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1696 QVector<QPointF> intersectionList;
1698 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1700 intersectionList.clear();
1701 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1703 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1704 for ( ; it != borderLines.constEnd(); ++it )
1706 QPointF intersectionPoint;
1707 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1709 intersectionList.push_back( intersectionPoint );
1710 if ( intersectionList.size() >= 2 )
1717 if ( intersectionList.size() >= 2 )
1720 newLine.coordinate = currentLevel;
1722 newLine.line = QPolygonF() <<
mMap->mapToItemCoords( intersectionList.at( 0 ) ) <<
mMap->mapToItemCoords( intersectionList.at( 1 ) );
1723 mGridLines.append( newLine );
1726 currentLevel += gridIntervalX;
1734 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1739 const double roundCorrection = bbox.
yMaximum() > mEvaluatedOffsetY ? 1.0 : 0.0;
1740 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1742 const double minX = bbox.
xMinimum();
1743 const double maxX = bbox.
xMaximum();
1744 double step = ( maxX - minX ) / 20;
1746 bool crosses180 =
false;
1747 bool crossed180 =
false;
1748 if ( mCRS.isGeographic() && ( minX > maxX ) )
1752 step = ( maxX + 360.0 - minX ) / 20;
1758 int gridLineCount = 0;
1762 double currentX = minX;
1766 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1773 const QgsPointXY mapPoint = t.
transform( currentX, currentLevel );
1774 gridLine.append(
mMap->mapToItemCoords( QPointF( mapPoint.
x(), mapPoint.
y() ) ) );
1776 catch ( QgsCsException &cse )
1783 if ( crosses180 && currentX > 180.0 )
1791 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, QgsRectangle(
mMap->rect() ) );
1792 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1793 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1795 if ( !( *lineIt ).isEmpty() )
1798 newLine.coordinate = currentLevel;
1800 newLine.line = QPolygonF( *lineIt );
1801 mGridLines.append( newLine );
1805 currentLevel -= mEvaluatedIntervalY;
1813 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1818 const double roundCorrection = bbox.
xMinimum() > mEvaluatedOffsetX ? 1.0 : 0.0;
1819 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1821 const double minY = bbox.
yMinimum();
1822 const double maxY = bbox.
yMaximum();
1823 const double step = ( maxY - minY ) / 20;
1828 bool crosses180 =
false;
1829 bool crossed180 =
false;
1836 int gridLineCount = 0;
1837 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1840 double currentY = minY;
1844 if ( currentY > maxY )
1851 const QgsPointXY mapPoint = t.
transform( currentLevel, currentY );
1853 gridLine.append(
mMap->mapToItemCoords( QPointF( mapPoint.
x(), mapPoint.
y() ) ) );
1855 catch ( QgsCsException &cse )
1864 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine, QgsRectangle(
mMap->rect() ) );
1865 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1866 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1868 if ( !( *lineIt ).isEmpty() )
1871 newLine.coordinate = currentLevel;
1873 newLine.line = QPolygonF( *lineIt );
1874 mGridLines.append( newLine );
1878 currentLevel += mEvaluatedIntervalX;
1879 if ( crosses180 && currentLevel > 180.0 )
1881 currentLevel -= 360.0;
1910 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1912 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1914 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1916 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1930 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1932 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1934 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1936 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
1942void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1947 mTransformDirty = mTransformDirty
1954 switch ( mGridUnit )
1967 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1969 mEvaluatedEnabled =
false;
1974 const double mapWidthMapUnits = mapWidth();
1975 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1976 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1978 mEvaluatedIntervalX = interval;
1979 mEvaluatedIntervalY = interval;
1980 mTransformDirty =
true;
2002double QgsLayoutItemMapGrid::mapWidth()
const
2009 const QgsRectangle mapExtent =
mMap->extent();
2013 return mapExtent.
width();
2030 catch ( QgsCsException & )
2033 QgsDebugError( QStringLiteral(
"An error occurred while calculating length" ) );
2039bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2041 return a.first < b.first;
2051 const double tolerance = std::max(
mMap->frameEnabled() ?
mMap->pen().widthF() : 0.0, 1.0 );
2054 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2055 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2056 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2057 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2063 if ( p.x() <= tolerance )
2074 if ( p.y() <= tolerance )
2086 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2092 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2093 return distanceToSide.at( 0 ).second;
2098 mGridLineSymbol.reset( symbol );
2103 return mGridLineSymbol.get();
2108 return mGridLineSymbol.get();
2113 mGridMarkerSymbol.reset( symbol );
2118 return mGridMarkerSymbol.get();
2123 return mGridMarkerSymbol.get();
2128 mAnnotationFormat.setFont( font );
2129 if ( font.pointSizeF() > 0 )
2131 mAnnotationFormat.setSize( font.pointSizeF() );
2134 else if ( font.pixelSize() > 0 )
2136 mAnnotationFormat.setSize( font.pixelSize() );
2143 return mAnnotationFormat.toQFont();
2148 mAnnotationFormat.
setColor( color );
2153 return mAnnotationFormat.color();
2161 mLeftGridAnnotationDisplay = display;
2164 mRightGridAnnotationDisplay = display;
2167 mTopGridAnnotationDisplay = display;
2170 mBottomGridAnnotationDisplay = display;
2174 refreshDataDefinedProperties();
2178 mMap->updateBoundingRect();
2188 return mLeftGridAnnotationDisplay;
2190 return mRightGridAnnotationDisplay;
2192 return mTopGridAnnotationDisplay;
2194 return mBottomGridAnnotationDisplay;
2196 return mBottomGridAnnotationDisplay;
2203 double bottom = 0.0;
2206 return std::max( std::max( std::max( top, right ), bottom ), left );
2216 if ( !
mMap || !mEvaluatedEnabled )
2226 GridExtension extension;
2229 switch ( mGridUnit )
2234 if ( mCRS.isValid() && mCRS !=
mMap->crs() )
2236 drawGridCrsTransform( context, 0,
true );
2243 drawGridNoTransform( context, 0,
true );
2248 updateGridLinesAnnotationsPositions();
2252 drawGridFrame(
nullptr, &extension );
2255 if ( mShowGridAnnotation )
2260 top = extension.top;
2261 right = extension.right;
2262 bottom = extension.bottom;
2263 left = extension.left;
2269 refreshDataDefinedProperties();
2274 if ( unit == mGridUnit )
2279 mTransformDirty =
true;
2288 mGridIntervalX = interval;
2289 mTransformDirty =
true;
2290 refreshDataDefinedProperties();
2299 mGridIntervalY = interval;
2300 mTransformDirty =
true;
2301 refreshDataDefinedProperties();
2310 mGridOffsetX = offset;
2311 mTransformDirty =
true;
2312 refreshDataDefinedProperties();
2321 mGridOffsetY = offset;
2322 mTransformDirty =
true;
2323 refreshDataDefinedProperties();
2332 mMinimumIntervalWidth = minWidth;
2333 mTransformDirty =
true;
2334 refreshDataDefinedProperties();
2343 mMaximumIntervalWidth = maxWidth;
2344 mTransformDirty =
true;
2345 refreshDataDefinedProperties();
2350 if (
style == mGridStyle )
2355 mTransformDirty =
true;
2360 mCrossLength = length;
2361 refreshDataDefinedProperties();
2369 mLeftGridAnnotationDirection = direction;
2372 mRightGridAnnotationDirection = direction;
2375 mTopGridAnnotationDirection = direction;
2378 mBottomGridAnnotationDirection = direction;
2384 mMap->updateBoundingRect();
2391 mGridFrameSides = flags;
2397 mGridFrameSides |= flag;
2399 mGridFrameSides &= ~flag;
2404 return mGridFrameSides;
2413 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2419 if ( mGridLineSymbol )
2425 if ( mGridMarkerSymbol )
2437 mTransformDirty =
true;
2438 refreshDataDefinedProperties();
2439 mMap->updateBoundingRect();
2445 return mGridFrameSides.testFlag( flag );
2450 mGridFrameWidth = width;
2451 refreshDataDefinedProperties();
2456 mGridFrameMargin = margin;
2457 refreshDataDefinedProperties();
2462 mGridFramePenThickness = width;
2463 refreshDataDefinedProperties();
2468 mLeftGridAnnotationDirection = direction;
2469 mRightGridAnnotationDirection = direction;
2470 mTopGridAnnotationDirection = direction;
2471 mBottomGridAnnotationDirection = direction;
2479 mLeftGridAnnotationPosition = position;
2482 mRightGridAnnotationPosition = position;
2485 mTopGridAnnotationPosition = position;
2488 mBottomGridAnnotationPosition = position;
2494 mMap->updateBoundingRect();
2504 return mLeftGridAnnotationPosition;
2506 return mRightGridAnnotationPosition;
2508 return mTopGridAnnotationPosition;
2510 return mBottomGridAnnotationPosition;
2512 return mLeftGridAnnotationPosition;
2517 mAnnotationFrameDistance = distance;
2518 refreshDataDefinedProperties();
2525 return mLeftGridAnnotationDirection;
2531 return mLeftGridAnnotationDirection;
2533 return mRightGridAnnotationDirection;
2535 return mTopGridAnnotationDirection;
2537 return mBottomGridAnnotationDirection;
2539 return mLeftGridAnnotationDirection;
2544 mGridAnnotationExpressionString = expression;
2545 mGridAnnotationExpression.reset();
2553 mLeftFrameDivisions = divisions;
2556 mRightFrameDivisions = divisions;
2559 mTopFrameDivisions = divisions;
2562 mBottomFrameDivisions = divisions;
2566 refreshDataDefinedProperties();
2579 return mLeftFrameDivisions;
2581 return mRightFrameDivisions;
2583 return mTopFrameDivisions;
2585 return mBottomFrameDivisions;
2587 return mLeftFrameDivisions;
2599 const QgsCoordinateTransform tr(
mMap->crs(), mCRS,
mLayout->project() );
2600 QgsCoordinateTransform extentTransform = tr;
2602 const QPolygonF mapPolygon =
mMap->transformedMapPolygon();
2603 const QRectF mbr = mapPolygon.boundingRect();
2604 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2607 if ( mCRS.isGeographic() )
2610 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2611 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2613 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2614 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2616 if ( lowerLeft.x() > upperRight.x() )
2632 inverseTransform = QgsCoordinateTransform( mCRS,
mMap->crs(),
mLayout->project() );
2634 catch ( QgsCsException &cse )
2643QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2648 const QgsGeometry intersected = lineGeom.
intersection( rectGeom );
2651 QList<QPolygonF> trimmedLines;
2652 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2653 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2655 trimmedLines << ( *geomIt ).asQPolygonF();
2657 return trimmedLines;
2732 refreshDataDefinedProperties();
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ Millimeters
Millimeters.
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes).
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
@ Forward
Forward transform (from source to destination).
@ Antialiasing
Use antialiasing when drawing items.
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(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
bool rotatedAnnotationsEnabled() const
Gets whether annotations rotation for rotated or reprojected grids is enabled.
QString annotationExpression() const
Returns the expression used for drawing grid annotations.
double rotatedTicksMarginToCorner() const
Gets the margin to corners (in canvas units) below which outwards facing ticks are not drawn.
GridStyle
Grid drawing style.
@ Markers
Draw markers at intersections of grid lines.
@ Cross
Draw line crosses at intersections of grid lines.
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
void setFrameFillColor2(const QColor &color)
Sets the second fill color used for the grid frame.
GridUnit
Unit for grid values.
@ CM
Grid units in centimeters.
@ MM
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnit
Grid units follow map units.
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ FrameTop
Top side of map.
@ FrameBottom
Bottom side of map.
@ FrameLeft
Left side of map.
@ FrameRight
Right side of map.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
void setAnnotationFormat(const AnnotationFormat format)
Sets the format for drawing grid annotations.
double frameWidth() const
Gets the grid frame width in layout units.
void draw(QPainter *painter) override
Draws the item on to a destination painter.
double crossLength() const
Retrieves the length (in layout units) of the cross segments drawn for the grid.
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
void setRotatedTicksMinimumAngle(const double angle)
Sets the minimum angle (in degrees) below which ticks are not drawn.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
QPainter::CompositionMode blendMode() const
Retrieves the blending mode used for drawing the grid.
void setAnnotationEnabled(const bool enabled)
Sets whether annotations should be shown for the grid.
QgsTextFormat annotationTextFormat() const
Returns the text format used when rendering grid annotations.
AnnotationFormat annotationFormat() const
Returns the format for drawing grid annotations.
double framePenSize() const
Retrieves the width of the stroke drawn in the grid frame.
void setFramePenColor(const QColor &color)
Sets the color of the stroke drawn in the grid frame.
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
void setRotatedTicksEnabled(const bool state)
Enable/disable ticks rotation for rotated or reprojected grids.
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
AnnotationPosition
Position for grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
TickLengthMode rotatedAnnotationsLengthMode() const
Returns the annotation length calculation mode.
double rotatedTicksMinimumAngle() const
Gets the minimum angle (in degrees) below which ticks are not drawn.
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
friend class QgsLayoutItemMap
AnnotationCoordinate
Annotation coordinate type.
@ Latitude
Coordinate is a latitude value.
@ Longitude
Coordinate is a longitude value.
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
void setRotatedTicksLengthMode(const TickLengthMode mode)
Sets the tick length calculation mode.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
DisplayMode
Display settings for grid annotations and frames.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
void crsChanged()
Emitted whenever the grid's CRS is changed.
void setRotatedAnnotationsMinimumAngle(const double angle)
Sets the minimum angle (in degrees) below which annotations are not drawn.
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
double rotatedAnnotationsMinimumAngle() const
Gets the minimum angle (in degrees) below which annotations are not drawn.
void setAnnotationTextFormat(const QgsTextFormat &format)
Sets the text format to use when rendering grid annotations.
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
~QgsLayoutItemMapGrid() override
void copyProperties(const QgsLayoutItemMapGrid *other)
Copies properties from specified map grid.
void setBlendMode(const QPainter::CompositionMode mode)
Sets the blending mode used for drawing the grid.
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
bool annotationEnabled() const
Returns whether annotations are shown for the grid.
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
void setFrameStyle(const FrameStyle style)
Sets the grid frame style.
QFlags< FrameSideFlag > FrameSideFlags
QColor framePenColor() const
Retrieves the color of the stroke drawn in the grid frame.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
FrameStyle frameStyle() const
Returns the grid frame style.
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
void setRotatedTicksMarginToCorner(const double margin)
Sets the margin to corners (in canvas units) below which outwards facing ticks are not drawn.
void setAnnotationPrecision(const int precision)
Sets the coordinate precision for grid annotations.
QColor frameFillColor2() const
Retrieves the second fill color for the grid frame.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
void setRotatedAnnotationsMarginToCorner(const double margin)
Sets the margin to corners (in canvas units) below which outwards facing annotations are not drawn.
double rotatedAnnotationsMarginToCorner() const
Gets the margin to corners (in canvas units) below which outwards facing annotations are not drawn.
void setRotatedAnnotationsLengthMode(const TickLengthMode mode)
Sets the annotation length calculation mode.
TickLengthMode
Tick length mode (useful for rotated grids).
@ OrthogonalTicks
Align ticks orthogonaly.
double offsetX() const
Returns the offset for grid lines in the x-direction.
bool rotatedTicksEnabled() const
Gets whether ticks rotation for rotated or reprojected grids is enabled.
AnnotationFormat
Format for displaying grid annotations.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ CustomFormat
Custom expression-based format.
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
AnnotationDirection
Direction of grid annotations.
@ OnTick
Draw annotations parallel to tick (on the line).
@ Horizontal
Draw annotations horizontally.
@ Vertical
Draw annotations vertically, ascending.
@ AboveTick
Draw annotations parallel to tick (above the line).
@ UnderTick
Draw annotations parallel to tick (under the line).
@ VerticalDescending
Draw annotations vertically, descending.
double annotationFrameDistance() const
Returns the distance between the map frame and annotations.
double intervalY() const
Returns the interval between grid lines in the y-direction.
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
double minimumIntervalWidth() const
Returns the minimum width (in millimeters) for grid segments.
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QColor frameFillColor1() const
Retrieves the first fill color for the grid frame.
void setRotatedAnnotationsEnabled(const bool state)
Enable/disable annotations rotation for rotated or reprojected grids.
FrameStyle
Style for grid frame.
@ Zebra
Black/white pattern.
@ InteriorTicks
Tick markers drawn inside map frame.
@ LineBorder
Simple solid line frame.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ NoFrame
Disable grid frame.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
void setFrameFillColor1(const QColor &color)
Sets the first fill color used for the grid frame.
double frameMargin() const
Sets the grid frame Margin (in layout units).
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
BorderSide
Border sides for annotations.
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
int annotationPrecision() const
Returns the coordinate precision for grid annotations, which is the number of decimal places shown wh...
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
double maximumIntervalWidth() const
Returns the maximum width (in millimeters) for grid segments.
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
TickLengthMode rotatedTicksLengthMode() const
Returns the grid frame style.
double intervalX() const
Returns the interval between grid lines in the x-direction.
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.
@ 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.
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)
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to the style entity currently being visited.