36 #define MAX_GRID_LINES 1000 //maximum number of horizontal or vertical grid lines to draw
114 for (
int i = 0; i < mapGridNodeList.
size(); ++i )
118 mapGrid->
readXML( mapGridElem, doc );
132 return qMax( qMax( qMax( top, right ), bottom ), left );
147 double gridTop = 0.0;
148 double gridRight = 0.0;
149 double gridBottom = 0.0;
150 double gridLeft = 0.0;
152 top = qMax( top, gridTop );
153 right = qMax( right, gridRight );
154 bottom = qMax( bottom, gridBottom );
155 left = qMax( left, gridLeft );
172 QgsComposerMapGrid::QgsComposerMapGrid()
178 void QgsComposerMapGrid::init()
180 mTransformDirty =
true;
182 mGridIntervalX = 0.0;
183 mGridIntervalY = 0.0;
186 mGridAnnotationFontColor = Qt::black;
187 mGridAnnotationPrecision = 3;
188 mShowGridAnnotation =
false;
197 mAnnotationFrameDistance = 1.0;
206 mGridFrameWidth = 2.0;
207 mGridFramePenThickness = 0.3;
208 mGridFramePenColor =
QColor( 0, 0, 0 );
209 mGridFrameFillColor1 = Qt::white;
210 mGridFrameFillColor2 = Qt::black;
217 mGridMarkerSymbol = 0;
219 mBlendMode = QPainter::CompositionMode_SourceOver;
224 if ( !defaultFontString.
isEmpty() )
226 mGridAnnotationFont.
setFamily( defaultFontString );
229 createDefaultGridLineSymbol();
230 createDefaultGridMarkerSymbol();
235 delete mGridLineSymbol;
236 delete mGridMarkerSymbol;
239 void QgsComposerMapGrid::createDefaultGridLineSymbol()
241 delete mGridLineSymbol;
243 properties.
insert(
"color",
"0,0,0,255" );
244 properties.
insert(
"width",
"0.3" );
245 properties.
insert(
"capstyle",
"flat" );
249 void QgsComposerMapGrid::createDefaultGridMarkerSymbol()
251 delete mGridMarkerSymbol;
253 properties.
insert(
"name",
"circle" );
254 properties.
insert(
"size",
"2.0" );
255 properties.
insert(
"color",
"0,0,0,255" );
261 if ( mGridLineSymbol )
269 if ( mGridLineSymbol )
297 markerStyleElem.
appendChild( gridMarkerStyleElem );
300 mapGridElem.
setAttribute(
"gridFrameStyle", mGridFrameStyle );
301 mapGridElem.
setAttribute(
"gridFrameSideFlags", mGridFrameSides );
307 mapGridElem.
setAttribute(
"leftFrameDivisions", mLeftFrameDivisions );
308 mapGridElem.
setAttribute(
"rightFrameDivisions", mRightFrameDivisions );
309 mapGridElem.
setAttribute(
"topFrameDivisions", mTopFrameDivisions );
310 mapGridElem.
setAttribute(
"bottomFrameDivisions", mBottomFrameDivisions );
316 mapGridElem.
setAttribute(
"annotationFormat", mGridAnnotationFormat );
317 mapGridElem.
setAttribute(
"showAnnotation", mShowGridAnnotation );
318 mapGridElem.
setAttribute(
"annotationExpression", mGridAnnotationExpressionString );
319 mapGridElem.
setAttribute(
"leftAnnotationDisplay", mLeftGridAnnotationDisplay );
320 mapGridElem.
setAttribute(
"rightAnnotationDisplay", mRightGridAnnotationDisplay );
321 mapGridElem.
setAttribute(
"topAnnotationDisplay", mTopGridAnnotationDisplay );
322 mapGridElem.
setAttribute(
"bottomAnnotationDisplay", mBottomGridAnnotationDisplay );
323 mapGridElem.
setAttribute(
"leftAnnotationPosition", mLeftGridAnnotationPosition );
324 mapGridElem.
setAttribute(
"rightAnnotationPosition", mRightGridAnnotationPosition );
325 mapGridElem.
setAttribute(
"topAnnotationPosition", mTopGridAnnotationPosition );
326 mapGridElem.
setAttribute(
"bottomAnnotationPosition", mBottomGridAnnotationPosition );
327 mapGridElem.
setAttribute(
"leftAnnotationDirection", mLeftGridAnnotationDirection );
328 mapGridElem.
setAttribute(
"rightAnnotationDirection", mRightGridAnnotationDirection );
329 mapGridElem.
setAttribute(
"topAnnotationDirection", mTopGridAnnotationDirection );
330 mapGridElem.
setAttribute(
"bottomAnnotationDirection", mBottomGridAnnotationDirection );
334 mapGridElem.
setAttribute(
"annotationPrecision", mGridAnnotationPrecision );
361 mGridFrameSides = ( QgsComposerMapGrid::FrameSideFlags )itemElem.
attribute(
"gridFrameSideFlags",
"15" ).
toInt();
363 mGridFramePenThickness = itemElem.
attribute(
"gridFramePenThickness",
"0.3" ).
toDouble();
373 if ( !lineStyleElem.isNull() )
376 if ( !symbolElem.
isNull() )
378 delete mGridLineSymbol;
379 mGridLineSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsLineSymbolV2>( symbolElem );
393 if ( !markerStyleElem.
isNull() )
396 if ( !symbolElem.
isNull() )
398 delete mGridMarkerSymbol;
399 mGridMarkerSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( symbolElem );
407 mCRS.
readXML( const_cast<QDomElement&>( itemElem ) );
413 mBlendMode = ( QPainter::CompositionMode )( itemElem.
attribute(
"blendMode",
"0" ).
toUInt() );
416 mShowGridAnnotation = ( itemElem.
attribute(
"showAnnotation",
"0" ) !=
"0" );
418 mGridAnnotationExpressionString = itemElem.
attribute(
"annotationExpression" );
419 mGridAnnotationExpression.
reset();
454 mAnnotationFrameDistance = itemElem.
attribute(
"frameAnnotationDistance",
"0" ).
toDouble();
460 mGridAnnotationPrecision = itemElem.
attribute(
"annotationPrecision",
"3" ).
toInt();
469 mTransformDirty =
true;
474 return mBlendMode == QPainter::CompositionMode_SourceOver;
477 QPolygonF QgsComposerMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const
480 return t.
map( polygon );
493 if ( mapPolygon != mPrevMapPolygon )
495 mTransformDirty =
true;
496 mPrevMapPolygon = mapPolygon;
499 if ( mTransformDirty )
501 calculateCRSTransformLines();
505 if ( !calculateLinesOnly )
510 for ( ; xGridIt != mTransformedXLines.
constEnd(); ++xGridIt )
512 drawGridLine( scalePolygon( xGridIt->second, dotsPerMM ), context );
516 for ( ; yGridIt != mTransformedYLines.
constEnd(); ++yGridIt )
518 drawGridLine( scalePolygon( yGridIt->second, dotsPerMM ), context );
527 for ( ; intersectionIt != mTransformedIntersections.
constEnd(); ++intersectionIt )
529 double x = intersectionIt->x();
530 double y = intersectionIt->y();
534 QLineF line1 =
QLineF( x - mCrossLength, y, x + mCrossLength, y );
535 line1.
p1().
rx() = line1.
p1().
x() < 0 ? 0 : line1.
p1().
x();
536 line1.
p2().
rx() = line1.
p2().
x() > maxX ? maxX : line1.
p2().
x();
537 QLineF line2 =
QLineF( x, y - mCrossLength, x, y + mCrossLength );
538 line2.
p1().
ry() = line2.
p1().
y() < 0 ? 0 : line2.
p1().
y();
539 line2.
p2().
ry() = line2.
p2().
y() > maxY ? maxY : line2.
p2().
y();
542 drawGridLine(
QLineF( line1.
p1() * dotsPerMM, line1.
p2() * dotsPerMM ), context );
543 drawGridLine(
QLineF( line2.
p1() * dotsPerMM, line2.
p2() * dotsPerMM ), context );
547 drawGridMarker(
QPointF( x, y ) * dotsPerMM, context );
555 for ( ; yGridLineIt != mTransformedYLines.
constEnd(); ++yGridLineIt )
557 verticalLines.push_back( qMakePair( yGridLineIt->
first,
QLineF( yGridLineIt->second.
first(), yGridLineIt->second.
last() ) ) );
560 for ( ; xGridLineIt != mTransformedXLines.
constEnd(); ++xGridLineIt )
562 horizontalLines.push_back( qMakePair( xGridLineIt->
first,
QLineF( xGridLineIt->second.
first(), xGridLineIt->second.
last() ) ) );
566 void QgsComposerMapGrid::calculateCRSTransformLines()
570 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
576 mTransformedXLines.
clear();
577 xGridLinesCRSTransform( crsBoundingRect, inverseTr, mTransformedXLines );
580 mTransformedYLines.
clear();
581 yGridLinesCRSTransform( crsBoundingRect, inverseTr, mTransformedYLines );
590 for ( ; yGridIt != mTransformedYLines.
constEnd(); ++yGridIt )
593 for (
int i = 0; i < ( *yGridIt ).second.size(); ++i )
595 yLine.
append(
QgsPoint(( *yGridIt ).second.at( i ).x(), ( *yGridIt ).second.at( i ).y() ) );
601 for ( ; xGridIt != mTransformedXLines.
constEnd(); ++xGridIt )
604 for (
int i = 0; i < ( *xGridIt ).second.size(); ++i )
606 xLine.
append(
QgsPoint(( *xGridIt ).second.at( i ).x(), ( *xGridIt ).second.at( i ).y() ) );
612 mTransformedIntersections.
clear();
614 for ( ; yLineIt != yLines.
constEnd(); ++yLineIt )
617 for ( ; xLineIt != xLines.
constEnd(); ++xLineIt )
627 while ( vertex !=
QgsPoint( 0, 0 ) )
629 mTransformedIntersections << vertex;
637 qDeleteAll( yLines );
639 qDeleteAll( xLines );
643 mTransformDirty =
false;
653 if ( !thePaintDevice )
664 if ( thisPaintRect != mPrevPaintRect )
667 mTransformDirty =
true;
668 mPrevPaintRect = thisPaintRect;
672 double dotsPerMM = thePaintDevice->
logicalDpiX() / 25.4;
673 p->
scale( 1 / dotsPerMM, 1 / dotsPerMM );
686 delete expressionContext;
694 drawGridCRSTransform( context, dotsPerMM, horizontalLines, verticalLines );
698 drawGridNoTransform( context, dotsPerMM, horizontalLines, verticalLines );
712 drawGridFrame( p, horizontalLines, verticalLines );
715 if ( mShowGridAnnotation )
717 drawCoordinateAnnotations( p, horizontalLines, verticalLines, context.
expressionContext() );
725 yGridLines( verticalLines );
726 xGridLines( horizontalLines );
728 if ( calculateLinesOnly )
740 for ( ; vIt != verticalLines.
constEnd(); ++vIt )
742 line =
QLineF( vIt->second.p1() * dotsPerMM, vIt->second.p2() * dotsPerMM );
743 drawGridLine( line, context );
746 for ( ; hIt != horizontalLines.
constEnd(); ++hIt )
748 line =
QLineF( hIt->second.p1() * dotsPerMM, hIt->second.p2() * dotsPerMM );
749 drawGridLine( line, context );
754 QPointF intersectionPoint, crossEnd1, crossEnd2;
755 for ( ; vIt != verticalLines.
constEnd(); ++vIt )
759 for ( ; hIt != horizontalLines.
constEnd(); ++hIt )
761 if ( hIt->second.intersect( vIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
766 crossEnd1 = (( intersectionPoint - vIt->second.p1() ).manhattanLength() > 0.01 ) ?
768 crossEnd2 = (( intersectionPoint - vIt->second.p2() ).manhattanLength() > 0.01 ) ?
771 drawGridLine(
QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
775 drawGridMarker( intersectionPoint * dotsPerMM, context );
788 for ( ; hIt != horizontalLines.
constEnd(); ++hIt )
791 for ( ; vIt != verticalLines.
constEnd(); ++vIt )
793 if ( vIt->second.intersect( hIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
796 crossEnd1 = (( intersectionPoint - hIt->second.p1() ).manhattanLength() > 0.01 ) ?
798 crossEnd2 = (( intersectionPoint - hIt->second.p2() ).manhattanLength() > 0.01 ) ?
801 drawGridLine(
QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
822 sortGridLinesOnBorders( hLines, vLines, leftGridFrame, rightGridFrame, topGridFrame, bottomGridFrame );
847 poly << line.
p1() << line.
p2();
848 drawGridLine( poly, context );
871 mGridMarkerSymbol->
renderPoint( point, 0, context );
882 switch ( mGridFrameStyle )
885 drawGridFrameZebraBorder( p, borderPos, border, extension );
890 drawGridFrameTicks( p, borderPos, border, extension );
894 drawGridFrameLineBorder( p, border, extension );
912 *extension = mGridFrameWidth + mGridFramePenThickness / 2.0;
918 double currentCoord = 0;
921 currentCoord = - mGridFrameWidth;
926 currentCoord = - mGridFrameWidth;
953 QPen framePen =
QPen( mGridFramePenColor );
954 framePen.
setWidthF( mGridFramePenThickness );
959 for ( ; posIt != pos.
constEnd(); ++posIt )
961 p->
setBrush(
QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
964 height = posIt.
key() - currentCoord;
965 width = mGridFrameWidth;
971 height = mGridFrameWidth;
972 width = posIt.
key() - currentCoord;
977 currentCoord = posIt.
key();
992 *extension = mGridFrameWidth;
1002 QPen framePen =
QPen( mGridFramePenColor );
1003 framePen.
setWidthF( mGridFramePenThickness );
1009 for ( ; posIt != borderPos.
constEnd(); ++posIt )
1017 width = mGridFrameWidth;
1022 width = mGridFrameWidth;
1027 width = mGridFrameWidth * 2;
1037 height = mGridFrameWidth;
1042 height = mGridFrameWidth;
1047 height = mGridFrameWidth * 2;
1064 *extension = mGridFramePenThickness / 2.0;
1069 QPen framePen =
QPen( mGridFramePenColor );
1070 framePen.
setWidthF( mGridFramePenThickness );
1093 GridExtension* extension )
const
1095 QString currentAnnotationString;
1097 for ( ; it != hLines.
constEnd(); ++it )
1105 for ( ; it != vLines.
constEnd(); ++it )
1113 void QgsComposerMapGrid::drawCoordinateAnnotation(
QPainter* p,
const QPointF& pos,
QString annotationString,
const AnnotationCoordinate coordinateType, GridExtension* extension )
const
1124 double xpos = pos.
x();
1125 double ypos = pos.
y();
1128 double gridFrameDistance = 0;
1131 gridFrameDistance = mGridFrameWidth;
1135 gridFrameDistance += ( mGridFramePenThickness / 2.0 );
1148 gridFrameDistance = 0;
1155 gridFrameDistance = 0;
1159 xpos += textHeight + mAnnotationFrameDistance + gridFrameDistance;
1160 ypos += textWidth / 2.0;
1165 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1166 ypos -= textWidth / 2.0;
1171 xpos += mAnnotationFrameDistance + gridFrameDistance;
1172 ypos += textHeight / 2.0;
1179 gridFrameDistance = 0;
1183 xpos -= ( mAnnotationFrameDistance + gridFrameDistance );
1184 ypos += textWidth / 2.0;
1187 extension->left = qMax( extension->left, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1191 xpos -= textHeight + mAnnotationFrameDistance + gridFrameDistance;
1192 ypos -= textWidth / 2.0;
1195 extension->left = qMax( extension->left, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1199 xpos -= ( textWidth + mAnnotationFrameDistance + gridFrameDistance );
1200 ypos += textHeight / 2.0;
1202 extension->left = qMax( extension->left, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1220 gridFrameDistance = 0;
1227 gridFrameDistance = 0;
1231 xpos -= mAnnotationFrameDistance + gridFrameDistance;
1232 ypos += textWidth / 2.0;
1237 xpos -= textHeight + mAnnotationFrameDistance + gridFrameDistance;
1238 ypos -= textWidth / 2.0;
1243 xpos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1244 ypos += textHeight / 2.0;
1251 gridFrameDistance = 0;
1255 xpos += ( textHeight + mAnnotationFrameDistance + gridFrameDistance );
1256 ypos += textWidth / 2.0;
1259 extension->right = qMax( extension->right, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1263 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1264 ypos -= textWidth / 2.0;
1267 extension->right = qMax( extension->right, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1271 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1272 ypos += textHeight / 2.0;
1274 extension->right = qMax( extension->right, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1292 gridFrameDistance = 0;
1299 gridFrameDistance = 0;
1303 ypos -= mAnnotationFrameDistance + gridFrameDistance;
1304 xpos -= textWidth / 2.0;
1308 xpos -= textHeight / 2.0;
1309 ypos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1314 xpos += textHeight / 2.0;
1315 ypos -= mAnnotationFrameDistance + gridFrameDistance;
1323 gridFrameDistance = 0;
1327 ypos += ( mAnnotationFrameDistance + textHeight + gridFrameDistance );
1328 xpos -= textWidth / 2.0;
1330 extension->bottom = qMax( extension->bottom, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1334 xpos -= textHeight / 2.0;
1335 ypos += gridFrameDistance + mAnnotationFrameDistance;
1338 extension->bottom = qMax( extension->bottom, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1342 xpos += textHeight / 2.0;
1343 ypos += ( textWidth + mAnnotationFrameDistance + gridFrameDistance );
1346 extension->bottom = qMax( extension->bottom, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1364 gridFrameDistance = 0;
1371 gridFrameDistance = 0;
1375 xpos -= textWidth / 2.0;
1376 ypos += textHeight + mAnnotationFrameDistance + gridFrameDistance;
1380 xpos -= textHeight / 2.0;
1381 ypos += mAnnotationFrameDistance + gridFrameDistance;
1386 xpos += textHeight / 2.0;
1387 ypos += textWidth + mAnnotationFrameDistance + gridFrameDistance;
1395 gridFrameDistance = 0;
1399 xpos -= textWidth / 2.0;
1400 ypos -= ( mAnnotationFrameDistance + gridFrameDistance );
1402 extension->top = qMax( extension->top, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1406 xpos -= textHeight / 2.0;
1407 ypos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1410 extension->top = qMax( extension->top, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1414 xpos += textHeight / 2.0;
1415 ypos -= ( mAnnotationFrameDistance + gridFrameDistance );
1418 extension->top = qMax( extension->top, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1427 if ( extension || !p )
1430 drawAnnotation( p,
QPointF( xpos, ypos ), rotation, annotationString );
1433 void QgsComposerMapGrid::drawAnnotation(
QPainter* p,
const QPointF& pos,
int rotation,
const QString& annotationText )
const
1450 bool geographic =
false;
1464 double wrappedX = fmod( value, 360.0 );
1465 if ( wrappedX > 180.0 )
1467 value = wrappedX - 360.0;
1469 else if ( wrappedX < -180.0 )
1471 value = wrappedX + 360.0;
1483 double coordRounded = qRound( value * pow( 10.0, mGridAnnotationPrecision ) ) / pow( 10.0, mGridAnnotationPrecision );
1487 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1495 if ( !geographic || coordRounded != 0.0 )
1503 return QString::number( qAbs( value ),
'f', mGridAnnotationPrecision ) +
QChar( 176 ) + hemisphere;
1507 return QString::number( qAbs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1514 if ( !mGridAnnotationExpression.
data() )
1516 mGridAnnotationExpression.
reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1517 mGridAnnotationExpression->prepare( &expressionContext );
1519 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1537 annotationString = p.
toDegreesMinutes( mGridAnnotationPrecision,
true,
true );
1555 return split.
at( 0 );
1559 if ( split.
size() < 2 )
1563 return split.
at( 1 );
1578 double gridIntervalY = mGridIntervalY;
1579 double gridOffsetY = mGridOffsetY;
1580 double annotationScale = 1.0;
1585 if ( mGridUnit ==
CM )
1587 annotationScale = 0.1;
1588 gridIntervalY *= 10; gridOffsetY *= 10;
1593 double roundCorrection = mapBoundingRect.
top() > 0 ? 1.0 : 0.0;
1594 double currentLevel = ( int )(( mapBoundingRect.
top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1596 int gridLineCount = 0;
1601 double yCanvasCoord;
1605 lines.push_back( qMakePair( currentLevel * annotationScale,
QLineF( 0, yCanvasCoord,
mComposerMap->
rect().
width(), yCanvasCoord ) ) );
1606 currentLevel += gridIntervalY;
1614 borderLines <<
QLineF( mapPolygon.
at( 0 ), mapPolygon.
at( 1 ) );
1615 borderLines <<
QLineF( mapPolygon.
at( 1 ), mapPolygon.
at( 2 ) );
1616 borderLines <<
QLineF( mapPolygon.
at( 2 ), mapPolygon.
at( 3 ) );
1617 borderLines <<
QLineF( mapPolygon.
at( 3 ), mapPolygon.
at( 0 ) );
1623 intersectionList.
clear();
1624 QLineF gridLine( mapBoundingRect.
left(), currentLevel, mapBoundingRect.
right(), currentLevel );
1627 for ( ; it != borderLines.
constEnd(); ++it )
1630 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1632 intersectionList.push_back( intersectionPoint );
1633 if ( intersectionList.size() >= 2 )
1640 if ( intersectionList.size() >= 2 )
1645 currentLevel += gridIntervalY;
1662 double gridIntervalX = mGridIntervalX;
1663 double gridOffsetX = mGridOffsetX;
1664 double annotationScale = 1.0;
1669 if ( mGridUnit ==
CM )
1671 annotationScale = 0.1;
1672 gridIntervalX *= 10; gridOffsetX *= 10;
1677 double roundCorrection = mapBoundingRect.
left() > 0 ? 1.0 : 0.0;
1678 double currentLevel = ( int )(( mapBoundingRect.
left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1680 int gridLineCount = 0;
1684 double xCanvasCoord;
1688 lines.push_back( qMakePair( currentLevel * annotationScale,
QLineF( xCanvasCoord, 0, xCanvasCoord,
mComposerMap->
rect().
height() ) ) );
1689 currentLevel += gridIntervalX;
1697 borderLines <<
QLineF( mapPolygon.
at( 0 ), mapPolygon.
at( 1 ) );
1698 borderLines <<
QLineF( mapPolygon.
at( 1 ), mapPolygon.
at( 2 ) );
1699 borderLines <<
QLineF( mapPolygon.
at( 2 ), mapPolygon.
at( 3 ) );
1700 borderLines <<
QLineF( mapPolygon.
at( 3 ), mapPolygon.
at( 0 ) );
1706 intersectionList.
clear();
1707 QLineF gridLine( currentLevel, mapBoundingRect.
bottom(), currentLevel, mapBoundingRect.
top() );
1710 for ( ; it != borderLines.
constEnd(); ++it )
1713 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1715 intersectionList.push_back( intersectionPoint );
1716 if ( intersectionList.size() >= 2 )
1723 if ( intersectionList.size() >= 2 )
1728 currentLevel += gridIntervalX;
1742 double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1743 double currentLevel = ( int )(( bbox.
yMaximum() - mGridOffsetY ) / mGridIntervalY + roundCorrection ) * mGridIntervalY + mGridOffsetY;
1747 double step = ( maxX - minX ) / 20;
1749 bool crosses180 =
false;
1750 bool crossed180 =
false;
1755 step = ( maxX + 360.0 - minX ) / 20;
1761 int gridLineCount = 0;
1765 double currentX = minX;
1769 if (( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1785 if ( crosses180 && currentX > 180.0 )
1795 for ( ; lineIt != lineSegments.
constEnd(); ++lineIt )
1797 if (( *lineIt ).size() > 0 )
1799 lines.append( qMakePair( currentLevel, *lineIt ) );
1803 currentLevel -= mGridIntervalY;
1817 double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1818 double currentLevel = ( int )(( bbox.
xMinimum() - mGridOffsetX ) / mGridIntervalX + roundCorrection ) * mGridIntervalX + mGridOffsetX;
1822 double step = ( maxY - minY ) / 20;
1827 bool crosses180 =
false;
1828 bool crossed180 =
false;
1835 int gridLineCount = 0;
1836 while (( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1839 double currentY = minY;
1843 if ( currentY > maxY )
1864 for ( ; lineIt != lineSegments.
constEnd(); ++lineIt )
1866 if (( *lineIt ).size() > 0 )
1868 lines.append( qMakePair( currentLevel, *lineIt ) );
1872 currentLevel += mGridIntervalX;
1873 if ( crosses180 && currentLevel > 180.0 )
1875 currentLevel -= 360.0;
1888 for ( ; it != hLines.
constEnd(); ++it )
1890 QgsMapAnnotation p1;
1891 p1.coordinate = it->
first;
1892 p1.itemPosition = it->second.p1();
1894 borderPositions << p1;
1896 QgsMapAnnotation p2;
1897 p2.coordinate = it->
first;
1898 p2.itemPosition = it->second.p2();
1900 borderPositions << p2;
1903 for ( ; it != vLines.
constEnd(); ++it )
1905 QgsMapAnnotation p1;
1906 p1.coordinate = it->
first;
1907 p1.itemPosition = it->second.p1();
1909 borderPositions << p1;
1911 QgsMapAnnotation p2;
1912 p2.coordinate = it->
first;
1913 p2.itemPosition = it->second.p2();
1915 borderPositions << p2;
1919 for ( ; bIt != borderPositions.
constEnd(); ++bIt )
1924 leftFrameEntries.
insert( bIt->itemPosition.y(), bIt->coordinate );
1928 rightFrameEntries.
insert( bIt->itemPosition.y(), bIt->coordinate );
1932 topFrameEntries.
insert( bIt->itemPosition.x(), bIt->coordinate );
1936 bottomFrameEntries.
insert( bIt->itemPosition.x(), bIt->coordinate );
1946 return shouldShowDivisionForDisplayMode( coordinate, mLeftFrameDivisions );
1948 return shouldShowDivisionForDisplayMode( coordinate, mRightFrameDivisions );
1950 return shouldShowDivisionForDisplayMode( coordinate, mTopFrameDivisions );
1953 return shouldShowDivisionForDisplayMode( coordinate, mBottomFrameDivisions );
1966 return a.first < b.first;
1979 if (( p.
y() <= tolerance && p.
x() <= tolerance )
1986 if ( coordinateType == QgsComposerMapGrid::Latitude )
1988 if ( p.
x() <= tolerance )
1999 if ( p.
y() <= tolerance )
2018 return distanceToSide.
at( 0 ).second;
2023 delete mGridLineSymbol;
2024 mGridLineSymbol = symbol;
2029 delete mGridMarkerSymbol;
2030 mGridMarkerSymbol = symbol;
2038 mLeftGridAnnotationDisplay = display;
2041 mRightGridAnnotationDisplay = display;
2044 mTopGridAnnotationDisplay = display;
2047 mBottomGridAnnotationDisplay = display;
2065 return mLeftGridAnnotationDisplay;
2068 return mRightGridAnnotationDisplay;
2071 return mTopGridAnnotationDisplay;
2075 return mBottomGridAnnotationDisplay;
2084 double bottom = 0.0;
2087 return qMax( qMax( qMax( top, right ), bottom ), left );
2107 delete expressionContext;
2109 GridExtension extension;
2116 drawGridCRSTransform( context, 0, horizontalLines, verticalLines,
false );
2120 drawGridNoTransform( context, 0, horizontalLines, verticalLines,
false );
2125 drawGridFrame( 0, horizontalLines, verticalLines, &extension );
2128 if ( mShowGridAnnotation )
2130 drawCoordinateAnnotations( 0, horizontalLines, verticalLines, context.
expressionContext(), &extension );
2133 top = extension.top;
2134 right = extension.right;
2135 bottom = extension.bottom;
2136 left = extension.left;
2141 if ( unit == mGridUnit )
2146 mTransformDirty =
true;
2151 if ( interval == mGridIntervalX )
2155 mGridIntervalX = interval;
2156 mTransformDirty =
true;
2161 if ( interval == mGridIntervalY )
2165 mGridIntervalY = interval;
2166 mTransformDirty =
true;
2171 if ( offset == mGridOffsetX )
2175 mGridOffsetX = offset;
2176 mTransformDirty =
true;
2181 if ( offset == mGridOffsetY )
2185 mGridOffsetY = offset;
2186 mTransformDirty =
true;
2191 if ( style == mGridStyle )
2196 mTransformDirty =
true;
2204 mLeftGridAnnotationDirection = direction;
2207 mRightGridAnnotationDirection = direction;
2210 mTopGridAnnotationDirection = direction;
2213 mBottomGridAnnotationDirection = direction;
2229 mGridFrameSides = flags;
2235 mGridFrameSides |= flag;
2237 mGridFrameSides &= ~flag;
2242 return mGridFrameSides;
2257 return mGridFrameSides.testFlag( flag );
2262 mLeftGridAnnotationDirection = direction;
2263 mRightGridAnnotationDirection = direction;
2264 mTopGridAnnotationDirection = direction;
2265 mBottomGridAnnotationDirection = direction;
2273 mLeftGridAnnotationPosition = position;
2276 mRightGridAnnotationPosition = position;
2279 mTopGridAnnotationPosition = position;
2282 mBottomGridAnnotationPosition = position;
2300 return mLeftGridAnnotationPosition;
2303 return mRightGridAnnotationPosition;
2306 return mTopGridAnnotationPosition;
2310 return mBottomGridAnnotationPosition;
2319 return mLeftGridAnnotationDirection;
2325 return mLeftGridAnnotationDirection;
2328 return mRightGridAnnotationDirection;
2331 return mTopGridAnnotationDirection;
2335 return mBottomGridAnnotationDirection;
2345 mLeftFrameDivisions = divisions;
2348 mRightFrameDivisions = divisions;
2351 mTopFrameDivisions = divisions;
2354 mBottomFrameDivisions = divisions;
2371 return mLeftFrameDivisions;
2374 return mRightFrameDivisions;
2377 return mTopFrameDivisions;
2381 return mBottomFrameDivisions;
2397 QRectF mbr = mapPolygon.boundingRect();
2404 QgsPoint lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2405 QgsPoint upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2407 lowerLeft =
tr.transform( lowerLeft.x(), lowerLeft.y() );
2408 upperRight =
tr.transform( upperRight.x(), upperRight.y() );
2410 if ( lowerLeft.x() > upperRight.x() )
2418 crsRect =
tr.transformBoundingBox( mapBoundingRect );
2423 crsRect =
tr.transformBoundingBox( mapBoundingRect );
2447 for ( ; geomIt != intersectedParts.
constEnd(); ++geomIt )
2449 trimmedLines << ( *geomIt )->asQPolygonF();
2452 qDeleteAll( intersectedParts );
2453 intersectedParts.
clear();
2457 return trimmedLines;
QgsComposerMapGrid(const QString &name, QgsComposerMap *map)
Constructor for QgsComposerMapGrid.
static QgsGeometry * fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Class for parsing and evaluation of expressions (formerly called "search strings").
void setStyle(const GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
void setForceVectorOutput(bool force)
void addGrid(QgsComposerMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
void draw(QPainter *painter) override
Draws a grid.
QDomNodeList elementsByTagName(const QString &tagname) const
A rectangle specified with double values.
static QgsMarkerSymbolV2 * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
void setAnnotationDirection(const AnnotationDirection direction, const BorderSide border)
Sets the direction for drawing frame annotations.
void setLineSymbol(QgsLineSymbolV2 *symbol)
Sets the line symbol used for drawing grid lines.
GridStyle
Grid drawing style.
QgsComposerMapGrid * grid(const QString &gridId) const
Returns a reference to a grid within the stack.
void setCompositionMode(CompositionMode mode)
void addItem(QgsComposerMapItem *item)
Adds a new map item to the stack and takes ownership of the item.
void setRenderHint(RenderHint hint, bool on)
void setOffsetY(const double offset)
Sets the offset for grid lines in the y-direction.
QDomNode appendChild(const QDomNode &newChild)
void append(const T &value)
QString attribute(const QString &name, const QString &defValue) const
double yMaximum() const
Get the y maximum value (top side of rectangle)
void setOutputDpi(int dpi)
Set DPI used for conversion between real world units (e.g. mm) and pixels.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
static QString encodeColor(const QColor &color)
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
FrameStyle
Style for grid frame.
void scale(qreal sx, qreal sy)
void setClipping(bool enable)
const_iterator constEnd() const
const_iterator constBegin() const
QList< QgsGeometry * > asGeometryCollection() const
Return contents of the geometry as a list of geometries.
const T & at(int i) const
static QDomElement saveSymbol(const QString &symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
QRectF sceneBoundingRect() const
static void drawText(QPainter *painter, const QPointF &pos, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of composer specific issues (calculation ...
virtual ~QgsComposerMapGrid()
A geometry is the spatial representation of a feature.
void setJoinStyle(Qt::PenJoinStyle style)
double maxExtension()
Calculates the maximum distance the grid extends beyond the QgsComposerMap's item rect...
static double fontAscentMM(const QFont &font)
Calculate font ascent in millimeters, including workarounds for QT font rendering issues...
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
void drawLine(const QLineF &line)
AnnotationDirection
Direction of grid annotations.
void removeGrid(const QString &gridId)
Removes a grid from the stack and deletes the corresponding QgsComposerMapGrid.
double toDouble(bool *ok) const
void setGridLineColor(const QColor &color)
Sets color of grid lines.
QString tr(const char *sourceText, const char *disambiguation, int n)
QMap< QString, QString > QgsStringMap
void setAnnotationDisplay(const DisplayMode display, const BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame...
AnnotationFormat
Format for displaying grid annotations.
void setVariable(const QString &name, const QVariant &value)
Convenience method for setting a variable in the context scope by name and value. ...
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
void update(const QRectF &rect)
double x() const
Get the x value of the point.
An item which is drawn inside a QgsComposerMap, eg a grid or map overview.
AnnotationPosition annotationPosition(const BorderSide border) const
Gets the position for the grid annotations on a specified side of the map frame.
void setWidth(double width)
void calculateMaxExtension(double &top, double &right, double &bottom, double &left)
Calculates the maximum distance the grid extends beyond the QgsComposerMap's item rect...
void setFrameSideFlag(const FrameSideFlag flag, bool on=true)
Sets whether the grid frame is drawn for a certain side of the map item.
The QgsMapSettings class contains configuration for rendering of the map.
const QgsComposerMapItem * constItem(const QString &itemId) const
Returns a const reference to an item within the stack.
QDomElement toElement() const
bool testFrameSideFlag(const FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item. ...
void setCapStyle(Qt::PenCapStyle style)
void drawRect(const QRectF &rectangle)
void setColor(const QColor &color)
virtual QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the objects's current state.
void setFrameSideFlags(const FrameSideFlags &flags)
Sets flags for grid frame sides.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QString number(int n, int base)
void append(const T &value)
virtual ~QgsComposerMapGridStack()
void updateBoundingRect()
Updates the bounding rect of this item.
bool fromString(const QString &descrip)
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
const QgsComposerMapGrid * constGrid(const QString &gridId) const
Returns a const reference to a grid within the stack.
bool mEnabled
True if item is to be displayed on map.
double xMaximum() const
Get the x maximum value (right side of rectangle)
DisplayMode frameDivisions(const BorderSide border) const
Gets the type of grid divisions which are used for frames on a specified side of the map...
bool writeXML(QDomElement &elem, QDomDocument &doc) const override
Stores grid state in DOM element.
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
static QgsLineSymbolV2 * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
QRectF mapRectFromScene(const QRectF &rect) const
const QgsComposition * composition() const
Returns the composition the item is attached to.
void removeItem(const QString &itemId)
Removes an item from the stack and deletes the corresponding QgsComposerMapItem.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
int toInt(bool *ok, int base) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
DisplayMode
Display settings for grid annotations and frames.
bool readXML(const QDomElement &elem, const QDomDocument &doc) override
Sets the grid stack's state from a DOM document.
FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on...
void moveItemUp(const QString &itemId)
Moves an item up the stack, causing it to be rendered above other items.
void renderPolyline(const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
AnnotationPosition
Position for grid annotations.
const_iterator constEnd() const
void setUnits(const GridUnit unit)
Sets the units to use for grid measurements such as the interval and offset for grid lines...
QPaintDevice * device() const
void setWidthF(qreal width)
void setBrush(const QBrush &brush)
void setPainter(QPainter *p)
GridStyle style() const
Gets the grid's style, which controls how the grid is drawn over the map's contents.
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
FrameSideFlag
Flags for controlling which side of the map a frame is drawn on.
void calculateMaxGridExtension(double &top, double &right, double &bottom, double &left) const
Calculates the maximum distance grids within the stack extend beyond the QgsComposerMap's item rect...
An individual grid which is drawn above the map content in a QgsComposerMap.
QgsComposerMapGrid & operator[](int idx)
Returns a reference to a grid within the stack.
QgsComposerMap * mComposerMap
Associated composer map.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the CRS for the grid.
bool usesAdvancedEffects() const override
Returns true if the item is drawn using advanced effects, such as blend modes.
void renderPoint(const QPointF &point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setGridLineWidth(const double width)
Sets width of grid lines.
double mapRotation(QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the composer item.
A class to represent a point.
bool readXML(const QDomElement &itemElem, const QDomDocument &doc) override
Sets grid state from a DOM document.
QgsComposerMapGridStack(QgsComposerMap *map)
Constructor for QgsComposerMapGridStack.
QgsComposerMapItem * item(const QString &itemId) const
Returns a reference to an item within the stack.
Object representing map window.
void moveItemDown(const QString &itemId)
Moves an item up the stack, causing it to be rendered above other items.
QgsRectangle * currentMapExtent()
Returns a pointer to the current map extent, which is either the original user specified extent or th...
QList< QgsComposerMapGrid * > asList() const
Returns a list of QgsComposerMapGrids contained by the stack.
virtual QgsExpressionContext * createExpressionContext() const override
Creates an expression context relating to the objects's current state.
void setX(double x)
Sets the x value of the point.
BorderSide
Border sides for annotations.
QString qgsDoubleToString(const double &a, const int &precision=17)
void setAnnotationPosition(const AnnotationPosition position, const BorderSide border)
Sets the position for the grid annotations on a specified side of the map frame.
void setY(double y)
Sets the y value of the point.
QgsExpressionContext & expressionContext()
Gets the expression context.
DisplayMode annotationDisplay(const BorderSide border) const
Gets the display mode for the grid annotations on a specified side of the map frame.
QList< QgsComposerMapItem * > mItems
static double textWidthMM(const QFont &font, const QString &text)
Calculate font width in millimeters for a string, including workarounds for QT font rendering issues...
QgsGeometry * intersection(const QgsGeometry *geometry) const
Returns a geometry representing the points shared by this geometry and other.
bool isValid() const
Find out whether this CRS is correctly initialised and usable.
const T & at(int i) const
QVariant value(const QString &key, const QVariant &defaultValue) const
const_iterator constBegin() const
bool writeXML(QDomNode &theNode, QDomDocument &theDoc) const
Stores state to the given Dom node in the given document.
Contains information about the context of a rendering operation.
QRectF boundingRect() const
void stopRender(QgsRenderContext &context)
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
void setOutputSize(const QSize &size)
Set the size of the resulting map image.
QString toDegreesMinutes(int thePrecision, const bool useSuffix=true, const bool padded=false) const
Return a string representation as degrees minutes.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
A collection of map items which are drawn above the map content in a QgsComposerMap.
bool hasFrame() const
Whether this item has a frame or not.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
QDomElement firstChildElement(const QString &tagName) const
void setFamily(const QString &family)
Class for storing a coordinate reference system (CRS)
void setExtent(const QgsRectangle &rect)
Set coordinates of the rectangle which should be rendered.
void setMarkerSymbol(QgsMarkerSymbolV2 *symbol)
Sets the marker symbol used for drawing grid points.
void setIntervalY(const double interval)
Sets the interval between grid lines in the y-direction.
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
void translate(const QPointF &offset)
void setFrameDivisions(const DisplayMode divisions, const BorderSide border)
Sets what type of grid divisions should be used for frames on a specified side of the map...
static QgsGeometry * fromPolyline(const QgsPolyline &polyline)
Creates a new geometry from a QgsPolyline object.
void moveGridUp(const QString &gridId)
Moves a grid up the stack, causing it to be rendered above other grids.
double y() const
Get the y value of the point.
virtual bool readXML(const QDomElement &itemElem, const QDomDocument &doc) override
Sets map item state from a DOM document.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
static QColor decodeColor(const QString &str)
iterator insert(const Key &key, const T &value)
QString toDegreesMinutesSeconds(int thePrecision, const bool useSuffix=true, const bool padded=false) const
Return a string representation as degrees minutes seconds.
bool readXML(QDomNode &theNode)
Restores state from the given Dom node.
Custom exception class for Coordinate Reference System related exceptions.
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
const_iterator constEnd() const
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsComposerMap's item rect...
QDomElement createElement(const QString &tagName)
const_iterator constBegin() const
void moveGridDown(const QString &gridId)
Moves a grid down the stack, causing it to be rendered below other grids.
void removeItems()
Clears the item stack and deletes all QgsComposerMapItems contained by the stack. ...
QPointF mapToItemCoords(const QPointF &mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset) ...
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const override
Stores map item state in DOM element.
AnnotationDirection annotationDirection(const BorderSide border) const
Gets the direction for drawing frame annotations.
static QPointF pointOnLineWithDistance(const QPointF &startPoint, const QPointF &directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
bool geographicFlag() const
Get this Geographic? flag.
double xMinimum() const
Get the x minimum value (left side of rectangle)
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
GridUnit
Unit for grid values.
void setIntervalX(const double interval)
Sets the interval between grid lines in the x-direction.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
void setOffsetX(const double offset)
Sets the offset for grid lines in the x-direction.
AnnotationCoordinate
Annotation coordinate type.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
bool sortByDistance(const QPair< qreal, QgsComposerMapGrid::BorderSide > &a, const QPair< qreal, QgsComposerMapGrid::BorderSide > &b)
QDomNode at(int index) const
Utilities for compositions.
QgsComposerMap * mComposerMap
uint toUInt(bool *ok, int base) const