Skip to content

Commit 4a70d1b

Browse files
committed
[composer] Correctly handle symbology using map units when drawing grid lines and overlays on maps (fix #8210)
1 parent 95f88ae commit 4a70d1b

File tree

2 files changed

+53
-27
lines changed

2 files changed

+53
-27
lines changed

src/core/composer/qgscomposermap.cpp

+52-26
Original file line numberDiff line numberDiff line change
@@ -1432,21 +1432,45 @@ void QgsComposerMap::drawGrid( QPainter* p )
14321432
QRectF thisPaintRect = QRectF( 0, 0, QGraphicsRectItem::rect().width(), QGraphicsRectItem::rect().height() );
14331433
p->setClipRect( thisPaintRect );
14341434

1435+
QPaintDevice* thePaintDevice = p->device();
1436+
if ( !thePaintDevice )
1437+
{
1438+
return;
1439+
}
1440+
14351441
// set the blend mode for drawing grid lines
14361442
p->save();
14371443
p->setCompositionMode( mGridBlendMode );
1444+
p->setRenderHint( QPainter::Antialiasing );
1445+
1446+
//setup painter scaling to dots so that raster symbology is drawn to scale
1447+
double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
1448+
p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
1449+
1450+
//setup render context
1451+
QgsMapSettings ms = mComposition->mapSettings();
1452+
//context units should be in dots
1453+
ms.setOutputSize( QSizeF( rect().width() * dotsPerMM, rect().height() * dotsPerMM ).toSize() );
1454+
ms.setExtent( *currentMapExtent() );
1455+
ms.setOutputDpi( p->device()->logicalDpiX() );
1456+
QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
1457+
context.setPainter( p );
14381458

14391459
//simpler approach: draw vertical lines first, then horizontal ones
14401460
if ( mGridStyle == QgsComposerMap::Solid )
14411461
{
1462+
//need to scale line to dots, rather then mm, since the painter has been scaled to dots
1463+
QLineF line;
14421464
for ( ; vIt != verticalLines.constEnd(); ++vIt )
14431465
{
1444-
drawGridLine( vIt->second, p );
1466+
line = QLineF( vIt->second.p1() * dotsPerMM, vIt->second.p2() * dotsPerMM ) ;
1467+
drawGridLine( line, context );
14451468
}
14461469

14471470
for ( ; hIt != horizontalLines.constEnd(); ++hIt )
14481471
{
1449-
drawGridLine( hIt->second, p );
1472+
line = QLineF( hIt->second.p1() * dotsPerMM, hIt->second.p2() * dotsPerMM ) ;
1473+
drawGridLine( line, context );
14501474
}
14511475
}
14521476
else //cross
@@ -1456,7 +1480,7 @@ void QgsComposerMap::drawGrid( QPainter* p )
14561480
{
14571481
//start mark
14581482
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( vIt->second.p1(), vIt->second.p2(), mCrossLength );
1459-
drawGridLine( QLineF( vIt->second.p1(), crossEnd1 ), p );
1483+
drawGridLine( QLineF( vIt->second.p1(), crossEnd1 ), context );
14601484

14611485
//test for intersection with every horizontal line
14621486
hIt = horizontalLines.constBegin();
@@ -1466,20 +1490,20 @@ void QgsComposerMap::drawGrid( QPainter* p )
14661490
{
14671491
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, vIt->second.p1(), mCrossLength );
14681492
crossEnd2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, vIt->second.p2(), mCrossLength );
1469-
drawGridLine( QLineF( crossEnd1, crossEnd2 ), p );
1493+
drawGridLine( QLineF( crossEnd1, crossEnd2 ), context );
14701494
}
14711495
}
14721496
//end mark
14731497
QPointF crossEnd2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( vIt->second.p2(), vIt->second.p1(), mCrossLength );
1474-
drawGridLine( QLineF( vIt->second.p2(), crossEnd2 ), p );
1498+
drawGridLine( QLineF( vIt->second.p2(), crossEnd2 ), context );
14751499
}
14761500

14771501
hIt = horizontalLines.constBegin();
14781502
for ( ; hIt != horizontalLines.constEnd(); ++hIt )
14791503
{
14801504
//start mark
14811505
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( hIt->second.p1(), hIt->second.p2(), mCrossLength );
1482-
drawGridLine( QLineF( hIt->second.p1(), crossEnd1 ), p );
1506+
drawGridLine( QLineF( hIt->second.p1(), crossEnd1 ), context );
14831507

14841508
vIt = verticalLines.constBegin();
14851509
for ( ; vIt != verticalLines.constEnd(); ++vIt )
@@ -1488,12 +1512,12 @@ void QgsComposerMap::drawGrid( QPainter* p )
14881512
{
14891513
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, hIt->second.p1(), mCrossLength );
14901514
crossEnd2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, hIt->second.p2(), mCrossLength );
1491-
drawGridLine( QLineF( crossEnd1, crossEnd2 ), p );
1515+
drawGridLine( QLineF( crossEnd1, crossEnd2 ), context );
14921516
}
14931517
}
14941518
//end mark
14951519
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( hIt->second.p2(), hIt->second.p1(), mCrossLength );
1496-
drawGridLine( QLineF( hIt->second.p2(), crossEnd1 ), p );
1520+
drawGridLine( QLineF( hIt->second.p2(), crossEnd1 ), context );
14971521
}
14981522
}
14991523
// reset composition mode
@@ -1529,25 +1553,16 @@ void QgsComposerMap::drawGridFrame( QPainter* p, const QList< QPair< double, QLi
15291553
drawGridFrameBorder( p, bottomGridFrame, QgsComposerMap::Bottom );
15301554
}
15311555

1532-
void QgsComposerMap::drawGridLine( const QLineF& line, QPainter* p )
1556+
void QgsComposerMap::drawGridLine( const QLineF& line, QgsRenderContext& context )
15331557
{
1534-
if ( !mGridLineSymbol || !p )
1558+
if ( !mGridLineSymbol )
15351559
{
15361560
return;
15371561
}
1538-
1539-
//setup render context
1540-
QgsRenderContext context;
1541-
context.setPainter( p );
15421562
if ( mPreviewMode == Rectangle )
15431563
{
15441564
return;
15451565
}
1546-
else
1547-
{
1548-
context.setScaleFactor( 1.0 );
1549-
context.setRasterScaleFactor( mComposition->printResolution() / 25.4 );
1550-
}
15511566

15521567
QPolygonF poly;
15531568
poly << line.p1() << line.p2();
@@ -2556,22 +2571,33 @@ void QgsComposerMap::drawOverviewMapExtent( QPainter* p )
25562571
QgsRectangle thisExtent = *currentMapExtent();
25572572
QgsRectangle intersectRect = thisExtent.intersect( &otherExtent );
25582573

2559-
QgsRenderContext context;
2574+
//setup painter scaling to dots so that raster symbology is drawn to scale
2575+
double dotsPerMM = p->device()->logicalDpiX() / 25.4;
2576+
2577+
//setup render context
2578+
QgsMapSettings ms = mComposition->mapSettings();
2579+
//context units should be in dots
2580+
ms.setOutputSize( QSizeF( rect().width() * dotsPerMM, rect().height() * dotsPerMM ).toSize() );
2581+
ms.setExtent( *currentMapExtent() );
2582+
ms.setOutputDpi( p->device()->logicalDpiX() );
2583+
QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
25602584
context.setPainter( p );
2561-
context.setScaleFactor( 1.0 );
2562-
context.setRasterScaleFactor( mComposition->printResolution() / 25.4 );
25632585

25642586
p->save();
25652587
p->setCompositionMode( mOverviewBlendMode );
25662588
p->translate( mXOffset, mYOffset );
2589+
p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
2590+
p->setRenderHint( QPainter::Antialiasing );
2591+
25672592
mOverviewFrameMapSymbol->startRender( context );
25682593

25692594
//construct a polygon corresponding to the intersecting map extent
2595+
//need to scale line to dots, rather then mm, since the painter has been scaled to dots
25702596
QPolygonF intersectPolygon;
2571-
double x = ( intersectRect.xMinimum() - thisExtent.xMinimum() ) / thisExtent.width() * rect().width();
2572-
double y = ( thisExtent.yMaximum() - intersectRect.yMaximum() ) / thisExtent.height() * rect().height();
2573-
double width = intersectRect.width() / thisExtent.width() * rect().width();
2574-
double height = intersectRect.height() / thisExtent.height() * rect().height();
2597+
double x = dotsPerMM * ( intersectRect.xMinimum() - thisExtent.xMinimum() ) / thisExtent.width() * rect().width();
2598+
double y = dotsPerMM * ( thisExtent.yMaximum() - intersectRect.yMaximum() ) / thisExtent.height() * rect().height();
2599+
double width = dotsPerMM * intersectRect.width() / thisExtent.width() * rect().width();
2600+
double height = dotsPerMM * intersectRect.height() / thisExtent.height() * rect().height();
25752601
intersectPolygon << QPointF( x, y ) << QPointF( x + width, y ) << QPointF( x + width, y + height ) << QPointF( x, y + height ) << QPointF( x, y );
25762602

25772603
QList<QPolygonF> rings; //empty list

src/core/composer/qgscomposermap.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
727727
void sortGridLinesOnBorders( const QList< QPair< double, QLineF > >& hLines, const QList< QPair< double, QLineF > >& vLines, QMap< double, double >& leftFrameEntries,
728728
QMap< double, double >& rightFrameEntries, QMap< double, double >& topFrameEntries, QMap< double, double >& bottomFrameEntries ) const;
729729
void drawGridFrameBorder( QPainter* p, const QMap< double, double >& borderPos, Border border );
730-
void drawGridLine( const QLineF& line, QPainter* p );
730+
void drawGridLine( const QLineF& line, QgsRenderContext& context );
731731
void drawOverviewMapExtent( QPainter* p );
732732
void createDefaultOverviewFrameSymbol();
733733
void createDefaultGridLineSymbol();

0 commit comments

Comments
 (0)