47 #define MAX_GRID_LINES 1000
78 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
84 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
89 QList< QgsLayoutItemMapGrid * > list;
112 QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
113 for (
int i = 0; i < mapGridNodeList.size(); ++i )
115 QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
117 mapGrid->
readXml( mapGridElem, doc, context );
131 return std::max( std::max( std::max( top, right ), bottom ), left );
145 double gridTop = 0.0;
146 double gridRight = 0.0;
147 double gridBottom = 0.0;
148 double gridLeft = 0.0;
150 top = std::max( top, gridTop );
151 right = std::max( right, gridRight );
152 bottom = std::max( bottom, gridBottom );
153 left = std::max( left, gridLeft );
169 return QVector2D( 0, 1 );
171 return QVector2D( -1, 0 );
173 return QVector2D( 0, -1 );
175 return QVector2D( 1, 0 );
183 return QVector2D( borderVector.y(), -borderVector.x() );
193 QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
194 if ( !defaultFontString.isEmpty() )
197 font.setFamily( defaultFontString );
198 mAnnotationFormat.
setFont( font );
201 createDefaultGridLineSymbol();
202 createDefaultGridMarkerSymbol();
213 void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
215 QVariantMap properties;
216 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
217 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
218 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
222 void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
224 QVariantMap properties;
225 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
226 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
227 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
233 if ( mGridLineSymbol )
235 mGridLineSymbol->setWidth( width );
241 if ( mGridLineSymbol )
243 mGridLineSymbol->setColor(
c );
254 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
255 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
256 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
257 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
258 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
259 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
260 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
262 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
264 lineStyleElem.appendChild( gridLineStyleElem );
265 mapGridElem.appendChild( lineStyleElem );
267 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
269 markerStyleElem.appendChild( gridMarkerStyleElem );
270 mapGridElem.appendChild( markerStyleElem );
272 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
273 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
274 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
275 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
276 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
280 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
281 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
282 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
283 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
284 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
285 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
286 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
287 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
288 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
289 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
297 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
298 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
299 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
300 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
301 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
302 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
303 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
304 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
305 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
306 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
307 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
308 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
309 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
310 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
311 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
312 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
313 mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
314 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
315 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
316 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
317 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
318 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
321 elem.appendChild( mapGridElem );
328 if ( itemElem.isNull() )
337 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
338 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
339 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
340 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
341 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
342 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
343 mGridFrameSides =
static_cast< QgsLayoutItemMapGrid::FrameSideFlags
>( itemElem.attribute( QStringLiteral(
"gridFrameSideFlags" ), QStringLiteral(
"15" ) ).toInt() );
344 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
345 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
346 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
354 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
355 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
356 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
357 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
358 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
359 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
360 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
361 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
363 QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
364 if ( !lineStyleElem.isNull() )
366 QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
367 if ( !symbolElem.isNull() )
369 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
376 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
377 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
378 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
379 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
382 QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
383 if ( !markerStyleElem.isNull() )
385 QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
386 if ( !symbolElem.isNull() )
388 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
392 if ( !mCRS.
readXml( itemElem ) )
395 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
398 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
400 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
401 mGridAnnotationExpression.reset();
406 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
407 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
409 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
415 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
417 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
419 mAnnotationFormat.
readXml( itemElem, context );
426 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
428 mAnnotationFormat.
setFont( font );
429 mAnnotationFormat.
setSize( font.pointSizeF() );
434 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
435 int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
437 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
438 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
440 refreshDataDefinedProperties();
450 mTransformDirty =
true;
456 return mBlendMode != QPainter::CompositionMode_SourceOver;
459 QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
461 QTransform t = QTransform::fromScale( scale, scale );
462 return t.map( polygon );
465 void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
467 if ( !
mMap || !mEvaluatedEnabled )
474 if ( mapPolygon != mPrevMapPolygon )
476 mTransformDirty =
true;
477 mPrevMapPolygon = mapPolygon;
480 if ( mTransformDirty )
482 calculateCrsTransformLines();
486 if ( !calculateLinesOnly )
490 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
491 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
493 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
498 double maxX =
mMap->rect().width();
499 double maxY =
mMap->rect().height();
501 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
502 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
504 double x = intersectionIt->x();
505 double y = intersectionIt->y();
509 QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
510 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
511 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
512 QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
513 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
514 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
517 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
518 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
522 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
529 void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
533 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
540 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
541 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
548 QList< QgsGeometry > xLines;
549 QList< QgsGeometry > yLines;
550 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
551 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
555 for (
int i = 0; i < gridIt->line.size(); ++i )
557 line.append(
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
559 if ( gridIt->coordinateType == AnnotationCoordinate::Longitude )
561 else if ( gridIt->coordinateType == AnnotationCoordinate::Latitude )
566 mTransformedIntersections.clear();
567 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
568 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
570 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
571 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
575 if ( intersects.
isNull() )
583 mTransformedIntersections << vertex;
591 mTransformDirty =
false;
596 if ( !
mMap || !mEvaluatedEnabled )
600 QPaintDevice *paintDevice = p->device();
607 p->setCompositionMode( mBlendMode );
610 QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
611 p->setClipRect( thisPaintRect );
612 if ( thisPaintRect != mPrevPaintRect )
615 mTransformDirty =
true;
616 mPrevPaintRect = thisPaintRect;
620 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
621 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
637 drawGridCrsTransform( context, dotsPerMM );
644 drawGridNoTransform( context, dotsPerMM );
649 p->setClipping(
false );
653 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
658 updateGridLinesAnnotationsPositions();
665 if ( mShowGridAnnotation )
671 void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
673 QList< GridLine >::iterator it = mGridLines.begin();
674 for ( ; it != mGridLines.end(); ++it )
676 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
677 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
678 it->startAnnotation.position = QVector2D( it->line.first() );
679 it->endAnnotation.position = QVector2D( it->line.last() );
680 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
681 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
683 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() );
685 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() );
689 void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
696 if ( calculateLinesOnly )
699 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
700 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
708 for ( ; vIt != mGridLines.constEnd(); ++vIt )
710 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
712 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
713 drawGridLine( line, context );
716 for ( ; hIt != mGridLines.constEnd(); ++hIt )
718 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
720 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
721 drawGridLine( line, context );
727 QPointF intersectionPoint, crossEnd1, crossEnd2;
728 for ( ; vIt != mGridLines.constEnd(); ++vIt )
730 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
733 l1 = QLineF( vIt->line.first(), vIt->line.last() );
736 hIt = mGridLines.constBegin();
737 for ( ; hIt != mGridLines.constEnd(); ++hIt )
739 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
742 l2 = QLineF( hIt->line.first(), hIt->line.last() );
744 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
745 if ( l2.intersect( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
747 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
753 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
755 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
758 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
762 drawGridMarker( intersectionPoint * dotsPerMM, context );
774 hIt = mGridLines.constBegin();
775 for ( ; hIt != mGridLines.constEnd(); ++hIt )
777 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
780 l1 = QLineF( hIt->line.first(), hIt->line.last() );
782 vIt = mGridLines.constBegin();
783 for ( ; vIt != mGridLines.constEnd(); ++vIt )
785 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
788 l2 = QLineF( vIt->line.first(), vIt->line.last() );
790 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
791 if ( l2.intersect( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
793 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
797 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
799 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
802 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
809 void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
818 switch ( mGridFrameStyle )
822 drawGridFrameZebra( p, extension );
827 drawGridFrameTicks( p, extension );
832 drawGridFrameLine( p, extension );
843 void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
846 poly << line.p1() << line.p2();
847 drawGridLine( poly, context );
850 void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
857 mGridLineSymbol->startRender( context );
858 mGridLineSymbol->renderPolyline( line,
nullptr, context );
859 mGridLineSymbol->stopRender( context );
862 void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
869 mGridMarkerSymbol->startRender( context );
870 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
871 mGridMarkerSymbol->stopRender( context );
874 void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
894 void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
903 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
907 double currentCoord = 0.0;
914 bool drawTLBox =
false;
915 bool drawTRBox =
false;
916 bool drawBLBox =
false;
917 bool drawBRBox =
false;
919 QMap< double, double > pos = QMap< double, double >();
920 QList< GridLine >::const_iterator it = mGridLines.constBegin();
921 for ( ; it != mGridLines.constEnd(); ++it )
924 for (
int i = 0 ; i < 2 ; ++i )
926 GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
929 if ( annot.border != border )
932 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
936 pos.insert( annot.position.y(), it->coordinate );
938 pos.insert( annot.position.x(), it->coordinate );
945 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
961 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
965 QPen framePen = QPen( mGridFramePenColor );
966 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
967 framePen.setJoinStyle( Qt::MiterJoin );
968 p->setPen( framePen );
970 QMap< double, double >::const_iterator posIt = pos.constBegin();
971 for ( ; posIt != pos.constEnd(); ++posIt )
973 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
976 height = posIt.key() - currentCoord;
977 width = mEvaluatedGridFrameWidth;
978 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
983 height = mEvaluatedGridFrameWidth;
984 width = posIt.key() - currentCoord;
986 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
988 p->drawRect( QRectF( x, y, width, height ) );
989 currentCoord = posIt.key();
996 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
997 p->setBrush( QBrush( mGridFrameFillColor1 ) );
999 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1001 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1003 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1005 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1009 void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1019 QPen framePen = QPen( mGridFramePenColor );
1020 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1021 framePen.setCapStyle( Qt::FlatCap );
1022 p->setBrush( Qt::NoBrush );
1023 p->setPen( framePen );
1026 QList< GridLine >::iterator it = mGridLines.begin();
1027 for ( ; it != mGridLines.end(); ++it )
1030 for (
int i = 0 ; i < 2 ; ++i )
1032 GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1034 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1038 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1046 facingLeft = ( annot.angle != 0 );
1047 facingRight = ( annot.angle != 0 );
1051 facingLeft = ( annot.angle > 0 );
1052 facingRight = ( annot.angle < 0 );
1056 facingLeft = ( annot.angle < 0 );
1057 facingRight = ( annot.angle > 0 );
1060 if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1061 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1063 if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1064 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1066 if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1067 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1069 if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1070 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1074 QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1076 double fA = mEvaluatedGridFrameMargin;
1077 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1079 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1081 fA /= QVector2D::dotProduct( vector, normalVector );
1082 fB /= QVector2D::dotProduct( vector, normalVector );
1089 extension->UpdateBorder( annot.border, fB );
1097 pA = annot.position + fA * vector;
1098 pB = annot.position + fB * vector;
1102 pA = annot.position - fA * vector;
1103 pB = annot.position - fB * vector;
1107 pA = annot.position - fB * vector;
1108 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1110 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1116 void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1126 QPen framePen = QPen( mGridFramePenColor );
1127 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1128 framePen.setCapStyle( Qt::SquareCap );
1129 p->setBrush( Qt::NoBrush );
1130 p->setPen( framePen );
1140 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1148 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1154 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1156 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1164 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1167 if ( ! extension && drawDiagonals )
1172 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1173 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1174 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1179 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1180 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1181 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1186 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1187 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1188 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1193 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1194 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1195 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1201 GridExtension *extension )
const
1203 QString currentAnnotationString;
1204 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1205 for ( ; it != mGridLines.constEnd(); ++it )
1207 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1208 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1209 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1213 void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1220 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1232 double xpos = annot.position.x();
1233 double ypos = annot.position.y();
1234 QPointF anchor = QPointF();
1241 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1245 QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1248 double f = mEvaluatedAnnotationFrameDistance;
1256 f += mEvaluatedGridFrameWidth;
1257 if ( hasBorderWidth )
1258 f += mEvaluatedGridFrameLineThickness / 2.0;
1263 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1265 f /= QVector2D::dotProduct( vector, normalVector );
1268 QVector2D pos = annot.position + f * vector;
1281 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1283 if ( rotation <= -90 || rotation > 90 )
1286 anchor.setX( outside ? 0 : textWidth );
1290 anchor.setX( outside ? textWidth : 0 );
1294 anchor.setY( 0.5 * textHeight );
1296 anchor.setY( -1.5 * textHeight );
1298 anchor.setY( -0.5 * textHeight );
1304 anchor.setX( 0.5 * textWidth );
1305 anchor.setY( -0.5 * textHeight );
1307 anchor.setY( outside ? 0 : -textHeight );
1309 anchor.setX( outside ? 0 : textWidth );
1311 anchor.setY( outside ? -textHeight : 0 );
1313 anchor.setX( outside ? textWidth : 0 );
1318 anchor.setX( 0.5 * textWidth );
1319 anchor.setY( -0.5 * textHeight );
1321 anchor.setX( outside ? 0 : textWidth );
1323 anchor.setY( outside ? -textHeight : 0 );
1325 anchor.setX( outside ? textWidth : 0 );
1327 anchor.setY( outside ? 0 : -textHeight );
1332 anchor.setX( 0.5 * textWidth );
1333 anchor.setY( -0.5 * textHeight );
1335 anchor.setX( outside ? textWidth : 0 );
1337 anchor.setY( outside ? 0 : -textHeight );
1339 anchor.setX( outside ? 0 : textWidth );
1341 anchor.setY( outside ? -textHeight : 0 );
1346 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1347 anchor.setX( 0.5 * textWidth );
1349 anchor.setY( -textHeight );
1357 extension->UpdateBorder( frameBorder, -f + textWidth );
1359 extension->UpdateAll( textWidth / 2.0 );
1362 if ( extension || !context.
painter() )
1366 bool facingLeft = ( annot.angle < 0 );
1367 bool facingRight = ( annot.angle > 0 );
1370 facingLeft = !facingLeft;
1371 facingRight = !facingRight;
1373 if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1374 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1376 if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1377 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1379 if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1380 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1382 if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1383 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1387 context.
painter()->translate( QPointF( xpos, ypos ) );
1388 context.
painter()->rotate( rotation );
1389 context.
painter()->translate( -anchor );
1397 bool geographic =
false;
1411 double wrappedX = std::fmod( value, 360.0 );
1412 if ( wrappedX > 180.0 )
1414 value = wrappedX - 360.0;
1416 else if ( wrappedX < -180.0 )
1418 value = wrappedX + 360.0;
1424 return QString::number( value,
'f', mGridAnnotationPrecision );
1430 double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1434 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1436 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1442 if ( !geographic || coordRounded != 0.0 )
1444 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1450 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1454 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1461 if ( !mGridAnnotationExpression )
1463 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1464 mGridAnnotationExpression->prepare( &expressionContext );
1466 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1470 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
1471 switch ( mGridAnnotationFormat )
1490 flags = QgsCoordinateFormatter::FormatFlags();
1500 flags = QgsCoordinateFormatter::FormatFlags();
1521 int QgsLayoutItemMapGrid::xGridLines()
const
1523 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1530 QRectF mapBoundingRect = mapPolygon.boundingRect();
1531 double gridIntervalY = mEvaluatedIntervalY;
1532 double gridOffsetY = mEvaluatedOffsetY;
1533 double annotationScale = 1.0;
1534 switch ( mGridUnit )
1539 mapBoundingRect =
mMap->rect();
1540 mapPolygon = QPolygonF(
mMap->rect() );
1541 if ( mGridUnit ==
CM )
1543 annotationScale = 0.1;
1544 gridIntervalY *= 10;
1556 double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1557 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1559 int gridLineCount = 0;
1564 double yCanvasCoord;
1565 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1567 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1569 newLine.coordinate = currentLevel * annotationScale;
1570 newLine.coordinateType = AnnotationCoordinate::Latitude;
1571 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1572 mGridLines.append( newLine );
1573 currentLevel += gridIntervalY;
1580 QVector<QLineF> borderLines;
1581 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1582 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1583 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1584 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1586 QVector<QPointF> intersectionList;
1588 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1590 intersectionList.clear();
1591 QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1593 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1594 for ( ; it != borderLines.constEnd(); ++it )
1596 QPointF intersectionPoint;
1597 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
1598 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1600 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1603 intersectionList.push_back( intersectionPoint );
1604 if ( intersectionList.size() >= 2 )
1611 if ( intersectionList.size() >= 2 )
1614 newLine.coordinate = currentLevel;
1615 newLine.coordinateType = AnnotationCoordinate::Latitude;
1617 mGridLines.append( newLine );
1620 currentLevel += gridIntervalY;
1627 int QgsLayoutItemMapGrid::yGridLines()
const
1629 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1635 QRectF mapBoundingRect = mapPolygon.boundingRect();
1636 double gridIntervalX = mEvaluatedIntervalX;
1637 double gridOffsetX = mEvaluatedOffsetX;
1638 double annotationScale = 1.0;
1639 switch ( mGridUnit )
1644 mapBoundingRect =
mMap->rect();
1645 mapPolygon = QPolygonF(
mMap->rect() );
1646 if ( mGridUnit ==
CM )
1648 annotationScale = 0.1;
1649 gridIntervalX *= 10;
1661 double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1662 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1664 int gridLineCount = 0;
1668 double xCanvasCoord;
1669 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1671 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1674 newLine.coordinate = currentLevel * annotationScale;
1675 newLine.coordinateType = AnnotationCoordinate::Longitude;
1676 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1677 mGridLines.append( newLine );
1678 currentLevel += gridIntervalX;
1685 QVector<QLineF> borderLines;
1686 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1687 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1688 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1689 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1691 QVector<QPointF> intersectionList;
1693 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1695 intersectionList.clear();
1696 QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1698 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1699 for ( ; it != borderLines.constEnd(); ++it )
1701 QPointF intersectionPoint;
1702 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
1703 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1705 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1708 intersectionList.push_back( intersectionPoint );
1709 if ( intersectionList.size() >= 2 )
1716 if ( intersectionList.size() >= 2 )
1719 newLine.coordinate = currentLevel;
1720 newLine.coordinateType = AnnotationCoordinate::Longitude;
1722 mGridLines.append( newLine );
1725 currentLevel += gridIntervalX;
1733 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1738 double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1739 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1743 double step = ( maxX - minX ) / 20;
1745 bool crosses180 =
false;
1746 bool crossed180 =
false;
1751 step = ( maxX + 360.0 - minX ) / 20;
1757 int gridLineCount = 0;
1761 double currentX = minX;
1765 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1778 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1782 if ( crosses180 && currentX > 180.0 )
1790 QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1791 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1792 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1794 if ( !( *lineIt ).isEmpty() )
1797 newLine.coordinate = currentLevel;
1798 newLine.coordinateType = AnnotationCoordinate::Latitude;
1799 newLine.line = QPolygonF( *lineIt );
1800 mGridLines.append( newLine );
1804 currentLevel -= mEvaluatedIntervalY;
1812 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1817 double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1818 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1822 double step = ( maxY - minY ) / 20;
1827 bool crosses180 =
false;
1828 bool crossed180 =
false;
1835 int gridLineCount = 0;
1836 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1839 double currentY = minY;
1843 if ( currentY > maxY )
1857 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1863 QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1864 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1865 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1867 if ( !( *lineIt ).isEmpty() )
1870 newLine.coordinate = currentLevel;
1871 newLine.coordinateType = AnnotationCoordinate::Longitude;
1872 newLine.line = QPolygonF( *lineIt );
1873 mGridLines.append( newLine );
1877 currentLevel += mEvaluatedIntervalX;
1878 if ( crosses180 && currentLevel > 180.0 )
1880 currentLevel -= 360.0;
1909 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1911 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1913 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1915 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1930 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1932 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1934 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1936 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
1943 void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1948 switch ( mGridUnit )
1961 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1963 mEvaluatedEnabled =
false;
1968 const double mapWidthMapUnits = mapWidth();
1969 double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1970 double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1972 mEvaluatedIntervalX = interval;
1973 mEvaluatedIntervalY = interval;
1996 double QgsLayoutItemMapGrid::mapWidth()
const
2007 return mapExtent.
width();
2024 bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2026 return a.first < b.first;
2039 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2040 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2041 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2042 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2048 if ( p.x() <= tolerance )
2059 if ( p.y() <= tolerance )
2071 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2077 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2078 return distanceToSide.at( 0 ).second;
2083 mGridLineSymbol.reset( symbol );
2088 return mGridLineSymbol.get();
2093 return mGridLineSymbol.get();
2098 mGridMarkerSymbol.reset( symbol );
2103 return mGridMarkerSymbol.get();
2108 return mGridMarkerSymbol.get();
2113 mAnnotationFormat.
setFont( font );
2114 if ( font.pointSizeF() > 0 )
2116 mAnnotationFormat.
setSize( font.pointSizeF() );
2119 else if ( font.pixelSize() > 0 )
2121 mAnnotationFormat.
setSize( font.pixelSize() );
2128 return mAnnotationFormat.
toQFont();
2133 mAnnotationFormat.
setColor( color );
2138 return mAnnotationFormat.
color();
2146 mLeftGridAnnotationDisplay = display;
2149 mRightGridAnnotationDisplay = display;
2152 mTopGridAnnotationDisplay = display;
2155 mBottomGridAnnotationDisplay = display;
2159 refreshDataDefinedProperties();
2173 return mLeftGridAnnotationDisplay;
2175 return mRightGridAnnotationDisplay;
2177 return mTopGridAnnotationDisplay;
2179 return mBottomGridAnnotationDisplay;
2181 return mBottomGridAnnotationDisplay;
2188 double bottom = 0.0;
2191 return std::max( std::max( std::max( top, right ), bottom ), left );
2201 if ( !
mMap || !mEvaluatedEnabled )
2211 GridExtension extension;
2214 switch ( mGridUnit )
2221 drawGridCrsTransform( context, 0,
true );
2228 drawGridNoTransform( context, 0,
true );
2233 updateGridLinesAnnotationsPositions();
2237 drawGridFrame(
nullptr, &extension );
2240 if ( mShowGridAnnotation )
2245 top = extension.top;
2246 right = extension.right;
2247 bottom = extension.bottom;
2248 left = extension.left;
2254 refreshDataDefinedProperties();
2259 if ( unit == mGridUnit )
2264 mTransformDirty =
true;
2273 mGridIntervalX = interval;
2274 mTransformDirty =
true;
2275 refreshDataDefinedProperties();
2284 mGridIntervalY = interval;
2285 mTransformDirty =
true;
2286 refreshDataDefinedProperties();
2295 mGridOffsetX = offset;
2296 mTransformDirty =
true;
2297 refreshDataDefinedProperties();
2306 mGridOffsetY = offset;
2307 mTransformDirty =
true;
2308 refreshDataDefinedProperties();
2317 mMinimumIntervalWidth = minWidth;
2318 mTransformDirty =
true;
2319 refreshDataDefinedProperties();
2328 mMaximumIntervalWidth = maxWidth;
2329 mTransformDirty =
true;
2330 refreshDataDefinedProperties();
2335 if (
style == mGridStyle )
2340 mTransformDirty =
true;
2345 mCrossLength = length;
2346 refreshDataDefinedProperties();
2354 mLeftGridAnnotationDirection = direction;
2357 mRightGridAnnotationDirection = direction;
2360 mTopGridAnnotationDirection = direction;
2363 mBottomGridAnnotationDirection = direction;
2376 mGridFrameSides = flags;
2382 mGridFrameSides |= flag;
2384 mGridFrameSides &= ~flag;
2389 return mGridFrameSides;
2398 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2404 if ( mGridLineSymbol )
2410 if ( mGridMarkerSymbol )
2422 mTransformDirty =
true;
2423 refreshDataDefinedProperties();
2430 return mGridFrameSides.testFlag( flag );
2435 mGridFrameWidth = width;
2436 refreshDataDefinedProperties();
2441 mGridFrameMargin = margin;
2442 refreshDataDefinedProperties();
2447 mGridFramePenThickness = width;
2448 refreshDataDefinedProperties();
2453 mLeftGridAnnotationDirection = direction;
2454 mRightGridAnnotationDirection = direction;
2455 mTopGridAnnotationDirection = direction;
2456 mBottomGridAnnotationDirection = direction;
2464 mLeftGridAnnotationPosition = position;
2467 mRightGridAnnotationPosition = position;
2470 mTopGridAnnotationPosition = position;
2473 mBottomGridAnnotationPosition = position;
2489 return mLeftGridAnnotationPosition;
2491 return mRightGridAnnotationPosition;
2493 return mTopGridAnnotationPosition;
2495 return mBottomGridAnnotationPosition;
2497 return mLeftGridAnnotationPosition;
2502 mAnnotationFrameDistance = distance;
2503 refreshDataDefinedProperties();
2510 return mLeftGridAnnotationDirection;
2516 return mLeftGridAnnotationDirection;
2518 return mRightGridAnnotationDirection;
2520 return mTopGridAnnotationDirection;
2522 return mBottomGridAnnotationDirection;
2524 return mLeftGridAnnotationDirection;
2532 mLeftFrameDivisions = divisions;
2535 mRightFrameDivisions = divisions;
2538 mTopFrameDivisions = divisions;
2541 mBottomFrameDivisions = divisions;
2545 refreshDataDefinedProperties();
2558 return mLeftFrameDivisions;
2560 return mRightFrameDivisions;
2562 return mTopFrameDivisions;
2564 return mBottomFrameDivisions;
2566 return mLeftFrameDivisions;
2580 QRectF mbr = mapPolygon.boundingRect();
2581 QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2587 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2588 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2590 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2591 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2593 if ( lowerLeft.x() > upperRight.x() )
2601 crsRect = tr.transformBoundingBox( mapBoundingRect );
2606 crsRect = tr.transformBoundingBox( mapBoundingRect );
2614 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
2620 QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2628 QList<QPolygonF> trimmedLines;
2629 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2630 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2632 trimmedLines << ( *geomIt ).asQPolygonF();
2634 return trimmedLines;
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
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.
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.
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.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
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, DrawMode mode=Point, QFontMetricsF *fontMetrics=nullptr)
Returns the height of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop)
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.