34 #define MAX_GRID_LINES 1000 //maximum number of horizontal or vertical grid lines to draw
86 QList< QgsComposerMapGrid* > list;
87 QList< QgsComposerMapItem* >::const_iterator it =
mItems.begin();
88 for ( ; it !=
mItems.end(); ++it )
111 QDomNodeList mapGridNodeList = elem.elementsByTagName(
"ComposerMapGrid" );
112 for (
int i = 0; i < mapGridNodeList.size(); ++i )
114 QDomElement mapGridElem = mapGridNodeList.at( i ).toElement();
116 mapGrid->
readXML( mapGridElem, doc );
127 QList< QgsComposerMapItem* >::const_iterator it =
mItems.constBegin();
128 for ( ; it !=
mItems.constEnd(); ++it )
133 maxGridExtension = qMax( maxGridExtension, grid->
maxExtension() );
152 QgsComposerMapGrid::QgsComposerMapGrid()
158 void QgsComposerMapGrid::init()
160 mTransformDirty =
true;
162 mGridIntervalX = 0.0;
163 mGridIntervalY = 0.0;
166 mGridAnnotationFontColor = Qt::black;
167 mGridAnnotationPrecision = 3;
168 mShowGridAnnotation =
false;
177 mAnnotationFrameDistance = 1.0;
186 mGridFrameWidth = 2.0;
187 mGridFramePenThickness = 0.3;
188 mGridFramePenColor = QColor( 0, 0, 0 );
189 mGridFrameFillColor1 = Qt::white;
190 mGridFrameFillColor2 = Qt::black;
197 mGridMarkerSymbol = 0;
199 mBlendMode = QPainter::CompositionMode_SourceOver;
203 QString defaultFontString = settings.value(
"/Composer/defaultFont" ).toString();
204 if ( !defaultFontString.isEmpty() )
206 mGridAnnotationFont.setFamily( defaultFontString );
209 createDefaultGridLineSymbol();
210 createDefaultGridMarkerSymbol();
215 delete mGridLineSymbol;
216 delete mGridMarkerSymbol;
219 void QgsComposerMapGrid::createDefaultGridLineSymbol()
221 delete mGridLineSymbol;
223 properties.insert(
"color",
"0,0,0,255" );
224 properties.insert(
"width",
"0.3" );
225 properties.insert(
"capstyle",
"flat" );
229 void QgsComposerMapGrid::createDefaultGridMarkerSymbol()
231 delete mGridMarkerSymbol;
233 properties.insert(
"name",
"circle" );
234 properties.insert(
"size",
"2.0" );
235 properties.insert(
"color",
"0,0,0,255" );
241 if ( mGridLineSymbol )
249 if ( mGridLineSymbol )
262 QDomElement mapGridElem = doc.createElement(
"ComposerMapGrid" );
263 mapGridElem.setAttribute(
"gridStyle", mGridStyle );
270 QDomElement lineStyleElem = doc.createElement(
"lineStyle" );
272 lineStyleElem.appendChild( gridLineStyleElem );
273 mapGridElem.appendChild( lineStyleElem );
275 QDomElement markerStyleElem = doc.createElement(
"markerStyle" );
277 markerStyleElem.appendChild( gridMarkerStyleElem );
278 mapGridElem.appendChild( markerStyleElem );
280 mapGridElem.setAttribute(
"gridFrameStyle", mGridFrameStyle );
281 mapGridElem.setAttribute(
"gridFrameSideFlags", mGridFrameSides );
282 mapGridElem.setAttribute(
"gridFrameWidth",
qgsDoubleToString( mGridFrameWidth ) );
283 mapGridElem.setAttribute(
"gridFramePenThickness",
qgsDoubleToString( mGridFramePenThickness ) );
287 mapGridElem.setAttribute(
"leftFrameDivisions", mLeftFrameDivisions );
288 mapGridElem.setAttribute(
"rightFrameDivisions", mRightFrameDivisions );
289 mapGridElem.setAttribute(
"topFrameDivisions", mTopFrameDivisions );
290 mapGridElem.setAttribute(
"bottomFrameDivisions", mBottomFrameDivisions );
296 mapGridElem.setAttribute(
"annotationFormat", mGridAnnotationFormat );
297 mapGridElem.setAttribute(
"showAnnotation", mShowGridAnnotation );
298 mapGridElem.setAttribute(
"leftAnnotationDisplay", mLeftGridAnnotationDisplay );
299 mapGridElem.setAttribute(
"rightAnnotationDisplay", mRightGridAnnotationDisplay );
300 mapGridElem.setAttribute(
"topAnnotationDisplay", mTopGridAnnotationDisplay );
301 mapGridElem.setAttribute(
"bottomAnnotationDisplay", mBottomGridAnnotationDisplay );
302 mapGridElem.setAttribute(
"leftAnnotationPosition", mLeftGridAnnotationPosition );
303 mapGridElem.setAttribute(
"rightAnnotationPosition", mRightGridAnnotationPosition );
304 mapGridElem.setAttribute(
"topAnnotationPosition", mTopGridAnnotationPosition );
305 mapGridElem.setAttribute(
"bottomAnnotationPosition", mBottomGridAnnotationPosition );
306 mapGridElem.setAttribute(
"leftAnnotationDirection", mLeftGridAnnotationDirection );
307 mapGridElem.setAttribute(
"rightAnnotationDirection", mRightGridAnnotationDirection );
308 mapGridElem.setAttribute(
"topAnnotationDirection", mTopGridAnnotationDirection );
309 mapGridElem.setAttribute(
"bottomAnnotationDirection", mBottomGridAnnotationDirection );
310 mapGridElem.setAttribute(
"frameAnnotationDistance", QString::number( mAnnotationFrameDistance ) );
311 mapGridElem.setAttribute(
"annotationFont", mGridAnnotationFont.toString() );
313 mapGridElem.setAttribute(
"annotationPrecision", mGridAnnotationPrecision );
314 mapGridElem.setAttribute(
"unit", mGridUnit );
315 mapGridElem.setAttribute(
"blendMode", mBlendMode );
318 elem.appendChild( mapGridElem );
325 if ( itemElem.isNull() )
334 mGridIntervalX = itemElem.attribute(
"intervalX",
"0" ).toDouble();
335 mGridIntervalY = itemElem.attribute(
"intervalY",
"0" ).toDouble();
336 mGridOffsetX = itemElem.attribute(
"offsetX",
"0" ).toDouble();
337 mGridOffsetY = itemElem.attribute(
"offsetY",
"0" ).toDouble();
338 mCrossLength = itemElem.attribute(
"crossLength",
"3" ).toDouble();
340 mGridFrameSides = ( QgsComposerMapGrid::FrameSideFlags )itemElem.attribute(
"gridFrameSideFlags",
"15" ).toInt();
341 mGridFrameWidth = itemElem.attribute(
"gridFrameWidth",
"2.0" ).toDouble();
342 mGridFramePenThickness = itemElem.attribute(
"gridFramePenThickness",
"0.3" ).toDouble();
351 QDomElement lineStyleElem = itemElem.firstChildElement(
"lineStyle" );
352 if ( !lineStyleElem.isNull() )
354 QDomElement symbolElem = lineStyleElem.firstChildElement(
"symbol" );
355 if ( !symbolElem.isNull() )
357 delete mGridLineSymbol;
358 mGridLineSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsLineSymbolV2>( symbolElem );
365 mGridLineSymbol->
setWidth( itemElem.attribute(
"penWidth",
"0" ).toDouble() );
366 mGridLineSymbol->
setColor( QColor( itemElem.attribute(
"penColorRed",
"0" ).toInt(),
367 itemElem.attribute(
"penColorGreen",
"0" ).toInt(),
368 itemElem.attribute(
"penColorBlue",
"0" ).toInt() ) );
371 QDomElement markerStyleElem = itemElem.firstChildElement(
"markerStyle" );
372 if ( !markerStyleElem.isNull() )
374 QDomElement symbolElem = markerStyleElem.firstChildElement(
"symbol" );
375 if ( !symbolElem.isNull() )
377 delete mGridMarkerSymbol;
378 mGridMarkerSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( symbolElem );
383 QDomElement crsElem = itemElem.firstChildElement(
"spatialrefsys" );
384 if ( !crsElem.isNull() )
386 mCRS.
readXML( const_cast<QDomElement&>( itemElem ) );
392 mBlendMode = ( QPainter::CompositionMode )( itemElem.attribute(
"blendMode",
"0" ).toUInt() );
395 mShowGridAnnotation = ( itemElem.attribute(
"showAnnotation",
"0" ) !=
"0" );
431 mAnnotationFrameDistance = itemElem.attribute(
"frameAnnotationDistance",
"0" ).toDouble();
432 mGridAnnotationFont.fromString( itemElem.attribute(
"annotationFont",
"" ) );
434 mGridAnnotationPrecision = itemElem.attribute(
"annotationPrecision",
"3" ).toInt();
435 int gridUnitInt = itemElem.attribute(
"unit", QString::number(
MapUnit ) ).toInt();
443 mTransformDirty =
true;
448 return mBlendMode == QPainter::CompositionMode_SourceOver;
451 QPolygonF QgsComposerMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
453 QTransform t = QTransform::fromScale( scale, scale );
454 return t.map( polygon );
457 void QgsComposerMapGrid::drawGridCRSTransform(
QgsRenderContext &context,
double dotsPerMM, QList< QPair< double, QLineF > > &horizontalLines,
458 QList< QPair< double, QLineF > > &verticalLines )
467 if ( mapPolygon != mPrevMapPolygon )
469 mTransformDirty =
true;
470 mPrevMapPolygon = mapPolygon;
473 if ( mTransformDirty )
475 calculateCRSTransformLines();
481 QList< QPair< double, QPolygonF > >::const_iterator xGridIt = mTransformedXLines.constBegin();
482 for ( ; xGridIt != mTransformedXLines.constEnd(); ++xGridIt )
484 drawGridLine( scalePolygon( xGridIt->second, dotsPerMM ), context );
487 QList< QPair< double, QPolygonF > >::const_iterator yGridIt = mTransformedYLines.constBegin();
488 for ( ; yGridIt != mTransformedYLines.constEnd(); ++yGridIt )
490 drawGridLine( scalePolygon( yGridIt->second, dotsPerMM ), context );
498 QList< QgsPoint >::const_iterator intersectionIt = mTransformedIntersections.constBegin();
499 for ( ; intersectionIt != mTransformedIntersections.constEnd(); ++intersectionIt )
501 double x = intersectionIt->x();
502 double y = intersectionIt->y();
506 QLineF line1 = QLineF( x - mCrossLength, y, x + mCrossLength, y );
507 line1.p1().rx() = line1.p1().x() < 0 ? 0 : line1.p1().x();
508 line1.p2().rx() = line1.p2().x() > maxX ? maxX : line1.p2().x();
509 QLineF line2 = QLineF( x, y - mCrossLength, x, y + mCrossLength );
510 line2.p1().ry() = line2.p1().y() < 0 ? 0 : line2.p1().y();
511 line2.p2().ry() = line2.p2().y() > maxY ? maxY : line2.p2().y();
514 drawGridLine( QLineF( line1.p1() * dotsPerMM, line1.p2() * dotsPerMM ), context );
515 drawGridLine( QLineF( line2.p1() * dotsPerMM, line2.p2() * dotsPerMM ), context );
519 drawGridMarker( QPointF( x, y ) * dotsPerMM, context );
525 QList< QPair< double, QPolygonF > >::const_iterator yGridLineIt = mTransformedYLines.constBegin();
526 for ( ; yGridLineIt != mTransformedYLines.constEnd(); ++yGridLineIt )
528 verticalLines.push_back( qMakePair( yGridLineIt->first, QLineF( yGridLineIt->second.first(), yGridLineIt->second.last() ) ) );
530 QList< QPair< double, QPolygonF > >::const_iterator xGridLineIt = mTransformedXLines.constBegin();
531 for ( ; xGridLineIt != mTransformedXLines.constEnd(); ++xGridLineIt )
533 horizontalLines.push_back( qMakePair( xGridLineIt->first, QLineF( xGridLineIt->second.first(), xGridLineIt->second.last() ) ) );
537 void QgsComposerMapGrid::calculateCRSTransformLines()
541 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
547 mTransformedXLines.clear();
548 xGridLinesCRSTransform( crsBoundingRect, inverseTr, mTransformedXLines );
551 mTransformedYLines.clear();
552 yGridLinesCRSTransform( crsBoundingRect, inverseTr, mTransformedYLines );
559 QList< QgsGeometry* > yLines;
560 QList< QPair< double, QPolygonF > >::const_iterator yGridIt = mTransformedYLines.constBegin();
561 for ( ; yGridIt != mTransformedYLines.constEnd(); ++yGridIt )
564 for (
int i = 0; i < ( *yGridIt ).second.size(); ++i )
566 yLine.append(
QgsPoint(( *yGridIt ).second.at( i ).x(), ( *yGridIt ).second.at( i ).y() ) );
570 QList< QgsGeometry* > xLines;
571 QList< QPair< double, QPolygonF > >::const_iterator xGridIt = mTransformedXLines.constBegin();
572 for ( ; xGridIt != mTransformedXLines.constEnd(); ++xGridIt )
575 for (
int i = 0; i < ( *xGridIt ).second.size(); ++i )
577 xLine.append(
QgsPoint(( *xGridIt ).second.at( i ).x(), ( *xGridIt ).second.at( i ).y() ) );
583 mTransformedIntersections.clear();
584 QList< QgsGeometry* >::const_iterator yLineIt = yLines.constBegin();
585 for ( ; yLineIt != yLines.constEnd(); ++yLineIt )
587 QList< QgsGeometry* >::const_iterator xLineIt = xLines.constBegin();
588 for ( ; xLineIt != xLines.constEnd(); ++xLineIt )
596 while ( vertex !=
QgsPoint( 0, 0 ) )
598 mTransformedIntersections << vertex;
605 qDeleteAll( yLines );
607 qDeleteAll( xLines );
611 mTransformDirty =
false;
620 QPaintDevice* thePaintDevice = p->device();
621 if ( !thePaintDevice )
627 p->setCompositionMode( mBlendMode );
628 p->setRenderHint( QPainter::Antialiasing );
631 p->setClipRect( thisPaintRect );
632 if ( thisPaintRect != mPrevPaintRect )
635 mTransformDirty =
true;
636 mPrevPaintRect = thisPaintRect;
640 double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
641 p->scale( 1 / dotsPerMM, 1 / dotsPerMM );
653 QList< QPair< double, QLineF > > verticalLines;
654 QList< QPair< double, QLineF > > horizontalLines;
659 drawGridCRSTransform( context, dotsPerMM, horizontalLines, verticalLines );
663 drawGridNoTransform( context, dotsPerMM, horizontalLines, verticalLines );
667 p->setClipping(
false );
671 drawGridFrame( p, horizontalLines, verticalLines );
674 if ( mShowGridAnnotation )
676 drawCoordinateAnnotations( p, horizontalLines, verticalLines );
680 void QgsComposerMapGrid::drawGridNoTransform(
QgsRenderContext &context,
double dotsPerMM, QList< QPair< double, QLineF > > &horizontalLines,
681 QList< QPair< double, QLineF > > &verticalLines )
const
684 yGridLines( verticalLines );
685 QList< QPair< double, QLineF > >::const_iterator vIt = verticalLines.constBegin();
686 xGridLines( horizontalLines );
687 QList< QPair< double, QLineF > >::const_iterator hIt = horizontalLines.constBegin();
695 for ( ; vIt != verticalLines.constEnd(); ++vIt )
697 line = QLineF( vIt->second.p1() * dotsPerMM, vIt->second.p2() * dotsPerMM );
698 drawGridLine( line, context );
701 for ( ; hIt != horizontalLines.constEnd(); ++hIt )
703 line = QLineF( hIt->second.p1() * dotsPerMM, hIt->second.p2() * dotsPerMM );
704 drawGridLine( line, context );
709 QPointF intersectionPoint, crossEnd1, crossEnd2;
710 for ( ; vIt != verticalLines.constEnd(); ++vIt )
713 hIt = horizontalLines.constBegin();
714 for ( ; hIt != horizontalLines.constEnd(); ++hIt )
716 if ( hIt->second.intersect( vIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
721 crossEnd1 = (( intersectionPoint - vIt->second.p1() ).manhattanLength() > 0.01 ) ?
723 crossEnd2 = (( intersectionPoint - vIt->second.p2() ).manhattanLength() > 0.01 ) ?
726 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
730 drawGridMarker( intersectionPoint * dotsPerMM, context );
742 hIt = horizontalLines.constBegin();
743 for ( ; hIt != horizontalLines.constEnd(); ++hIt )
745 vIt = verticalLines.constBegin();
746 for ( ; vIt != verticalLines.constEnd(); ++vIt )
748 if ( vIt->second.intersect( hIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
751 crossEnd1 = (( intersectionPoint - hIt->second.p1() ).manhattanLength() > 0.01 ) ?
753 crossEnd2 = (( intersectionPoint - hIt->second.p2() ).manhattanLength() > 0.01 ) ?
756 drawGridLine( QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
763 void QgsComposerMapGrid::drawGridFrame( QPainter* p,
const QList< QPair< double, QLineF > >& hLines,
const QList< QPair< double, QLineF > >& vLines )
const
766 p->setRenderHint( QPainter::Antialiasing );
769 QMap< double, double > leftGridFrame;
770 QMap< double, double > rightGridFrame;
771 QMap< double, double > topGridFrame;
772 QMap< double, double > bottomGridFrame;
774 sortGridLinesOnBorders( hLines, vLines, leftGridFrame, rightGridFrame, topGridFrame, bottomGridFrame );
795 void QgsComposerMapGrid::drawGridLine(
const QLineF& line,
QgsRenderContext& context )
const
798 poly << line.p1() << line.p2();
799 drawGridLine( poly, context );
802 void QgsComposerMapGrid::drawGridLine(
const QPolygonF& line,
QgsRenderContext& context )
const
814 void QgsComposerMapGrid::drawGridMarker(
const QPointF& point,
QgsRenderContext& context )
const
822 mGridMarkerSymbol->
renderPoint( point, 0, context );
833 switch ( mGridFrameStyle )
836 drawGridFrameZebraBorder( p, borderPos, border );
841 drawGridFrameTicks( p, borderPos, border );
845 drawGridFrameLineBorder( p, border );
854 void QgsComposerMapGrid::drawGridFrameZebraBorder( QPainter* p,
const QMap< double, double >& borderPos,
QgsComposerMapGrid::BorderSide border )
const
861 QMap< double, double > pos = borderPos;
863 double currentCoord = 0;
866 currentCoord = - mGridFrameWidth;
871 currentCoord = - mGridFrameWidth;
898 QPen framePen = QPen( mGridFramePenColor );
899 framePen.setWidthF( mGridFramePenThickness );
900 framePen.setJoinStyle( Qt::MiterJoin );
901 p->setPen( framePen );
903 QMap< double, double >::const_iterator posIt = pos.constBegin();
904 for ( ; posIt != pos.constEnd(); ++posIt )
906 p->setBrush( QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
909 height = posIt.key() - currentCoord;
910 width = mGridFrameWidth;
916 height = mGridFrameWidth;
917 width = posIt.key() - currentCoord;
921 p->drawRect( QRectF( x, y, width, height ) );
922 currentCoord = posIt.key();
940 QPen framePen = QPen( mGridFramePenColor );
941 framePen.setWidthF( mGridFramePenThickness );
942 framePen.setCapStyle( Qt::FlatCap );
943 p->setBrush( Qt::NoBrush );
944 p->setPen( framePen );
946 QMap< double, double >::const_iterator posIt = borderPos.constBegin();
947 for ( ; posIt != borderPos.constEnd(); ++posIt )
955 width = mGridFrameWidth;
960 width = mGridFrameWidth;
965 width = mGridFrameWidth * 2;
975 height = mGridFrameWidth;
980 height = mGridFrameWidth;
985 height = mGridFrameWidth * 2;
989 p->drawLine( QLineF( x, y, x + width, y + height ) );
1001 QPen framePen = QPen( mGridFramePenColor );
1002 framePen.setWidthF( mGridFramePenThickness );
1003 framePen.setCapStyle( Qt::SquareCap );
1004 p->setBrush( Qt::NoBrush );
1005 p->setPen( framePen );
1010 p->drawLine( QLineF( 0, 0, 0,
mComposerMap->rect().height() ) );
1016 p->drawLine( QLineF( 0, 0,
mComposerMap->rect().width(), 0 ) );
1024 void QgsComposerMapGrid::drawCoordinateAnnotations( QPainter* p,
const QList< QPair< double, QLineF > >& hLines,
const QList< QPair< double, QLineF > >& vLines )
const
1031 QString currentAnnotationString;
1032 QList< QPair< double, QLineF > >::const_iterator it = hLines.constBegin();
1033 for ( ; it != hLines.constEnd(); ++it )
1040 it = vLines.constBegin();
1041 for ( ; it != vLines.constEnd(); ++it )
1049 void QgsComposerMapGrid::drawCoordinateAnnotation( QPainter* p,
const QPointF& pos, QString annotationString,
const AnnotationCoordinate coordinateType )
const
1059 double xpos = pos.x();
1060 double ypos = pos.y();
1063 double gridFrameDistance = 0;
1066 gridFrameDistance = mGridFrameWidth;
1070 gridFrameDistance += ( mGridFramePenThickness / 2.0 );
1083 gridFrameDistance = 0;
1090 gridFrameDistance = 0;
1094 xpos += textHeight + mAnnotationFrameDistance + gridFrameDistance;
1095 ypos += textWidth / 2.0;
1100 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1101 ypos -= textWidth / 2.0;
1106 xpos += mAnnotationFrameDistance + gridFrameDistance;
1107 ypos += textHeight / 2.0;
1114 gridFrameDistance = 0;
1118 xpos -= ( mAnnotationFrameDistance + gridFrameDistance );
1119 ypos += textWidth / 2.0;
1124 xpos -= textHeight + mAnnotationFrameDistance + gridFrameDistance;
1125 ypos -= textWidth / 2.0;
1130 xpos -= ( textWidth + mAnnotationFrameDistance + gridFrameDistance );
1131 ypos += textHeight / 2.0;
1150 gridFrameDistance = 0;
1157 gridFrameDistance = 0;
1161 xpos -= mAnnotationFrameDistance + gridFrameDistance;
1162 ypos += textWidth / 2.0;
1167 xpos -= textHeight + mAnnotationFrameDistance + gridFrameDistance;
1168 ypos -= textWidth / 2.0;
1173 xpos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1174 ypos += textHeight / 2.0;
1181 gridFrameDistance = 0;
1185 xpos += ( textHeight + mAnnotationFrameDistance + gridFrameDistance );
1186 ypos += textWidth / 2.0;
1191 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1192 ypos -= textWidth / 2.0;
1197 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1198 ypos += textHeight / 2.0;
1216 gridFrameDistance = 0;
1223 gridFrameDistance = 0;
1227 ypos -= mAnnotationFrameDistance + gridFrameDistance;
1228 xpos -= textWidth / 2.0;
1232 xpos -= textHeight / 2.0;
1233 ypos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1238 xpos += textHeight / 2.0;
1239 ypos -= mAnnotationFrameDistance + gridFrameDistance;
1247 gridFrameDistance = 0;
1251 ypos += ( mAnnotationFrameDistance + textHeight + gridFrameDistance );
1252 xpos -= textWidth / 2.0;
1256 xpos -= textHeight / 2.0;
1257 ypos += gridFrameDistance + mAnnotationFrameDistance;
1262 xpos += textHeight / 2.0;
1263 ypos += ( textWidth + mAnnotationFrameDistance + gridFrameDistance );
1282 gridFrameDistance = 0;
1289 gridFrameDistance = 0;
1293 xpos -= textWidth / 2.0;
1294 ypos += textHeight + mAnnotationFrameDistance + gridFrameDistance;
1298 xpos -= textHeight / 2.0;
1299 ypos += mAnnotationFrameDistance + gridFrameDistance;
1304 xpos += textHeight / 2.0;
1305 ypos += textWidth + mAnnotationFrameDistance + gridFrameDistance;
1313 gridFrameDistance = 0;
1317 xpos -= textWidth / 2.0;
1318 ypos -= ( mAnnotationFrameDistance + gridFrameDistance );
1322 xpos -= textHeight / 2.0;
1323 ypos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1328 xpos += textHeight / 2.0;
1329 ypos -= ( mAnnotationFrameDistance + gridFrameDistance );
1339 drawAnnotation( p, QPointF( xpos, ypos ), rotation, annotationString );
1342 void QgsComposerMapGrid::drawAnnotation( QPainter* p,
const QPointF& pos,
int rotation,
const QString& annotationText )
const
1350 p->translate( pos );
1351 p->rotate( rotation );
1360 return QString::number( value,
'f', mGridAnnotationPrecision );
1367 bool geographic =
false;
1377 double coordRounded = qRound( value * pow( 10.0, mGridAnnotationPrecision ) ) / pow( 10.0, mGridAnnotationPrecision );
1381 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1383 hemisphere = value < 0 ?
QObject::tr(
"W" ) : QObject::
tr(
"E" );
1389 if ( !geographic || coordRounded != 0.0 )
1391 hemisphere = value < 0 ?
QObject::tr(
"S" ) : QObject::
tr(
"N" );
1397 return QString::number( qAbs( value ),
'f', mGridAnnotationPrecision ) + QChar( 176 ) + hemisphere;
1401 return QString::number( qAbs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1409 QString annotationString;
1420 annotationString = p.
toDegreesMinutes( mGridAnnotationPrecision,
true,
true );
1435 QStringList split = annotationString.split(
"," );
1438 return split.at( 0 );
1442 if ( split.size() < 2 )
1446 return split.at( 1 );
1450 int QgsComposerMapGrid::xGridLines( QList< QPair< double, QLineF > >& lines )
const
1460 QRectF mapBoundingRect = mapPolygon.boundingRect();
1461 double gridIntervalY = mGridIntervalY;
1462 double gridOffsetY = mGridOffsetY;
1463 double annotationScale = 1.0;
1468 if ( mGridUnit ==
CM )
1470 annotationScale = 0.1;
1471 gridIntervalY *= 10; gridOffsetY *= 10;
1476 double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
1477 double currentLevel = ( int )(( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1479 int gridLineCount = 0;
1484 double yCanvasCoord;
1485 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1487 yCanvasCoord =
mComposerMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
1488 lines.push_back( qMakePair( currentLevel * annotationScale, QLineF( 0, yCanvasCoord,
mComposerMap->rect().width(), yCanvasCoord ) ) );
1489 currentLevel += gridIntervalY;
1496 QVector<QLineF> borderLines;
1497 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1498 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1499 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1500 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1502 QList<QPointF> intersectionList;
1504 while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount <
MAX_GRID_LINES )
1506 intersectionList.clear();
1507 QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
1509 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1510 for ( ; it != borderLines.constEnd(); ++it )
1512 QPointF intersectionPoint;
1513 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1515 intersectionList.push_back( intersectionPoint );
1516 if ( intersectionList.size() >= 2 )
1523 if ( intersectionList.size() >= 2 )
1528 currentLevel += gridIntervalY;
1535 int QgsComposerMapGrid::yGridLines( QList< QPair< double, QLineF > >& lines )
const
1544 QRectF mapBoundingRect = mapPolygon.boundingRect();
1545 double gridIntervalX = mGridIntervalX;
1546 double gridOffsetX = mGridOffsetX;
1547 double annotationScale = 1.0;
1552 if ( mGridUnit ==
CM )
1554 annotationScale = 0.1;
1555 gridIntervalX *= 10; gridOffsetX *= 10;
1560 double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
1561 double currentLevel = ( int )(( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1563 int gridLineCount = 0;
1567 double xCanvasCoord;
1568 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1570 xCanvasCoord =
mComposerMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
1571 lines.push_back( qMakePair( currentLevel * annotationScale, QLineF( xCanvasCoord, 0, xCanvasCoord,
mComposerMap->rect().height() ) ) );
1572 currentLevel += gridIntervalX;
1579 QVector<QLineF> borderLines;
1580 borderLines << QLineF( mapPolygon.at( 0 ), mapPolygon.at( 1 ) );
1581 borderLines << QLineF( mapPolygon.at( 1 ), mapPolygon.at( 2 ) );
1582 borderLines << QLineF( mapPolygon.at( 2 ), mapPolygon.at( 3 ) );
1583 borderLines << QLineF( mapPolygon.at( 3 ), mapPolygon.at( 0 ) );
1585 QList<QPointF> intersectionList;
1587 while ( currentLevel <= mapBoundingRect.right() && gridLineCount <
MAX_GRID_LINES )
1589 intersectionList.clear();
1590 QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
1592 QVector<QLineF>::const_iterator it = borderLines.constBegin();
1593 for ( ; it != borderLines.constEnd(); ++it )
1595 QPointF intersectionPoint;
1596 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1598 intersectionList.push_back( intersectionPoint );
1599 if ( intersectionList.size() >= 2 )
1606 if ( intersectionList.size() >= 2 )
1611 currentLevel += gridIntervalX;
1625 double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1626 double currentLevel = ( int )(( bbox.
yMaximum() - mGridOffsetY ) / mGridIntervalY + roundCorrection ) * mGridIntervalY + mGridOffsetY;
1630 double step = ( maxX - minX ) / 20;
1632 bool crosses180 =
false;
1633 bool crossed180 =
false;
1638 step = ( maxX + 360.0 - minX ) / 20;
1641 int gridLineCount = 0;
1645 double currentX = minX;
1649 if (( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1661 QgsDebugMsg( QString(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1665 if ( crosses180 && currentX > 180.0 )
1674 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1675 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1677 if (( *lineIt ).size() > 0 )
1679 lines.append( qMakePair( currentLevel, *lineIt ) );
1683 currentLevel -= mGridIntervalY;
1697 double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1698 double currentLevel = ( int )(( bbox.
xMinimum() - mGridOffsetX ) / mGridIntervalX + roundCorrection ) * mGridIntervalX + mGridOffsetX;
1702 double step = ( maxY - minY ) / 20;
1704 bool crosses180 =
false;
1705 bool crossed180 =
false;
1712 int gridLineCount = 0;
1713 while (( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1716 double currentY = minY;
1720 if ( currentY > maxY )
1733 QgsDebugMsg( QString(
"Caught CRS exception %1" ).arg( cse.
what() ) );
1740 QList<QPolygonF>::const_iterator lineIt = lineSegments.constBegin();
1741 for ( ; lineIt != lineSegments.constEnd(); ++lineIt )
1743 if (( *lineIt ).size() > 0 )
1745 lines.append( qMakePair( currentLevel, *lineIt ) );
1749 currentLevel += mGridIntervalX;
1750 if ( crosses180 && currentLevel > 180.0 )
1752 currentLevel -= 360.0;
1760 void QgsComposerMapGrid::sortGridLinesOnBorders(
const QList< QPair< double, QLineF > >& hLines,
const QList< QPair< double, QLineF > >& vLines, QMap< double, double >& leftFrameEntries,
1761 QMap< double, double >& rightFrameEntries, QMap< double, double >& topFrameEntries, QMap< double, double >& bottomFrameEntries )
const
1763 QList< QgsMapAnnotation > borderPositions;
1764 QList< QPair< double, QLineF > >::const_iterator it = hLines.constBegin();
1765 for ( ; it != hLines.constEnd(); ++it )
1767 QgsMapAnnotation p1;
1768 p1.coordinate = it->first;
1769 p1.itemPosition = it->second.p1();
1771 borderPositions << p1;
1773 QgsMapAnnotation p2;
1774 p2.coordinate = it->first;
1775 p2.itemPosition = it->second.p2();
1777 borderPositions << p2;
1779 it = vLines.constBegin();
1780 for ( ; it != vLines.constEnd(); ++it )
1782 QgsMapAnnotation p1;
1783 p1.coordinate = it->first;
1784 p1.itemPosition = it->second.p1();
1786 borderPositions << p1;
1788 QgsMapAnnotation p2;
1789 p2.coordinate = it->first;
1790 p2.itemPosition = it->second.p2();
1792 borderPositions << p2;
1795 QList< QgsMapAnnotation >::const_iterator bIt = borderPositions.constBegin();
1796 for ( ; bIt != borderPositions.constEnd(); ++bIt )
1801 leftFrameEntries.insert( bIt->itemPosition.y(), bIt->coordinate );
1805 rightFrameEntries.insert( bIt->itemPosition.y(), bIt->coordinate );
1809 topFrameEntries.insert( bIt->itemPosition.x(), bIt->coordinate );
1813 bottomFrameEntries.insert( bIt->itemPosition.x(), bIt->coordinate );
1823 return shouldShowDivisionForDisplayMode( coordinate, mLeftFrameDivisions );
1825 return shouldShowDivisionForDisplayMode( coordinate, mRightFrameDivisions );
1827 return shouldShowDivisionForDisplayMode( coordinate, mTopFrameDivisions );
1830 return shouldShowDivisionForDisplayMode( coordinate, mBottomFrameDivisions );
1841 bool sortByDistance(
const QPair<double, QgsComposerMapGrid::BorderSide>& a,
const QPair<double, QgsComposerMapGrid::BorderSide>& b )
1843 return a.first < b.first;
1856 if (( p.y() <= tolerance && p.x() <= tolerance )
1857 || ( p.y() <= tolerance && p.x() >= (
mComposerMap->rect().width() - tolerance ) )
1858 || ( p.y() >= (
mComposerMap->rect().height() - tolerance ) && p.x() <= tolerance )
1859 || ( p.y() >= (
mComposerMap->rect().height() - tolerance ) && p.x() >= (
mComposerMap->rect().width() - tolerance ) )
1865 if ( p.x() <= tolerance )
1876 if ( p.y() <= tolerance )
1888 QList< QPair<double, QgsComposerMapGrid::BorderSide > > distanceToSide;
1894 qSort( distanceToSide.begin(), distanceToSide.end(),
sortByDistance );
1895 return distanceToSide.at( 0 ).second;
1900 delete mGridLineSymbol;
1901 mGridLineSymbol = symbol;
1906 delete mGridMarkerSymbol;
1907 mGridMarkerSymbol = symbol;
1915 mLeftGridAnnotationDisplay = display;
1918 mRightGridAnnotationDisplay = display;
1921 mTopGridAnnotationDisplay = display;
1924 mBottomGridAnnotationDisplay = display;
1942 return mLeftGridAnnotationDisplay;
1945 return mRightGridAnnotationDisplay;
1948 return mTopGridAnnotationDisplay;
1952 return mBottomGridAnnotationDisplay;
1974 QStringList coordStrings;
1977 QList< QPair< double, QPolygonF > > xGridLines;
1978 QList< QPair< double, QPolygonF > > yGridLines;
1981 if ( crsGridParams( crsRect, inverseTransform ) != 0 )
1986 int xGridReturn = xGridLinesCRSTransform( crsRect, inverseTransform, xGridLines );
1987 int yGridReturn = yGridLinesCRSTransform( crsRect, inverseTransform, yGridLines );
1988 if ( xGridReturn != 0 || yGridReturn != 0 )
1993 QList< QPair< double, QPolygonF > >::const_iterator it = xGridLines.constBegin();
1994 for ( ; it != xGridLines.constEnd(); ++it )
1998 it = yGridLines.constBegin();
1999 for ( ; it != yGridLines.constEnd(); ++it )
2006 QList< QPair< double, QLineF > > xLines;
2007 QList< QPair< double, QLineF > > yLines;
2008 int xGridReturn = xGridLines( xLines );
2009 int yGridReturn = yGridLines( yLines );
2010 if ( xGridReturn != 0 && yGridReturn != 0 )
2015 QList< QPair< double, QLineF > >::const_iterator it = xLines.constBegin();
2016 for ( ; it != xLines.constEnd(); ++it )
2021 it = yLines.constBegin();
2022 for ( ; it != yLines.constEnd(); ++it )
2029 double currentExtension = 0;
2031 QStringList::const_iterator coordIt = coordStrings.constBegin();
2032 for ( ; coordIt != coordStrings.constEnd(); ++coordIt )
2035 maxExtension = qMax( maxExtension, currentExtension );
2039 double gridFrameDist = ( mGridFrameStyle ==
QgsComposerMapGrid::NoFrame ) ? 0 : mGridFrameWidth + ( mGridFramePenThickness / 2.0 );
2040 return maxExtension + mAnnotationFrameDistance + gridFrameDist;
2045 if ( unit == mGridUnit )
2050 mTransformDirty =
true;
2055 if ( interval == mGridIntervalX )
2059 mGridIntervalX = interval;
2060 mTransformDirty =
true;
2065 if ( interval == mGridIntervalY )
2069 mGridIntervalY = interval;
2070 mTransformDirty =
true;
2075 if ( offset == mGridOffsetX )
2079 mGridOffsetX = offset;
2080 mTransformDirty =
true;
2085 if ( offset == mGridOffsetY )
2089 mGridOffsetY = offset;
2090 mTransformDirty =
true;
2095 if ( style == mGridStyle )
2100 mTransformDirty =
true;
2108 mLeftGridAnnotationDirection = direction;
2111 mRightGridAnnotationDirection = direction;
2114 mTopGridAnnotationDirection = direction;
2117 mBottomGridAnnotationDirection = direction;
2133 mGridFrameSides = flags;
2139 mGridFrameSides |= flag;
2141 mGridFrameSides &= ~flag;
2146 return mGridFrameSides;
2151 return mGridFrameSides.testFlag( flag );
2156 mLeftGridAnnotationDirection = direction;
2157 mRightGridAnnotationDirection = direction;
2158 mTopGridAnnotationDirection = direction;
2159 mBottomGridAnnotationDirection = direction;
2167 mLeftGridAnnotationPosition = position;
2170 mRightGridAnnotationPosition = position;
2173 mTopGridAnnotationPosition = position;
2176 mBottomGridAnnotationPosition = position;
2194 return mLeftGridAnnotationPosition;
2197 return mRightGridAnnotationPosition;
2200 return mTopGridAnnotationPosition;
2204 return mBottomGridAnnotationPosition;
2213 return mLeftGridAnnotationDirection;
2219 return mLeftGridAnnotationDirection;
2222 return mRightGridAnnotationDirection;
2225 return mTopGridAnnotationDirection;
2229 return mBottomGridAnnotationDirection;
2239 mLeftFrameDivisions = divisions;
2242 mRightFrameDivisions = divisions;
2245 mTopFrameDivisions = divisions;
2248 mBottomFrameDivisions = divisions;
2265 return mLeftFrameDivisions;
2268 return mRightFrameDivisions;
2271 return mTopFrameDivisions;
2275 return mBottomFrameDivisions;
2291 QRectF mbr = mapPolygon.boundingRect();
2292 QgsRectangle mapBoundingRect( mbr.left(), mbr.bottom(), mbr.right(), mbr.top() );
2298 QgsPoint lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2299 QgsPoint upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2301 lowerLeft =
tr.transform( lowerLeft.x(), lowerLeft.y() );
2302 upperRight =
tr.transform( upperRight.x(), upperRight.y() );
2304 if ( lowerLeft.x() > upperRight.x() )
2312 crsRect =
tr.transformBoundingBox( mapBoundingRect );
2317 crsRect =
tr.transformBoundingBox( mapBoundingRect );
2325 QgsDebugMsg( QString(
"Caught CRS exception %1" ).arg( cse.
what() ) );
2331 QList<QPolygonF> QgsComposerMapGrid::trimLinesToMap(
const QPolygonF& line,
const QgsRectangle& rect )
2339 QList<QPolygonF> trimmedLines;
2340 QList<QgsGeometry*>::const_iterator geomIt = intersectedParts.constBegin();
2341 for ( ; geomIt != intersectedParts.constEnd(); ++geomIt )
2343 trimmedLines << ( *geomIt )->asQPolygonF();
2346 qDeleteAll( intersectedParts );
2347 intersectedParts.clear();
2351 return trimmedLines;