mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[composer] Correctly handle symbology using map units when drawing grid lines and overlays on maps (fix #8210)
This commit is contained in:
parent
95f88aeea9
commit
4a70d1b9e2
@ -1432,21 +1432,45 @@ void QgsComposerMap::drawGrid( QPainter* p )
|
||||
QRectF thisPaintRect = QRectF( 0, 0, QGraphicsRectItem::rect().width(), QGraphicsRectItem::rect().height() );
|
||||
p->setClipRect( thisPaintRect );
|
||||
|
||||
QPaintDevice* thePaintDevice = p->device();
|
||||
if ( !thePaintDevice )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// set the blend mode for drawing grid lines
|
||||
p->save();
|
||||
p->setCompositionMode( mGridBlendMode );
|
||||
p->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
//setup painter scaling to dots so that raster symbology is drawn to scale
|
||||
double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
|
||||
p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
|
||||
|
||||
//setup render context
|
||||
QgsMapSettings ms = mComposition->mapSettings();
|
||||
//context units should be in dots
|
||||
ms.setOutputSize( QSizeF( rect().width() * dotsPerMM, rect().height() * dotsPerMM ).toSize() );
|
||||
ms.setExtent( *currentMapExtent() );
|
||||
ms.setOutputDpi( p->device()->logicalDpiX() );
|
||||
QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
|
||||
context.setPainter( p );
|
||||
|
||||
//simpler approach: draw vertical lines first, then horizontal ones
|
||||
if ( mGridStyle == QgsComposerMap::Solid )
|
||||
{
|
||||
//need to scale line to dots, rather then mm, since the painter has been scaled to dots
|
||||
QLineF line;
|
||||
for ( ; vIt != verticalLines.constEnd(); ++vIt )
|
||||
{
|
||||
drawGridLine( vIt->second, p );
|
||||
line = QLineF( vIt->second.p1() * dotsPerMM, vIt->second.p2() * dotsPerMM ) ;
|
||||
drawGridLine( line, context );
|
||||
}
|
||||
|
||||
for ( ; hIt != horizontalLines.constEnd(); ++hIt )
|
||||
{
|
||||
drawGridLine( hIt->second, p );
|
||||
line = QLineF( hIt->second.p1() * dotsPerMM, hIt->second.p2() * dotsPerMM ) ;
|
||||
drawGridLine( line, context );
|
||||
}
|
||||
}
|
||||
else //cross
|
||||
@ -1456,7 +1480,7 @@ void QgsComposerMap::drawGrid( QPainter* p )
|
||||
{
|
||||
//start mark
|
||||
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( vIt->second.p1(), vIt->second.p2(), mCrossLength );
|
||||
drawGridLine( QLineF( vIt->second.p1(), crossEnd1 ), p );
|
||||
drawGridLine( QLineF( vIt->second.p1(), crossEnd1 ), context );
|
||||
|
||||
//test for intersection with every horizontal line
|
||||
hIt = horizontalLines.constBegin();
|
||||
@ -1466,12 +1490,12 @@ void QgsComposerMap::drawGrid( QPainter* p )
|
||||
{
|
||||
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, vIt->second.p1(), mCrossLength );
|
||||
crossEnd2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, vIt->second.p2(), mCrossLength );
|
||||
drawGridLine( QLineF( crossEnd1, crossEnd2 ), p );
|
||||
drawGridLine( QLineF( crossEnd1, crossEnd2 ), context );
|
||||
}
|
||||
}
|
||||
//end mark
|
||||
QPointF crossEnd2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( vIt->second.p2(), vIt->second.p1(), mCrossLength );
|
||||
drawGridLine( QLineF( vIt->second.p2(), crossEnd2 ), p );
|
||||
drawGridLine( QLineF( vIt->second.p2(), crossEnd2 ), context );
|
||||
}
|
||||
|
||||
hIt = horizontalLines.constBegin();
|
||||
@ -1479,7 +1503,7 @@ void QgsComposerMap::drawGrid( QPainter* p )
|
||||
{
|
||||
//start mark
|
||||
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( hIt->second.p1(), hIt->second.p2(), mCrossLength );
|
||||
drawGridLine( QLineF( hIt->second.p1(), crossEnd1 ), p );
|
||||
drawGridLine( QLineF( hIt->second.p1(), crossEnd1 ), context );
|
||||
|
||||
vIt = verticalLines.constBegin();
|
||||
for ( ; vIt != verticalLines.constEnd(); ++vIt )
|
||||
@ -1488,12 +1512,12 @@ void QgsComposerMap::drawGrid( QPainter* p )
|
||||
{
|
||||
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, hIt->second.p1(), mCrossLength );
|
||||
crossEnd2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( intersectionPoint, hIt->second.p2(), mCrossLength );
|
||||
drawGridLine( QLineF( crossEnd1, crossEnd2 ), p );
|
||||
drawGridLine( QLineF( crossEnd1, crossEnd2 ), context );
|
||||
}
|
||||
}
|
||||
//end mark
|
||||
crossEnd1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( hIt->second.p2(), hIt->second.p1(), mCrossLength );
|
||||
drawGridLine( QLineF( hIt->second.p2(), crossEnd1 ), p );
|
||||
drawGridLine( QLineF( hIt->second.p2(), crossEnd1 ), context );
|
||||
}
|
||||
}
|
||||
// reset composition mode
|
||||
@ -1529,25 +1553,16 @@ void QgsComposerMap::drawGridFrame( QPainter* p, const QList< QPair< double, QLi
|
||||
drawGridFrameBorder( p, bottomGridFrame, QgsComposerMap::Bottom );
|
||||
}
|
||||
|
||||
void QgsComposerMap::drawGridLine( const QLineF& line, QPainter* p )
|
||||
void QgsComposerMap::drawGridLine( const QLineF& line, QgsRenderContext& context )
|
||||
{
|
||||
if ( !mGridLineSymbol || !p )
|
||||
if ( !mGridLineSymbol )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//setup render context
|
||||
QgsRenderContext context;
|
||||
context.setPainter( p );
|
||||
if ( mPreviewMode == Rectangle )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.setScaleFactor( 1.0 );
|
||||
context.setRasterScaleFactor( mComposition->printResolution() / 25.4 );
|
||||
}
|
||||
|
||||
QPolygonF poly;
|
||||
poly << line.p1() << line.p2();
|
||||
@ -2556,22 +2571,33 @@ void QgsComposerMap::drawOverviewMapExtent( QPainter* p )
|
||||
QgsRectangle thisExtent = *currentMapExtent();
|
||||
QgsRectangle intersectRect = thisExtent.intersect( &otherExtent );
|
||||
|
||||
QgsRenderContext context;
|
||||
//setup painter scaling to dots so that raster symbology is drawn to scale
|
||||
double dotsPerMM = p->device()->logicalDpiX() / 25.4;
|
||||
|
||||
//setup render context
|
||||
QgsMapSettings ms = mComposition->mapSettings();
|
||||
//context units should be in dots
|
||||
ms.setOutputSize( QSizeF( rect().width() * dotsPerMM, rect().height() * dotsPerMM ).toSize() );
|
||||
ms.setExtent( *currentMapExtent() );
|
||||
ms.setOutputDpi( p->device()->logicalDpiX() );
|
||||
QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
|
||||
context.setPainter( p );
|
||||
context.setScaleFactor( 1.0 );
|
||||
context.setRasterScaleFactor( mComposition->printResolution() / 25.4 );
|
||||
|
||||
p->save();
|
||||
p->setCompositionMode( mOverviewBlendMode );
|
||||
p->translate( mXOffset, mYOffset );
|
||||
p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
|
||||
p->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
mOverviewFrameMapSymbol->startRender( context );
|
||||
|
||||
//construct a polygon corresponding to the intersecting map extent
|
||||
//need to scale line to dots, rather then mm, since the painter has been scaled to dots
|
||||
QPolygonF intersectPolygon;
|
||||
double x = ( intersectRect.xMinimum() - thisExtent.xMinimum() ) / thisExtent.width() * rect().width();
|
||||
double y = ( thisExtent.yMaximum() - intersectRect.yMaximum() ) / thisExtent.height() * rect().height();
|
||||
double width = intersectRect.width() / thisExtent.width() * rect().width();
|
||||
double height = intersectRect.height() / thisExtent.height() * rect().height();
|
||||
double x = dotsPerMM * ( intersectRect.xMinimum() - thisExtent.xMinimum() ) / thisExtent.width() * rect().width();
|
||||
double y = dotsPerMM * ( thisExtent.yMaximum() - intersectRect.yMaximum() ) / thisExtent.height() * rect().height();
|
||||
double width = dotsPerMM * intersectRect.width() / thisExtent.width() * rect().width();
|
||||
double height = dotsPerMM * intersectRect.height() / thisExtent.height() * rect().height();
|
||||
intersectPolygon << QPointF( x, y ) << QPointF( x + width, y ) << QPointF( x + width, y + height ) << QPointF( x, y + height ) << QPointF( x, y );
|
||||
|
||||
QList<QPolygonF> rings; //empty list
|
||||
|
@ -727,7 +727,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
void sortGridLinesOnBorders( const QList< QPair< double, QLineF > >& hLines, const QList< QPair< double, QLineF > >& vLines, QMap< double, double >& leftFrameEntries,
|
||||
QMap< double, double >& rightFrameEntries, QMap< double, double >& topFrameEntries, QMap< double, double >& bottomFrameEntries ) const;
|
||||
void drawGridFrameBorder( QPainter* p, const QMap< double, double >& borderPos, Border border );
|
||||
void drawGridLine( const QLineF& line, QPainter* p );
|
||||
void drawGridLine( const QLineF& line, QgsRenderContext& context );
|
||||
void drawOverviewMapExtent( QPainter* p );
|
||||
void createDefaultOverviewFrameSymbol();
|
||||
void createDefaultGridLineSymbol();
|
||||
|
Loading…
x
Reference in New Issue
Block a user