49 #define MAX_GRID_LINES 1000
80 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
86 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
91 QList< QgsLayoutItemMapGrid * > list;
114 const QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
115 for (
int i = 0; i < mapGridNodeList.size(); ++i )
117 const QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
119 mapGrid->
readXml( mapGridElem, doc, context );
133 return std::max( std::max( std::max( top, right ), bottom ), left );
147 double gridTop = 0.0;
148 double gridRight = 0.0;
149 double gridBottom = 0.0;
150 double gridLeft = 0.0;
152 top = std::max( top, gridTop );
153 right = std::max( right, gridRight );
154 bottom = std::max( bottom, gridBottom );
155 left = std::max( left, gridLeft );
171 return QVector2D( 0, 1 );
173 return QVector2D( -1, 0 );
175 return QVector2D( 0, -1 );
177 return QVector2D( 1, 0 );
185 return QVector2D( borderVector.y(), -borderVector.x() );
195 const QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
196 if ( !defaultFontString.isEmpty() )
199 font.setFamily( defaultFontString );
200 mAnnotationFormat.
setFont( font );
203 createDefaultGridLineSymbol();
204 createDefaultGridMarkerSymbol();
217 void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
219 QVariantMap properties;
220 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
221 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
222 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
226 void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
228 QVariantMap properties;
229 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
230 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
231 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
237 if ( mGridLineSymbol )
239 mGridLineSymbol->setWidth( width );
245 if ( mGridLineSymbol )
247 mGridLineSymbol->setColor(
c );
258 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
259 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
260 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
261 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
262 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
263 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
264 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
266 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
268 lineStyleElem.appendChild( gridLineStyleElem );
269 mapGridElem.appendChild( lineStyleElem );
271 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
273 markerStyleElem.appendChild( gridMarkerStyleElem );
274 mapGridElem.appendChild( markerStyleElem );
276 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
277 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
278 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
279 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
280 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
284 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
285 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
286 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
287 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
288 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksLengthMode" ), mRotatedTicksLengthMode );
289 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksEnabled" ), mRotatedTicksEnabled );
290 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QString::number( mRotatedTicksMinimumAngle ) );
291 mapGridElem.setAttribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QString::number( mRotatedTicksMarginToCorner ) );
292 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), mRotatedAnnotationsLengthMode );
293 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), mRotatedAnnotationsEnabled );
294 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QString::number( mRotatedAnnotationsMinimumAngle ) );
295 mapGridElem.setAttribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QString::number( mRotatedAnnotationsMarginToCorner ) );
301 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
302 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
303 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
304 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
305 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
306 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
307 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
308 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
309 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
310 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
311 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
312 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
313 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
314 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
315 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
316 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
317 mapGridElem.appendChild( mAnnotationFormat.
writeXml( doc, context ) );
318 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
319 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
320 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
321 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
322 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
325 elem.appendChild( mapGridElem );
332 if ( itemElem.isNull() )
341 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
342 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
343 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
344 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
345 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
346 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
347 mGridFrameSides =
static_cast< QgsLayoutItemMapGrid::FrameSideFlags
>( itemElem.attribute( QStringLiteral(
"gridFrameSideFlags" ), QStringLiteral(
"15" ) ).toInt() );
348 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
349 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
350 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
358 mRotatedTicksLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedTicksLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
359 mRotatedTicksEnabled = itemElem.attribute( QStringLiteral(
"rotatedTicksEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
360 mRotatedTicksMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedTicksMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
361 mRotatedTicksMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedTicksMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
362 mRotatedAnnotationsLengthMode =
TickLengthMode( itemElem.attribute( QStringLiteral(
"rotatedAnnotationsLengthMode" ), QStringLiteral(
"0" ) ).toInt() );
363 mRotatedAnnotationsEnabled = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsEnabled" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" );
364 mRotatedAnnotationsMinimumAngle = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMinimumAngle" ), QStringLiteral(
"0" ) ).toDouble();
365 mRotatedAnnotationsMarginToCorner = itemElem.attribute( QStringLiteral(
"rotatedAnnotationsMarginToCorner" ), QStringLiteral(
"0" ) ).toDouble();
367 const QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
368 if ( !lineStyleElem.isNull() )
370 const QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
371 if ( !symbolElem.isNull() )
373 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
380 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
381 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
382 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
383 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
386 const QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
387 if ( !markerStyleElem.isNull() )
389 const QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
390 if ( !symbolElem.isNull() )
392 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
396 if ( !mCRS.
readXml( itemElem ) )
399 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
402 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
404 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
405 mGridAnnotationExpression.reset();
410 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
411 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
413 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
419 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
421 if ( !itemElem.firstChildElement(
"text-style" ).isNull() )
423 mAnnotationFormat.
readXml( itemElem, context );
430 font.fromString( itemElem.attribute(
"annotationFont", QString() ) );
432 mAnnotationFormat.
setFont( font );
433 mAnnotationFormat.
setSize( font.pointSizeF() );
438 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
439 const int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
441 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
442 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
444 refreshDataDefinedProperties();
454 mTransformDirty =
true;
460 return mBlendMode != QPainter::CompositionMode_SourceOver;
463 QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
465 const QTransform t = QTransform::fromScale( scale, scale );
466 return t.map( polygon );
469 void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
471 if ( !
mMap || !mEvaluatedEnabled )
478 if ( mapPolygon != mPrevMapPolygon )
480 mTransformDirty =
true;
481 mPrevMapPolygon = mapPolygon;
484 if ( mTransformDirty )
486 calculateCrsTransformLines();
490 if ( !calculateLinesOnly )
494 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
495 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
497 drawGridLine( scalePolygon( gridIt->line, dotsPerMM ), context );
502 const double maxX =
mMap->rect().width();
503 const double maxY =
mMap->rect().height();
505 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
506 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
508 const double x = intersectionIt->x();
509 const double y = intersectionIt->y();
513 const QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
514 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
515 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
516 const QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
517 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
518 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
521 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
522 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
526 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
533 void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
537 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
544 xGridLinesCrsTransform( crsBoundingRect, inverseTr );
545 yGridLinesCrsTransform( crsBoundingRect, inverseTr );
552 QList< QgsGeometry > xLines;
553 QList< QgsGeometry > yLines;
554 QList< GridLine >::const_iterator gridIt = mGridLines.constBegin();
555 for ( ; gridIt != mGridLines.constEnd(); ++gridIt )
559 for (
int i = 0; i < gridIt->line.size(); ++i )
561 line.append(
QgsPointXY( gridIt->line.at( i ).x(), gridIt->line.at( i ).y() ) );
563 if ( gridIt->coordinateType == AnnotationCoordinate::Longitude )
565 else if ( gridIt->coordinateType == AnnotationCoordinate::Latitude )
570 mTransformedIntersections.clear();
571 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
572 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
574 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
575 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
579 if ( intersects.
isNull() )
587 mTransformedIntersections << vertex;
595 mTransformDirty =
false;
600 if ( !
mMap || !mEvaluatedEnabled )
604 QPaintDevice *paintDevice = p->device();
611 p->setCompositionMode( mBlendMode );
614 const QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
615 p->setClipRect( thisPaintRect );
616 if ( thisPaintRect != mPrevPaintRect )
619 mTransformDirty =
true;
620 mPrevPaintRect = thisPaintRect;
624 const double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
625 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
641 drawGridCrsTransform( context, dotsPerMM );
648 drawGridNoTransform( context, dotsPerMM );
653 p->setClipping(
false );
657 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
662 updateGridLinesAnnotationsPositions();
669 if ( mShowGridAnnotation )
675 void QgsLayoutItemMapGrid::updateGridLinesAnnotationsPositions()
const
677 QList< GridLine >::iterator it = mGridLines.begin();
678 for ( ; it != mGridLines.end(); ++it )
680 it->startAnnotation.border = borderForLineCoord( it->line.first(), it->coordinateType );
681 it->endAnnotation.border = borderForLineCoord( it->line.last(), it->coordinateType );
682 it->startAnnotation.position = QVector2D( it->line.first() );
683 it->endAnnotation.position = QVector2D( it->line.last() );
684 it->startAnnotation.vector = QVector2D( it->line.at( 1 ) - it->line.first() ).normalized();
685 it->endAnnotation.vector = QVector2D( it->line.at( it->line.count() - 2 ) - it->line.last() ).normalized();
687 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() );
689 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() );
693 void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM,
bool calculateLinesOnly )
const
700 if ( calculateLinesOnly )
703 QList< GridLine >::const_iterator vIt = mGridLines.constBegin();
704 QList< GridLine >::const_iterator hIt = mGridLines.constBegin();
712 for ( ; vIt != mGridLines.constEnd(); ++vIt )
714 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
716 line = QLineF( vIt->line.first() * dotsPerMM, vIt->line.last() * dotsPerMM );
717 drawGridLine( line, context );
720 for ( ; hIt != mGridLines.constEnd(); ++hIt )
722 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
724 line = QLineF( hIt->line.first() * dotsPerMM, hIt->line.last() * dotsPerMM );
725 drawGridLine( line, context );
731 QPointF intersectionPoint, crossEnd1, crossEnd2;
732 for ( ; vIt != mGridLines.constEnd(); ++vIt )
734 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
737 l1 = QLineF( vIt->line.first(), vIt->line.last() );
740 hIt = mGridLines.constBegin();
741 for ( ; hIt != mGridLines.constEnd(); ++hIt )
743 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
746 l2 = QLineF( hIt->line.first(), hIt->line.last() );
748 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
749 if ( l2.intersect( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
751 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
757 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
759 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
762 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
766 drawGridMarker( intersectionPoint * dotsPerMM, context );
778 hIt = mGridLines.constBegin();
779 for ( ; hIt != mGridLines.constEnd(); ++hIt )
781 if ( hIt->coordinateType != AnnotationCoordinate::Latitude )
784 l1 = QLineF( hIt->line.first(), hIt->line.last() );
786 vIt = mGridLines.constBegin();
787 for ( ; vIt != mGridLines.constEnd(); ++vIt )
789 if ( vIt->coordinateType != AnnotationCoordinate::Longitude )
792 l2 = QLineF( vIt->line.first(), vIt->line.last() );
794 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
795 if ( l2.intersect( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
797 if ( l2.intersects( l1, &intersectionPoint ) == QLineF::BoundedIntersection )
801 crossEnd1 = ( ( intersectionPoint - l1.p1() ).manhattanLength() > 0.01 ) ?
803 crossEnd2 = ( ( intersectionPoint - l1.p2() ).manhattanLength() > 0.01 ) ?
806 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
813 void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p, GridExtension *extension )
const
822 switch ( mGridFrameStyle )
826 drawGridFrameZebra( p, extension );
831 drawGridFrameTicks( p, extension );
836 drawGridFrameLine( p, extension );
847 void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
850 poly << line.p1() << line.p2();
851 drawGridLine( poly, context );
854 void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
861 mGridLineSymbol->startRender( context );
862 mGridLineSymbol->renderPolyline( line,
nullptr, context );
863 mGridLineSymbol->stopRender( context );
866 void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
873 mGridMarkerSymbol->startRender( context );
874 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
875 mGridMarkerSymbol->stopRender( context );
878 void QgsLayoutItemMapGrid::drawGridFrameZebra( QPainter *p, GridExtension *extension )
const
898 void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p, BorderSide border,
double *extension )
const
907 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
911 double currentCoord = 0.0;
918 bool drawTLBox =
false;
919 bool drawTRBox =
false;
920 bool drawBLBox =
false;
921 bool drawBRBox =
false;
923 QMap< double, double > pos = QMap< double, double >();
924 QList< GridLine >::const_iterator it = mGridLines.constBegin();
925 for ( ; it != mGridLines.constEnd(); ++it )
928 for (
int i = 0 ; i < 2 ; ++i )
930 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
933 if ( annot.border != border )
936 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
940 pos.insert( annot.position.y(), it->coordinate );
942 pos.insert( annot.position.x(), it->coordinate );
949 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
965 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
969 QPen framePen = QPen( mGridFramePenColor );
970 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
971 framePen.setJoinStyle( Qt::MiterJoin );
972 p->setPen( framePen );
974 QMap< double, double >::const_iterator posIt = pos.constBegin();
975 for ( ; posIt != pos.constEnd(); ++posIt )
977 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
980 height = posIt.key() - currentCoord;
981 width = mEvaluatedGridFrameWidth;
982 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
987 height = mEvaluatedGridFrameWidth;
988 width = posIt.key() - currentCoord;
990 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
992 p->drawRect( QRectF( x, y, width, height ) );
993 currentCoord = posIt.key();
1000 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
1001 p->setBrush( QBrush( mGridFrameFillColor1 ) );
1003 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1005 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
1007 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
1009 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
1013 void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p, GridExtension *extension )
const
1023 QPen framePen = QPen( mGridFramePenColor );
1024 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1025 framePen.setCapStyle( Qt::FlatCap );
1026 p->setBrush( Qt::NoBrush );
1027 p->setPen( framePen );
1030 QList< GridLine >::iterator it = mGridLines.begin();
1031 for ( ; it != mGridLines.end(); ++it )
1034 for (
int i = 0 ; i < 2 ; ++i )
1036 const GridLineAnnotation annot = ( i == 0 ) ? it->startAnnotation : it->endAnnotation;
1038 if ( ! shouldShowDivisionForSide( it->coordinateType, annot.border ) )
1042 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedTicksMinimumAngle + 0.0001 )
1050 facingLeft = ( annot.angle != 0 );
1051 facingRight = ( annot.angle != 0 );
1055 facingLeft = ( annot.angle > 0 );
1056 facingRight = ( annot.angle < 0 );
1060 facingLeft = ( annot.angle < 0 );
1061 facingRight = ( annot.angle > 0 );
1064 if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedTicksMarginToCorner ) ||
1065 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ) )
1067 if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedTicksMarginToCorner ) ||
1068 ( facingRight && annot.position.x() < mRotatedTicksMarginToCorner ) ) )
1070 if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ||
1071 ( facingRight && annot.position.y() < mRotatedTicksMarginToCorner ) ) )
1073 if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedTicksMarginToCorner ) ||
1074 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedTicksMarginToCorner ) ) )
1078 const QVector2D vector = ( mRotatedTicksEnabled ) ? annot.vector : normalVector;
1080 double fA = mEvaluatedGridFrameMargin;
1081 double fB = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
1083 if ( mRotatedTicksEnabled && mRotatedTicksLengthMode ==
OrthogonalTicks )
1085 fA /= QVector2D::dotProduct( vector, normalVector );
1086 fB /= QVector2D::dotProduct( vector, normalVector );
1093 extension->UpdateBorder( annot.border, fB );
1101 pA = annot.position + fA * vector;
1102 pB = annot.position + fB * vector;
1106 pA = annot.position - fA * vector;
1107 pB = annot.position - fB * vector;
1111 pA = annot.position - fB * vector;
1112 pB = annot.position + ( fB - 2.0 * mEvaluatedGridFrameMargin ) * vector;
1114 p->drawLine( QLineF( pA.toPointF(), pB.toPointF() ) );
1120 void QgsLayoutItemMapGrid::drawGridFrameLine( QPainter *p, GridExtension *extension )
const
1130 QPen framePen = QPen( mGridFramePenColor );
1131 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
1132 framePen.setCapStyle( Qt::SquareCap );
1133 p->setBrush( Qt::NoBrush );
1134 p->setPen( framePen );
1144 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1152 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1158 extension->UpdateBorder(
QgsLayoutItemMapGrid::Top, mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 );
1160 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1168 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1171 if ( ! extension && drawDiagonals )
1176 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1177 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1178 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1183 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1184 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1185 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1190 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1191 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1192 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1197 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1198 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1199 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1205 GridExtension *extension )
const
1207 QString currentAnnotationString;
1208 QList< GridLine >::const_iterator it = mGridLines.constBegin();
1209 for ( ; it != mGridLines.constEnd(); ++it )
1211 currentAnnotationString = gridAnnotationString( it->coordinate, it->coordinateType, expressionContext );
1212 drawCoordinateAnnotation( context, it->startAnnotation, currentAnnotationString, it->coordinateType, extension );
1213 drawCoordinateAnnotation( context, it->endAnnotation, currentAnnotationString, it->coordinateType, extension );
1217 void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
QgsRenderContext &context, GridLineAnnotation annot,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1224 if ( ! shouldShowAnnotationForSide( coordinateType, annot.border ) )
1236 double xpos = annot.position.x();
1237 double ypos = annot.position.y();
1238 QPointF anchor = QPointF();
1245 if ( abs( annot.angle ) / M_PI * 180.0 > 90.0 - mRotatedAnnotationsMinimumAngle + 0.0001 )
1249 const QVector2D vector = ( mRotatedAnnotationsEnabled ) ? annot.vector : normalVector;
1252 double f = mEvaluatedAnnotationFrameDistance;
1260 f += mEvaluatedGridFrameWidth;
1261 if ( hasBorderWidth )
1262 f += mEvaluatedGridFrameLineThickness / 2.0;
1267 if ( mRotatedAnnotationsEnabled && mRotatedAnnotationsLengthMode ==
OrthogonalTicks )
1269 f /= QVector2D::dotProduct( vector, normalVector );
1272 const QVector2D pos = annot.position + f * vector;
1285 rotation = atan2( vector.y(), vector.x() ) / M_PI * 180;
1287 if ( rotation <= -90 || rotation > 90 )
1290 anchor.setX( outside ? 0 : textWidth );
1294 anchor.setX( outside ? textWidth : 0 );
1298 anchor.setY( 0.5 * textHeight );
1300 anchor.setY( -1.5 * textHeight );
1302 anchor.setY( -0.5 * textHeight );
1308 anchor.setX( 0.5 * textWidth );
1309 anchor.setY( -0.5 * textHeight );
1311 anchor.setY( outside ? 0 : -textHeight );
1313 anchor.setX( outside ? 0 : textWidth );
1315 anchor.setY( outside ? -textHeight : 0 );
1317 anchor.setX( outside ? textWidth : 0 );
1322 anchor.setX( 0.5 * textWidth );
1323 anchor.setY( -0.5 * textHeight );
1325 anchor.setX( outside ? 0 : textWidth );
1327 anchor.setY( outside ? -textHeight : 0 );
1329 anchor.setX( outside ? textWidth : 0 );
1331 anchor.setY( outside ? 0 : -textHeight );
1336 anchor.setX( 0.5 * textWidth );
1337 anchor.setY( -0.5 * textHeight );
1339 anchor.setX( outside ? textWidth : 0 );
1341 anchor.setY( outside ? 0 : -textHeight );
1343 anchor.setX( outside ? 0 : textWidth );
1345 anchor.setY( outside ? -textHeight : 0 );
1350 rotation = atan2( borderVector.y(), borderVector.x() ) / M_PI * 180;
1351 anchor.setX( 0.5 * textWidth );
1353 anchor.setY( -textHeight );
1361 extension->UpdateBorder( frameBorder, -f + textWidth );
1363 extension->UpdateAll( textWidth / 2.0 );
1366 if ( extension || !context.
painter() )
1370 bool facingLeft = ( annot.angle < 0 );
1371 bool facingRight = ( annot.angle > 0 );
1374 facingLeft = !facingLeft;
1375 facingRight = !facingRight;
1377 if ( annot.border == BorderSide::Top && ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ||
1378 ( facingRight && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
1380 if ( annot.border == BorderSide::Bottom && ( ( facingLeft && annot.position.x() >
mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ||
1381 ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
1383 if ( annot.border == BorderSide::Left && ( ( facingLeft && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ||
1384 ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
1386 if ( annot.border == BorderSide::Right && ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ||
1387 ( facingRight && annot.position.y() >
mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
1391 context.
painter()->translate( QPointF( xpos, ypos ) );
1392 context.
painter()->rotate( rotation );
1393 context.
painter()->translate( -anchor );
1401 bool geographic =
false;
1415 const double wrappedX = std::fmod( value, 360.0 );
1416 if ( wrappedX > 180.0 )
1418 value = wrappedX - 360.0;
1420 else if ( wrappedX < -180.0 )
1422 value = wrappedX + 360.0;
1428 return QString::number( value,
'f', mGridAnnotationPrecision );
1434 const double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1438 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1440 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1446 if ( !geographic || coordRounded != 0.0 )
1448 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1454 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1458 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1465 if ( !mGridAnnotationExpression )
1467 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1468 mGridAnnotationExpression->prepare( &expressionContext );
1470 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1474 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
1475 switch ( mGridAnnotationFormat )
1494 flags = QgsCoordinateFormatter::FormatFlags();
1504 flags = QgsCoordinateFormatter::FormatFlags();
1525 int QgsLayoutItemMapGrid::xGridLines()
const
1527 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1534 QRectF mapBoundingRect = mapPolygon.boundingRect();
1535 double gridIntervalY = mEvaluatedIntervalY;
1536 double gridOffsetY = mEvaluatedOffsetY;
1537 double annotationScale = 1.0;
1538 switch ( mGridUnit )
1543 mapBoundingRect =
mMap->rect();
1544 mapPolygon = QPolygonF(
mMap->rect() );
1545 if ( mGridUnit ==
CM )
1547 annotationScale = 0.1;
1548 gridIntervalY *= 10;
1560 const double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1561 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1563 int gridLineCount = 0;
1568 double yCanvasCoord;
1569 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1571 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1573 newLine.coordinate = currentLevel * annotationScale;
1574 newLine.coordinateType = AnnotationCoordinate::Latitude;
1575 newLine.line = QPolygonF() << QPointF( 0, yCanvasCoord ) << QPointF(
mMap->rect().width(), yCanvasCoord );
1576 mGridLines.append( newLine );
1577 currentLevel += gridIntervalY;
1584 QVector<QLineF> borderLines;
1585 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1586 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1587 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1588 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1590 QVector<QPointF> intersectionList;
1592 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1594 intersectionList.clear();
1595 const QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1597 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1598 for ( ; it != borderLines.constEnd(); ++it )
1600 QPointF intersectionPoint;
1601 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
1602 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1604 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1607 intersectionList.push_back( intersectionPoint );
1608 if ( intersectionList.size() >= 2 )
1615 if ( intersectionList.size() >= 2 )
1618 newLine.coordinate = currentLevel;
1619 newLine.coordinateType = AnnotationCoordinate::Latitude;
1621 mGridLines.append( newLine );
1624 currentLevel += gridIntervalY;
1631 int QgsLayoutItemMapGrid::yGridLines()
const
1633 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1639 QRectF mapBoundingRect = mapPolygon.boundingRect();
1640 double gridIntervalX = mEvaluatedIntervalX;
1641 double gridOffsetX = mEvaluatedOffsetX;
1642 double annotationScale = 1.0;
1643 switch ( mGridUnit )
1648 mapBoundingRect =
mMap->rect();
1649 mapPolygon = QPolygonF(
mMap->rect() );
1650 if ( mGridUnit ==
CM )
1652 annotationScale = 0.1;
1653 gridIntervalX *= 10;
1665 const double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1666 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1668 int gridLineCount = 0;
1672 double xCanvasCoord;
1673 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1675 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1678 newLine.coordinate = currentLevel * annotationScale;
1679 newLine.coordinateType = AnnotationCoordinate::Longitude;
1680 newLine.line = QPolygonF() << QPointF( xCanvasCoord, 0 ) << QPointF( xCanvasCoord,
mMap->rect().height() );
1681 mGridLines.append( newLine );
1682 currentLevel += gridIntervalX;
1689 QVector<QLineF> borderLines;
1690 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1691 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1692 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1693 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1695 QVector<QPointF> intersectionList;
1697 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1699 intersectionList.clear();
1700 const QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1702 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1703 for ( ; it != borderLines.constEnd(); ++it )
1705 QPointF intersectionPoint;
1706 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
1707 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1709 if ( it->intersects( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1712 intersectionList.push_back( intersectionPoint );
1713 if ( intersectionList.size() >= 2 )
1720 if ( intersectionList.size() >= 2 )
1723 newLine.coordinate = currentLevel;
1724 newLine.coordinateType = AnnotationCoordinate::Longitude;
1726 mGridLines.append( newLine );
1729 currentLevel += gridIntervalX;
1737 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1742 const double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1743 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1745 const double minX = bbox.
xMinimum();
1746 const double maxX = bbox.
xMaximum();
1747 double step = ( maxX - minX ) / 20;
1749 bool crosses180 =
false;
1750 bool crossed180 =
false;
1755 step = ( maxX + 360.0 - minX ) / 20;
1761 int gridLineCount = 0;
1765 double currentX = minX;
1769 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1782 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1786 if ( crosses180 && currentX > 180.0 )
1794 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1795 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1796 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1798 if ( !( *lineIt ).isEmpty() )
1801 newLine.coordinate = currentLevel;
1802 newLine.coordinateType = AnnotationCoordinate::Latitude;
1803 newLine.line = QPolygonF( *lineIt );
1804 mGridLines.append( newLine );
1808 currentLevel -= mEvaluatedIntervalY;
1816 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1821 const double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1822 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1824 const double minY = bbox.
yMinimum();
1825 const double maxY = bbox.
yMaximum();
1826 const double step = ( maxY - minY ) / 20;
1831 bool crosses180 =
false;
1832 bool crossed180 =
false;
1839 int gridLineCount = 0;
1840 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1843 double currentY = minY;
1847 if ( currentY > maxY )
1861 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1867 const QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1868 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1869 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1871 if ( !( *lineIt ).isEmpty() )
1874 newLine.coordinate = currentLevel;
1875 newLine.coordinateType = AnnotationCoordinate::Longitude;
1876 newLine.line = QPolygonF( *lineIt );
1877 mGridLines.append( newLine );
1881 currentLevel += mEvaluatedIntervalX;
1882 if ( crosses180 && currentLevel > 180.0 )
1884 currentLevel -= 360.0;
1913 return shouldShowForDisplayMode( coordinate, mEvaluatedLeftGridAnnotationDisplay );
1915 return shouldShowForDisplayMode( coordinate, mEvaluatedRightGridAnnotationDisplay );
1917 return shouldShowForDisplayMode( coordinate, mEvaluatedTopGridAnnotationDisplay );
1919 return shouldShowForDisplayMode( coordinate, mEvaluatedBottomGridAnnotationDisplay );
1934 if ( ddValue.compare( QLatin1String(
"x_only" ), Qt::CaseInsensitive ) == 0 )
1936 else if ( ddValue.compare( QLatin1String(
"y_only" ), Qt::CaseInsensitive ) == 0 )
1938 else if ( ddValue.compare( QLatin1String(
"disabled" ), Qt::CaseInsensitive ) == 0 )
1940 else if ( ddValue.compare( QLatin1String(
"all" ), Qt::CaseInsensitive ) == 0 )
1947 void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1952 mTransformDirty = mTransformDirty
1959 switch ( mGridUnit )
1972 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1974 mEvaluatedEnabled =
false;
1979 const double mapWidthMapUnits = mapWidth();
1980 const double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1981 const double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1983 mEvaluatedIntervalX = interval;
1984 mEvaluatedIntervalY = interval;
1985 mTransformDirty =
true;
2008 double QgsLayoutItemMapGrid::mapWidth()
const
2019 return mapExtent.
width();
2036 bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2038 return a.first < b.first;
2051 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2052 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2053 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2054 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2060 if ( p.x() <= tolerance )
2071 if ( p.y() <= tolerance )
2083 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2089 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2090 return distanceToSide.at( 0 ).second;
2095 mGridLineSymbol.reset( symbol );
2100 return mGridLineSymbol.get();
2105 return mGridLineSymbol.get();
2110 mGridMarkerSymbol.reset( symbol );
2115 return mGridMarkerSymbol.get();
2120 return mGridMarkerSymbol.get();
2125 mAnnotationFormat.
setFont( font );
2126 if ( font.pointSizeF() > 0 )
2128 mAnnotationFormat.
setSize( font.pointSizeF() );
2131 else if ( font.pixelSize() > 0 )
2133 mAnnotationFormat.
setSize( font.pixelSize() );
2140 return mAnnotationFormat.
toQFont();
2145 mAnnotationFormat.
setColor( color );
2150 return mAnnotationFormat.
color();
2158 mLeftGridAnnotationDisplay = display;
2161 mRightGridAnnotationDisplay = display;
2164 mTopGridAnnotationDisplay = display;
2167 mBottomGridAnnotationDisplay = display;
2171 refreshDataDefinedProperties();
2185 return mLeftGridAnnotationDisplay;
2187 return mRightGridAnnotationDisplay;
2189 return mTopGridAnnotationDisplay;
2191 return mBottomGridAnnotationDisplay;
2193 return mBottomGridAnnotationDisplay;
2200 double bottom = 0.0;
2203 return std::max( std::max( std::max( top, right ), bottom ), left );
2213 if ( !
mMap || !mEvaluatedEnabled )
2223 GridExtension extension;
2226 switch ( mGridUnit )
2233 drawGridCrsTransform( context, 0,
true );
2240 drawGridNoTransform( context, 0,
true );
2245 updateGridLinesAnnotationsPositions();
2249 drawGridFrame(
nullptr, &extension );
2252 if ( mShowGridAnnotation )
2257 top = extension.top;
2258 right = extension.right;
2259 bottom = extension.bottom;
2260 left = extension.left;
2266 refreshDataDefinedProperties();
2271 if ( unit == mGridUnit )
2276 mTransformDirty =
true;
2285 mGridIntervalX = interval;
2286 mTransformDirty =
true;
2287 refreshDataDefinedProperties();
2296 mGridIntervalY = interval;
2297 mTransformDirty =
true;
2298 refreshDataDefinedProperties();
2307 mGridOffsetX = offset;
2308 mTransformDirty =
true;
2309 refreshDataDefinedProperties();
2318 mGridOffsetY = offset;
2319 mTransformDirty =
true;
2320 refreshDataDefinedProperties();
2329 mMinimumIntervalWidth = minWidth;
2330 mTransformDirty =
true;
2331 refreshDataDefinedProperties();
2340 mMaximumIntervalWidth = maxWidth;
2341 mTransformDirty =
true;
2342 refreshDataDefinedProperties();
2347 if (
style == mGridStyle )
2352 mTransformDirty =
true;
2357 mCrossLength = length;
2358 refreshDataDefinedProperties();
2366 mLeftGridAnnotationDirection = direction;
2369 mRightGridAnnotationDirection = direction;
2372 mTopGridAnnotationDirection = direction;
2375 mBottomGridAnnotationDirection = direction;
2388 mGridFrameSides = flags;
2394 mGridFrameSides |= flag;
2396 mGridFrameSides &= ~flag;
2401 return mGridFrameSides;
2410 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2416 if ( mGridLineSymbol )
2422 if ( mGridMarkerSymbol )
2434 mTransformDirty =
true;
2435 refreshDataDefinedProperties();
2442 return mGridFrameSides.testFlag( flag );
2447 mGridFrameWidth = width;
2448 refreshDataDefinedProperties();
2453 mGridFrameMargin = margin;
2454 refreshDataDefinedProperties();
2459 mGridFramePenThickness = width;
2460 refreshDataDefinedProperties();
2465 mLeftGridAnnotationDirection = direction;
2466 mRightGridAnnotationDirection = direction;
2467 mTopGridAnnotationDirection = direction;
2468 mBottomGridAnnotationDirection = direction;
2476 mLeftGridAnnotationPosition = position;
2479 mRightGridAnnotationPosition = position;
2482 mTopGridAnnotationPosition = position;
2485 mBottomGridAnnotationPosition = position;
2501 return mLeftGridAnnotationPosition;
2503 return mRightGridAnnotationPosition;
2505 return mTopGridAnnotationPosition;
2507 return mBottomGridAnnotationPosition;
2509 return mLeftGridAnnotationPosition;
2514 mAnnotationFrameDistance = distance;
2515 refreshDataDefinedProperties();
2522 return mLeftGridAnnotationDirection;
2528 return mLeftGridAnnotationDirection;
2530 return mRightGridAnnotationDirection;
2532 return mTopGridAnnotationDirection;
2534 return mBottomGridAnnotationDirection;
2536 return mLeftGridAnnotationDirection;
2544 mLeftFrameDivisions = divisions;
2547 mRightFrameDivisions = divisions;
2550 mTopFrameDivisions = divisions;
2553 mBottomFrameDivisions = divisions;
2557 refreshDataDefinedProperties();
2570 return mLeftFrameDivisions;
2572 return mRightFrameDivisions;
2574 return mTopFrameDivisions;
2576 return mBottomFrameDivisions;
2578 return mLeftFrameDivisions;
2594 const QRectF mbr = mapPolygon.boundingRect();
2595 const QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2601 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2602 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2604 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2605 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2607 if ( lowerLeft.x() > upperRight.x() )
2610 crsRect = extentTransform.
transformBoundingBox( mapBoundingRect, Qgis::TransformDirection::Forward,
true );
2628 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
2634 QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2642 QList<QPolygonF> trimmedLines;
2643 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2644 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2646 trimmedLines << ( *geomIt ).asQPolygonF();
2648 return trimmedLines;
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Custom exception class for Coordinate Reference System related exceptions.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
QgsUnitTypes::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
A geometry is the spatial representation of a feature.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
QList< QgsLayoutItemMapGrid * > asList() const
Returns a list of QgsLayoutItemMapGrids contained by the stack.
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void removeGrid(const QString &gridId)
Removes a grid with matching gridId from the stack and deletes the corresponding QgsLayoutItemMapGrid...
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsLayoutItemMap's item rect...
void addGrid(QgsLayoutItemMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
QgsLayoutItemMapGrid * grid(const QString &gridId) const
Returns a reference to a grid with matching gridId within the stack.
bool readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the item stack's state from a DOM document, where element is a DOM node corresponding to a 'Layo...
QgsLayoutItemMapGrid & operator[](int index)
Returns a reference to a grid at the specified index within the stack.
void moveGridUp(const QString &gridId)
Moves a grid with matching gridId up the stack, causing it to be rendered above other grids.
void moveGridDown(const QString &gridId)
Moves a grid with matching gridId down the stack, causing it to be rendered below other grids.
QgsLayoutItemMapGridStack(QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGridStack, attached to the specified map.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
void setFrameSideFlags(QgsLayoutItemMapGrid::FrameSideFlags flags)
Sets flags for grid frame sides.
GridStyle
Grid drawing style.
@ Markers
Draw markers at intersections of grid lines.
@ Cross
Draw line crosses at intersections of grid lines.
@ FrameAnnotationsOnly
No grid lines over the map, only draw frame and annotations.
void calculateMaxExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect.
GridUnit
Unit for grid values.
@ CM
Grid units in centimeters.
@ MM
Grid units in millimeters.
@ DynamicPageSizeBased
Dynamically sized, based on a on-page size range.
@ MapUnit
Grid units follow map units.
bool writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
void refresh() override
Refreshes the object, causing a recalculation of any property overrides.
GridStyle style() const
Returns the grid's style, which controls how the grid is drawn over the map's contents.
void setFrameSideFlag(QgsLayoutItemMapGrid::FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
@ FrameTop
Top side of map.
@ FrameBottom
Bottom side of map.
@ FrameLeft
Left side of map.
@ FrameRight
Right side of map.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
void draw(QPainter *painter) override
Draws the item on to a destination painter.
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Returns the font color used for drawing grid annotations.
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void setAnnotationDisplay(DisplayMode display, BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame,...
Q_DECL_DEPRECATED QFont annotationFont() const
Returns the font used for drawing grid annotations.
double maxExtension() const
Calculates the maximum distance the grid extends beyond the QgsLayoutItemMap's item rect (in layout u...
AnnotationPosition
Position for grid annotations.
@ InsideMapFrame
Draw annotations inside the map frame.
@ OutsideMapFrame
Draw annotations outside the map frame.
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
AnnotationPosition annotationPosition(BorderSide side) const
Returns the position for the grid annotations on a specified side of the map frame.
void setUnits(GridUnit unit)
Sets the unit to use for grid measurements such as the interval and offset for grid lines.
QgsLayoutItemMapGrid::FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
bool testFrameSideFlag(FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item.
void setFrameDivisions(DisplayMode divisions, BorderSide side)
Sets what type of grid divisions should be used for frames on a specified side of the map.
void setMinimumIntervalWidth(double width)
Sets the minimum width (in millimeters) for grid segments.
AnnotationCoordinate
Annotation coordinate type.
@ Latitude
Coordinate is a latitude value.
@ Longitude
Coordinate is a longitude value.
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
DisplayMode
Display settings for grid annotations and frames.
@ LongitudeOnly
Show longitude/x annotations/divisions only.
@ ShowAll
Show both latitude and longitude annotations/divisions.
@ LatitudeOnly
Show latitude/y annotations/divisions only.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
void crsChanged()
Emitted whenever the grid's CRS is changed.
void setFrameMargin(const double margin)
Sets the grid frame margin (in layout units).
QgsLayoutItemMapGrid(const QString &name, QgsLayoutItemMap *map)
Constructor for QgsLayoutItemMapGrid.
~QgsLayoutItemMapGrid() override
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the marker symbol used for drawing grid points.
void setMaximumIntervalWidth(double width)
Sets the maximum width (in millimeters) for grid segments.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
Q_DECL_DEPRECATED void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
TickLengthMode
Tick length mode (useful for rotated grids)
@ OrthogonalTicks
Align ticks orthogonaly.
AnnotationFormat
Format for displaying grid annotations.
@ DegreeMinuteSecondNoSuffix
Degree/minutes/seconds, use - for S/W coordinates.
@ DegreeMinuteSecondPadded
Degree/minutes/seconds, with minutes using leading zeros where required.
@ DegreeMinuteSecond
Degree/minutes/seconds, use NSEW suffix.
@ DecimalWithSuffix
Decimal degrees, use NSEW suffix.
@ DegreeMinute
Degree/minutes, use NSEW suffix.
@ DegreeMinuteNoSuffix
Degree/minutes, use - for S/W coordinates.
@ Decimal
Decimal degrees, use - for S/W coordinates.
@ DegreeMinutePadded
Degree/minutes, with minutes using leading zeros where required.
@ CustomFormat
Custom expression-based format.
DisplayMode frameDivisions(BorderSide side) const
Returns the type of grid divisions which are used for frames on a specified side of the map.
AnnotationDirection
Direction of grid annotations.
@ OnTick
Draw annotations parallel to tick (on the line)
@ Horizontal
Draw annotations horizontally.
@ Vertical
Draw annotations vertically, ascending.
@ AboveTick
Draw annotations parallel to tick (above the line)
@ UnderTick
Draw annotations parallel to tick (under the line)
@ VerticalDescending
Draw annotations vertically, descending.
GridUnit units() const
Returns the units used for grid measurements such as the interval and offset for grid lines.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs for the grid.
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
const QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol used for drawing grid points.
const QgsLineSymbol * lineSymbol() const
Returns the line symbol used for drawing grid lines.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
FrameStyle
Style for grid frame.
@ Zebra
Black/white pattern.
@ InteriorTicks
Tick markers drawn inside map frame.
@ LineBorder
Simple solid line frame.
@ InteriorExteriorTicks
Tick markers drawn both inside and outside the map frame.
@ LineBorderNautical
Simple solid line frame, with nautical style diagonals on corners.
@ ExteriorTicks
Tick markers drawn outside map frame.
@ NoFrame
Disable grid frame.
@ ZebraNautical
Black/white pattern, with nautical style diagonals on corners.
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
DisplayMode annotationDisplay(BorderSide border) const
Returns the display mode for the grid annotations on a specified side of the map frame.
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
BorderSide
Border sides for annotations.
AnnotationDirection annotationDirection(BorderSide border) const
Returns the direction for drawing frame annotations, on the specified side of the map.
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
void setGridLineColor(const QColor &color)
Sets the color of grid lines.
void setGridLineWidth(double width)
Sets the width of grid lines (in layout units).
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
A collection of map items which are drawn above the map content in a QgsLayoutItemMap.
void addItem(QgsLayoutItemMapItem *item)
Adds a new map item to the stack and takes ownership of the item.
void removeItem(const QString &itemId)
Removes an item which matching itemId from the stack and deletes the corresponding QgsLayoutItemMapIt...
QgsLayoutItemMapItem * item(int index) const
Returns a reference to the item at the specified index within the stack.
void moveItemUp(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
void removeItems()
Clears the item stack and deletes all QgsLayoutItemMapItems contained by the stack.
QList< QgsLayoutItemMapItem * > mItems
void moveItemDown(const QString &itemId)
Moves an item which matching itemId up the stack, causing it to be rendered above other items.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
QgsLayoutItemMap * mMap
Associated map.
virtual bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the map item state from a DOM document, where element is the DOM node corresponding to a 'Layout...
virtual bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores map item state in a DOM element, where element is the DOM element corresponding to a 'LayoutMa...
virtual void setEnabled(bool enabled)
Controls whether the item will be drawn.
bool enabled() const
Returns whether the item will be drawn.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
QgsRectangle extent() const
Returns the current map extent.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
bool frameEnabled() const
Returns true if the item includes a frame.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
QPointer< QgsLayout > mLayout
@ MapGridIntervalX
Map grid interval X.
@ MapGridAnnotationDisplayBottom
Map annotation display bottom.
@ MapGridIntervalY
Map grid interval Y.
@ MapGridFrameSize
Map grid frame size.
@ MapGridFrameDivisionsBottom
Map frame division display bottom.
@ MapGridAnnotationDisplayRight
Map annotation display right.
@ MapGridFrameMargin
Map grid frame margin.
@ MapGridOffsetX
Map grid offset X.
@ MapGridLabelDistance
Map grid label distance.
@ MapGridAnnotationDisplayLeft
Map annotation display left.
@ MapGridFrameDivisionsLeft
Map frame division display left.
@ MapGridEnabled
Map grid enabled.
@ MapGridFrameLineThickness
Map grid frame line thickness.
@ MapGridFrameDivisionsRight
Map frame division display right.
@ MapGridFrameDivisionsTop
Map frame division display top.
@ MapGridCrossSize
Map grid cross size.
@ MapGridOffsetY
Map grid offset Y.
@ MapGridAnnotationDisplayTop
Map annotation display top.
QgsLayoutRenderContext::Flags flags() const
Returns the current combination of flags used for rendering the layout.
@ FlagAntialiasing
Use antialiasing when drawing items.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
A line symbol type, for rendering LineString and MultiLineString geometries.
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
A class to represent a 2D point.
bool isEmpty() const SIP_HOLDGIL
Returns true if the geometry is empty.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Scoped object for saving and restoring a QPainter object's state.
Scoped object for temporary scaling of a QgsRenderContext for pixel based rendering.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
static QColor decodeColor(const QString &str)
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QString encodeColor(const QColor &color)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, DrawMode mode=Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
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.