42 #define MAX_GRID_LINES 1000 //maximum number of horizontal or vertical grid lines to draw
73 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
79 return qobject_cast<QgsLayoutItemMapGrid *>(
item );
84 QList< QgsLayoutItemMapGrid * > list;
107 QDomNodeList mapGridNodeList = elem.elementsByTagName( QStringLiteral(
"ComposerMapGrid" ) );
108 for (
int i = 0; i < mapGridNodeList.size(); ++i )
110 QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
112 mapGrid->
readXml( mapGridElem, doc, context );
126 return std::max( std::max( std::max( top, right ), bottom ), left );
140 double gridTop = 0.0;
141 double gridRight = 0.0;
142 double gridBottom = 0.0;
143 double gridLeft = 0.0;
145 top = std::max( top, gridTop );
146 right = std::max( right, gridRight );
147 bottom = std::max( bottom, gridBottom );
148 left = std::max( left, gridLeft );
166 QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
167 if ( !defaultFontString.isEmpty() )
169 mGridAnnotationFont.setFamily( defaultFontString );
172 createDefaultGridLineSymbol();
173 createDefaultGridMarkerSymbol();
179 void QgsLayoutItemMapGrid::createDefaultGridLineSymbol()
182 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
183 properties.insert( QStringLiteral(
"width" ), QStringLiteral(
"0.3" ) );
184 properties.insert( QStringLiteral(
"capstyle" ), QStringLiteral(
"flat" ) );
188 void QgsLayoutItemMapGrid::createDefaultGridMarkerSymbol()
191 properties.insert( QStringLiteral(
"name" ), QStringLiteral(
"circle" ) );
192 properties.insert( QStringLiteral(
"size" ), QStringLiteral(
"2.0" ) );
193 properties.insert( QStringLiteral(
"color" ), QStringLiteral(
"0,0,0,255" ) );
199 if ( mGridLineSymbol )
201 mGridLineSymbol->setWidth( width );
207 if ( mGridLineSymbol )
209 mGridLineSymbol->setColor(
c );
220 QDomElement mapGridElem = doc.createElement( QStringLiteral(
"ComposerMapGrid" ) );
221 mapGridElem.setAttribute( QStringLiteral(
"gridStyle" ), mGridStyle );
222 mapGridElem.setAttribute( QStringLiteral(
"intervalX" ),
qgsDoubleToString( mGridIntervalX ) );
223 mapGridElem.setAttribute( QStringLiteral(
"intervalY" ),
qgsDoubleToString( mGridIntervalY ) );
224 mapGridElem.setAttribute( QStringLiteral(
"offsetX" ),
qgsDoubleToString( mGridOffsetX ) );
225 mapGridElem.setAttribute( QStringLiteral(
"offsetY" ),
qgsDoubleToString( mGridOffsetY ) );
226 mapGridElem.setAttribute( QStringLiteral(
"crossLength" ),
qgsDoubleToString( mCrossLength ) );
228 QDomElement lineStyleElem = doc.createElement( QStringLiteral(
"lineStyle" ) );
230 lineStyleElem.appendChild( gridLineStyleElem );
231 mapGridElem.appendChild( lineStyleElem );
233 QDomElement markerStyleElem = doc.createElement( QStringLiteral(
"markerStyle" ) );
235 markerStyleElem.appendChild( gridMarkerStyleElem );
236 mapGridElem.appendChild( markerStyleElem );
238 mapGridElem.setAttribute( QStringLiteral(
"gridFrameStyle" ), mGridFrameStyle );
239 mapGridElem.setAttribute( QStringLiteral(
"gridFrameSideFlags" ), mGridFrameSides );
240 mapGridElem.setAttribute( QStringLiteral(
"gridFrameWidth" ),
qgsDoubleToString( mGridFrameWidth ) );
241 mapGridElem.setAttribute( QStringLiteral(
"gridFrameMargin" ),
qgsDoubleToString( mGridFrameMargin ) );
242 mapGridElem.setAttribute( QStringLiteral(
"gridFramePenThickness" ),
qgsDoubleToString( mGridFramePenThickness ) );
246 mapGridElem.setAttribute( QStringLiteral(
"leftFrameDivisions" ), mLeftFrameDivisions );
247 mapGridElem.setAttribute( QStringLiteral(
"rightFrameDivisions" ), mRightFrameDivisions );
248 mapGridElem.setAttribute( QStringLiteral(
"topFrameDivisions" ), mTopFrameDivisions );
249 mapGridElem.setAttribute( QStringLiteral(
"bottomFrameDivisions" ), mBottomFrameDivisions );
255 mapGridElem.setAttribute( QStringLiteral(
"annotationFormat" ), mGridAnnotationFormat );
256 mapGridElem.setAttribute( QStringLiteral(
"showAnnotation" ), mShowGridAnnotation );
257 mapGridElem.setAttribute( QStringLiteral(
"annotationExpression" ), mGridAnnotationExpressionString );
258 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDisplay" ), mLeftGridAnnotationDisplay );
259 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDisplay" ), mRightGridAnnotationDisplay );
260 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDisplay" ), mTopGridAnnotationDisplay );
261 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDisplay" ), mBottomGridAnnotationDisplay );
262 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationPosition" ), mLeftGridAnnotationPosition );
263 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationPosition" ), mRightGridAnnotationPosition );
264 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationPosition" ), mTopGridAnnotationPosition );
265 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationPosition" ), mBottomGridAnnotationPosition );
266 mapGridElem.setAttribute( QStringLiteral(
"leftAnnotationDirection" ), mLeftGridAnnotationDirection );
267 mapGridElem.setAttribute( QStringLiteral(
"rightAnnotationDirection" ), mRightGridAnnotationDirection );
268 mapGridElem.setAttribute( QStringLiteral(
"topAnnotationDirection" ), mTopGridAnnotationDirection );
269 mapGridElem.setAttribute( QStringLiteral(
"bottomAnnotationDirection" ), mBottomGridAnnotationDirection );
270 mapGridElem.setAttribute( QStringLiteral(
"frameAnnotationDistance" ), QString::number( mAnnotationFrameDistance ) );
271 mapGridElem.appendChild(
QgsFontUtils::toXmlElement( mGridAnnotationFont, doc, QStringLiteral(
"annotationFontProperties" ) ) );
273 mapGridElem.setAttribute( QStringLiteral(
"annotationPrecision" ), mGridAnnotationPrecision );
274 mapGridElem.setAttribute( QStringLiteral(
"unit" ), mGridUnit );
275 mapGridElem.setAttribute( QStringLiteral(
"blendMode" ), mBlendMode );
276 mapGridElem.setAttribute( QStringLiteral(
"minimumIntervalWidth" ), QString::number( mMinimumIntervalWidth ) );
277 mapGridElem.setAttribute( QStringLiteral(
"maximumIntervalWidth" ), QString::number( mMaximumIntervalWidth ) );
280 elem.appendChild( mapGridElem );
287 if ( itemElem.isNull() )
296 mGridIntervalX = itemElem.attribute( QStringLiteral(
"intervalX" ), QStringLiteral(
"0" ) ).toDouble();
297 mGridIntervalY = itemElem.attribute( QStringLiteral(
"intervalY" ), QStringLiteral(
"0" ) ).toDouble();
298 mGridOffsetX = itemElem.attribute( QStringLiteral(
"offsetX" ), QStringLiteral(
"0" ) ).toDouble();
299 mGridOffsetY = itemElem.attribute( QStringLiteral(
"offsetY" ), QStringLiteral(
"0" ) ).toDouble();
300 mCrossLength = itemElem.attribute( QStringLiteral(
"crossLength" ), QStringLiteral(
"3" ) ).toDouble();
301 mGridFrameStyle =
static_cast< QgsLayoutItemMapGrid::FrameStyle >( itemElem.attribute( QStringLiteral(
"gridFrameStyle" ), QStringLiteral(
"0" ) ).toInt() );
302 mGridFrameSides =
static_cast< QgsLayoutItemMapGrid::FrameSideFlags
>( itemElem.attribute( QStringLiteral(
"gridFrameSideFlags" ), QStringLiteral(
"15" ) ).toInt() );
303 mGridFrameWidth = itemElem.attribute( QStringLiteral(
"gridFrameWidth" ), QStringLiteral(
"2.0" ) ).toDouble();
304 mGridFrameMargin = itemElem.attribute( QStringLiteral(
"gridFrameMargin" ), QStringLiteral(
"0.0" ) ).toDouble();
305 mGridFramePenThickness = itemElem.attribute( QStringLiteral(
"gridFramePenThickness" ), QStringLiteral(
"0.3" ) ).toDouble();
314 QDomElement lineStyleElem = itemElem.firstChildElement( QStringLiteral(
"lineStyle" ) );
315 if ( !lineStyleElem.isNull() )
317 QDomElement symbolElem = lineStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
318 if ( !symbolElem.isNull() )
320 mGridLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
327 mGridLineSymbol->setWidth( itemElem.attribute( QStringLiteral(
"penWidth" ), QStringLiteral(
"0" ) ).toDouble() );
328 mGridLineSymbol->setColor( QColor( itemElem.attribute( QStringLiteral(
"penColorRed" ), QStringLiteral(
"0" ) ).toInt(),
329 itemElem.attribute( QStringLiteral(
"penColorGreen" ), QStringLiteral(
"0" ) ).toInt(),
330 itemElem.attribute( QStringLiteral(
"penColorBlue" ), QStringLiteral(
"0" ) ).toInt() ) );
333 QDomElement markerStyleElem = itemElem.firstChildElement( QStringLiteral(
"markerStyle" ) );
334 if ( !markerStyleElem.isNull() )
336 QDomElement symbolElem = markerStyleElem.firstChildElement( QStringLiteral(
"symbol" ) );
337 if ( !symbolElem.isNull() )
339 mGridMarkerSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) );
343 if ( !mCRS.
readXml( itemElem ) )
346 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.attribute( QStringLiteral(
"blendMode" ), QStringLiteral(
"0" ) ).toUInt() );
349 mShowGridAnnotation = ( itemElem.attribute( QStringLiteral(
"showAnnotation" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
351 mGridAnnotationExpressionString = itemElem.attribute( QStringLiteral(
"annotationExpression" ) );
352 mGridAnnotationExpression.reset();
357 mLeftGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"leftAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
358 mRightGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"rightAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
360 mBottomGridAnnotationDisplay =
QgsLayoutItemMapGrid::DisplayMode( itemElem.attribute( QStringLiteral(
"bottomAnnotationDisplay" ), QStringLiteral(
"0" ) ).toInt() );
366 mAnnotationFrameDistance = itemElem.attribute( QStringLiteral(
"frameAnnotationDistance" ), QStringLiteral(
"0" ) ).toDouble();
369 mGridAnnotationFont.fromString( itemElem.attribute( QStringLiteral(
"annotationFont" ), QString() ) );
371 mGridAnnotationFontColor =
QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral(
"annotationFontColor" ), QStringLiteral(
"0,0,0,255" ) ) );
372 mGridAnnotationPrecision = itemElem.attribute( QStringLiteral(
"annotationPrecision" ), QStringLiteral(
"3" ) ).toInt();
373 int gridUnitInt = itemElem.attribute( QStringLiteral(
"unit" ), QString::number(
MapUnit ) ).toInt();
375 mMinimumIntervalWidth = itemElem.attribute( QStringLiteral(
"minimumIntervalWidth" ), QStringLiteral(
"50" ) ).toDouble();
376 mMaximumIntervalWidth = itemElem.attribute( QStringLiteral(
"maximumIntervalWidth" ), QStringLiteral(
"100" ) ).toDouble();
378 refreshDataDefinedProperties();
385 mTransformDirty =
true;
390 return mBlendMode != QPainter::CompositionMode_SourceOver;
393 QPolygonF QgsLayoutItemMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
395 QTransform t = QTransform::fromScale( scale, scale );
396 return t.map( polygon );
399 void QgsLayoutItemMapGrid::drawGridCrsTransform(
QgsRenderContext &context,
double dotsPerMM, QList< QPair< double, QLineF > > &horizontalLines,
400 QList< QPair< double, QLineF > > &verticalLines,
bool calculateLinesOnly )
const
402 if ( !
mMap || !mEvaluatedEnabled )
409 if ( mapPolygon != mPrevMapPolygon )
411 mTransformDirty =
true;
412 mPrevMapPolygon = mapPolygon;
415 if ( mTransformDirty )
417 calculateCrsTransformLines();
421 if ( !calculateLinesOnly )
425 QList< QPair< double, QPolygonF > >::const_iterator xGridIt = mTransformedXLines.constBegin();
426 for ( ; xGridIt != mTransformedXLines.constEnd(); ++xGridIt )
428 drawGridLine( scalePolygon( xGridIt->second, dotsPerMM ), context );
431 QList< QPair< double, QPolygonF > >::const_iterator yGridIt = mTransformedYLines.constBegin();
432 for ( ; yGridIt != mTransformedYLines.constEnd(); ++yGridIt )
434 drawGridLine( scalePolygon( yGridIt->second, dotsPerMM ), context );
439 double maxX =
mMap->rect().width();
440 double maxY =
mMap->rect().height();
442 QList< QgsPointXY >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
443 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
445 double x = intersectionIt->x();
446 double y = intersectionIt->y();
450 QLineF line1 = QLineF( x - mEvaluatedCrossLength, y, x + mEvaluatedCrossLength, y );
451 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
452 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
453 QLineF line2 = QLineF( x, y - mEvaluatedCrossLength, x, y + mEvaluatedCrossLength );
454 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
455 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
458 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
459 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
463 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
470 QList< QPair< double, QPolygonF > >::const_iterator yGridLineIt = mTransformedYLines.constBegin();
471 for ( ; yGridLineIt != mTransformedYLines.constEnd(); ++yGridLineIt )
473 verticalLines.push_back( qMakePair( yGridLineIt->first, QLineF( yGridLineIt->second.first(), yGridLineIt->second.last() ) ) );
475 QList< QPair< double, QPolygonF > >::const_iterator xGridLineIt = mTransformedXLines.constBegin();
476 for ( ; xGridLineIt != mTransformedXLines.constEnd(); ++xGridLineIt )
478 horizontalLines.push_back( qMakePair( xGridLineIt->first, QLineF( xGridLineIt->second.first(), xGridLineIt->second.last() ) ) );
482 void QgsLayoutItemMapGrid::calculateCrsTransformLines()
const
486 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
492 mTransformedXLines.clear();
493 xGridLinesCrsTransform( crsBoundingRect, inverseTr, mTransformedXLines );
496 mTransformedYLines.clear();
497 yGridLinesCrsTransform( crsBoundingRect, inverseTr, mTransformedYLines );
504 QList< QgsGeometry > yLines;
505 QList< QPair< double, QPolygonF > >::const_iterator yGridIt = mTransformedYLines.constBegin();
506 for ( ; yGridIt != mTransformedYLines.constEnd(); ++yGridIt )
509 for (
int i = 0; i < ( *yGridIt ).second.size(); ++i )
511 yLine.append(
QgsPointXY( ( *yGridIt ).second.at( i ).x(), ( *yGridIt ).second.at( i ).y() ) );
515 QList< QgsGeometry > xLines;
516 QList< QPair< double, QPolygonF > >::const_iterator xGridIt = mTransformedXLines.constBegin();
517 for ( ; xGridIt != mTransformedXLines.constEnd(); ++xGridIt )
520 for (
int i = 0; i < ( *xGridIt ).second.size(); ++i )
522 xLine.append(
QgsPointXY( ( *xGridIt ).second.at( i ).x(), ( *xGridIt ).second.at( i ).y() ) );
528 mTransformedIntersections.clear();
529 QList< QgsGeometry >::const_iterator yLineIt = yLines.constBegin();
530 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
532 QList< QgsGeometry >::const_iterator xLineIt = xLines.constBegin();
533 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
537 if ( intersects.
isNull() )
545 mTransformedIntersections << vertex;
553 mTransformDirty =
false;
558 if ( !
mMap || !mEvaluatedEnabled )
562 QPaintDevice *paintDevice = p->device();
569 p->setCompositionMode( mBlendMode );
572 QRectF thisPaintRect = QRectF( 0, 0,
mMap->rect().width(),
mMap->rect().height() );
573 p->setClipRect( thisPaintRect );
574 if ( thisPaintRect != mPrevPaintRect )
577 mTransformDirty =
true;
578 mPrevPaintRect = thisPaintRect;
582 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
583 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
591 QList< QPair< double, QLineF > > verticalLines;
592 QList< QPair< double, QLineF > > horizontalLines;
601 drawGridCrsTransform( context, dotsPerMM, horizontalLines, verticalLines );
608 drawGridNoTransform( context, dotsPerMM, horizontalLines, verticalLines );
613 p->setClipping(
false );
617 p->setClipRect(
mMap->mapRectFromScene(
mMap->sceneBoundingRect() ).adjusted( -10, -10, 10, 10 ) );
622 drawGridFrame( p, horizontalLines, verticalLines );
625 if ( mShowGridAnnotation )
627 drawCoordinateAnnotations( p, horizontalLines, verticalLines, context.
expressionContext() );
631 void QgsLayoutItemMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM, QList< QPair< double, QLineF > > &horizontalLines,
632 QList< QPair< double, QLineF > > &verticalLines,
bool calculateLinesOnly )
const
635 yGridLines( verticalLines );
636 xGridLines( horizontalLines );
638 if ( calculateLinesOnly )
641 QList< QPair< double, QLineF > >::const_iterator vIt = verticalLines.constBegin();
642 QList< QPair< double, QLineF > >::const_iterator hIt = horizontalLines.constBegin();
650 for ( ; vIt != verticalLines.constEnd(); ++vIt )
652 line = QLineF( vIt->second.p1() * dotsPerMM, vIt->second.p2() * dotsPerMM );
653 drawGridLine( line, context );
656 for ( ; hIt != horizontalLines.constEnd(); ++hIt )
658 line = QLineF( hIt->second.p1() * dotsPerMM, hIt->second.p2() * dotsPerMM );
659 drawGridLine( line, context );
664 QPointF intersectionPoint, crossEnd1, crossEnd2;
665 for ( ; vIt != verticalLines.constEnd(); ++vIt )
668 hIt = horizontalLines.constBegin();
669 for ( ; hIt != horizontalLines.constEnd(); ++hIt )
671 if ( hIt->second.intersect( vIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
676 crossEnd1 = ( ( intersectionPoint - vIt->second.p1() ).manhattanLength() > 0.01 ) ?
678 crossEnd2 = ( ( intersectionPoint - vIt->second.p2() ).manhattanLength() > 0.01 ) ?
681 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
685 drawGridMarker( intersectionPoint * dotsPerMM, context );
697 hIt = horizontalLines.constBegin();
698 for ( ; hIt != horizontalLines.constEnd(); ++hIt )
700 vIt = verticalLines.constBegin();
701 for ( ; vIt != verticalLines.constEnd(); ++vIt )
703 if ( vIt->second.intersect( hIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
706 crossEnd1 = ( ( intersectionPoint - hIt->second.p1() ).manhattanLength() > 0.01 ) ?
708 crossEnd2 = ( ( intersectionPoint - hIt->second.p2() ).manhattanLength() > 0.01 ) ?
711 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
718 void QgsLayoutItemMapGrid::drawGridFrame( QPainter *p,
const QList< QPair< double, QLineF > > &hLines,
const QList< QPair< double, QLineF > > &vLines, GridExtension *extension )
const
727 QMap< double, double > leftGridFrame;
728 QMap< double, double > rightGridFrame;
729 QMap< double, double > topGridFrame;
730 QMap< double, double > bottomGridFrame;
732 sortGridLinesOnBorders( hLines, vLines, leftGridFrame, rightGridFrame, topGridFrame, bottomGridFrame );
754 void QgsLayoutItemMapGrid::drawGridLine(
const QLineF &line,
QgsRenderContext &context )
const
757 poly << line.p1() << line.p2();
758 drawGridLine( poly, context );
761 void QgsLayoutItemMapGrid::drawGridLine(
const QPolygonF &line,
QgsRenderContext &context )
const
768 mGridLineSymbol->startRender( context );
769 mGridLineSymbol->renderPolyline( line,
nullptr, context );
770 mGridLineSymbol->stopRender( context );
773 void QgsLayoutItemMapGrid::drawGridMarker( QPointF point,
QgsRenderContext &context )
const
780 mGridMarkerSymbol->startRender( context );
781 mGridMarkerSymbol->renderPoint( point,
nullptr, context );
782 mGridMarkerSymbol->stopRender( context );
785 void QgsLayoutItemMapGrid::drawGridFrameBorder( QPainter *p,
const QMap< double, double > &borderPos,
QgsLayoutItemMapGrid::BorderSide border,
double *extension )
const
792 switch ( mGridFrameStyle )
796 drawGridFrameZebraBorder( p, borderPos, border, extension );
801 drawGridFrameTicks( p, borderPos, border, extension );
806 drawGridFrameLineBorder( p, border, extension );
815 void QgsLayoutItemMapGrid::drawGridFrameZebraBorder( QPainter *p,
const QMap< double, double > &borderPos,
QgsLayoutItemMapGrid::BorderSide border,
double *extension )
const
824 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth + mEvaluatedGridFrameLineThickness / 2.0;
828 QMap< double, double > pos = borderPos;
830 double currentCoord = 0.0;
837 bool drawTLBox =
false;
838 bool drawTRBox =
false;
839 bool drawBLBox =
false;
840 bool drawBRBox =
false;
844 pos.insert(
mMap->rect().height(),
mMap->rect().height() );
860 pos.insert(
mMap->rect().width(),
mMap->rect().width() );
864 QPen framePen = QPen( mGridFramePenColor );
865 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
866 framePen.setJoinStyle( Qt::MiterJoin );
867 p->setPen( framePen );
869 QMap< double, double >::const_iterator posIt = pos.constBegin();
870 for ( ; posIt != pos.constEnd(); ++posIt )
872 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
875 height = posIt.key() - currentCoord;
876 width = mEvaluatedGridFrameWidth;
877 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().width() + mEvaluatedGridFrameMargin;
882 height = mEvaluatedGridFrameWidth;
883 width = posIt.key() - currentCoord;
885 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) :
mMap->rect().height() + mEvaluatedGridFrameMargin;
887 p->drawRect( QRectF( x, y, width, height ) );
888 currentCoord = posIt.key();
895 width = height = ( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ) ;
896 p->setBrush( QBrush( mGridFrameFillColor1 ) );
898 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
900 p->drawRect( QRectF(
mMap->rect().width(), -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ), width, height ) );
902 p->drawRect( QRectF( -( mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin ),
mMap->rect().height(), width, height ) );
904 p->drawRect( QRectF(
mMap->rect().width(),
mMap->rect().height(), width, height ) );
908 void QgsLayoutItemMapGrid::drawGridFrameTicks( QPainter *p,
const QMap< double, double > &borderPos,
QgsLayoutItemMapGrid::BorderSide border,
double *extension )
const
918 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameWidth;
928 QPen framePen = QPen( mGridFramePenColor );
929 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
930 framePen.setCapStyle( Qt::FlatCap );
931 p->setBrush( Qt::NoBrush );
932 p->setPen( framePen );
934 QMap< double, double >::const_iterator posIt = borderPos.constBegin();
935 for ( ; posIt != borderPos.constEnd(); ++posIt )
943 width = mEvaluatedGridFrameWidth;
944 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? 0 + mEvaluatedGridFrameMargin :
mMap->rect().width() - mEvaluatedGridFrameWidth - mEvaluatedGridFrameMargin;
948 width = mEvaluatedGridFrameWidth;
949 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? - mEvaluatedGridFrameWidth - mEvaluatedGridFrameMargin :
mMap->rect().width() + mEvaluatedGridFrameMargin;
953 width = mEvaluatedGridFrameWidth * 2;
954 x = ( border ==
QgsLayoutItemMapGrid::Left ) ? - mEvaluatedGridFrameWidth - mEvaluatedGridFrameMargin :
mMap->rect().width() - mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin;
963 height = mEvaluatedGridFrameWidth;
964 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? 0 + mEvaluatedGridFrameMargin :
mMap->rect().height() - mEvaluatedGridFrameWidth - mEvaluatedGridFrameMargin;
968 height = mEvaluatedGridFrameWidth;
969 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -mEvaluatedGridFrameWidth - mEvaluatedGridFrameMargin :
mMap->rect().height() + mEvaluatedGridFrameMargin;
973 height = mEvaluatedGridFrameWidth * 2;
974 y = ( border ==
QgsLayoutItemMapGrid::Top ) ? -mEvaluatedGridFrameWidth - mEvaluatedGridFrameMargin :
mMap->rect().height() - mEvaluatedGridFrameWidth + mEvaluatedGridFrameMargin;
977 p->drawLine( QLineF( x, y, x + width, y + height ) );
990 *extension = mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
995 QPen framePen = QPen( mGridFramePenColor );
996 framePen.setWidthF( mEvaluatedGridFrameLineThickness );
997 framePen.setCapStyle( Qt::SquareCap );
998 p->setBrush( Qt::NoBrush );
999 p->setPen( framePen );
1006 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1008 if ( drawDiagonals )
1010 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1011 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0;
1012 p->drawLine( QLineF( 0, 0, X1, Y1 ) );
1016 p->drawLine( QLineF(
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1018 if ( drawDiagonals )
1020 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1021 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1022 p->drawLine( QLineF(
mMap->rect().width(),
mMap->rect().height(), X1, Y1 ) );
1026 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin, 0 - mEvaluatedGridFrameMargin ) );
1028 if ( drawDiagonals )
1030 const double X1 =
mMap->rect().width() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1031 const double Y1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1032 p->drawLine( QLineF(
mMap->rect().width(), 0, X1, Y1 ) );
1036 p->drawLine( QLineF( 0 - mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin,
mMap->rect().width() + mEvaluatedGridFrameMargin,
mMap->rect().height() + mEvaluatedGridFrameMargin ) );
1038 if ( drawDiagonals )
1040 const double X1 = 0 - mEvaluatedGridFrameMargin + mEvaluatedGridFrameLineThickness / 2.0 ;
1041 const double Y1 =
mMap->rect().height() + mEvaluatedGridFrameMargin - mEvaluatedGridFrameLineThickness / 2.0 ;
1042 p->drawLine( QLineF( 0,
mMap->rect().height(), X1, Y1 ) );
1048 void QgsLayoutItemMapGrid::drawCoordinateAnnotations( QPainter *p,
const QList< QPair< double, QLineF > > &hLines,
const QList< QPair< double, QLineF > > &vLines,
QgsExpressionContext &expressionContext,
1049 GridExtension *extension )
const
1051 QString currentAnnotationString;
1052 QList< QPair< double, QLineF > >::const_iterator it = hLines.constBegin();
1053 for ( ; it != hLines.constEnd(); ++it )
1060 it = vLines.constBegin();
1061 for ( ; it != vLines.constEnd(); ++it )
1069 void QgsLayoutItemMapGrid::drawCoordinateAnnotation( QPainter *p, QPointF pos,
const QString &annotationString,
const AnnotationCoordinate coordinateType, GridExtension *extension )
const
1080 :
QgsLayoutUtils::fontHeightCharacterMM( mGridAnnotationFont, QChar(
'0' ) );
1081 double xpos = pos.x();
1082 double ypos = pos.y();
1085 double gridFrameDistance = 0;
1086 switch ( mGridFrameStyle )
1091 gridFrameDistance = mEvaluatedGridFrameWidth;
1096 gridFrameDistance = mEvaluatedGridFrameWidth + ( mEvaluatedGridFrameLineThickness / 2.0 );
1101 gridFrameDistance = mEvaluatedGridFrameLineThickness / 2.0;
1118 gridFrameDistance = 0;
1125 gridFrameDistance = 0;
1129 xpos += textHeight + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1130 ypos += textWidth / 2.0;
1135 xpos += ( mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1136 ypos -= textWidth / 2.0;
1141 xpos += mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1142 ypos += textHeight / 2.0;
1149 gridFrameDistance = 0;
1153 xpos -= ( mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1154 ypos += textWidth / 2.0;
1157 extension->left = std::max( extension->left, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textHeight );
1161 xpos -= textHeight + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1162 ypos -= textWidth / 2.0;
1165 extension->left = std::max( extension->left, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textHeight );
1169 xpos -= ( textWidth + mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1170 ypos += textHeight / 2.0;
1172 extension->left = std::max( extension->left, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textWidth );
1190 gridFrameDistance = 0;
1197 gridFrameDistance = 0;
1201 xpos -= mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1202 ypos += textWidth / 2.0;
1207 xpos -= textHeight + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1208 ypos -= textWidth / 2.0;
1213 xpos -= textWidth + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1214 ypos += textHeight / 2.0;
1221 gridFrameDistance = 0;
1225 xpos += ( textHeight + mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1226 ypos += textWidth / 2.0;
1229 extension->right = std::max( extension->right, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textHeight );
1233 xpos += ( mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1234 ypos -= textWidth / 2.0;
1237 extension->right = std::max( extension->right, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textHeight );
1241 xpos += ( mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1242 ypos += textHeight / 2.0;
1244 extension->right = std::max( extension->right, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textWidth );
1262 gridFrameDistance = 0;
1269 gridFrameDistance = 0;
1273 ypos -= mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1274 xpos -= textWidth / 2.0;
1278 xpos -= textHeight / 2.0;
1279 ypos -= textWidth + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1284 xpos += textHeight / 2.0;
1285 ypos -= mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1293 gridFrameDistance = 0;
1297 ypos += ( mEvaluatedAnnotationFrameDistance + textHeight + gridFrameDistance );
1298 xpos -= textWidth / 2.0;
1301 extension->bottom = std::max( extension->bottom, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textHeight );
1302 extension->left = std::max( extension->left, textWidth / 2.0 );
1303 extension->right = std::max( extension->right, textWidth / 2.0 );
1308 xpos -= textHeight / 2.0;
1309 ypos += gridFrameDistance + mEvaluatedAnnotationFrameDistance;
1312 extension->bottom = std::max( extension->bottom, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textWidth );
1316 xpos += textHeight / 2.0;
1317 ypos += ( textWidth + mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1320 extension->bottom = std::max( extension->bottom, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textWidth );
1338 gridFrameDistance = 0;
1345 gridFrameDistance = 0;
1349 xpos -= textWidth / 2.0;
1350 ypos += textHeight + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1354 xpos -= textHeight / 2.0;
1355 ypos += mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1360 xpos += textHeight / 2.0;
1361 ypos += textWidth + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1369 gridFrameDistance = 0;
1373 xpos -= textWidth / 2.0;
1374 ypos -= ( mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1376 extension->top = std::max( extension->top, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textHeight );
1380 xpos -= textHeight / 2.0;
1381 ypos -= textWidth + mEvaluatedAnnotationFrameDistance + gridFrameDistance;
1384 extension->top = std::max( extension->top, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textWidth );
1388 xpos += textHeight / 2.0;
1389 ypos -= ( mEvaluatedAnnotationFrameDistance + gridFrameDistance );
1392 extension->top = std::max( extension->top, mEvaluatedAnnotationFrameDistance + gridFrameDistance + textWidth );
1401 if ( extension || !p )
1404 drawAnnotation( p, QPointF( xpos, ypos ), rotation, annotationString );
1407 void QgsLayoutItemMapGrid::drawAnnotation( QPainter *p, QPointF pos,
int rotation,
const QString &annotationText )
const
1415 p->translate( pos );
1416 p->rotate( rotation );
1424 bool geographic =
false;
1438 double wrappedX = std::fmod( value, 360.0 );
1439 if ( wrappedX > 180.0 )
1441 value = wrappedX - 360.0;
1443 else if ( wrappedX < -180.0 )
1445 value = wrappedX + 360.0;
1451 return QString::number( value,
'f', mGridAnnotationPrecision );
1457 double coordRounded =
qgsRound( value, mGridAnnotationPrecision );
1461 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1463 hemisphere = value < 0 ? QObject::tr(
"W" ) : QObject::tr(
"E" );
1469 if ( !geographic || coordRounded != 0.0 )
1471 hemisphere = value < 0 ? QObject::tr(
"S" ) : QObject::tr(
"N" );
1477 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1481 return QString::number( std::fabs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1488 if ( !mGridAnnotationExpression )
1490 mGridAnnotationExpression.reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1491 mGridAnnotationExpression->prepare( &expressionContext );
1493 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1497 QgsCoordinateFormatter::FormatFlags flags = QgsCoordinateFormatter::FormatFlags();
1498 switch ( mGridAnnotationFormat )
1548 int QgsLayoutItemMapGrid::xGridLines( QList< QPair< double, QLineF > > &lines )
const
1551 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1558 QRectF mapBoundingRect = mapPolygon.boundingRect();
1559 double gridIntervalY = mEvaluatedIntervalY;
1560 double gridOffsetY = mEvaluatedOffsetY;
1561 double annotationScale = 1.0;
1562 switch ( mGridUnit )
1567 mapBoundingRect =
mMap->rect();
1568 mapPolygon = QPolygonF(
mMap->rect() );
1569 if ( mGridUnit ==
CM )
1571 annotationScale = 0.1;
1572 gridIntervalY *= 10;
1584 double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1585 double currentLevel =
static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1587 int gridLineCount = 0;
1592 double yCanvasCoord;
1593 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1595 yCanvasCoord =
mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1596 lines.push_back( qMakePair( currentLevel * annotationScale, QLineF( 0, yCanvasCoord,
mMap->rect().width(), yCanvasCoord ) ) );
1597 currentLevel += gridIntervalY;
1604 QVector<QLineF> borderLines;
1605 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1606 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1607 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1608 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1610 QVector<QPointF> intersectionList;
1612 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1614 intersectionList.clear();
1615 QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1617 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1618 for ( ; it != borderLines.constEnd(); ++it )
1620 QPointF intersectionPoint;
1621 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1623 intersectionList.push_back( intersectionPoint );
1624 if ( intersectionList.size() >= 2 )
1631 if ( intersectionList.size() >= 2 )
1636 currentLevel += gridIntervalY;
1643 int QgsLayoutItemMapGrid::yGridLines( QList< QPair< double, QLineF > > &lines )
const
1646 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1652 QRectF mapBoundingRect = mapPolygon.boundingRect();
1653 double gridIntervalX = mEvaluatedIntervalX;
1654 double gridOffsetX = mEvaluatedOffsetX;
1655 double annotationScale = 1.0;
1656 switch ( mGridUnit )
1661 mapBoundingRect =
mMap->rect();
1662 mapPolygon = QPolygonF(
mMap->rect() );
1663 if ( mGridUnit ==
CM )
1665 annotationScale = 0.1;
1666 gridIntervalX *= 10;
1678 double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1679 double currentLevel =
static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1681 int gridLineCount = 0;
1685 double xCanvasCoord;
1686 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1688 xCanvasCoord =
mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1689 lines.push_back( qMakePair( currentLevel * annotationScale, QLineF( xCanvasCoord, 0, xCanvasCoord,
mMap->rect().height() ) ) );
1690 currentLevel += gridIntervalX;
1697 QVector<QLineF> borderLines;
1698 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1699 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1700 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1701 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1703 QVector<QPointF> intersectionList;
1705 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1707 intersectionList.clear();
1708 QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1710 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1711 for ( ; it != borderLines.constEnd(); ++it )
1713 QPointF intersectionPoint;
1714 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1716 intersectionList.push_back( intersectionPoint );
1717 if ( intersectionList.size() >= 2 )
1724 if ( intersectionList.size() >= 2 )
1729 currentLevel += gridIntervalX;
1738 if ( !
mMap || mEvaluatedIntervalY <= 0.0 )
1743 double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1744 double currentLevel =
static_cast< int >( ( bbox.
yMaximum() - mEvaluatedOffsetY ) / mEvaluatedIntervalY + roundCorrection ) * mEvaluatedIntervalY + mEvaluatedOffsetY;
1748 double step = ( maxX - minX ) / 20;
1750 bool crosses180 =
false;
1751 bool crossed180 =
false;
1756 step = ( maxX + 360.0 - minX ) / 20;
1762 int gridLineCount = 0;
1766 double currentX = minX;
1770 if ( ( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1783 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1787 if ( crosses180 && currentX > 180.0 )
1795 QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1796 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1797 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1799 if ( !( *lineIt ).isEmpty() )
1801 lines.append( qMakePair( currentLevel, *lineIt ) );
1805 currentLevel -= mEvaluatedIntervalY;
1814 if ( !
mMap || mEvaluatedIntervalX <= 0.0 )
1819 double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1820 double currentLevel =
static_cast< int >( ( bbox.
xMinimum() - mEvaluatedOffsetX ) / mEvaluatedIntervalX + roundCorrection ) * mEvaluatedIntervalX + mEvaluatedOffsetX;
1824 double step = ( maxY - minY ) / 20;
1829 bool crosses180 =
false;
1830 bool crossed180 =
false;
1837 int gridLineCount = 0;
1838 while ( ( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1841 double currentY = minY;
1845 if ( currentY > maxY )
1859 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1865 QList<QPolygonF> lineSegments = trimLinesToMap( gridLine,
QgsRectangle(
mMap->rect() ) );
1866 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1867 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1869 if ( !( *lineIt ).isEmpty() )
1871 lines.append( qMakePair( currentLevel, *lineIt ) );
1875 currentLevel += mEvaluatedIntervalX;
1876 if ( crosses180 && currentLevel > 180.0 )
1878 currentLevel -= 360.0;
1886 void QgsLayoutItemMapGrid::sortGridLinesOnBorders(
const QList< QPair< double, QLineF > > &hLines,
const QList< QPair< double, QLineF > > &vLines, QMap< double, double > &leftFrameEntries,
1887 QMap< double, double > &rightFrameEntries, QMap< double, double > &topFrameEntries, QMap< double, double > &bottomFrameEntries )
const
1889 QList< QgsMapAnnotation > borderPositions;
1890 QList< QPair< double, QLineF > >::const_iterator it = hLines.constBegin();
1891 for ( ; it != hLines.constEnd(); ++it )
1893 QgsMapAnnotation p1;
1894 p1.coordinate = it->first;
1895 p1.itemPosition = it->second.p1();
1897 borderPositions << p1;
1899 QgsMapAnnotation p2;
1900 p2.coordinate = it->first;
1901 p2.itemPosition = it->second.p2();
1903 borderPositions << p2;
1905 it = vLines.constBegin();
1906 for ( ; it != vLines.constEnd(); ++it )
1908 QgsMapAnnotation p1;
1909 p1.coordinate = it->first;
1910 p1.itemPosition = it->second.p1();
1912 borderPositions << p1;
1914 QgsMapAnnotation p2;
1915 p2.coordinate = it->first;
1916 p2.itemPosition = it->second.p2();
1918 borderPositions << p2;
1921 QList< QgsMapAnnotation >::const_iterator bIt = borderPositions.constBegin();
1922 for ( ; bIt != borderPositions.constEnd(); ++bIt )
1927 leftFrameEntries.insert( bIt->itemPosition.y(), bIt->coordinate );
1931 rightFrameEntries.insert( bIt->itemPosition.y(), bIt->coordinate );
1935 topFrameEntries.insert( bIt->itemPosition.x(), bIt->coordinate );
1939 bottomFrameEntries.insert( bIt->itemPosition.x(), bIt->coordinate );
1949 return shouldShowDivisionForDisplayMode( coordinate, mLeftFrameDivisions );
1951 return shouldShowDivisionForDisplayMode( coordinate, mRightFrameDivisions );
1953 return shouldShowDivisionForDisplayMode( coordinate, mTopFrameDivisions );
1955 return shouldShowDivisionForDisplayMode( coordinate, mBottomFrameDivisions );
1967 void QgsLayoutItemMapGrid::refreshDataDefinedProperties()
1972 switch ( mGridUnit )
1985 if ( mMaximumIntervalWidth < mMinimumIntervalWidth )
1987 mEvaluatedEnabled =
false;
1992 const double mapWidthMapUnits = mapWidth();
1993 double minUnitsPerSeg = ( mMinimumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1994 double maxUnitsPerSeg = ( mMaximumIntervalWidth * mapWidthMapUnits ) / mapWidthMm;
1996 mEvaluatedIntervalX = interval;
1997 mEvaluatedIntervalY = interval;
2011 double QgsLayoutItemMapGrid::mapWidth()
const
2022 return mapExtent.
width();
2039 bool sortByDistance( QPair<qreal, QgsLayoutItemMapGrid::BorderSide> a, QPair<qreal, QgsLayoutItemMapGrid::BorderSide> b )
2041 return a.first < b.first;
2054 if ( ( p.y() <= tolerance && p.x() <= tolerance )
2055 || ( p.y() <= tolerance && p.x() >= (
mMap->rect().width() - tolerance ) )
2056 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() <= tolerance )
2057 || ( p.y() >= (
mMap->rect().height() - tolerance ) && p.x() >= (
mMap->rect().width() - tolerance ) )
2063 if ( p.x() <= tolerance )
2074 if ( p.y() <= tolerance )
2086 QList< QPair<qreal, QgsLayoutItemMapGrid::BorderSide > > distanceToSide;
2092 std::sort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
2093 return distanceToSide.at( 0 ).second;
2098 mGridLineSymbol.reset( symbol );
2103 return mGridLineSymbol.get();
2108 return mGridLineSymbol.get();
2113 mGridMarkerSymbol.reset( symbol );
2118 return mGridMarkerSymbol.get();
2123 return mGridMarkerSymbol.get();
2131 mLeftGridAnnotationDisplay = display;
2134 mRightGridAnnotationDisplay = display;
2137 mTopGridAnnotationDisplay = display;
2140 mBottomGridAnnotationDisplay = display;
2156 return mLeftGridAnnotationDisplay;
2158 return mRightGridAnnotationDisplay;
2160 return mTopGridAnnotationDisplay;
2162 return mBottomGridAnnotationDisplay;
2164 return mBottomGridAnnotationDisplay;
2171 double bottom = 0.0;
2174 return std::max( std::max( std::max( top, right ), bottom ), left );
2184 if ( !
mMap || !mEvaluatedEnabled )
2194 GridExtension extension;
2197 QList< QPair< double, QLineF > > verticalLines;
2198 QList< QPair< double, QLineF > > horizontalLines;
2199 switch ( mGridUnit )
2206 drawGridCrsTransform( context, 0, horizontalLines, verticalLines,
true );
2213 drawGridNoTransform( context, 0, horizontalLines, verticalLines,
true );
2219 drawGridFrame(
nullptr, horizontalLines, verticalLines, &extension );
2222 if ( mShowGridAnnotation )
2224 drawCoordinateAnnotations(
nullptr, horizontalLines, verticalLines, context.
expressionContext(), &extension );
2227 top = extension.top;
2228 right = extension.right;
2229 bottom = extension.bottom;
2230 left = extension.left;
2236 refreshDataDefinedProperties();
2241 if ( unit == mGridUnit )
2246 mTransformDirty =
true;
2255 mGridIntervalX = interval;
2256 mTransformDirty =
true;
2257 refreshDataDefinedProperties();
2266 mGridIntervalY = interval;
2267 mTransformDirty =
true;
2268 refreshDataDefinedProperties();
2277 mGridOffsetX = offset;
2278 mTransformDirty =
true;
2279 refreshDataDefinedProperties();
2288 mGridOffsetY = offset;
2289 mTransformDirty =
true;
2290 refreshDataDefinedProperties();
2299 mMinimumIntervalWidth = minWidth;
2300 mTransformDirty =
true;
2301 refreshDataDefinedProperties();
2310 mMaximumIntervalWidth = maxWidth;
2311 mTransformDirty =
true;
2312 refreshDataDefinedProperties();
2317 if (
style == mGridStyle )
2322 mTransformDirty =
true;
2327 mCrossLength = length;
2328 refreshDataDefinedProperties();
2336 mLeftGridAnnotationDirection = direction;
2339 mRightGridAnnotationDirection = direction;
2342 mTopGridAnnotationDirection = direction;
2345 mBottomGridAnnotationDirection = direction;
2358 mGridFrameSides = flags;
2364 mGridFrameSides |= flag;
2366 mGridFrameSides &= ~flag;
2371 return mGridFrameSides;
2380 context.
setHighlightedVariables( QStringList() << QStringLiteral(
"grid_number" ) << QStringLiteral(
"grid_axis" ) );
2386 if ( mGridLineSymbol )
2392 if ( mGridMarkerSymbol )
2404 mTransformDirty =
true;
2405 refreshDataDefinedProperties();
2412 return mGridFrameSides.testFlag( flag );
2417 mGridFrameWidth = width;
2418 refreshDataDefinedProperties();
2423 mGridFrameMargin = margin;
2424 refreshDataDefinedProperties();
2429 mGridFramePenThickness = width;
2430 refreshDataDefinedProperties();
2435 mLeftGridAnnotationDirection = direction;
2436 mRightGridAnnotationDirection = direction;
2437 mTopGridAnnotationDirection = direction;
2438 mBottomGridAnnotationDirection = direction;
2446 mLeftGridAnnotationPosition = position;
2449 mRightGridAnnotationPosition = position;
2452 mTopGridAnnotationPosition = position;
2455 mBottomGridAnnotationPosition = position;
2471 return mLeftGridAnnotationPosition;
2473 return mRightGridAnnotationPosition;
2475 return mTopGridAnnotationPosition;
2477 return mBottomGridAnnotationPosition;
2479 return mLeftGridAnnotationPosition;
2484 mAnnotationFrameDistance = distance;
2485 refreshDataDefinedProperties();
2492 return mLeftGridAnnotationDirection;
2498 return mLeftGridAnnotationDirection;
2500 return mRightGridAnnotationDirection;
2502 return mTopGridAnnotationDirection;
2504 return mBottomGridAnnotationDirection;
2506 return mLeftGridAnnotationDirection;
2514 mLeftFrameDivisions = divisions;
2517 mRightFrameDivisions = divisions;
2520 mTopFrameDivisions = divisions;
2523 mBottomFrameDivisions = divisions;
2538 return mLeftFrameDivisions;
2540 return mRightFrameDivisions;
2542 return mTopFrameDivisions;
2544 return mBottomFrameDivisions;
2546 return mLeftFrameDivisions;
2560 QRectF mbr = mapPolygon.boundingRect();
2561 QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2567 QgsPointXY lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2568 QgsPointXY upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2570 lowerLeft = tr.transform( lowerLeft.x(), lowerLeft.y() );
2571 upperRight = tr.transform( upperRight.x(), upperRight.y() );
2573 if ( lowerLeft.x() > upperRight.x() )
2581 crsRect = tr.transformBoundingBox( mapBoundingRect );
2586 crsRect = tr.transformBoundingBox( mapBoundingRect );
2594 QgsDebugMsg( QStringLiteral(
"Caught CRS exception %1" ).arg( cse.
what() ) );
2600 QList<QPolygonF> QgsLayoutItemMapGrid::trimLinesToMap(
const QPolygonF &line,
const QgsRectangle &rect )
2608 QList<QPolygonF> trimmedLines;
2609 QVector<QgsGeometry>::const_iterator geomIt = intersectedParts.constBegin();
2610 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2612 trimmedLines << ( *geomIt ).asQPolygonF();
2614 return trimmedLines;