46#define MAX_GRID_LINES 1000
77 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
83 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
88 QList< QgsLayoutItemMapGrid * > list;
111 const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
112 for (
int i = 0; i < mapGridNodeList.size(); ++i )
114 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
116 mapGrid->
readXml( mapGridElem, doc, context );
130 return std::max( std::max( std::max( top, right ), bottom ), left );
144 double gridTop = 0.0;
145 double gridRight = 0.0;
146 double gridBottom = 0.0;
147 double gridLeft = 0.0;
149 top = std::max( top, gridTop );
150 right = std::max( right, gridRight );
151 bottom = std::max( bottom, gridBottom );
152 left = std::max( left, gridLeft );
168 return QVector2D( 0, 1 );
170 return QVector2D( -1, 0 );
172 return QVector2D( 0, -1 );
174 return QVector2D( 1, 0 );
182 return QVector2D( borderVector.y(), -borderVector.x() );
192 const QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
193 if ( !defaultFontString.isEmpty() )
196 font.setFamily( defaultFontString );
197 mAnnotationFormat.
setFont( font );
200 createDefaultGridLineSymbol();
201 createDefaultGridMarkerSymbol();
214void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
216 QVariantMap properties;
217 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
218 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
219 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
223void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
225 QVariantMap properties;
226 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
227 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
228 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
234 if ( mGridLineSymbol )
236 mGridLineSymbol->setWidth( width );
242 if ( mGridLineSymbol )
244 mGridLineSymbol->setColor(
c );
255 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
256 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
257 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
258 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
259 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
260 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
261 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
263 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
265 lineStyleElem.appendChild( gridLineStyleElem );
266 mapGridElem.appendChild( lineStyleElem );
268 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
270 markerStyleElem.appendChild( gridMarkerStyleElem );
271 mapGridElem.appendChild( markerStyleElem );
273 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
274 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
275 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
276 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
277 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
281 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
282 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
283 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
284 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
285 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
286 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
287 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
288 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
289 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
292 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
298 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
299 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
300 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
301 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
302 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
303 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
304 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
305 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
306 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
307 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
308 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
309 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
310 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
311 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
312 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
313 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
314 mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
315 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
316 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
317 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
318 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
319 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
322 elem.appendChild( mapGridElem );
329 if ( itemElem.isNull() )
338 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
339 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
340 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
341 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
342 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
343 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
344 mGridFrameSides =
static_cast< QgsLayoutItemMapGrid::FrameSideFlags
>( itemElem.attribute( QStringLiteral(
"gridFrameSideFlags" ), QStringLiteral(
"15" ) ).toInt() );
345 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
346 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
347 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
355 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
356 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
357 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
358 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
359 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
360 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
361 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
362 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
364 const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
365 if ( !lineStyleElem.isNull() )
367 const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
368 if ( !symbolElem.isNull() )
370 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
377 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
378 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
379 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
380 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
383 const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
384 if ( !markerStyleElem.isNull() )
386 const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
387 if ( !symbolElem.isNull() )
389 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
393 if ( !mCRS.
readXml( itemElem ) )
396 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
399 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
401 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
402 mGridAnnotationExpression.reset();
407 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
408 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
410 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
416 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
418 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
420 mAnnotationFormat.
readXml( itemElem, context );
427 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
429 mAnnotationFormat.
setFont( font );
430 mAnnotationFormat.
setSize( font.pointSizeF() );
435 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
436 const int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
438 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
439 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
441 refreshDataDefinedProperties();
451 mTransformDirty =
true;
457 return mBlendMode != QPainter::CompositionMode_SourceOver;
460QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
462 const QTransform t = QTransform::fromScale( scale, scale );
463 return t.map( polygon );
466void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
468 if ( !
mMap || !mEvaluatedEnabled )
475 if ( mapPolygon != mPrevMapPolygon )
477 mTransformDirty =
true;
478 mPrevMapPolygon = mapPolygon;
481 if ( mTransformDirty )
483 calculateCrsTransformLines();
487 if ( !calculateLinesOnly )
491 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
492 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
494 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
499 const double maxX =
mMap->rect().width();
500 const double maxY =
mMap->rect().height();
502 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
503 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
505 const double x = intersectionIt->x();
506 const double y = intersectionIt->y();
510 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
511 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
512 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
513 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
514 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
515 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
518 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
519 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
523 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
530void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
534 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
541 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
542 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
549 QList< QgsGeometry > xLines;
550 QList< QgsGeometry > yLines;
551 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
552 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
556 for (
int i = 0; i < gridIt->line.size(); ++i )
558 line.append(
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
560 if ( gridIt->coordinateType == AnnotationCoordinate::Longitude )
562 else if ( gridIt->coordinateType == AnnotationCoordinate::Latitude )
567 mTransformedIntersections.clear();
568 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
569 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
571 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
572 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
576 if ( intersects.
isNull() )
584 mTransformedIntersections << vertex;
592 mTransformDirty =
false;
597 if ( !
mMap || !mEvaluatedEnabled )
601 QPaintDevice *paintDevice = p->device();
608 p->setCompositionMode( mBlendMode );
611 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
612 p->setClipRect( thisPaintRect );
613 if ( thisPaintRect != mPrevPaintRect )
616 mTransformDirty =
true;
617 mPrevPaintRect = thisPaintRect;
621 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
622 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
638 drawGridCrsTransform( context, dotsPerMM );
645 drawGridNoTransform( context, dotsPerMM );
650 p->setClipping(
false );
654 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
659 updateGridLinesAnnotationsPositions();
666 if ( mShowGridAnnotation )
672void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
674 QList< GridLine >::iterator it = mGridLines.begin();
675 for ( ; it != mGridLines.end(); ++it )
677 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
678 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
679 it->startAnnotation.position = QVector2D( it->line.first() );
680 it->endAnnotation.position = QVector2D( it->line.last() );
681 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
682 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
684 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() );
686 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() );
690void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
697 if ( calculateLinesOnly )
700 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
701 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
709 for ( ; vIt != mGridLines.constEnd(); ++vIt )
711 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
713 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
714 drawGridLine( line, context );
717 for ( ; hIt != mGridLines.constEnd(); ++hIt )
719 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
721 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
722 drawGridLine( line, context );
728 QPointF intersectionPoint, crossEnd1, crossEnd2;
729 for ( ; vIt != mGridLines.constEnd(); ++vIt )
731 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
734 l1 = QLineF( vIt->line.first(), vIt->line.last() );
737 hIt = mGridLines.constBegin();
738 for ( ; hIt != mGridLines.constEnd(); ++hIt )
740 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
743 l2 = QLineF( hIt->line.first(), hIt->line.last() );
745 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
750 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
752 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
755 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
759 drawGridMarker( intersectionPoint * dotsPerMM, context );
771 hIt = mGridLines.constBegin();
772 for ( ; hIt != mGridLines.constEnd(); ++hIt )
774 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
777 l1 = QLineF( hIt->line.first(), hIt->line.last() );
779 vIt = mGridLines.constBegin();
780 for ( ; vIt != mGridLines.constEnd(); ++vIt )
782 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
785 l2 = QLineF( vIt->line.first(), vIt->line.last() );
787 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
790 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
792 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
795 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
802void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
811 switch ( mGridFrameStyle )
815 drawGridFrameZebra( p, extension );
820 drawGridFrameTicks( p, extension );
825 drawGridFrameLine( p, extension );
836void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
839 poly << line.p1() << line.p2();
840 drawGridLine( poly, context );
843void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
850 mGridLineSymbol->startRender( context );
851 mGridLineSymbol->renderPolyline( line,
nullptr, context );
852 mGridLineSymbol->stopRender( context );
855void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
862 mGridMarkerSymbol->startRender( context );
863 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
864 mGridMarkerSymbol->stopRender( context );
867void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
887void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
896 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
900 double currentCoord = 0.0;
907 bool drawTLBox =
false;
908 bool drawTRBox =
false;
909 bool drawBLBox =
false;
910 bool drawBRBox =
false;
912 QMap< double, double > pos = QMap< double, double >();
913 QList< GridLine >::const_iterator it = mGridLines.constBegin();
914 for ( ; it != mGridLines.constEnd(); ++it )
917 for (
int i = 0 ; i < 2 ; ++i )
919 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
922 if ( annot.border != border )
925 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
929 pos.insert( annot.position.y(), it->coordinate );
931 pos.insert( annot.position.x(), it->coordinate );
938 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
954 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
958 QPen framePen = QPen( mGridFramePenColor );
959 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
960 framePen.setJoinStyle( Qt::MiterJoin );
961 p->setPen( framePen );
963 QMap< double, double >::const_iterator posIt = pos.constBegin();
964 for ( ; posIt != pos.constEnd(); ++posIt )
966 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
969 height = posIt.key() - currentCoord;
970 width = mEvaluatedGridFrameWidth;
971 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
976 height = mEvaluatedGridFrameWidth;
977 width = posIt.key() - currentCoord;
979 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
981 p->drawRect( QRectF( x, y, width, height ) );
982 currentCoord = posIt.key();
989 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
990 p->setBrush( QBrush( mGridFrameFillColor1 ) );
992 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
994 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
996 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
998 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1002void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1012 QPen framePen = QPen( mGridFramePenColor );
1013 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1014 framePen.setCapStyle( Qt::FlatCap );
1015 p->setBrush( Qt::NoBrush );
1016 p->setPen( framePen );
1019 QList< GridLine >::iterator it = mGridLines.begin();
1020 for ( ; it != mGridLines.end(); ++it )
1023 for (
int i = 0 ; i < 2 ; ++i )
1025 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1027 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1031 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1039 facingLeft = ( annot.angle != 0 );
1040 facingRight = ( annot.angle != 0 );
1044 facingLeft = ( annot.angle > 0 );
1045 facingRight = ( annot.angle < 0 );
1049 facingLeft = ( annot.angle < 0 );
1050 facingRight = ( annot.angle > 0 );
1053 if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1054 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1056 if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1057 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1059 if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1060 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1062 if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1063 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1067 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1069 double fA = mEvaluatedGridFrameMargin;
1070 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1072 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1074 fA /= QVector2D::dotProduct( vector, normalVector );
1075 fB /= QVector2D::dotProduct( vector, normalVector );
1082 extension->UpdateBorder( annot.border, fB );
1090 pA = annot.position + fA * vector;
1091 pB = annot.position + fB * vector;
1095 pA = annot.position - fA * vector;
1096 pB = annot.position - fB * vector;
1100 pA = annot.position - fB * vector;
1101 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1103 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1109void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1119 QPen framePen = QPen( mGridFramePenColor );
1120 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1121 framePen.setCapStyle( Qt::SquareCap );
1122 p->setBrush( Qt::NoBrush );
1123 p->setPen( framePen );
1133 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1141 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1147 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1149 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1157 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1160 if ( ! extension && drawDiagonals )
1165 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1166 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1167 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1172 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1173 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1174 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1179 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1180 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1181 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1186 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1187 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1188 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1194 GridExtension *extension )
const
1196 QString currentAnnotationString;
1197 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1198 for ( ; it != mGridLines.constEnd(); ++it )
1200 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1201 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1202 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1206void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1213 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1225 double xpos = annot.position.x();
1226 double ypos = annot.position.y();
1227 QPointF anchor = QPointF();
1234 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1238 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1241 double f = mEvaluatedAnnotationFrameDistance;
1249 f += mEvaluatedGridFrameWidth;
1250 if ( hasBorderWidth )
1251 f += mEvaluatedGridFrameLineThickness / 2.0;
1256 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1258 f /= QVector2D::dotProduct( vector, normalVector );
1261 const QVector2D pos = annot.position + f * vector;
1274 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1276 if ( rotation <= -90 || rotation > 90 )
1279 anchor.setX( outside ? 0 : textWidth );
1283 anchor.setX( outside ? textWidth : 0 );
1287 anchor.setY( 0.5 * textHeight );
1289 anchor.setY( -1.5 * textHeight );
1291 anchor.setY( -0.5 * textHeight );
1297 anchor.setX( 0.5 * textWidth );
1298 anchor.setY( -0.5 * textHeight );
1300 anchor.setY( outside ? 0 : -textHeight );
1302 anchor.setX( outside ? 0 : textWidth );
1304 anchor.setY( outside ? -textHeight : 0 );
1306 anchor.setX( outside ? textWidth : 0 );
1311 anchor.setX( 0.5 * textWidth );
1312 anchor.setY( -0.5 * textHeight );
1314 anchor.setX( outside ? 0 : textWidth );
1316 anchor.setY( outside ? -textHeight : 0 );
1318 anchor.setX( outside ? textWidth : 0 );
1320 anchor.setY( outside ? 0 : -textHeight );
1325 anchor.setX( 0.5 * textWidth );
1326 anchor.setY( -0.5 * textHeight );
1328 anchor.setX( outside ? textWidth : 0 );
1330 anchor.setY( outside ? 0 : -textHeight );
1332 anchor.setX( outside ? 0 : textWidth );
1334 anchor.setY( outside ? -textHeight : 0 );
1339 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1340 anchor.setX( 0.5 * textWidth );
1342 anchor.setY( -textHeight );
1350 extension->UpdateBorder( frameBorder, -f + textWidth );
1352 extension->UpdateAll( textWidth / 2.0 );
1355 if ( extension || !context.
painter() )
1359 bool facingLeft = ( annot.angle < 0 );
1360 bool facingRight = ( annot.angle > 0 );
1363 facingLeft = !facingLeft;
1364 facingRight = !facingRight;
1366 if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1367 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1369 if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1370 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1372 if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1373 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1375 if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1376 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1380 context.
painter()->translate( QPointF( xpos, ypos ) );
1381 context.
painter()->rotate( rotation );
1382 context.
painter()->translate( -anchor );
1384 QgsTextRenderer::drawText( QPointF( 0, 0 ), 0, Qgis::TextHorizontalAlignment::Left, annotationString.split(
'\n' ), context, mAnnotationFormat );
1390 bool geographic =
false;
1404 const double wrappedX = std::fmod( value, 360.0 );
1405 if ( wrappedX > 180.0 )
1407 value = wrappedX - 360.0;
1409 else if ( wrappedX < -180.0 )
1411 value = wrappedX + 360.0;
1417 return QString::number( value,
'f', mGridAnnotationPrecision );
1423 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1427 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1429 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1435 if ( !geographic || coordRounded != 0.0 )
1437 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1443 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1447 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1454 if ( !mGridAnnotationExpression )
1456 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1457 mGridAnnotationExpression->prepare( &expressionContext );
1459 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1463 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
1464 switch ( mGridAnnotationFormat )
1483 flags = QgsCoordinateFormatter::FormatFlags();
1493 flags = QgsCoordinateFormatter::FormatFlags();
1514int QgsLayoutItemMapGrid::xGridLines()
const
1516 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1523 QRectF mapBoundingRect = mapPolygon.boundingRect();
1524 double gridIntervalY = mEvaluatedIntervalY;
1525 double gridOffsetY = mEvaluatedOffsetY;
1526 double annotationScale = 1.0;
1527 switch ( mGridUnit )
1532 mapBoundingRect =
mMap->rect();
1533 mapPolygon = QPolygonF(
mMap->rect() );
1534 if ( mGridUnit ==
CM )
1536 annotationScale = 0.1;
1537 gridIntervalY *= 10;
1549 const double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1550 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1552 int gridLineCount = 0;
1557 double yCanvasCoord;
1558 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1560 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1562 newLine.coordinate = currentLevel * annotationScale;
1563 newLine.coordinateType = AnnotationCoordinate::Latitude;
1564 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1565 mGridLines.append( newLine );
1566 currentLevel += gridIntervalY;
1573 QVector<QLineF> borderLines;
1574 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1575 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1576 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1577 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1579 QVector<QPointF> intersectionList;
1581 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1583 intersectionList.clear();
1584 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1586 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1587 for ( ; it != borderLines.constEnd(); ++it )
1589 QPointF intersectionPoint;
1590 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1592 intersectionList.push_back( intersectionPoint );
1593 if ( intersectionList.size() >= 2 )
1600 if ( intersectionList.size() >= 2 )
1603 newLine.coordinate = currentLevel;
1604 newLine.coordinateType = AnnotationCoordinate::Latitude;
1606 mGridLines.append( newLine );
1609 currentLevel += gridIntervalY;
1616int QgsLayoutItemMapGrid::yGridLines()
const
1618 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1624 QRectF mapBoundingRect = mapPolygon.boundingRect();
1625 double gridIntervalX = mEvaluatedIntervalX;
1626 double gridOffsetX = mEvaluatedOffsetX;
1627 double annotationScale = 1.0;
1628 switch ( mGridUnit )
1633 mapBoundingRect =
mMap->rect();
1634 mapPolygon = QPolygonF(
mMap->rect() );
1635 if ( mGridUnit ==
CM )
1637 annotationScale = 0.1;
1638 gridIntervalX *= 10;
1650 const double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1651 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1653 int gridLineCount = 0;
1657 double xCanvasCoord;
1658 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1660 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1663 newLine.coordinate = currentLevel * annotationScale;
1664 newLine.coordinateType = AnnotationCoordinate::Longitude;
1665 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1666 mGridLines.append( newLine );
1667 currentLevel += gridIntervalX;
1674 QVector<QLineF> borderLines;
1675 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1676 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1677 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1678 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1680 QVector<QPointF> intersectionList;
1682 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1684 intersectionList.clear();
1685 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1687 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1688 for ( ; it != borderLines.constEnd(); ++it )
1690 QPointF intersectionPoint;
1691 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1693 intersectionList.push_back( intersectionPoint );
1694 if ( intersectionList.size() >= 2 )
1701 if ( intersectionList.size() >= 2 )
1704 newLine.coordinate = currentLevel;
1705 newLine.coordinateType = AnnotationCoordinate::Longitude;
1707 mGridLines.append( newLine );
1710 currentLevel += gridIntervalX;
1718 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1723 const double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1724 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1726 const double minX = bbox.
xMinimum();
1727 const double maxX = bbox.
xMaximum();
1728 double step = ( maxX - minX ) / 20;
1730 bool crosses180 =
false;
1731 bool crossed180 =
false;
1736 step = ( maxX + 360.0 - minX ) / 20;
1742 int gridLineCount = 0;
1746 double currentX = minX;
1750 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1763 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1767 if ( crosses180 && currentX > 180.0 )
1775 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1776 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1777 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1779 if ( !( *lineIt ).isEmpty() )
1782 newLine.coordinate = currentLevel;
1783 newLine.coordinateType = AnnotationCoordinate::Latitude;
1784 newLine.line = QPolygonF( *lineIt );
1785 mGridLines.append( newLine );
1789 currentLevel -= mEvaluatedIntervalY;
1797 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1802 const double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1803 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1805 const double minY = bbox.
yMinimum();
1806 const double maxY = bbox.
yMaximum();
1807 const double step = ( maxY - minY ) / 20;
1812 bool crosses180 =
false;
1813 bool crossed180 =
false;
1820 int gridLineCount = 0;
1821 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1824 double currentY = minY;
1828 if ( currentY > maxY )
1842 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1848 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1849 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1850 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1852 if ( !( *lineIt ).isEmpty() )
1855 newLine.coordinate = currentLevel;
1856 newLine.coordinateType = AnnotationCoordinate::Longitude;
1857 newLine.line = QPolygonF( *lineIt );
1858 mGridLines.append( newLine );
1862 currentLevel += mEvaluatedIntervalX;
1863 if ( crosses180 && currentLevel > 180.0 )
1865 currentLevel -= 360.0;
1894 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1896 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1898 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1900 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1915 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1917 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1919 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1921 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
1928void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1933 mTransformDirty = mTransformDirty
1940 switch ( mGridUnit )
1953 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1955 mEvaluatedEnabled =
false;
1960 const double mapWidthMapUnits = mapWidth();
1961 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1962 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1964 mEvaluatedIntervalX = interval;
1965 mEvaluatedIntervalY = interval;
1966 mTransformDirty =
true;
1989double QgsLayoutItemMapGrid::mapWidth()
const
2000 return mapExtent.
width();
2017bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2019 return a.first < b.first;
2032 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2033 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2034 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2035 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2041 if ( p.x() <= tolerance )
2052 if ( p.y() <= tolerance )
2064 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2070 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2071 return distanceToSide.at( 0 ).second;
2076 mGridLineSymbol.reset( symbol );
2081 return mGridLineSymbol.get();
2086 return mGridLineSymbol.get();
2091 mGridMarkerSymbol.reset( symbol );
2096 return mGridMarkerSymbol.get();
2101 return mGridMarkerSymbol.get();
2106 mAnnotationFormat.
setFont( font );
2107 if ( font.pointSizeF() > 0 )
2109 mAnnotationFormat.
setSize( font.pointSizeF() );
2112 else if ( font.pixelSize() > 0 )
2114 mAnnotationFormat.
setSize( font.pixelSize() );
2121 return mAnnotationFormat.
toQFont();
2126 mAnnotationFormat.
setColor( color );
2131 return mAnnotationFormat.
color();
2139 mLeftGridAnnotationDisplay = display;
2142 mRightGridAnnotationDisplay = display;
2145 mTopGridAnnotationDisplay = display;
2148 mBottomGridAnnotationDisplay = display;
2152 refreshDataDefinedProperties();
2166 return mLeftGridAnnotationDisplay;
2168 return mRightGridAnnotationDisplay;
2170 return mTopGridAnnotationDisplay;
2172 return mBottomGridAnnotationDisplay;
2174 return mBottomGridAnnotationDisplay;
2181 double bottom = 0.0;
2184 return std::max( std::max( std::max( top, right ), bottom ), left );
2194 if ( !
mMap || !mEvaluatedEnabled )
2204 GridExtension extension;
2207 switch ( mGridUnit )
2214 drawGridCrsTransform( context, 0,
true );
2221 drawGridNoTransform( context, 0,
true );
2226 updateGridLinesAnnotationsPositions();
2230 drawGridFrame(
nullptr, &extension );
2233 if ( mShowGridAnnotation )
2238 top = extension.top;
2239 right = extension.right;
2240 bottom = extension.bottom;
2241 left = extension.left;
2247 refreshDataDefinedProperties();
2252 if ( unit == mGridUnit )
2257 mTransformDirty =
true;
2266 mGridIntervalX = interval;
2267 mTransformDirty =
true;
2268 refreshDataDefinedProperties();
2277 mGridIntervalY = interval;
2278 mTransformDirty =
true;
2279 refreshDataDefinedProperties();
2288 mGridOffsetX = offset;
2289 mTransformDirty =
true;
2290 refreshDataDefinedProperties();
2299 mGridOffsetY = offset;
2300 mTransformDirty =
true;
2301 refreshDataDefinedProperties();
2310 mMinimumIntervalWidth = minWidth;
2311 mTransformDirty =
true;
2312 refreshDataDefinedProperties();
2321 mMaximumIntervalWidth = maxWidth;
2322 mTransformDirty =
true;
2323 refreshDataDefinedProperties();
2328 if (
style == mGridStyle )
2333 mTransformDirty =
true;
2338 mCrossLength = length;
2339 refreshDataDefinedProperties();
2347 mLeftGridAnnotationDirection = direction;
2350 mRightGridAnnotationDirection = direction;
2353 mTopGridAnnotationDirection = direction;
2356 mBottomGridAnnotationDirection = direction;
2369 mGridFrameSides = flags;
2375 mGridFrameSides |= flag;
2377 mGridFrameSides &= ~flag;
2382 return mGridFrameSides;
2391 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2397 if ( mGridLineSymbol )
2403 if ( mGridMarkerSymbol )
2415 mTransformDirty =
true;
2416 refreshDataDefinedProperties();
2423 return mGridFrameSides.testFlag( flag );
2428 mGridFrameWidth = width;
2429 refreshDataDefinedProperties();
2434 mGridFrameMargin = margin;
2435 refreshDataDefinedProperties();
2440 mGridFramePenThickness = width;
2441 refreshDataDefinedProperties();
2446 mLeftGridAnnotationDirection = direction;
2447 mRightGridAnnotationDirection = direction;
2448 mTopGridAnnotationDirection = direction;
2449 mBottomGridAnnotationDirection = direction;
2457 mLeftGridAnnotationPosition = position;
2460 mRightGridAnnotationPosition = position;
2463 mTopGridAnnotationPosition = position;
2466 mBottomGridAnnotationPosition = position;
2482 return mLeftGridAnnotationPosition;
2484 return mRightGridAnnotationPosition;
2486 return mTopGridAnnotationPosition;
2488 return mBottomGridAnnotationPosition;
2490 return mLeftGridAnnotationPosition;
2495 mAnnotationFrameDistance = distance;
2496 refreshDataDefinedProperties();
2503 return mLeftGridAnnotationDirection;
2509 return mLeftGridAnnotationDirection;
2511 return mRightGridAnnotationDirection;
2513 return mTopGridAnnotationDirection;
2515 return mBottomGridAnnotationDirection;
2517 return mLeftGridAnnotationDirection;
2525 mLeftFrameDivisions = divisions;
2528 mRightFrameDivisions = divisions;
2531 mTopFrameDivisions = divisions;
2534 mBottomFrameDivisions = divisions;
2538 refreshDataDefinedProperties();
2551 return mLeftFrameDivisions;
2553 return mRightFrameDivisions;
2555 return mTopFrameDivisions;
2557 return mBottomFrameDivisions;
2559 return mLeftFrameDivisions;
2575 const QRectF mbr = mapPolygon.boundingRect();
2576 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2582 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2583 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2585 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2586 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2588 if ( lowerLeft.x() > upperRight.x() )
2591 crsRect = extentTransform.
transformBoundingBox( mapBoundingRect, Qgis::TransformDirection::Forward,
true );
2609 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
2615QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2623 QList<QPolygonF> trimmedLines;
2624 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2625 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2627 trimmedLines << ( *geomIt ).asQPolygonF();
2629 return trimmedLines;
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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.
Q_GADGET QgsUnitTypes::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.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
QgsUnitTypes::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
A geometry is the spatial representation of a feature.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QList< QgsLayoutItemMapGrid * > asList() const
Returns a list of QgsLayoutItemMapGrids contained by the stack.
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void removeGrid(const QString &gridId)
Removes a grid with matching gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid...
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void addGrid(QgsLayoutItemMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
QgsLayoutItemMapGrid * grid(const QString &gridId) const
Returns a reference to a grid with matching gridId within the stack.
bool readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the item stack's state from a DOM document, where element is a DOM node corresponding to a 'Layo...
QgsLayoutItemMapGrid & operator[](int index)
Returns a reference to a grid at the specified index within the stack.
void moveGridUp(const QString &gridId)
Moves a grid with matching gridId up the stack, causing it to be rendered above other grids.
void moveGridDown(const QString &gridId)
Moves a grid with matching gridId down the stack, causing it to be rendered below other grids.
QgsLayoutItemMapGridStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGridStack, attached to the specified map.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
void setFrameSideFlags(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
GridStyle
Grid drawing style.
@ Markers
Draw markers at intersections of grid lines.
@ Cross
Draw line crosses at intersections of grid lines.
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
GridUnit
Unit for grid values.
@ CM
Grid units in centimeters.
@ MM
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnit
Grid units follow map units.
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ FrameTop
Top side of map.
@ FrameBottom
Bottom side of map.
@ FrameLeft
Left side of map.
@ FrameRight
Right side of map.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
void draw(QPainter *painter) override
Draws the item on to a destination painter.
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
AnnotationPosition
Position for grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
AnnotationCoordinate
Annotation coordinate type.
@ Latitude
Coordinate is a latitude value.
@ Longitude
Coordinate is a longitude value.
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
DisplayMode
Display settings for grid annotations and frames.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
void crsChanged()
Emitted whenever the grid's CRS is changed.
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
~QgsLayoutItemMapGrid() override
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
TickLengthMode
Tick length mode (useful for rotated grids)
@ OrthogonalTicks
Align ticks orthogonaly.
AnnotationFormat
Format for displaying grid annotations.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ CustomFormat
Custom expression-based format.
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
AnnotationDirection
Direction of grid annotations.
@ OnTick
Draw annotations parallel to tick (on the line)
@ Horizontal
Draw annotations horizontally.
@ Vertical
Draw annotations vertically, ascending.
@ AboveTick
Draw annotations parallel to tick (above the line)
@ UnderTick
Draw annotations parallel to tick (under the line)
@ VerticalDescending
Draw annotations vertically, descending.
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
FrameStyle
Style for grid frame.
@ Zebra
Black/white pattern.
@ InteriorTicks
Tick markers drawn inside map frame.
@ LineBorder
Simple solid line frame.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ NoFrame
Disable grid frame.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
BorderSide
Border sides for annotations.
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
A collection of map items which are drawn above the map content in a QgsLayoutItemMap.
void addItem(QgsLayoutItemMapItem *item)
Adds a new map item to the stack and takes ownership of the item.
void removeItem(const QString &itemId)
Removes an item which matching itemId from the stack and deletes the corresponding QgsLayoutItemMapIt...
QgsLayoutItemMapItem * item(int index) const
Returns a reference to the item at the specified index within the stack.
void moveItemUp(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
void removeItems()
Clears the item stack and deletes all QgsLayoutItemMapItems contained by the stack.
QList< QgsLayoutItemMapItem * > mItems
void moveItemDown(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
QgsLayoutItemMap * mMap
Associated map.
virtual bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
virtual bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
virtual void setEnabled(bool enabled)
Controls whether the item will be drawn.
bool enabled() const
Returns whether the item will be drawn.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
QgsRectangle extent() const
Returns the current map extent.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
bool frameEnabled() const
Returns true if the item includes a frame.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
QPointer< QgsLayout > mLayout
@ MapGridIntervalX
Map grid interval X.
@ MapGridAnnotationDisplayBottom
Map annotation display bottom.
@ MapGridIntervalY
Map grid interval Y.
@ MapGridFrameSize
Map grid frame size.
@ MapGridFrameDivisionsBottom
Map frame division display bottom.
@ MapGridAnnotationDisplayRight
Map annotation display right.
@ MapGridFrameMargin
Map grid frame margin.
@ MapGridOffsetX
Map grid offset X.
@ MapGridLabelDistance
Map grid label distance.
@ MapGridAnnotationDisplayLeft
Map annotation display left.
@ MapGridFrameDivisionsLeft
Map frame division display left.
@ MapGridEnabled
Map grid enabled.
@ MapGridFrameLineThickness
Map grid frame line thickness.
@ MapGridFrameDivisionsRight
Map frame division display right.
@ MapGridFrameDivisionsTop
Map frame division display top.
@ MapGridCrossSize
Map grid cross size.
@ MapGridOffsetY
Map grid offset Y.
@ MapGridAnnotationDisplayTop
Map annotation display top.
QgsLayoutRenderContext::Flags flags() const
Returns the current combination of flags used for rendering the layout.
@ FlagAntialiasing
Use antialiasing when drawing items.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
A line symbol type, for rendering LineString and MultiLineString geometries.
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
A class to represent a 2D point.
bool isEmpty() const SIP_HOLDGIL
Returns true if the geometry is empty.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
QPainter * painter()
Returns the destination QPainter for the render operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Scoped object for saving and restoring a QPainter object's state.
Scoped object for temporary scaling of a QgsRenderContext for pixel based rendering.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
static QColor decodeColor(const QString &str)
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QString encodeColor(const QColor &color)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void 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.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static 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 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())
Draws text within a rectangle using the specified settings.
DistanceUnit
Units of distance.
@ DistanceUnknownUnit
Unknown distance unit.
@ LayoutMillimeters
Millimeters.
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
@ RenderPoints
Points (e.g., for font sizes)
@ RenderMillimeters
Millimeters.
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)
const QgsCoordinateReferenceSystem & crs
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to the style entity currently being visited.