48#define MAX_GRID_LINES 1000
79 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
85 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
90 QList< QgsLayoutItemMapGrid * > list;
113 const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
114 for (
int i = 0; i < mapGridNodeList.size(); ++i )
116 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
118 mapGrid->
readXml( mapGridElem, doc, context );
132 return std::max( std::max( std::max( top, right ), bottom ), left );
146 double gridTop = 0.0;
147 double gridRight = 0.0;
148 double gridBottom = 0.0;
149 double gridLeft = 0.0;
151 top = std::max( top, gridTop );
152 right = std::max( right, gridRight );
153 bottom = std::max( bottom, gridBottom );
154 left = std::max( left, gridLeft );
170 return QVector2D( 0, 1 );
172 return QVector2D( -1, 0 );
174 return QVector2D( 0, -1 );
176 return QVector2D( 1, 0 );
184 return QVector2D( borderVector.y(), -borderVector.x() );
194 const QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
195 if ( !defaultFontString.isEmpty() )
199 mAnnotationFormat.
setFont( font );
202 createDefaultGridLineSymbol();
203 createDefaultGridMarkerSymbol();
216void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
218 QVariantMap properties;
219 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
220 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
221 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
225void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
227 QVariantMap properties;
228 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
229 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
230 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
236 if ( mGridLineSymbol )
238 mGridLineSymbol->setWidth( width );
244 if ( mGridLineSymbol )
246 mGridLineSymbol->setColor(
c );
257 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
258 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
259 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
260 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
261 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
262 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
263 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
265 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
267 lineStyleElem.appendChild( gridLineStyleElem );
268 mapGridElem.appendChild( lineStyleElem );
270 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
272 markerStyleElem.appendChild( gridMarkerStyleElem );
273 mapGridElem.appendChild( markerStyleElem );
275 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
276 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
277 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
278 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
279 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
283 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
284 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
285 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
286 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
287 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
288 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
289 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
292 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
293 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
294 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
300 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
301 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
302 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
303 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
304 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
305 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
306 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
307 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
308 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
309 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
310 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
311 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
312 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
313 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
314 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
315 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
316 mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
317 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
318 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
319 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
320 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
321 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
324 elem.appendChild( mapGridElem );
331 if ( itemElem.isNull() )
340 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
341 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
342 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
343 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
344 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
345 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
346 mGridFrameSides =
static_cast< QgsLayoutItemMapGrid::FrameSideFlags
>( itemElem.attribute( QStringLiteral(
"gridFrameSideFlags" ), QStringLiteral(
"15" ) ).toInt() );
347 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
348 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
349 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
357 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
358 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
359 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
360 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
361 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
362 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
363 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
364 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
366 const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
367 if ( !lineStyleElem.isNull() )
369 const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
370 if ( !symbolElem.isNull() )
372 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
379 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
380 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
381 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
382 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
385 const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
386 if ( !markerStyleElem.isNull() )
388 const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
389 if ( !symbolElem.isNull() )
391 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
395 if ( !mCRS.
readXml( itemElem ) )
398 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
401 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
403 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
404 mGridAnnotationExpression.reset();
409 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
410 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
412 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
418 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
420 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
422 mAnnotationFormat.
readXml( itemElem, context );
429 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
431 mAnnotationFormat.
setFont( font );
432 mAnnotationFormat.
setSize( font.pointSizeF() );
437 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
438 const int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
440 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
441 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
443 refreshDataDefinedProperties();
453 mTransformDirty =
true;
459 return mBlendMode != QPainter::CompositionMode_SourceOver;
462QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
464 const QTransform t = QTransform::fromScale( scale, scale );
465 return t.map( polygon );
468void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
470 if ( !
mMap || !mEvaluatedEnabled )
477 if ( mapPolygon != mPrevMapPolygon )
479 mTransformDirty =
true;
480 mPrevMapPolygon = mapPolygon;
483 if ( mTransformDirty )
485 calculateCrsTransformLines();
489 if ( !calculateLinesOnly )
493 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
494 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
496 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
501 const double maxX =
mMap->rect().width();
502 const double maxY =
mMap->rect().height();
504 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
505 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
507 const double x = intersectionIt->x();
508 const double y = intersectionIt->y();
512 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
513 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
514 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
515 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
516 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
517 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
520 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
521 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
525 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
532void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
536 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
543 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
544 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
551 QList< QgsGeometry > xLines;
552 QList< QgsGeometry > yLines;
553 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
554 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
558 for (
int i = 0; i < gridIt->line.size(); ++i )
560 line.append(
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
569 mTransformedIntersections.clear();
570 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
571 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
573 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
574 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
578 if ( intersects.
isNull() )
586 mTransformedIntersections << vertex;
594 mTransformDirty =
false;
599 if ( !
mMap || !mEvaluatedEnabled )
603 QPaintDevice *paintDevice = p->device();
610 p->setCompositionMode( mBlendMode );
613 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
614 p->setClipRect( thisPaintRect );
615 if ( thisPaintRect != mPrevPaintRect )
618 mTransformDirty =
true;
619 mPrevPaintRect = thisPaintRect;
623 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
624 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
640 drawGridCrsTransform( context, dotsPerMM );
647 drawGridNoTransform( context, dotsPerMM );
652 p->setClipping(
false );
656 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
661 updateGridLinesAnnotationsPositions();
668 if ( mShowGridAnnotation )
674void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
676 QList< GridLine >::iterator it = mGridLines.begin();
677 for ( ; it != mGridLines.end(); ++it )
679 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
680 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
681 it->startAnnotation.position = QVector2D( it->line.first() );
682 it->endAnnotation.position = QVector2D( it->line.last() );
683 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
684 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
686 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() );
688 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() );
692void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
699 if ( calculateLinesOnly )
702 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
703 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
711 for ( ; vIt != mGridLines.constEnd(); ++vIt )
715 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
716 drawGridLine( line, context );
719 for ( ; hIt != mGridLines.constEnd(); ++hIt )
723 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
724 drawGridLine( line, context );
730 QPointF intersectionPoint, crossEnd1, crossEnd2;
731 for ( ; vIt != mGridLines.constEnd(); ++vIt )
736 l1 = QLineF( vIt->line.first(), vIt->line.last() );
739 hIt = mGridLines.constBegin();
740 for ( ; hIt != mGridLines.constEnd(); ++hIt )
745 l2 = QLineF( hIt->line.first(), hIt->line.last() );
747 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
752 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
754 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
757 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
761 drawGridMarker( intersectionPoint * dotsPerMM, context );
773 hIt = mGridLines.constBegin();
774 for ( ; hIt != mGridLines.constEnd(); ++hIt )
779 l1 = QLineF( hIt->line.first(), hIt->line.last() );
781 vIt = mGridLines.constBegin();
782 for ( ; vIt != mGridLines.constEnd(); ++vIt )
787 l2 = QLineF( vIt->line.first(), vIt->line.last() );
789 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
792 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
794 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
797 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
804void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
813 switch ( mGridFrameStyle )
817 drawGridFrameZebra( p, extension );
822 drawGridFrameTicks( p, extension );
827 drawGridFrameLine( p, extension );
838void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
841 poly << line.p1() << line.p2();
842 drawGridLine( poly, context );
845void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
852 mGridLineSymbol->startRender( context );
853 mGridLineSymbol->renderPolyline( line,
nullptr, context );
854 mGridLineSymbol->stopRender( context );
857void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
864 mGridMarkerSymbol->startRender( context );
865 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
866 mGridMarkerSymbol->stopRender( context );
869void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
889void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
898 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
902 double currentCoord = 0.0;
909 bool drawTLBox =
false;
910 bool drawTRBox =
false;
911 bool drawBLBox =
false;
912 bool drawBRBox =
false;
914 QMap< double, double > pos = QMap< double, double >();
915 QList< GridLine >::const_iterator it = mGridLines.constBegin();
916 for ( ; it != mGridLines.constEnd(); ++it )
919 for (
int i = 0 ; i < 2 ; ++i )
921 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
924 if ( annot.border != border )
927 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
931 pos.insert( annot.position.y(), it->coordinate );
933 pos.insert( annot.position.x(), it->coordinate );
940 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
956 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
960 QPen framePen = QPen( mGridFramePenColor );
961 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
962 framePen.setJoinStyle( Qt::MiterJoin );
963 p->setPen( framePen );
965 QMap< double, double >::const_iterator posIt = pos.constBegin();
966 for ( ; posIt != pos.constEnd(); ++posIt )
968 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
971 height = posIt.key() - currentCoord;
972 width = mEvaluatedGridFrameWidth;
973 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
978 height = mEvaluatedGridFrameWidth;
979 width = posIt.key() - currentCoord;
981 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
983 p->drawRect( QRectF( x, y, width, height ) );
984 currentCoord = posIt.key();
991 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
992 p->setBrush( QBrush( mGridFrameFillColor1 ) );
994 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
996 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
998 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1000 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1004void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1014 QPen framePen = QPen( mGridFramePenColor );
1015 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1016 framePen.setCapStyle( Qt::FlatCap );
1017 p->setBrush( Qt::NoBrush );
1018 p->setPen( framePen );
1021 QList< GridLine >::iterator it = mGridLines.begin();
1022 for ( ; it != mGridLines.end(); ++it )
1025 for (
int i = 0 ; i < 2 ; ++i )
1027 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1029 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1033 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1041 facingLeft = ( annot.angle != 0 );
1042 facingRight = ( annot.angle != 0 );
1046 facingLeft = ( annot.angle > 0 );
1047 facingRight = ( annot.angle < 0 );
1051 facingLeft = ( annot.angle < 0 );
1052 facingRight = ( annot.angle > 0 );
1055 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1056 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1058 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1059 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1061 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1062 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1064 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1065 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1069 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1071 double fA = mEvaluatedGridFrameMargin;
1072 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1074 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1076 fA /= QVector2D::dotProduct( vector, normalVector );
1077 fB /= QVector2D::dotProduct( vector, normalVector );
1084 extension->UpdateBorder( annot.border, fB );
1092 pA = annot.position + fA * vector;
1093 pB = annot.position + fB * vector;
1097 pA = annot.position - fA * vector;
1098 pB = annot.position - fB * vector;
1102 pA = annot.position - fB * vector;
1103 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1105 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1111void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1121 QPen framePen = QPen( mGridFramePenColor );
1122 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1123 framePen.setCapStyle( Qt::SquareCap );
1124 p->setBrush( Qt::NoBrush );
1125 p->setPen( framePen );
1135 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1143 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1149 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1151 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1159 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1162 if ( ! extension && drawDiagonals )
1167 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1168 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1169 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1174 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1175 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1176 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1181 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1182 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1183 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1188 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1189 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1190 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1196 GridExtension *extension )
const
1198 QString currentAnnotationString;
1199 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1200 for ( ; it != mGridLines.constEnd(); ++it )
1202 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1203 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1204 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1208void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1215 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1225 : (
QgsTextRenderer::textHeight( context, mAnnotationFormat,
'0', false ) ) ) / context.convertToPainterUnits( 1,
Qgis::RenderUnit::Millimeters );
1227 double xpos = annot.position.x();
1228 double ypos = annot.position.y();
1229 QPointF anchor = QPointF();
1236 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1240 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1243 double f = mEvaluatedAnnotationFrameDistance;
1251 f += mEvaluatedGridFrameWidth;
1252 if ( hasBorderWidth )
1253 f += mEvaluatedGridFrameLineThickness / 2.0;
1258 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1260 f /= QVector2D::dotProduct( vector, normalVector );
1263 const QVector2D pos = annot.position + f * vector;
1276 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1278 if ( rotation <= -90 || rotation > 90 )
1281 anchor.setX( outside ? 0 : textWidth );
1285 anchor.setX( outside ? textWidth : 0 );
1289 anchor.setY( 0.5 * textHeight );
1291 anchor.setY( -1.5 * textHeight );
1293 anchor.setY( -0.5 * textHeight );
1299 anchor.setX( 0.5 * textWidth );
1300 anchor.setY( -0.5 * textHeight );
1302 anchor.setY( outside ? 0 : -textHeight );
1304 anchor.setX( outside ? 0 : textWidth );
1306 anchor.setY( outside ? -textHeight : 0 );
1308 anchor.setX( outside ? textWidth : 0 );
1313 anchor.setX( 0.5 * textWidth );
1314 anchor.setY( -0.5 * textHeight );
1316 anchor.setX( outside ? 0 : textWidth );
1318 anchor.setY( outside ? -textHeight : 0 );
1320 anchor.setX( outside ? textWidth : 0 );
1322 anchor.setY( outside ? 0 : -textHeight );
1327 anchor.setX( 0.5 * textWidth );
1328 anchor.setY( -0.5 * textHeight );
1330 anchor.setX( outside ? textWidth : 0 );
1332 anchor.setY( outside ? 0 : -textHeight );
1334 anchor.setX( outside ? 0 : textWidth );
1336 anchor.setY( outside ? -textHeight : 0 );
1341 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1342 anchor.setX( 0.5 * textWidth );
1344 anchor.setY( -textHeight );
1352 extension->UpdateBorder( frameBorder, -f + textWidth );
1354 extension->UpdateAll( textWidth / 2.0 );
1357 if ( extension || !context.
painter() )
1361 bool facingLeft = ( annot.angle < 0 );
1362 bool facingRight = ( annot.angle > 0 );
1365 facingLeft = !facingLeft;
1366 facingRight = !facingRight;
1368 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1369 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1371 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1372 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1374 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1375 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1377 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1378 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1382 context.
painter()->translate( QPointF( xpos, ypos ) );
1383 context.
painter()->rotate( rotation );
1384 context.
painter()->translate( -anchor );
1392 bool geographic =
false;
1406 const double wrappedX = std::fmod( value, 360.0 );
1407 if ( wrappedX > 180.0 )
1409 value = wrappedX - 360.0;
1411 else if ( wrappedX < -180.0 )
1413 value = wrappedX + 360.0;
1419 return QString::number( value,
'f', mGridAnnotationPrecision );
1425 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1429 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1431 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1437 if ( !geographic || coordRounded != 0.0 )
1439 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1445 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1449 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1456 if ( !mGridAnnotationExpression )
1458 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1459 mGridAnnotationExpression->prepare( &expressionContext );
1461 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1465 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
1466 switch ( mGridAnnotationFormat )
1485 flags = QgsCoordinateFormatter::FormatFlags();
1495 flags = QgsCoordinateFormatter::FormatFlags();
1516int QgsLayoutItemMapGrid::xGridLines()
const
1518 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1525 QRectF mapBoundingRect = mapPolygon.boundingRect();
1526 double gridIntervalY = mEvaluatedIntervalY;
1527 double gridOffsetY = mEvaluatedOffsetY;
1528 double annotationScale = 1.0;
1529 switch ( mGridUnit )
1534 mapBoundingRect =
mMap->rect();
1535 mapPolygon = QPolygonF(
mMap->rect() );
1536 if ( mGridUnit ==
CM )
1538 annotationScale = 0.1;
1539 gridIntervalY *= 10;
1551 const double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1552 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1554 int gridLineCount = 0;
1559 double yCanvasCoord;
1560 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1562 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1564 newLine.coordinate = currentLevel * annotationScale;
1566 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1567 mGridLines.append( newLine );
1568 currentLevel += gridIntervalY;
1575 QVector<QLineF> borderLines;
1576 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1577 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1578 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1579 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1581 QVector<QPointF> intersectionList;
1583 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1585 intersectionList.clear();
1586 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1588 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1589 for ( ; it != borderLines.constEnd(); ++it )
1591 QPointF intersectionPoint;
1592 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1594 intersectionList.push_back( intersectionPoint );
1595 if ( intersectionList.size() >= 2 )
1602 if ( intersectionList.size() >= 2 )
1605 newLine.coordinate = currentLevel;
1608 mGridLines.append( newLine );
1611 currentLevel += gridIntervalY;
1618int QgsLayoutItemMapGrid::yGridLines()
const
1620 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1626 QRectF mapBoundingRect = mapPolygon.boundingRect();
1627 double gridIntervalX = mEvaluatedIntervalX;
1628 double gridOffsetX = mEvaluatedOffsetX;
1629 double annotationScale = 1.0;
1630 switch ( mGridUnit )
1635 mapBoundingRect =
mMap->rect();
1636 mapPolygon = QPolygonF(
mMap->rect() );
1637 if ( mGridUnit ==
CM )
1639 annotationScale = 0.1;
1640 gridIntervalX *= 10;
1652 const double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1653 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1655 int gridLineCount = 0;
1659 double xCanvasCoord;
1660 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1662 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1665 newLine.coordinate = currentLevel * annotationScale;
1667 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1668 mGridLines.append( newLine );
1669 currentLevel += gridIntervalX;
1676 QVector<QLineF> borderLines;
1677 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1678 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1679 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1680 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1682 QVector<QPointF> intersectionList;
1684 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1686 intersectionList.clear();
1687 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1689 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1690 for ( ; it != borderLines.constEnd(); ++it )
1692 QPointF intersectionPoint;
1693 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1695 intersectionList.push_back( intersectionPoint );
1696 if ( intersectionList.size() >= 2 )
1703 if ( intersectionList.size() >= 2 )
1706 newLine.coordinate = currentLevel;
1709 mGridLines.append( newLine );
1712 currentLevel += gridIntervalX;
1720 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1725 const double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1726 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1728 const double minX = bbox.
xMinimum();
1729 const double maxX = bbox.
xMaximum();
1730 double step = ( maxX - minX ) / 20;
1732 bool crosses180 =
false;
1733 bool crossed180 =
false;
1738 step = ( maxX + 360.0 - minX ) / 20;
1744 int gridLineCount = 0;
1748 double currentX = minX;
1752 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1769 if ( crosses180 && currentX > 180.0 )
1777 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1778 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1779 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1781 if ( !( *lineIt ).isEmpty() )
1784 newLine.coordinate = currentLevel;
1786 newLine.line = QPolygonF( *lineIt );
1787 mGridLines.append( newLine );
1791 currentLevel -= mEvaluatedIntervalY;
1799 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1804 const double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1805 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1807 const double minY = bbox.
yMinimum();
1808 const double maxY = bbox.
yMaximum();
1809 const double step = ( maxY - minY ) / 20;
1814 bool crosses180 =
false;
1815 bool crossed180 =
false;
1822 int gridLineCount = 0;
1823 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1826 double currentY = minY;
1830 if ( currentY > maxY )
1850 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1851 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1852 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1854 if ( !( *lineIt ).isEmpty() )
1857 newLine.coordinate = currentLevel;
1859 newLine.line = QPolygonF( *lineIt );
1860 mGridLines.append( newLine );
1864 currentLevel += mEvaluatedIntervalX;
1865 if ( crosses180 && currentLevel > 180.0 )
1867 currentLevel -= 360.0;
1896 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1898 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1900 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1902 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1917 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1919 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1921 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1923 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
1930void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1935 mTransformDirty = mTransformDirty
1942 switch ( mGridUnit )
1955 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1957 mEvaluatedEnabled =
false;
1962 const double mapWidthMapUnits = mapWidth();
1963 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1964 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1966 mEvaluatedIntervalX = interval;
1967 mEvaluatedIntervalY = interval;
1968 mTransformDirty =
true;
1991double QgsLayoutItemMapGrid::mapWidth()
const
2002 return mapExtent.
width();
2019bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2021 return a.first < b.first;
2034 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2035 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2036 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2037 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2043 if ( p.x() <= tolerance )
2054 if ( p.y() <= tolerance )
2066 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2072 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2073 return distanceToSide.at( 0 ).second;
2078 mGridLineSymbol.reset( symbol );
2083 return mGridLineSymbol.get();
2088 return mGridLineSymbol.get();
2093 mGridMarkerSymbol.reset( symbol );
2098 return mGridMarkerSymbol.get();
2103 return mGridMarkerSymbol.get();
2108 mAnnotationFormat.
setFont( font );
2109 if ( font.pointSizeF() > 0 )
2111 mAnnotationFormat.
setSize( font.pointSizeF() );
2114 else if ( font.pixelSize() > 0 )
2116 mAnnotationFormat.
setSize( font.pixelSize() );
2123 return mAnnotationFormat.
toQFont();
2128 mAnnotationFormat.
setColor( color );
2133 return mAnnotationFormat.
color();
2141 mLeftGridAnnotationDisplay = display;
2144 mRightGridAnnotationDisplay = display;
2147 mTopGridAnnotationDisplay = display;
2150 mBottomGridAnnotationDisplay = display;
2154 refreshDataDefinedProperties();
2168 return mLeftGridAnnotationDisplay;
2170 return mRightGridAnnotationDisplay;
2172 return mTopGridAnnotationDisplay;
2174 return mBottomGridAnnotationDisplay;
2176 return mBottomGridAnnotationDisplay;
2183 double bottom = 0.0;
2186 return std::max( std::max( std::max( top, right ), bottom ), left );
2196 if ( !
mMap || !mEvaluatedEnabled )
2206 GridExtension extension;
2209 switch ( mGridUnit )
2216 drawGridCrsTransform( context, 0,
true );
2223 drawGridNoTransform( context, 0,
true );
2228 updateGridLinesAnnotationsPositions();
2232 drawGridFrame(
nullptr, &extension );
2235 if ( mShowGridAnnotation )
2240 top = extension.top;
2241 right = extension.right;
2242 bottom = extension.bottom;
2243 left = extension.left;
2249 refreshDataDefinedProperties();
2254 if ( unit == mGridUnit )
2259 mTransformDirty =
true;
2268 mGridIntervalX = interval;
2269 mTransformDirty =
true;
2270 refreshDataDefinedProperties();
2279 mGridIntervalY = interval;
2280 mTransformDirty =
true;
2281 refreshDataDefinedProperties();
2290 mGridOffsetX = offset;
2291 mTransformDirty =
true;
2292 refreshDataDefinedProperties();
2301 mGridOffsetY = offset;
2302 mTransformDirty =
true;
2303 refreshDataDefinedProperties();
2312 mMinimumIntervalWidth = minWidth;
2313 mTransformDirty =
true;
2314 refreshDataDefinedProperties();
2323 mMaximumIntervalWidth = maxWidth;
2324 mTransformDirty =
true;
2325 refreshDataDefinedProperties();
2330 if (
style == mGridStyle )
2335 mTransformDirty =
true;
2340 mCrossLength = length;
2341 refreshDataDefinedProperties();
2349 mLeftGridAnnotationDirection = direction;
2352 mRightGridAnnotationDirection = direction;
2355 mTopGridAnnotationDirection = direction;
2358 mBottomGridAnnotationDirection = direction;
2371 mGridFrameSides = flags;
2377 mGridFrameSides |= flag;
2379 mGridFrameSides &= ~flag;
2384 return mGridFrameSides;
2393 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2399 if ( mGridLineSymbol )
2405 if ( mGridMarkerSymbol )
2417 mTransformDirty =
true;
2418 refreshDataDefinedProperties();
2425 return mGridFrameSides.testFlag( flag );
2430 mGridFrameWidth = width;
2431 refreshDataDefinedProperties();
2436 mGridFrameMargin = margin;
2437 refreshDataDefinedProperties();
2442 mGridFramePenThickness = width;
2443 refreshDataDefinedProperties();
2448 mLeftGridAnnotationDirection = direction;
2449 mRightGridAnnotationDirection = direction;
2450 mTopGridAnnotationDirection = direction;
2451 mBottomGridAnnotationDirection = direction;
2459 mLeftGridAnnotationPosition = position;
2462 mRightGridAnnotationPosition = position;
2465 mTopGridAnnotationPosition = position;
2468 mBottomGridAnnotationPosition = position;
2484 return mLeftGridAnnotationPosition;
2486 return mRightGridAnnotationPosition;
2488 return mTopGridAnnotationPosition;
2490 return mBottomGridAnnotationPosition;
2492 return mLeftGridAnnotationPosition;
2497 mAnnotationFrameDistance = distance;
2498 refreshDataDefinedProperties();
2505 return mLeftGridAnnotationDirection;
2511 return mLeftGridAnnotationDirection;
2513 return mRightGridAnnotationDirection;
2515 return mTopGridAnnotationDirection;
2517 return mBottomGridAnnotationDirection;
2519 return mLeftGridAnnotationDirection;
2524 mGridAnnotationExpressionString = expression;
2525 mGridAnnotationExpression.reset();
2533 mLeftFrameDivisions = divisions;
2536 mRightFrameDivisions = divisions;
2539 mTopFrameDivisions = divisions;
2542 mBottomFrameDivisions = divisions;
2546 refreshDataDefinedProperties();
2559 return mLeftFrameDivisions;
2561 return mRightFrameDivisions;
2563 return mTopFrameDivisions;
2565 return mBottomFrameDivisions;
2567 return mLeftFrameDivisions;
2583 const QRectF mbr = mapPolygon.boundingRect();
2584 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2590 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2591 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2593 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2594 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2596 if ( lowerLeft.x() > upperRight.x() )
2623QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2631 QList<QPolygonF> trimmedLines;
2632 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2633 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2635 trimmedLines << ( *geomIt ).asQPolygonF();
2637 return trimmedLines;
The Qgis class provides global constants for use throughout the application.
@ Millimeters
Millimeters.
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
@ Forward
Forward transform (from source to destination)
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Qgis::DistanceUnit mapUnits
Custom exception class for Coordinate Reference System related exceptions.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Qgis::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
A geometry is the spatial representation of a feature.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QList< QgsLayoutItemMapGrid * > asList() const
Returns a list of QgsLayoutItemMapGrids contained by the stack.
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void removeGrid(const QString &gridId)
Removes a grid with matching gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid...
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void addGrid(QgsLayoutItemMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
QgsLayoutItemMapGrid * grid(const QString &gridId) const
Returns a reference to a grid with matching gridId within the stack.
bool readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the item stack's state from a DOM document, where element is a DOM node corresponding to a 'Layo...
QgsLayoutItemMapGrid & operator[](int index)
Returns a reference to a grid at the specified index within the stack.
void moveGridUp(const QString &gridId)
Moves a grid with matching gridId up the stack, causing it to be rendered above other grids.
void moveGridDown(const QString &gridId)
Moves a grid with matching gridId down the stack, causing it to be rendered below other grids.
QgsLayoutItemMapGridStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGridStack, attached to the specified map.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
void setFrameSideFlags(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
GridStyle
Grid drawing style.
@ Markers
Draw markers at intersections of grid lines.
@ Cross
Draw line crosses at intersections of grid lines.
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
GridUnit
Unit for grid values.
@ CM
Grid units in centimeters.
@ MM
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnit
Grid units follow map units.
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ FrameTop
Top side of map.
@ FrameBottom
Bottom side of map.
@ FrameLeft
Left side of map.
@ FrameRight
Right side of map.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
void draw(QPainter *painter) override
Draws the item on to a destination painter.
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
AnnotationPosition
Position for grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
AnnotationCoordinate
Annotation coordinate type.
@ Latitude
Coordinate is a latitude value.
@ Longitude
Coordinate is a longitude value.
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
DisplayMode
Display settings for grid annotations and frames.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
void crsChanged()
Emitted whenever the grid's CRS is changed.
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
~QgsLayoutItemMapGrid() override
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
TickLengthMode
Tick length mode (useful for rotated grids)
@ OrthogonalTicks
Align ticks orthogonaly.
AnnotationFormat
Format for displaying grid annotations.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ CustomFormat
Custom expression-based format.
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
AnnotationDirection
Direction of grid annotations.
@ OnTick
Draw annotations parallel to tick (on the line)
@ Horizontal
Draw annotations horizontally.
@ Vertical
Draw annotations vertically, ascending.
@ AboveTick
Draw annotations parallel to tick (above the line)
@ UnderTick
Draw annotations parallel to tick (under the line)
@ VerticalDescending
Draw annotations vertically, descending.
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
FrameStyle
Style for grid frame.
@ Zebra
Black/white pattern.
@ InteriorTicks
Tick markers drawn inside map frame.
@ LineBorder
Simple solid line frame.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ NoFrame
Disable grid frame.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
BorderSide
Border sides for annotations.
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
A collection of map items which are drawn above the map content in a QgsLayoutItemMap.
void addItem(QgsLayoutItemMapItem *item)
Adds a new map item to the stack and takes ownership of the item.
void removeItem(const QString &itemId)
Removes an item which matching itemId from the stack and deletes the corresponding QgsLayoutItemMapIt...
QgsLayoutItemMapItem * item(int index) const
Returns a reference to the item at the specified index within the stack.
void moveItemUp(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
void removeItems()
Clears the item stack and deletes all QgsLayoutItemMapItems contained by the stack.
QList< QgsLayoutItemMapItem * > mItems
void moveItemDown(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
QgsLayoutItemMap * mMap
Associated map.
virtual bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
virtual bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
virtual void setEnabled(bool enabled)
Controls whether the item will be drawn.
bool enabled() const
Returns whether the item will be drawn.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
QgsRectangle extent() const
Returns the current map extent.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
bool frameEnabled() const
Returns true if the item includes a frame.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
QPointer< QgsLayout > mLayout
@ 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
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 xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Scoped object for saving and restoring a QPainter object's state.
Scoped object for temporary scaling of a QgsRenderContext for pixel based rendering.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
static 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 setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
Handles rendering text using rich formatting options, including drop shadows, buffers and background ...
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
QgsLayoutItemMapGrid::DisplayMode gridAnnotationDisplayModeFromDD(QString ddValue, QgsLayoutItemMapGrid::DisplayMode defValue)
bool sortByDistance(QPair< qreal, QgsLayoutItemMapGrid::BorderSide > a, QPair< qreal, QgsLayoutItemMapGrid::BorderSide > b)
QVector2D borderToNormal2D(QgsLayoutItemMapGrid::BorderSide border)
QVector2D borderToVector2D(QgsLayoutItemMapGrid::BorderSide border)
#define QgsDebugError(str)
const QgsCoordinateReferenceSystem & crs
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to the style entity currently being visited.