20#include "moc_qgslayoutitemmapgrid.cpp"
50#define MAX_GRID_LINES 1000
81 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
87 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
92 QList< QgsLayoutItemMapGrid * > list;
115 const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
116 for (
int i = 0; i < mapGridNodeList.size(); ++i )
118 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
120 mapGrid->
readXml( mapGridElem, doc, context );
134 return std::max( std::max( std::max( top, right ), bottom ), left );
148 double gridTop = 0.0;
149 double gridRight = 0.0;
150 double gridBottom = 0.0;
151 double gridLeft = 0.0;
153 top = std::max( top, gridTop );
154 right = std::max( right, gridRight );
155 bottom = std::max( bottom, gridBottom );
156 left = std::max( left, gridLeft );
172 return QVector2D( 0, 1 );
174 return QVector2D( -1, 0 );
176 return QVector2D( 0, -1 );
178 return QVector2D( 1, 0 );
186 return QVector2D( borderVector.y(), -borderVector.x() );
196 const QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
197 if ( !defaultFontString.isEmpty() )
201 mAnnotationFormat.
setFont( font );
204 createDefaultGridLineSymbol();
205 createDefaultGridMarkerSymbol();
218void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
220 QVariantMap properties;
221 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
222 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
223 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
227void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
229 QVariantMap properties;
230 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
231 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
232 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
238 if ( mGridLineSymbol )
240 mGridLineSymbol->setWidth( width );
246 if ( mGridLineSymbol )
248 mGridLineSymbol->setColor(
c );
259 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
260 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
261 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
262 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
263 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
264 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
265 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
267 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
269 lineStyleElem.appendChild( gridLineStyleElem );
270 mapGridElem.appendChild( lineStyleElem );
272 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
274 markerStyleElem.appendChild( gridMarkerStyleElem );
275 mapGridElem.appendChild( markerStyleElem );
277 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
278 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
279 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
280 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
281 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
285 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
286 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
287 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
288 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
289 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
292 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
293 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
294 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
295 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
296 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
302 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
303 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
304 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
305 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
306 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
307 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
308 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
309 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
310 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
311 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
312 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
313 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
314 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
315 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
316 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
317 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
318 mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
319 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
320 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
321 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
322 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
323 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
326 elem.appendChild( mapGridElem );
333 if ( itemElem.isNull() )
342 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
343 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
344 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
345 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
346 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
347 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
349 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
350 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
351 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
353 mGridFrameFillColor1 =
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral(
"frameFillColor1" ), QStringLiteral(
"255,255,255,255" ) ) );
354 mGridFrameFillColor2 =
QgsColorUtils::colorFromString( itemElem.attribute( QStringLiteral(
"frameFillColor2" ), QStringLiteral(
"0,0,0,255" ) ) );
359 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
360 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
361 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
362 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
363 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
364 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
365 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
366 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
368 const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
369 if ( !lineStyleElem.isNull() )
371 const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
372 if ( !symbolElem.isNull() )
374 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
381 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
382 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
383 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
384 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
387 const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
388 if ( !markerStyleElem.isNull() )
390 const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
391 if ( !symbolElem.isNull() )
393 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
397 if ( !mCRS.
readXml( itemElem ) )
400 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
403 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
405 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
406 mGridAnnotationExpression.reset();
411 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
412 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
414 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
420 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
422 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
424 mAnnotationFormat.
readXml( itemElem, context );
431 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
433 mAnnotationFormat.
setFont( font );
434 mAnnotationFormat.
setSize( font.pointSizeF() );
439 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
440 const int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
442 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
443 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
445 refreshDataDefinedProperties();
455 mTransformDirty =
true;
461 return mBlendMode != QPainter::CompositionMode_SourceOver;
464QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
466 const QTransform t = QTransform::fromScale( scale, scale );
467 return t.map( polygon );
470void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
472 if ( !
mMap || !mEvaluatedEnabled )
479 if ( mapPolygon != mPrevMapPolygon )
481 mTransformDirty =
true;
482 mPrevMapPolygon = mapPolygon;
485 if ( mTransformDirty )
487 calculateCrsTransformLines();
491 if ( !calculateLinesOnly )
495 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
496 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
498 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
503 const double maxX =
mMap->rect().width();
504 const double maxY =
mMap->rect().height();
506 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
507 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
509 const double x = intersectionIt->x();
510 const double y = intersectionIt->y();
514 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
515 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
516 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
517 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
518 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
519 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
522 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
523 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
527 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
534void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
538 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
545 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
546 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
553 QList< QgsGeometry > xLines;
554 QList< QgsGeometry > yLines;
555 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
556 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
560 for (
int i = 0; i < gridIt->line.size(); ++i )
562 line.append(
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
571 mTransformedIntersections.clear();
572 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
573 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
575 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
576 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
580 if ( intersects.
isNull() )
588 mTransformedIntersections << vertex;
596 mTransformDirty =
false;
601 if ( !
mMap || !mEvaluatedEnabled )
605 QPaintDevice *paintDevice = p->device();
612 p->setCompositionMode( mBlendMode );
615 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
616 p->setClipRect( thisPaintRect );
617 if ( thisPaintRect != mPrevPaintRect )
620 mTransformDirty =
true;
621 mPrevPaintRect = thisPaintRect;
625 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
626 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
642 drawGridCrsTransform( context, dotsPerMM );
649 drawGridNoTransform( context, dotsPerMM );
654 p->setClipping(
false );
658 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
663 updateGridLinesAnnotationsPositions();
670 if ( mShowGridAnnotation )
676void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
678 QList< GridLine >::iterator it = mGridLines.begin();
679 for ( ; it != mGridLines.end(); ++it )
681 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
682 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
683 it->startAnnotation.position = QVector2D( it->line.first() );
684 it->endAnnotation.position = QVector2D( it->line.last() );
685 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
686 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
688 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() );
690 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() );
694void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
701 if ( calculateLinesOnly )
704 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
705 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
713 for ( ; vIt != mGridLines.constEnd(); ++vIt )
717 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
718 drawGridLine( line, context );
721 for ( ; hIt != mGridLines.constEnd(); ++hIt )
725 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
726 drawGridLine( line, context );
732 QPointF intersectionPoint, crossEnd1, crossEnd2;
733 for ( ; vIt != mGridLines.constEnd(); ++vIt )
738 l1 = QLineF( vIt->line.first(), vIt->line.last() );
741 hIt = mGridLines.constBegin();
742 for ( ; hIt != mGridLines.constEnd(); ++hIt )
747 l2 = QLineF( hIt->line.first(), hIt->line.last() );
749 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
754 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
756 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
759 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
763 drawGridMarker( intersectionPoint * dotsPerMM, context );
775 hIt = mGridLines.constBegin();
776 for ( ; hIt != mGridLines.constEnd(); ++hIt )
781 l1 = QLineF( hIt->line.first(), hIt->line.last() );
783 vIt = mGridLines.constBegin();
784 for ( ; vIt != mGridLines.constEnd(); ++vIt )
789 l2 = QLineF( vIt->line.first(), vIt->line.last() );
791 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
794 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
796 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
799 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
806void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
815 switch ( mGridFrameStyle )
819 drawGridFrameZebra( p, extension );
824 drawGridFrameTicks( p, extension );
829 drawGridFrameLine( p, extension );
840void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
843 poly << line.p1() << line.p2();
844 drawGridLine( poly, context );
847void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
854 mGridLineSymbol->startRender( context );
855 mGridLineSymbol->renderPolyline( line,
nullptr, context );
856 mGridLineSymbol->stopRender( context );
859void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
866 mGridMarkerSymbol->startRender( context );
867 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
868 mGridMarkerSymbol->stopRender( context );
871void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
891void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
900 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
904 double currentCoord = 0.0;
911 bool drawTLBox =
false;
912 bool drawTRBox =
false;
913 bool drawBLBox =
false;
914 bool drawBRBox =
false;
916 QMap< double, double > pos = QMap< double, double >();
917 QList< GridLine >::const_iterator it = mGridLines.constBegin();
918 for ( ; it != mGridLines.constEnd(); ++it )
921 for (
int i = 0 ; i < 2 ; ++i )
923 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
926 if ( annot.border != border )
929 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
933 pos.insert( annot.position.y(), it->coordinate );
935 pos.insert( annot.position.x(), it->coordinate );
942 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
958 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
962 QPen framePen = QPen( mGridFramePenColor );
963 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
964 framePen.setJoinStyle( Qt::MiterJoin );
965 p->setPen( framePen );
967 QMap< double, double >::const_iterator posIt = pos.constBegin();
968 for ( ; posIt != pos.constEnd(); ++posIt )
970 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
973 height = posIt.key() - currentCoord;
974 width = mEvaluatedGridFrameWidth;
975 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
980 height = mEvaluatedGridFrameWidth;
981 width = posIt.key() - currentCoord;
983 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
985 p->drawRect( QRectF( x, y, width, height ) );
986 currentCoord = posIt.key();
993 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
994 p->setBrush( QBrush( mGridFrameFillColor1 ) );
996 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
998 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1000 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1002 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1006void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1016 QPen framePen = QPen( mGridFramePenColor );
1017 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1018 framePen.setCapStyle( Qt::FlatCap );
1019 p->setBrush( Qt::NoBrush );
1020 p->setPen( framePen );
1023 QList< GridLine >::iterator it = mGridLines.begin();
1024 for ( ; it != mGridLines.end(); ++it )
1027 for (
int i = 0 ; i < 2 ; ++i )
1029 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1031 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1035 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1043 facingLeft = ( annot.angle != 0 );
1044 facingRight = ( annot.angle != 0 );
1048 facingLeft = ( annot.angle > 0 );
1049 facingRight = ( annot.angle < 0 );
1053 facingLeft = ( annot.angle < 0 );
1054 facingRight = ( annot.angle > 0 );
1057 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1058 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1060 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1061 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1063 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1064 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1066 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1067 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1071 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1073 double fA = mEvaluatedGridFrameMargin;
1074 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1076 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1078 fA /= QVector2D::dotProduct( vector, normalVector );
1079 fB /= QVector2D::dotProduct( vector, normalVector );
1086 extension->UpdateBorder( annot.border, fB );
1094 pA = annot.position + fA * vector;
1095 pB = annot.position + fB * vector;
1099 pA = annot.position - fA * vector;
1100 pB = annot.position - fB * vector;
1104 pA = annot.position - fB * vector;
1105 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1107 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1113void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1123 QPen framePen = QPen( mGridFramePenColor );
1124 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1125 framePen.setCapStyle( Qt::SquareCap );
1126 p->setBrush( Qt::NoBrush );
1127 p->setPen( framePen );
1137 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1145 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1151 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1153 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1161 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1164 if ( ! extension && drawDiagonals )
1169 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1170 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1171 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1176 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1177 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1178 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1183 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1184 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1185 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1190 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1191 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1192 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1198 GridExtension *extension )
const
1200 QString currentAnnotationString;
1201 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1202 for ( ; it != mGridLines.constEnd(); ++it )
1204 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1205 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1206 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1210void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1217 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1227 : (
QgsTextRenderer::textHeight( context, mAnnotationFormat,
'0', false ) ) ) / context.convertToPainterUnits( 1,
Qgis::RenderUnit::Millimeters );
1229 double xpos = annot.position.x();
1230 double ypos = annot.position.y();
1231 QPointF anchor = QPointF();
1238 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1242 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1245 double f = mEvaluatedAnnotationFrameDistance;
1253 f += mEvaluatedGridFrameWidth;
1254 if ( hasBorderWidth )
1255 f += mEvaluatedGridFrameLineThickness / 2.0;
1260 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1262 f /= QVector2D::dotProduct( vector, normalVector );
1265 const QVector2D pos = annot.position + f * vector;
1278 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1280 if ( rotation <= -90 || rotation > 90 )
1283 anchor.setX( outside ? 0 : textWidth );
1287 anchor.setX( outside ? textWidth : 0 );
1291 anchor.setY( 0.5 * textHeight );
1293 anchor.setY( -1.5 * textHeight );
1295 anchor.setY( -0.5 * textHeight );
1301 anchor.setX( 0.5 * textWidth );
1302 anchor.setY( -0.5 * textHeight );
1304 anchor.setY( outside ? 0 : -textHeight );
1306 anchor.setX( outside ? 0 : textWidth );
1308 anchor.setY( outside ? -textHeight : 0 );
1310 anchor.setX( outside ? textWidth : 0 );
1315 anchor.setX( 0.5 * textWidth );
1316 anchor.setY( -0.5 * textHeight );
1318 anchor.setX( outside ? 0 : textWidth );
1320 anchor.setY( outside ? -textHeight : 0 );
1322 anchor.setX( outside ? textWidth : 0 );
1324 anchor.setY( outside ? 0 : -textHeight );
1329 anchor.setX( 0.5 * textWidth );
1330 anchor.setY( -0.5 * textHeight );
1332 anchor.setX( outside ? textWidth : 0 );
1334 anchor.setY( outside ? 0 : -textHeight );
1336 anchor.setX( outside ? 0 : textWidth );
1338 anchor.setY( outside ? -textHeight : 0 );
1343 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1344 anchor.setX( 0.5 * textWidth );
1346 anchor.setY( -textHeight );
1354 extension->UpdateBorder( frameBorder, -f + textWidth );
1356 extension->UpdateAll( textWidth / 2.0 );
1359 if ( extension || !context.
painter() )
1363 bool facingLeft = ( annot.angle < 0 );
1364 bool facingRight = ( annot.angle > 0 );
1367 facingLeft = !facingLeft;
1368 facingRight = !facingRight;
1370 if ( annot.border ==
BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1371 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1373 if ( annot.border ==
BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1374 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1376 if ( annot.border ==
BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1377 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1379 if ( annot.border ==
BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1380 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1384 context.
painter()->translate( QPointF( xpos, ypos ) );
1385 context.
painter()->rotate( rotation );
1386 context.
painter()->translate( -anchor );
1394 bool geographic =
false;
1408 const double wrappedX = std::fmod( value, 360.0 );
1409 if ( wrappedX > 180.0 )
1411 value = wrappedX - 360.0;
1413 else if ( wrappedX < -180.0 )
1415 value = wrappedX + 360.0;
1421 return QString::number( value,
'f', mGridAnnotationPrecision );
1427 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1431 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1433 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1439 if ( !geographic || coordRounded != 0.0 )
1441 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1447 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1451 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1458 if ( !mGridAnnotationExpression )
1460 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1461 mGridAnnotationExpression->prepare( &expressionContext );
1463 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1468 switch ( mGridAnnotationFormat )
1518int QgsLayoutItemMapGrid::xGridLines()
const
1520 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1527 QRectF mapBoundingRect = mapPolygon.boundingRect();
1528 double gridIntervalY = mEvaluatedIntervalY;
1529 double gridOffsetY = mEvaluatedOffsetY;
1530 double annotationScale = 1.0;
1531 switch ( mGridUnit )
1536 mapBoundingRect =
mMap->rect();
1537 mapPolygon = QPolygonF(
mMap->rect() );
1538 if ( mGridUnit ==
CM )
1540 annotationScale = 0.1;
1541 gridIntervalY *= 10;
1553 const double roundCorrection = mapBoundingRect.top() > gridOffsetY ? 1.0 : 0.0;
1554 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1556 int gridLineCount = 0;
1561 double yCanvasCoord;
1562 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1564 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1566 newLine.coordinate = currentLevel * annotationScale;
1568 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1569 mGridLines.append( newLine );
1570 currentLevel += gridIntervalY;
1577 QVector<QLineF> borderLines;
1578 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1579 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1580 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1581 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1583 QVector<QPointF> intersectionList;
1585 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1587 intersectionList.clear();
1588 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1590 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1591 for ( ; it != borderLines.constEnd(); ++it )
1593 QPointF intersectionPoint;
1594 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1596 intersectionList.push_back( intersectionPoint );
1597 if ( intersectionList.size() >= 2 )
1604 if ( intersectionList.size() >= 2 )
1607 newLine.coordinate = currentLevel;
1610 mGridLines.append( newLine );
1613 currentLevel += gridIntervalY;
1620int QgsLayoutItemMapGrid::yGridLines()
const
1622 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1628 QRectF mapBoundingRect = mapPolygon.boundingRect();
1629 double gridIntervalX = mEvaluatedIntervalX;
1630 double gridOffsetX = mEvaluatedOffsetX;
1631 double annotationScale = 1.0;
1632 switch ( mGridUnit )
1637 mapBoundingRect =
mMap->rect();
1638 mapPolygon = QPolygonF(
mMap->rect() );
1639 if ( mGridUnit ==
CM )
1641 annotationScale = 0.1;
1642 gridIntervalX *= 10;
1654 const double roundCorrection = mapBoundingRect.left() > gridOffsetX ? 1.0 : 0.0;
1655 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1657 int gridLineCount = 0;
1661 double xCanvasCoord;
1662 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1664 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1667 newLine.coordinate = currentLevel * annotationScale;
1669 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1670 mGridLines.append( newLine );
1671 currentLevel += gridIntervalX;
1678 QVector<QLineF> borderLines;
1679 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1680 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1681 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1682 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1684 QVector<QPointF> intersectionList;
1686 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1688 intersectionList.clear();
1689 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1691 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1692 for ( ; it != borderLines.constEnd(); ++it )
1694 QPointF intersectionPoint;
1695 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1697 intersectionList.push_back( intersectionPoint );
1698 if ( intersectionList.size() >= 2 )
1705 if ( intersectionList.size() >= 2 )
1708 newLine.coordinate = currentLevel;
1711 mGridLines.append( newLine );
1714 currentLevel += gridIntervalX;
1722 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1727 const double roundCorrection = bbox.
yMaximum() > mEvaluatedOffsetY ? 1.0 : 0.0;
1728 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1730 const double minX = bbox.
xMinimum();
1731 const double maxX = bbox.
xMaximum();
1732 double step = ( maxX - minX ) / 20;
1734 bool crosses180 =
false;
1735 bool crossed180 =
false;
1740 step = ( maxX + 360.0 - minX ) / 20;
1746 int gridLineCount = 0;
1750 double currentX = minX;
1754 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1771 if ( crosses180 && currentX > 180.0 )
1779 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1780 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1781 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1783 if ( !( *lineIt ).isEmpty() )
1786 newLine.coordinate = currentLevel;
1788 newLine.line = QPolygonF( *lineIt );
1789 mGridLines.append( newLine );
1793 currentLevel -= mEvaluatedIntervalY;
1801 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1806 const double roundCorrection = bbox.
xMinimum() > mEvaluatedOffsetX ? 1.0 : 0.0;
1807 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1809 const double minY = bbox.
yMinimum();
1810 const double maxY = bbox.
yMaximum();
1811 const double step = ( maxY - minY ) / 20;
1816 bool crosses180 =
false;
1817 bool crossed180 =
false;
1824 int gridLineCount = 0;
1825 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1828 double currentY = minY;
1832 if ( currentY > maxY )
1852 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1853 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1854 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1856 if ( !( *lineIt ).isEmpty() )
1859 newLine.coordinate = currentLevel;
1861 newLine.line = QPolygonF( *lineIt );
1862 mGridLines.append( newLine );
1866 currentLevel += mEvaluatedIntervalX;
1867 if ( crosses180 && currentLevel > 180.0 )
1869 currentLevel -= 360.0;
1898 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1900 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1902 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1904 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1918 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1920 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1922 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1924 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
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;
1990double QgsLayoutItemMapGrid::mapWidth()
const
2001 return mapExtent.
width();
2021 QgsDebugError( QStringLiteral(
"An error occurred while calculating length" ) );
2027bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2029 return a.first < b.first;
2042 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2043 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2044 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2045 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2051 if ( p.x() <= tolerance )
2062 if ( p.y() <= tolerance )
2074 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2080 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2081 return distanceToSide.at( 0 ).second;
2086 mGridLineSymbol.reset( symbol );
2091 return mGridLineSymbol.get();
2096 return mGridLineSymbol.get();
2101 mGridMarkerSymbol.reset( symbol );
2106 return mGridMarkerSymbol.get();
2111 return mGridMarkerSymbol.get();
2116 mAnnotationFormat.
setFont( font );
2117 if ( font.pointSizeF() > 0 )
2119 mAnnotationFormat.
setSize( font.pointSizeF() );
2122 else if ( font.pixelSize() > 0 )
2124 mAnnotationFormat.
setSize( font.pixelSize() );
2131 return mAnnotationFormat.
toQFont();
2136 mAnnotationFormat.
setColor( color );
2141 return mAnnotationFormat.
color();
2149 mLeftGridAnnotationDisplay = display;
2152 mRightGridAnnotationDisplay = display;
2155 mTopGridAnnotationDisplay = display;
2158 mBottomGridAnnotationDisplay = display;
2162 refreshDataDefinedProperties();
2176 return mLeftGridAnnotationDisplay;
2178 return mRightGridAnnotationDisplay;
2180 return mTopGridAnnotationDisplay;
2182 return mBottomGridAnnotationDisplay;
2184 return mBottomGridAnnotationDisplay;
2191 double bottom = 0.0;
2194 return std::max( std::max( std::max( top, right ), bottom ), left );
2204 if ( !
mMap || !mEvaluatedEnabled )
2214 GridExtension extension;
2217 switch ( mGridUnit )
2224 drawGridCrsTransform( context, 0,
true );
2231 drawGridNoTransform( context, 0,
true );
2236 updateGridLinesAnnotationsPositions();
2240 drawGridFrame(
nullptr, &extension );
2243 if ( mShowGridAnnotation )
2248 top = extension.top;
2249 right = extension.right;
2250 bottom = extension.bottom;
2251 left = extension.left;
2257 refreshDataDefinedProperties();
2262 if ( unit == mGridUnit )
2267 mTransformDirty =
true;
2276 mGridIntervalX = interval;
2277 mTransformDirty =
true;
2278 refreshDataDefinedProperties();
2287 mGridIntervalY = interval;
2288 mTransformDirty =
true;
2289 refreshDataDefinedProperties();
2298 mGridOffsetX = offset;
2299 mTransformDirty =
true;
2300 refreshDataDefinedProperties();
2309 mGridOffsetY = offset;
2310 mTransformDirty =
true;
2311 refreshDataDefinedProperties();
2320 mMinimumIntervalWidth = minWidth;
2321 mTransformDirty =
true;
2322 refreshDataDefinedProperties();
2331 mMaximumIntervalWidth = maxWidth;
2332 mTransformDirty =
true;
2333 refreshDataDefinedProperties();
2338 if (
style == mGridStyle )
2343 mTransformDirty =
true;
2348 mCrossLength = length;
2349 refreshDataDefinedProperties();
2357 mLeftGridAnnotationDirection = direction;
2360 mRightGridAnnotationDirection = direction;
2363 mTopGridAnnotationDirection = direction;
2366 mBottomGridAnnotationDirection = direction;
2379 mGridFrameSides = flags;
2385 mGridFrameSides |= flag;
2387 mGridFrameSides &= ~flag;
2392 return mGridFrameSides;
2401 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2407 if ( mGridLineSymbol )
2413 if ( mGridMarkerSymbol )
2425 mTransformDirty =
true;
2426 refreshDataDefinedProperties();
2433 return mGridFrameSides.testFlag( flag );
2438 mGridFrameWidth = width;
2439 refreshDataDefinedProperties();
2444 mGridFrameMargin = margin;
2445 refreshDataDefinedProperties();
2450 mGridFramePenThickness = width;
2451 refreshDataDefinedProperties();
2456 mLeftGridAnnotationDirection = direction;
2457 mRightGridAnnotationDirection = direction;
2458 mTopGridAnnotationDirection = direction;
2459 mBottomGridAnnotationDirection = direction;
2467 mLeftGridAnnotationPosition = position;
2470 mRightGridAnnotationPosition = position;
2473 mTopGridAnnotationPosition = position;
2476 mBottomGridAnnotationPosition = position;
2492 return mLeftGridAnnotationPosition;
2494 return mRightGridAnnotationPosition;
2496 return mTopGridAnnotationPosition;
2498 return mBottomGridAnnotationPosition;
2500 return mLeftGridAnnotationPosition;
2505 mAnnotationFrameDistance = distance;
2506 refreshDataDefinedProperties();
2513 return mLeftGridAnnotationDirection;
2519 return mLeftGridAnnotationDirection;
2521 return mRightGridAnnotationDirection;
2523 return mTopGridAnnotationDirection;
2525 return mBottomGridAnnotationDirection;
2527 return mLeftGridAnnotationDirection;
2532 mGridAnnotationExpressionString = expression;
2533 mGridAnnotationExpression.reset();
2541 mLeftFrameDivisions = divisions;
2544 mRightFrameDivisions = divisions;
2547 mTopFrameDivisions = divisions;
2550 mBottomFrameDivisions = divisions;
2554 refreshDataDefinedProperties();
2567 return mLeftFrameDivisions;
2569 return mRightFrameDivisions;
2571 return mTopFrameDivisions;
2573 return mBottomFrameDivisions;
2575 return mLeftFrameDivisions;
2591 const QRectF mbr = mapPolygon.boundingRect();
2592 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2598 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2599 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2601 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2602 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2604 if ( lowerLeft.x() > upperRight.x() )
2631QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2639 QList<QPolygonF> trimmedLines;
2640 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2641 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2643 trimmedLines << ( *geomIt ).asQPolygonF();
2645 return trimmedLines;
2720 refreshDataDefinedProperties();
The Qgis class provides global constants for use throughout the application.
@ Millimeters
Millimeters.
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
@ Forward
Forward transform (from source to destination)
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Qgis::DistanceUnit mapUnits
Custom exception class for Coordinate Reference System related exceptions.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Qgis::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
A geometry is the spatial representation of a feature.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QList< QgsLayoutItemMapGrid * > asList() const
Returns a list of QgsLayoutItemMapGrids contained by the stack.
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void removeGrid(const QString &gridId)
Removes a grid with matching gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid...
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void addGrid(QgsLayoutItemMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
QgsLayoutItemMapGrid * grid(const QString &gridId) const
Returns a reference to a grid with matching gridId within the stack.
bool readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the item stack's state from a DOM document, where element is a DOM node corresponding to a 'Layo...
QgsLayoutItemMapGrid & operator[](int index)
Returns a reference to a grid at the specified index within the stack.
void moveGridUp(const QString &gridId)
Moves a grid with matching gridId up the stack, causing it to be rendered above other grids.
void moveGridDown(const QString &gridId)
Moves a grid with matching gridId down the stack, causing it to be rendered below other grids.
QgsLayoutItemMapGridStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGridStack, attached to the specified map.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
void setFrameSideFlags(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
QString annotationExpression() const
Returns the expression used for drawing grid annotations.
double rotatedTicksMarginToCorner() const
Gets the margin to corners (in canvas units) below which outwards facing ticks are not drawn.
GridStyle
Grid drawing style.
@ Markers
Draw markers at intersections of grid lines.
@ Cross
Draw line crosses at intersections of grid lines.
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
void setFrameFillColor2(const QColor &color)
Sets the second fill color used for the grid frame.
GridUnit
Unit for grid values.
@ CM
Grid units in centimeters.
@ MM
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnit
Grid units follow map units.
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ FrameTop
Top side of map.
@ FrameBottom
Bottom side of map.
@ FrameLeft
Left side of map.
@ FrameRight
Right side of map.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
void setAnnotationFormat(const AnnotationFormat format)
Sets the format for drawing grid annotations.
double frameWidth() const
Gets the grid frame width in layout units.
void draw(QPainter *painter) override
Draws the item on to a destination painter.
double crossLength() const
Retrieves the length (in layout units) of the cross segments drawn for the grid.
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
void setRotatedTicksMinimumAngle(const double angle)
Sets the minimum angle (in degrees) below which ticks are not drawn.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
QPainter::CompositionMode blendMode() const
Retrieves the blending mode used for drawing the grid.
void setAnnotationEnabled(const bool enabled)
Sets whether annotations should be shown for the grid.
QgsTextFormat annotationTextFormat() const
Returns the text format used when rendering grid annotations.
AnnotationFormat annotationFormat() const
Returns the format for drawing grid annotations.
double framePenSize() const
Retrieves the width of the stroke drawn in the grid frame.
void setFramePenColor(const QColor &color)
Sets the color of the stroke drawn in the grid frame.
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
void setRotatedTicksEnabled(const bool state)
Enable/disable ticks rotation for rotated or reprojected grids.
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
AnnotationPosition
Position for grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
TickLengthMode rotatedAnnotationsLengthMode() const
Returns the annotation length calculation mode.
double rotatedTicksMinimumAngle() const
Gets the minimum angle (in degrees) below which ticks are not drawn.
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
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.
double rotatedAnnotationsEnabled() const
Gets whether annotations rotation for rotated or reprojected grids is enabled.
void setRotatedTicksLengthMode(const TickLengthMode mode)
Sets the tick length calculation mode.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
DisplayMode
Display settings for grid annotations and frames.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
void crsChanged()
Emitted whenever the grid's CRS is changed.
void setRotatedAnnotationsMinimumAngle(const double angle)
Sets the minimum angle (in degrees) below which annotations are not drawn.
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
double rotatedAnnotationsMinimumAngle() const
Gets the minimum angle (in degrees) below which annotations are not drawn.
void setAnnotationTextFormat(const QgsTextFormat &format)
Sets the text format to use when rendering grid annotations.
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
~QgsLayoutItemMapGrid() override
void copyProperties(const QgsLayoutItemMapGrid *other)
Copies properties from specified map grid.
void setBlendMode(const QPainter::CompositionMode mode)
Sets the blending mode used for drawing the grid.
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
bool annotationEnabled() const
Returns whether annotations are shown for the grid.
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
void setFrameStyle(const FrameStyle style)
Sets the grid frame style.
QFlags< FrameSideFlag > FrameSideFlags
QColor framePenColor() const
Retrieves the color of the stroke drawn in the grid frame.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
FrameStyle frameStyle() const
Returns the grid frame style.
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
void setRotatedTicksMarginToCorner(const double margin)
Sets the margin to corners (in canvas units) below which outwards facing ticks are not drawn.
void setAnnotationPrecision(const int precision)
Sets the coordinate precision for grid annotations.
QColor frameFillColor2() const
Retrieves the second fill color for the grid frame.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
void setRotatedAnnotationsMarginToCorner(const double margin)
Sets the margin to corners (in canvas units) below which outwards facing annotations are not drawn.
double rotatedAnnotationsMarginToCorner() const
Gets the margin to corners (in canvas units) below which outwards facing annotations are not drawn.
void setRotatedAnnotationsLengthMode(const TickLengthMode mode)
Sets the annotation length calculation mode.
TickLengthMode
Tick length mode (useful for rotated grids)
@ OrthogonalTicks
Align ticks orthogonaly.
double offsetX() const
Returns the offset for grid lines in the x-direction.
AnnotationFormat
Format for displaying grid annotations.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ CustomFormat
Custom expression-based format.
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
AnnotationDirection
Direction of grid annotations.
@ OnTick
Draw annotations parallel to tick (on the line)
@ Horizontal
Draw annotations horizontally.
@ Vertical
Draw annotations vertically, ascending.
@ AboveTick
Draw annotations parallel to tick (above the line)
@ UnderTick
Draw annotations parallel to tick (under the line)
@ VerticalDescending
Draw annotations vertically, descending.
double annotationFrameDistance() const
Returns the distance between the map frame and annotations.
double intervalY() const
Returns the interval between grid lines in the y-direction.
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
double minimumIntervalWidth() const
Returns the minimum width (in millimeters) for grid segments.
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QColor frameFillColor1() const
Retrieves the first fill color for the grid frame.
void setRotatedAnnotationsEnabled(const bool state)
Enable/disable annotations rotation for rotated or reprojected grids.
FrameStyle
Style for grid frame.
@ Zebra
Black/white pattern.
@ InteriorTicks
Tick markers drawn inside map frame.
@ LineBorder
Simple solid line frame.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ NoFrame
Disable grid frame.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
void setFrameFillColor1(const QColor &color)
Sets the first fill color used for the grid frame.
double frameMargin() const
Sets the grid frame Margin (in layout units).
double rotatedTicksEnabled() const
Gets whether ticks rotation for rotated or reprojected grids is enabled.
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
BorderSide
Border sides for annotations.
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
int annotationPrecision() const
Returns the coordinate precision for grid annotations, which is the number of decimal places shown wh...
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
double maximumIntervalWidth() const
Returns the maximum width (in millimeters) for grid segments.
void setAnnotationExpression(const QString &expression)
Sets the expression used for drawing grid annotations.
TickLengthMode rotatedTicksLengthMode() const
Returns the grid frame style.
double intervalX() const
Returns the interval between grid lines in the x-direction.
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
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
const QgsLayout * layout() const
Returns the layout the object is attached to.
QPointer< QgsLayout > mLayout
@ MapGridOffsetY
Map grid offset Y.
@ MapGridFrameDivisionsBottom
Map frame division display bottom.
@ MapGridEnabled
Map grid enabled.
@ MapGridIntervalX
Map grid interval X.
@ MapGridFrameDivisionsTop
Map frame division display top.
@ MapGridAnnotationDisplayLeft
Map annotation display left.
@ MapGridFrameMargin
Map grid frame margin.
@ MapGridCrossSize
Map grid cross size.
@ MapGridAnnotationDisplayRight
Map annotation display right.
@ MapGridOffsetX
Map grid offset X.
@ MapGridAnnotationDisplayTop
Map annotation display top.
@ MapGridAnnotationDisplayBottom
Map annotation display bottom.
@ MapGridFrameDivisionsRight
Map frame division display right.
@ MapGridLabelDistance
Map grid label distance.
@ MapGridIntervalY
Map grid interval Y.
@ MapGridFrameSize
Map grid frame size.
@ MapGridFrameLineThickness
Map grid frame line thickness.
@ MapGridFrameDivisionsLeft
Map frame division display left.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the objects's property collection, used for data defined overrides.
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.
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
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.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
A class to represent a 2D point.
bool isEmpty() const
Returns true if the geometry is empty.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Scoped object for saving and restoring a QPainter object's state.
Scoped object for temporary scaling of a QgsRenderContext for pixel based rendering.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
Handles rendering text using rich formatting options, including drop shadows, buffers and background ...
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
QgsLayoutItemMapGrid::DisplayMode gridAnnotationDisplayModeFromDD(QString ddValue, QgsLayoutItemMapGrid::DisplayMode defValue)
bool sortByDistance(QPair< qreal, QgsLayoutItemMapGrid::BorderSide > a, QPair< qreal, QgsLayoutItemMapGrid::BorderSide > b)
QVector2D borderToNormal2D(QgsLayoutItemMapGrid::BorderSide border)
QVector2D borderToVector2D(QgsLayoutItemMapGrid::BorderSide border)
#define QgsDebugError(str)
const QgsCoordinateReferenceSystem & crs
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to the style entity currently being visited.