@@ -144,6 +144,7 @@ double QgsComposerMapGridStack::maxGridExtension() const
144144
145145QgsComposerMapGrid::QgsComposerMapGrid ( const QString& name, QgsComposerMap* map )
146146 : QgsComposerMapItem( name, map )
147+ , mTransformDirty( true )
147148 , mGridStyle( QgsComposerMapGrid::Solid )
148149 , mGridIntervalX( 0.0 )
149150 , mGridIntervalY( 0.0 )
@@ -382,6 +383,12 @@ bool QgsComposerMapGrid::readXML( const QDomElement& itemElem, const QDomDocumen
382383 return ok;
383384}
384385
386+ void QgsComposerMapGrid::setCrs ( const QgsCoordinateReferenceSystem &crs )
387+ {
388+ mCRS = crs;
389+ mTransformDirty = true ;
390+ }
391+
385392bool QgsComposerMapGrid::usesAdvancedEffects () const
386393{
387394 return mBlendMode == QPainter::CompositionMode_SourceOver;
@@ -394,48 +401,110 @@ QPolygonF QgsComposerMapGrid::scalePolygon( const QPolygonF &polygon, const doub
394401}
395402
396403void QgsComposerMapGrid::drawGridCRSTransform ( QgsRenderContext &context, double dotsPerMM, QList< QPair< double , QLineF > > &horizontalLines,
397- QList< QPair< double , QLineF > > &verticalLines ) const
404+ QList< QPair< double , QLineF > > &verticalLines )
398405{
399406 if ( !mComposerMap || !mEnabled )
400407 {
401408 return ;
402409 }
403410
404- QgsRectangle crsBoundingRect;
405- QgsCoordinateTransform inverseTr ;
406- if ( crsGridParams ( crsBoundingRect, inverseTr ) != 0 )
411+ // has map extent/scale changed?
412+ QPolygonF mapPolygon = mComposerMap -> transformedMapPolygon () ;
413+ if ( mapPolygon != mPrevMapPolygon )
407414 {
408- return ;
415+ mTransformDirty = true ;
416+ mPrevMapPolygon = mapPolygon;
409417 }
410418
411- // x grid lines
412- QList< QPair< double , QPolygonF > > xGridLines;
413- xGridLinesCRSTransform ( crsBoundingRect, inverseTr, xGridLines );
414-
415- // y grid lines
416- QList< QPair< double , QPolygonF > > yGridLines;
417- yGridLinesCRSTransform ( crsBoundingRect, inverseTr, yGridLines );
419+ if ( mTransformDirty )
420+ {
421+ calculateCRSTransformLines ();
422+ }
418423
424+ // draw lines
419425 if ( mGridStyle == QgsComposerMapGrid::Solid )
420426 {
421- QList< QPair< double , QPolygonF > >::const_iterator xGridIt = xGridLines .constBegin ();
422- for ( ; xGridIt != xGridLines .constEnd (); ++xGridIt )
427+ QList< QPair< double , QPolygonF > >::const_iterator xGridIt = mTransformedXLines .constBegin ();
428+ for ( ; xGridIt != mTransformedXLines .constEnd (); ++xGridIt )
423429 {
424430 drawGridLine ( scalePolygon ( xGridIt->second , dotsPerMM ), context );
425431 }
426432
427- QList< QPair< double , QPolygonF > >::const_iterator yGridIt = yGridLines .constBegin ();
428- for ( ; yGridIt != yGridLines .constEnd (); ++yGridIt )
433+ QList< QPair< double , QPolygonF > >::const_iterator yGridIt = mTransformedYLines .constBegin ();
434+ for ( ; yGridIt != mTransformedYLines .constEnd (); ++yGridIt )
429435 {
430436 drawGridLine ( scalePolygon ( yGridIt->second , dotsPerMM ), context );
431437 }
432438 }
433- else if ( mGridStyle != QgsComposerMapGrid::FrameAnnotationsOnly ) // cross or markers
439+ else if ( mGridStyle == QgsComposerMapGrid::Cross || mGridStyle == QgsComposerMapGrid::Markers )
440+ {
441+ double maxX = mComposerMap ->rect ().width ();
442+ double maxY = mComposerMap ->rect ().height ();
443+
444+ QList< QgsPoint >::const_iterator intersectionIt = mTransformedIntersections .constBegin ();
445+ for ( ; intersectionIt != mTransformedIntersections .constEnd (); ++intersectionIt )
446+ {
447+ double x = intersectionIt->x ();
448+ double y = intersectionIt->y ();
449+ if ( mGridStyle == QgsComposerMapGrid::Cross )
450+ {
451+ // ensure that crosses don't overshoot the map item bounds
452+ QLineF line1 = QLineF ( x - mCrossLength , y, x + mCrossLength , y );
453+ line1.p1 ().rx () = line1.p1 ().x () < 0 ? 0 : line1.p1 ().x ();
454+ line1.p2 ().rx () = line1.p2 ().x () > maxX ? maxX : line1.p2 ().x ();
455+ QLineF line2 = QLineF ( x, y - mCrossLength , x, y + mCrossLength );
456+ line2.p1 ().ry () = line2.p1 ().y () < 0 ? 0 : line2.p1 ().y ();
457+ line2.p2 ().ry () = line2.p2 ().y () > maxY ? maxY : line2.p2 ().y ();
458+
459+ // draw line using coordinates scaled to dots
460+ drawGridLine ( QLineF ( line1.p1 () * dotsPerMM, line1.p2 () * dotsPerMM ), context );
461+ drawGridLine ( QLineF ( line2.p1 () * dotsPerMM, line2.p2 () * dotsPerMM ), context );
462+ }
463+ else if ( mGridStyle == QgsComposerMapGrid::Markers )
464+ {
465+ drawGridMarker ( QPointF ( x, y ) * dotsPerMM , context );
466+ }
467+ }
468+ }
469+
470+ // convert QPolygonF to QLineF to draw grid frames and annotations
471+ QList< QPair< double , QPolygonF > >::const_iterator yGridLineIt = mTransformedYLines .constBegin ();
472+ for ( ; yGridLineIt != mTransformedYLines .constEnd (); ++yGridLineIt )
434473 {
435- // convert lines to QgsGeometry
474+ verticalLines.push_back ( qMakePair ( yGridLineIt->first , QLineF ( yGridLineIt->second .first (), yGridLineIt->second .last () ) ) );
475+ }
476+ QList< QPair< double , QPolygonF > >::const_iterator xGridLineIt = mTransformedXLines .constBegin ();
477+ for ( ; xGridLineIt != mTransformedXLines .constEnd (); ++xGridLineIt )
478+ {
479+ horizontalLines.push_back ( qMakePair ( xGridLineIt->first , QLineF ( xGridLineIt->second .first (), xGridLineIt->second .last () ) ) );
480+ }
481+ }
482+
483+ void QgsComposerMapGrid::calculateCRSTransformLines ()
484+ {
485+ QgsRectangle crsBoundingRect;
486+ QgsCoordinateTransform inverseTr;
487+ if ( crsGridParams ( crsBoundingRect, inverseTr ) != 0 )
488+ {
489+ return ;
490+ }
491+
492+ // calculate x grid lines
493+ mTransformedXLines .clear ();
494+ xGridLinesCRSTransform ( crsBoundingRect, inverseTr, mTransformedXLines );
495+
496+ // calculate y grid lines
497+ mTransformedYLines .clear ();
498+ yGridLinesCRSTransform ( crsBoundingRect, inverseTr, mTransformedYLines );
499+
500+ if ( mGridStyle == QgsComposerMapGrid::Cross || mGridStyle == QgsComposerMapGrid::Markers )
501+ {
502+ // cross or markers style - we also need to calculate intersections of lines
503+
504+ // first convert lines to QgsGeometry
436505 QList< QgsGeometry* > yLines;
437- QList< QPair< double , QPolygonF > >::const_iterator yGridIt = yGridLines .constBegin ();
438- for ( ; yGridIt != yGridLines .constEnd (); ++yGridIt )
506+ QList< QPair< double , QPolygonF > >::const_iterator yGridIt = mTransformedYLines .constBegin ();
507+ for ( ; yGridIt != mTransformedYLines .constEnd (); ++yGridIt )
439508 {
440509 QgsPolyline yLine;
441510 for ( int i = 0 ; i < ( *yGridIt ).second .size (); ++i )
@@ -445,8 +514,8 @@ void QgsComposerMapGrid::drawGridCRSTransform( QgsRenderContext &context, double
445514 yLines << QgsGeometry::fromPolyline ( yLine );
446515 }
447516 QList< QgsGeometry* > xLines;
448- QList< QPair< double , QPolygonF > >::const_iterator xGridIt = xGridLines .constBegin ();
449- for ( ; xGridIt != xGridLines .constEnd (); ++xGridIt )
517+ QList< QPair< double , QPolygonF > >::const_iterator xGridIt = mTransformedXLines .constBegin ();
518+ for ( ; xGridIt != mTransformedXLines .constEnd (); ++xGridIt )
450519 {
451520 QgsPolyline xLine;
452521 for ( int i = 0 ; i < ( *xGridIt ).second .size (); ++i )
@@ -456,9 +525,8 @@ void QgsComposerMapGrid::drawGridCRSTransform( QgsRenderContext &context, double
456525 xLines << QgsGeometry::fromPolyline ( xLine );
457526 }
458527
459- double maxX = mComposerMap ->rect ().width ();
460- double maxY = mComposerMap ->rect ().height ();
461-
528+ // now, loop through geometries and calculate intersection points
529+ mTransformedIntersections .clear ();
462530 QList< QgsGeometry* >::const_iterator yLineIt = yLines.constBegin ();
463531 for ( ; yLineIt != yLines.constEnd (); ++yLineIt )
464532 {
@@ -473,52 +541,23 @@ void QgsComposerMapGrid::drawGridCRSTransform( QgsRenderContext &context, double
473541 QgsPoint vertex = intersects->vertexAt ( i );
474542 while ( vertex != QgsPoint ( 0 , 0 ) )
475543 {
476- if ( mGridStyle == QgsComposerMapGrid::Cross )
477- {
478- // ensure that crosses don't overshoot the map item bounds
479- QLineF line1 = QLineF ( vertex.x () - mCrossLength , vertex.y (), vertex.x () + mCrossLength , vertex.y () );
480- line1.p1 ().rx () = line1.p1 ().x () < 0 ? 0 : line1.p1 ().x ();
481- line1.p2 ().rx () = line1.p2 ().x () > maxX ? maxX : line1.p2 ().x ();
482- QLineF line2 = QLineF ( vertex.x () , vertex.y () - mCrossLength , vertex.x (), vertex.y () + mCrossLength );
483- line2.p1 ().ry () = line2.p1 ().y () < 0 ? 0 : line2.p1 ().y ();
484- line2.p2 ().ry () = line2.p2 ().y () > maxY ? maxY : line2.p2 ().y ();
485-
486- // draw line using coordinates scaled to dots
487- drawGridLine ( QLineF ( line1.p1 () * dotsPerMM, line1.p2 () * dotsPerMM ), context );
488- drawGridLine ( QLineF ( line2.p1 () * dotsPerMM, line2.p2 () * dotsPerMM ), context );
489- }
490- else if ( mGridStyle == QgsComposerMapGrid::Markers )
491- {
492- drawGridMarker ( QPointF ( vertex.x (), vertex.y () ) * dotsPerMM , context );
493- }
494-
544+ mTransformedIntersections << vertex;
495545 i = i + 1 ;
496546 vertex = intersects->vertexAt ( i );
497547 }
498548 }
499549 }
500-
550+ // clean up
501551 qDeleteAll ( yLines );
502552 yLines.clear ();
503553 qDeleteAll ( xLines );
504554 xLines.clear ();
505555 }
506556
507- // convert QPolygonF to QLineF to draw grid frames and annotations
508- QList< QPair< double , QPolygonF > >::const_iterator yGridLineIt = yGridLines.constBegin ();
509- for ( ; yGridLineIt != yGridLines.constEnd (); ++yGridLineIt )
510- {
511- verticalLines.push_back ( qMakePair ( yGridLineIt->first , QLineF ( yGridLineIt->second .first (), yGridLineIt->second .last () ) ) );
512- }
513- QList< QPair< double , QPolygonF > >::const_iterator xGridLineIt = xGridLines.constBegin ();
514- for ( ; xGridLineIt != xGridLines.constEnd (); ++xGridLineIt )
515- {
516- horizontalLines.push_back ( qMakePair ( xGridLineIt->first , QLineF ( xGridLineIt->second .first (), xGridLineIt->second .last () ) ) );
517- }
518-
557+ mTransformDirty = false ;
519558}
520559
521- void QgsComposerMapGrid::draw ( QPainter* p ) const
560+ void QgsComposerMapGrid::draw ( QPainter* p )
522561{
523562 if ( !mComposerMap || !mEnabled )
524563 {
@@ -536,6 +575,12 @@ void QgsComposerMapGrid::draw( QPainter* p ) const
536575
537576 QRectF thisPaintRect = QRectF ( 0 , 0 , mComposerMap ->rect ().width (), mComposerMap ->rect ().height () );
538577 p->setClipRect ( thisPaintRect );
578+ if ( thisPaintRect != mPrevPaintRect )
579+ {
580+ // rect has changed, so need to recalculate transform
581+ mTransformDirty = true ;
582+ mPrevPaintRect = thisPaintRect;
583+ }
539584
540585 // setup painter scaling to dots so that raster symbology is drawn to scale
541586 double dotsPerMM = thePaintDevice->logicalDpiX () / 25.4 ;
@@ -1694,6 +1739,66 @@ double QgsComposerMapGrid::maxExtension() const
16941739 return maxExtension + mAnnotationFrameDistance + gridFrameDist;
16951740}
16961741
1742+ void QgsComposerMapGrid::setUnits ( const QgsComposerMapGrid::GridUnit unit )
1743+ {
1744+ if ( unit == mGridUnit )
1745+ {
1746+ return ;
1747+ }
1748+ mGridUnit = unit;
1749+ mTransformDirty = true ;
1750+ }
1751+
1752+ void QgsComposerMapGrid::setIntervalX ( const double interval )
1753+ {
1754+ if ( interval == mGridIntervalX )
1755+ {
1756+ return ;
1757+ }
1758+ mGridIntervalX = interval;
1759+ mTransformDirty = true ;
1760+ }
1761+
1762+ void QgsComposerMapGrid::setIntervalY ( const double interval )
1763+ {
1764+ if ( interval == mGridIntervalY )
1765+ {
1766+ return ;
1767+ }
1768+ mGridIntervalY = interval;
1769+ mTransformDirty = true ;
1770+ }
1771+
1772+ void QgsComposerMapGrid::setOffsetX ( const double offset )
1773+ {
1774+ if ( offset == mGridOffsetX )
1775+ {
1776+ return ;
1777+ }
1778+ mGridOffsetX = offset;
1779+ mTransformDirty = true ;
1780+ }
1781+
1782+ void QgsComposerMapGrid::setOffsetY ( const double offset )
1783+ {
1784+ if ( offset == mGridOffsetY )
1785+ {
1786+ return ;
1787+ }
1788+ mGridOffsetY = offset;
1789+ mTransformDirty = true ;
1790+ }
1791+
1792+ void QgsComposerMapGrid::setStyle ( const QgsComposerMapGrid::GridStyle style )
1793+ {
1794+ if ( style == mGridStyle )
1795+ {
1796+ return ;
1797+ }
1798+ mGridStyle = style;
1799+ mTransformDirty = true ;
1800+ }
1801+
16971802void QgsComposerMapGrid::setAnnotationDirection ( const QgsComposerMapGrid::AnnotationDirection direction, const QgsComposerMapGrid::BorderSide border )
16981803{
16991804 switch ( border )
0 commit comments