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 );
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;
216 mGridLineSymbol =
nullptr;
217 mGridMarkerSymbol =
nullptr;
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 =
static_cast< 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 );
403 if ( !mCRS.
readXML( itemElem ) )
406 mBlendMode =
static_cast< QPainter::CompositionMode
>( itemElem.
attribute(
"blendMode",
"0" ).
toUInt() );
409 mShowGridAnnotation = ( itemElem.
attribute(
"showAnnotation",
"0" ) !=
"0" );
411 mGridAnnotationExpressionString = itemElem.
attribute(
"annotationExpression" );
412 mGridAnnotationExpression.
reset();
447 mAnnotationFrameDistance = itemElem.
attribute(
"frameAnnotationDistance",
"0" ).
toDouble();
453 mGridAnnotationPrecision = itemElem.
attribute(
"annotationPrecision",
"3" ).
toInt();
455 mGridUnit = ( gridUnitInt <= static_cast< int >(
CM ) ) ?
static_cast< GridUnit >( gridUnitInt ) :
MapUnit;
462 mTransformDirty =
true;
467 return mBlendMode == QPainter::CompositionMode_SourceOver;
470 QPolygonF QgsComposerMapGrid::scalePolygon(
const QPolygonF &polygon,
const double scale )
const 473 return t.
map( polygon );
486 if ( mapPolygon != mPrevMapPolygon )
488 mTransformDirty =
true;
489 mPrevMapPolygon = mapPolygon;
492 if ( mTransformDirty )
494 calculateCRSTransformLines();
498 if ( !calculateLinesOnly )
503 for ( ; xGridIt != mTransformedXLines.
constEnd(); ++xGridIt )
505 drawGridLine( scalePolygon( xGridIt->second, dotsPerMM ), context );
509 for ( ; yGridIt != mTransformedYLines.
constEnd(); ++yGridIt )
511 drawGridLine( scalePolygon( yGridIt->second, dotsPerMM ), context );
520 for ( ; intersectionIt != mTransformedIntersections.
constEnd(); ++intersectionIt )
522 double x = intersectionIt->x();
523 double y = intersectionIt->y();
527 QLineF line1 =
QLineF( x - mCrossLength, y, x + mCrossLength, y );
528 line1.
p1().
rx() = line1.
p1().
x() < 0 ? 0 : line1.
p1().
x();
529 line1.
p2().
rx() = line1.
p2().
x() > maxX ? maxX : line1.
p2().
x();
530 QLineF line2 =
QLineF( x, y - mCrossLength, x, y + mCrossLength );
531 line2.
p1().
ry() = line2.
p1().
y() < 0 ? 0 : line2.
p1().
y();
532 line2.
p2().
ry() = line2.
p2().
y() > maxY ? maxY : line2.
p2().
y();
535 drawGridLine(
QLineF( line1.
p1() * dotsPerMM, line1.
p2() * dotsPerMM ), context );
536 drawGridLine(
QLineF( line2.
p1() * dotsPerMM, line2.
p2() * dotsPerMM ), context );
540 drawGridMarker(
QPointF( x, y ) * dotsPerMM, context );
548 for ( ; yGridLineIt != mTransformedYLines.
constEnd(); ++yGridLineIt )
550 verticalLines.push_back( qMakePair( yGridLineIt->
first,
QLineF( yGridLineIt->second.
first(), yGridLineIt->second.
last() ) ) );
553 for ( ; xGridLineIt != mTransformedXLines.
constEnd(); ++xGridLineIt )
555 horizontalLines.push_back( qMakePair( xGridLineIt->
first,
QLineF( xGridLineIt->second.
first(), xGridLineIt->second.
last() ) ) );
559 void QgsComposerMapGrid::calculateCRSTransformLines()
563 if ( crsGridParams( crsBoundingRect, inverseTr ) != 0 )
569 mTransformedXLines.
clear();
570 xGridLinesCRSTransform( crsBoundingRect, inverseTr, mTransformedXLines );
573 mTransformedYLines.
clear();
574 yGridLinesCRSTransform( crsBoundingRect, inverseTr, mTransformedYLines );
583 for ( ; yGridIt != mTransformedYLines.
constEnd(); ++yGridIt )
586 for (
int i = 0; i < ( *yGridIt ).second.size(); ++i )
588 yLine.
append(
QgsPoint(( *yGridIt ).second.at( i ).x(), ( *yGridIt ).second.at( i ).y() ) );
594 for ( ; xGridIt != mTransformedXLines.
constEnd(); ++xGridIt )
597 for (
int i = 0; i < ( *xGridIt ).second.size(); ++i )
599 xLine.
append(
QgsPoint(( *xGridIt ).second.at( i ).x(), ( *xGridIt ).second.at( i ).y() ) );
605 mTransformedIntersections.
clear();
607 for ( ; yLineIt != yLines.
constEnd(); ++yLineIt )
610 for ( ; xLineIt != xLines.
constEnd(); ++xLineIt )
620 while ( vertex !=
QgsPoint( 0, 0 ) )
622 mTransformedIntersections << vertex;
630 qDeleteAll( yLines );
632 qDeleteAll( xLines );
636 mTransformDirty =
false;
646 if ( !thePaintDevice )
657 if ( thisPaintRect != mPrevPaintRect )
660 mTransformDirty =
true;
661 mPrevPaintRect = thisPaintRect;
665 double dotsPerMM = thePaintDevice->
logicalDpiX() / 25.4;
666 p->
scale( 1 / dotsPerMM, 1 / dotsPerMM );
679 delete expressionContext;
687 drawGridCRSTransform( context, dotsPerMM, horizontalLines, verticalLines );
691 drawGridNoTransform( context, dotsPerMM, horizontalLines, verticalLines );
705 drawGridFrame( p, horizontalLines, verticalLines );
708 if ( mShowGridAnnotation )
710 drawCoordinateAnnotations( p, horizontalLines, verticalLines, context.
expressionContext() );
718 yGridLines( verticalLines );
719 xGridLines( horizontalLines );
721 if ( calculateLinesOnly )
733 for ( ; vIt != verticalLines.
constEnd(); ++vIt )
735 line =
QLineF( vIt->second.p1() * dotsPerMM, vIt->second.p2() * dotsPerMM );
736 drawGridLine( line, context );
739 for ( ; hIt != horizontalLines.
constEnd(); ++hIt )
741 line =
QLineF( hIt->second.p1() * dotsPerMM, hIt->second.p2() * dotsPerMM );
742 drawGridLine( line, context );
747 QPointF intersectionPoint, crossEnd1, crossEnd2;
748 for ( ; vIt != verticalLines.
constEnd(); ++vIt )
752 for ( ; hIt != horizontalLines.
constEnd(); ++hIt )
754 if ( hIt->second.intersect( vIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
759 crossEnd1 = (( intersectionPoint - vIt->second.p1() ).manhattanLength() > 0.01 ) ?
761 crossEnd2 = (( intersectionPoint - vIt->second.p2() ).manhattanLength() > 0.01 ) ?
764 drawGridLine(
QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
768 drawGridMarker( intersectionPoint * dotsPerMM, context );
781 for ( ; hIt != horizontalLines.
constEnd(); ++hIt )
784 for ( ; vIt != verticalLines.
constEnd(); ++vIt )
786 if ( vIt->second.intersect( hIt->second, &intersectionPoint ) == QLineF::BoundedIntersection )
789 crossEnd1 = (( intersectionPoint - hIt->second.p1() ).manhattanLength() > 0.01 ) ?
791 crossEnd2 = (( intersectionPoint - hIt->second.p2() ).manhattanLength() > 0.01 ) ?
794 drawGridLine(
QLineF( crossEnd1 * dotsPerMM, crossEnd2 * dotsPerMM ), context );
815 sortGridLinesOnBorders( hLines, vLines, leftGridFrame, rightGridFrame, topGridFrame, bottomGridFrame );
840 poly << line.
p1() << line.
p2();
841 drawGridLine( poly, context );
864 mGridMarkerSymbol->
renderPoint( point,
nullptr, context );
875 switch ( mGridFrameStyle )
878 drawGridFrameZebraBorder( p, borderPos, border, extension );
883 drawGridFrameTicks( p, borderPos, border, extension );
887 drawGridFrameLineBorder( p, border, extension );
905 *extension = mGridFrameWidth + mGridFramePenThickness / 2.0;
911 double currentCoord = 0;
914 currentCoord = - mGridFrameWidth;
919 currentCoord = - mGridFrameWidth;
946 QPen framePen =
QPen( mGridFramePenColor );
947 framePen.
setWidthF( mGridFramePenThickness );
952 for ( ; posIt != pos.
constEnd(); ++posIt )
954 p->
setBrush(
QBrush( color1 ? mGridFrameFillColor1 : mGridFrameFillColor2 ) );
957 height = posIt.
key() - currentCoord;
958 width = mGridFrameWidth;
964 height = mGridFrameWidth;
965 width = posIt.
key() - currentCoord;
970 currentCoord = posIt.
key();
985 *extension = mGridFrameWidth;
995 QPen framePen =
QPen( mGridFramePenColor );
996 framePen.
setWidthF( mGridFramePenThickness );
1002 for ( ; posIt != borderPos.
constEnd(); ++posIt )
1010 width = mGridFrameWidth;
1015 width = mGridFrameWidth;
1020 width = mGridFrameWidth * 2;
1030 height = mGridFrameWidth;
1035 height = mGridFrameWidth;
1040 height = mGridFrameWidth * 2;
1057 *extension = mGridFramePenThickness / 2.0;
1062 QPen framePen =
QPen( mGridFramePenColor );
1063 framePen.
setWidthF( mGridFramePenThickness );
1086 GridExtension* extension )
const 1088 QString currentAnnotationString;
1090 for ( ; it != hLines.
constEnd(); ++it )
1098 for ( ; it != vLines.constEnd(); ++it )
1117 double xpos = pos.
x();
1118 double ypos = pos.
y();
1121 double gridFrameDistance = 0;
1124 gridFrameDistance = mGridFrameWidth;
1128 gridFrameDistance += ( mGridFramePenThickness / 2.0 );
1141 gridFrameDistance = 0;
1148 gridFrameDistance = 0;
1152 xpos += textHeight + mAnnotationFrameDistance + gridFrameDistance;
1153 ypos += textWidth / 2.0;
1158 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1159 ypos -= textWidth / 2.0;
1164 xpos += mAnnotationFrameDistance + gridFrameDistance;
1165 ypos += textHeight / 2.0;
1172 gridFrameDistance = 0;
1176 xpos -= ( mAnnotationFrameDistance + gridFrameDistance );
1177 ypos += textWidth / 2.0;
1180 extension->left = qMax( extension->left, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1184 xpos -= textHeight + mAnnotationFrameDistance + gridFrameDistance;
1185 ypos -= textWidth / 2.0;
1188 extension->left = qMax( extension->left, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1192 xpos -= ( textWidth + mAnnotationFrameDistance + gridFrameDistance );
1193 ypos += textHeight / 2.0;
1195 extension->left = qMax( extension->left, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1213 gridFrameDistance = 0;
1220 gridFrameDistance = 0;
1224 xpos -= mAnnotationFrameDistance + gridFrameDistance;
1225 ypos += textWidth / 2.0;
1230 xpos -= textHeight + mAnnotationFrameDistance + gridFrameDistance;
1231 ypos -= textWidth / 2.0;
1236 xpos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1237 ypos += textHeight / 2.0;
1244 gridFrameDistance = 0;
1248 xpos += ( textHeight + mAnnotationFrameDistance + gridFrameDistance );
1249 ypos += textWidth / 2.0;
1252 extension->right = qMax( extension->right, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1256 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1257 ypos -= textWidth / 2.0;
1260 extension->right = qMax( extension->right, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1264 xpos += ( mAnnotationFrameDistance + gridFrameDistance );
1265 ypos += textHeight / 2.0;
1267 extension->right = qMax( extension->right, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1285 gridFrameDistance = 0;
1292 gridFrameDistance = 0;
1296 ypos -= mAnnotationFrameDistance + gridFrameDistance;
1297 xpos -= textWidth / 2.0;
1301 xpos -= textHeight / 2.0;
1302 ypos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1307 xpos += textHeight / 2.0;
1308 ypos -= mAnnotationFrameDistance + gridFrameDistance;
1316 gridFrameDistance = 0;
1320 ypos += ( mAnnotationFrameDistance + textHeight + gridFrameDistance );
1321 xpos -= textWidth / 2.0;
1323 extension->bottom = qMax( extension->bottom, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1327 xpos -= textHeight / 2.0;
1328 ypos += gridFrameDistance + mAnnotationFrameDistance;
1331 extension->bottom = qMax( extension->bottom, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1335 xpos += textHeight / 2.0;
1336 ypos += ( textWidth + mAnnotationFrameDistance + gridFrameDistance );
1339 extension->bottom = qMax( extension->bottom, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1357 gridFrameDistance = 0;
1364 gridFrameDistance = 0;
1368 xpos -= textWidth / 2.0;
1369 ypos += textHeight + mAnnotationFrameDistance + gridFrameDistance;
1373 xpos -= textHeight / 2.0;
1374 ypos += mAnnotationFrameDistance + gridFrameDistance;
1379 xpos += textHeight / 2.0;
1380 ypos += textWidth + mAnnotationFrameDistance + gridFrameDistance;
1388 gridFrameDistance = 0;
1392 xpos -= textWidth / 2.0;
1393 ypos -= ( mAnnotationFrameDistance + gridFrameDistance );
1395 extension->top = qMax( extension->top, mAnnotationFrameDistance + gridFrameDistance + textHeight );
1399 xpos -= textHeight / 2.0;
1400 ypos -= textWidth + mAnnotationFrameDistance + gridFrameDistance;
1403 extension->top = qMax( extension->top, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1407 xpos += textHeight / 2.0;
1408 ypos -= ( mAnnotationFrameDistance + gridFrameDistance );
1411 extension->top = qMax( extension->top, mAnnotationFrameDistance + gridFrameDistance + textWidth );
1420 if ( extension || !p )
1423 drawAnnotation( p,
QPointF( xpos, ypos ), rotation, annotationString );
1426 void QgsComposerMapGrid::drawAnnotation(
QPainter* p,
QPointF pos,
int rotation,
const QString& annotationText )
const 1443 bool geographic =
false;
1457 double wrappedX = fmod( value, 360.0 );
1458 if ( wrappedX > 180.0 )
1460 value = wrappedX - 360.0;
1462 else if ( wrappedX < -180.0 )
1464 value = wrappedX + 360.0;
1476 double coordRounded = qRound( value * pow( 10.0, mGridAnnotationPrecision ) ) / pow( 10.0, mGridAnnotationPrecision );
1480 if ( !geographic || ( coordRounded != 180.0 && coordRounded != 0.0 ) )
1488 if ( !geographic || coordRounded != 0.0 )
1496 return QString::number( qAbs( value ),
'f', mGridAnnotationPrecision ) +
QChar( 176 ) + hemisphere;
1500 return QString::number( qAbs( value ),
'f', mGridAnnotationPrecision ) + hemisphere;
1507 if ( !mGridAnnotationExpression.
data() )
1509 mGridAnnotationExpression.
reset(
new QgsExpression( mGridAnnotationExpressionString ) );
1510 mGridAnnotationExpression->prepare( &expressionContext );
1512 return mGridAnnotationExpression->evaluate( &expressionContext ).toString();
1530 annotationString = p.
toDegreesMinutes( mGridAnnotationPrecision,
true,
true );
1548 return split.
at( 0 );
1552 if ( split.
size() < 2 )
1556 return split.
at( 1 );
1571 double gridIntervalY = mGridIntervalY;
1572 double gridOffsetY = mGridOffsetY;
1573 double annotationScale = 1.0;
1578 if ( mGridUnit ==
CM )
1580 annotationScale = 0.1;
1581 gridIntervalY *= 10;
1587 double roundCorrection = mapBoundingRect.
top() > 0 ? 1.0 : 0.0;
1588 double currentLevel =
static_cast< int >(( mapBoundingRect.
top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
1590 int gridLineCount = 0;
1595 double yCanvasCoord;
1599 lines.push_back( qMakePair( currentLevel * annotationScale,
QLineF( 0, yCanvasCoord,
mComposerMap->
rect().
width(), yCanvasCoord ) ) );
1600 currentLevel += gridIntervalY;
1608 borderLines <<
QLineF( mapPolygon.
at( 0 ), mapPolygon.
at( 1 ) );
1609 borderLines <<
QLineF( mapPolygon.
at( 1 ), mapPolygon.
at( 2 ) );
1610 borderLines <<
QLineF( mapPolygon.
at( 2 ), mapPolygon.
at( 3 ) );
1611 borderLines <<
QLineF( mapPolygon.
at( 3 ), mapPolygon.
at( 0 ) );
1617 intersectionList.
clear();
1618 QLineF gridLine( mapBoundingRect.
left(), currentLevel, mapBoundingRect.
right(), currentLevel );
1621 for ( ; it != borderLines.
constEnd(); ++it )
1624 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1626 intersectionList.push_back( intersectionPoint );
1627 if ( intersectionList.size() >= 2 )
1634 if ( intersectionList.size() >= 2 )
1639 currentLevel += gridIntervalY;
1656 double gridIntervalX = mGridIntervalX;
1657 double gridOffsetX = mGridOffsetX;
1658 double annotationScale = 1.0;
1663 if ( mGridUnit ==
CM )
1665 annotationScale = 0.1;
1666 gridIntervalX *= 10;
1672 double roundCorrection = mapBoundingRect.
left() > 0 ? 1.0 : 0.0;
1673 double currentLevel =
static_cast< int >(( mapBoundingRect.
left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
1675 int gridLineCount = 0;
1679 double xCanvasCoord;
1683 lines.push_back( qMakePair( currentLevel * annotationScale,
QLineF( xCanvasCoord, 0, xCanvasCoord,
mComposerMap->
rect().
height() ) ) );
1684 currentLevel += gridIntervalX;
1692 borderLines <<
QLineF( mapPolygon.
at( 0 ), mapPolygon.
at( 1 ) );
1693 borderLines <<
QLineF( mapPolygon.
at( 1 ), mapPolygon.
at( 2 ) );
1694 borderLines <<
QLineF( mapPolygon.
at( 2 ), mapPolygon.
at( 3 ) );
1695 borderLines <<
QLineF( mapPolygon.
at( 3 ), mapPolygon.
at( 0 ) );
1701 intersectionList.
clear();
1702 QLineF gridLine( currentLevel, mapBoundingRect.
bottom(), currentLevel, mapBoundingRect.
top() );
1705 for ( ; it != borderLines.
constEnd(); ++it )
1708 if ( it->intersect( gridLine, &intersectionPoint ) == QLineF::BoundedIntersection )
1710 intersectionList.push_back( intersectionPoint );
1711 if ( intersectionList.size() >= 2 )
1718 if ( intersectionList.size() >= 2 )
1723 currentLevel += gridIntervalX;
1737 double roundCorrection = bbox.
yMaximum() > 0 ? 1.0 : 0.0;
1738 double currentLevel =
static_cast< int >(( bbox.
yMaximum() - mGridOffsetY ) / mGridIntervalY + roundCorrection ) * mGridIntervalY + mGridOffsetY;
1742 double step = ( maxX - minX ) / 20;
1744 bool crosses180 =
false;
1745 bool crossed180 =
false;
1750 step = ( maxX + 360.0 - minX ) / 20;
1756 int gridLineCount = 0;
1760 double currentX = minX;
1764 if (( !crosses180 || crossed180 ) && ( currentX > maxX ) )
1781 if ( crosses180 && currentX > 180.0 )
1791 for ( ; lineIt != lineSegments.
constEnd(); ++lineIt )
1793 if ( !( *lineIt ).isEmpty() )
1795 lines.append( qMakePair( currentLevel, *lineIt ) );
1799 currentLevel -= mGridIntervalY;
1813 double roundCorrection = bbox.
xMinimum() > 0 ? 1.0 : 0.0;
1814 double currentLevel =
static_cast< int >(( bbox.
xMinimum() - mGridOffsetX ) / mGridIntervalX + roundCorrection ) * mGridIntervalX + mGridOffsetX;
1818 double step = ( maxY - minY ) / 20;
1823 bool crosses180 =
false;
1824 bool crossed180 =
false;
1831 int gridLineCount = 0;
1832 while (( currentLevel <= bbox.
xMaximum() || ( crosses180 && !crossed180 ) ) && gridLineCount <
MAX_GRID_LINES )
1835 double currentY = minY;
1839 if ( currentY > maxY )
1861 for ( ; lineIt != lineSegments.
constEnd(); ++lineIt )
1863 if ( !( *lineIt ).isEmpty() )
1865 lines.append( qMakePair( currentLevel, *lineIt ) );
1869 currentLevel += mGridIntervalX;
1870 if ( crosses180 && currentLevel > 180.0 )
1872 currentLevel -= 360.0;
1885 for ( ; it != hLines.
constEnd(); ++it )
1887 QgsMapAnnotation p1;
1888 p1.coordinate = it->
first;
1889 p1.itemPosition = it->second.p1();
1891 borderPositions << p1;
1893 QgsMapAnnotation p2;
1894 p2.coordinate = it->
first;
1895 p2.itemPosition = it->second.p2();
1897 borderPositions << p2;
1900 for ( ; it != vLines.
constEnd(); ++it )
1902 QgsMapAnnotation p1;
1903 p1.coordinate = it->
first;
1904 p1.itemPosition = it->second.p1();
1906 borderPositions << p1;
1908 QgsMapAnnotation p2;
1909 p2.coordinate = it->
first;
1910 p2.itemPosition = it->second.p2();
1912 borderPositions << p2;
1916 for ( ; bIt != borderPositions.
constEnd(); ++bIt )
1921 leftFrameEntries.
insert( bIt->itemPosition.y(), bIt->coordinate );
1925 rightFrameEntries.
insert( bIt->itemPosition.y(), bIt->coordinate );
1929 topFrameEntries.
insert( bIt->itemPosition.x(), bIt->coordinate );
1933 bottomFrameEntries.
insert( bIt->itemPosition.x(), bIt->coordinate );
1943 return shouldShowDivisionForDisplayMode( coordinate, mLeftFrameDivisions );
1945 return shouldShowDivisionForDisplayMode( coordinate, mRightFrameDivisions );
1947 return shouldShowDivisionForDisplayMode( coordinate, mTopFrameDivisions );
1950 return shouldShowDivisionForDisplayMode( coordinate, mBottomFrameDivisions );
1963 return a.first < b.first;
1976 if (( p.
y() <= tolerance && p.
x() <= tolerance )
1985 if ( p.
x() <= tolerance )
1996 if ( p.
y() <= tolerance )
2015 return distanceToSide.
at( 0 ).second;
2020 delete mGridLineSymbol;
2021 mGridLineSymbol = symbol;
2026 delete mGridMarkerSymbol;
2027 mGridMarkerSymbol = symbol;
2035 mLeftGridAnnotationDisplay = display;
2038 mRightGridAnnotationDisplay = display;
2041 mTopGridAnnotationDisplay = display;
2044 mBottomGridAnnotationDisplay = display;
2062 return mLeftGridAnnotationDisplay;
2064 return mRightGridAnnotationDisplay;
2066 return mTopGridAnnotationDisplay;
2069 return mBottomGridAnnotationDisplay;
2077 double bottom = 0.0;
2080 return qMax( qMax( qMax( top, right ), bottom ), left );
2100 delete expressionContext;
2102 GridExtension extension;
2109 drawGridCRSTransform( context, 0, horizontalLines, verticalLines,
false );
2113 drawGridNoTransform( context, 0, horizontalLines, verticalLines,
false );
2118 drawGridFrame(
nullptr, horizontalLines, verticalLines, &extension );
2121 if ( mShowGridAnnotation )
2123 drawCoordinateAnnotations(
nullptr, horizontalLines, verticalLines, context.
expressionContext(), &extension );
2126 top = extension.top;
2127 right = extension.right;
2128 bottom = extension.bottom;
2129 left = extension.left;
2134 if ( unit == mGridUnit )
2139 mTransformDirty =
true;
2148 mGridIntervalX = interval;
2149 mTransformDirty =
true;
2158 mGridIntervalY = interval;
2159 mTransformDirty =
true;
2168 mGridOffsetX = offset;
2169 mTransformDirty =
true;
2178 mGridOffsetY = offset;
2179 mTransformDirty =
true;
2184 if ( style == mGridStyle )
2189 mTransformDirty =
true;
2197 mLeftGridAnnotationDirection = direction;
2200 mRightGridAnnotationDirection = direction;
2203 mTopGridAnnotationDirection = direction;
2206 mBottomGridAnnotationDirection = direction;
2221 mGridFrameSides = flags;
2227 mGridFrameSides |= flag;
2229 mGridFrameSides &= ~flag;
2234 return mGridFrameSides;
2249 return mGridFrameSides.testFlag( flag );
2254 mLeftGridAnnotationDirection = direction;
2255 mRightGridAnnotationDirection = direction;
2256 mTopGridAnnotationDirection = direction;
2257 mBottomGridAnnotationDirection = direction;
2265 mLeftGridAnnotationPosition = position;
2268 mRightGridAnnotationPosition = position;
2271 mTopGridAnnotationPosition = position;
2274 mBottomGridAnnotationPosition = position;
2292 return mLeftGridAnnotationPosition;
2294 return mRightGridAnnotationPosition;
2296 return mTopGridAnnotationPosition;
2299 return mBottomGridAnnotationPosition;
2307 return mLeftGridAnnotationDirection;
2313 return mLeftGridAnnotationDirection;
2315 return mRightGridAnnotationDirection;
2317 return mTopGridAnnotationDirection;
2320 return mBottomGridAnnotationDirection;
2329 mLeftFrameDivisions = divisions;
2332 mRightFrameDivisions = divisions;
2335 mTopFrameDivisions = divisions;
2338 mBottomFrameDivisions = divisions;
2355 return mLeftFrameDivisions;
2357 return mRightFrameDivisions;
2359 return mTopFrameDivisions;
2362 return mBottomFrameDivisions;
2377 QRectF mbr = mapPolygon.boundingRect();
2384 QgsPoint lowerLeft( mapBoundingRect.xMinimum(), mapBoundingRect.yMinimum() );
2385 QgsPoint upperRight( mapBoundingRect.xMaximum(), mapBoundingRect.yMaximum() );
2387 lowerLeft =
tr.transform( lowerLeft.x(), lowerLeft.y() );
2388 upperRight =
tr.transform( upperRight.x(), upperRight.y() );
2390 if ( lowerLeft.x() > upperRight.x() )
2398 crsRect =
tr.transformBoundingBox( mapBoundingRect );
2403 crsRect =
tr.transformBoundingBox( mapBoundingRect );
2428 for ( ; geomIt != intersectedParts.
constEnd(); ++geomIt )
2430 trimmedLines << ( *geomIt )->asQPolygonF();
2433 qDeleteAll( intersectedParts );
2434 intersectedParts.
clear();
2438 return trimmedLines;
QgsComposerMapGrid(const QString &name, QgsComposerMap *map)
Constructor for QgsComposerMapGrid.
QgsComposerMapItem * item(const QString &itemId) const
Returns a reference to an item within the stack.
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
Single variable definition for use within a QgsExpressionContextScope.
A rectangle specified with double values.
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...
static QgsMarkerSymbolV2 * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Set coordinates of the rectangle which should be rendered.
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.
const QgsComposerMapGrid * constGrid(const QString &gridId) const
Returns a const 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
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
static QString encodeColor(const QColor &color)
FrameStyle
Style for grid frame.
QgsComposerMapItem(const QString &name, QgsComposerMap *map)
Constructor for QgsComposerMapItem.
void scale(qreal sx, qreal sy)
void setClipping(bool enable)
const_iterator constEnd() const
const_iterator constBegin() const
const T & at(int i) const
void setOutputDpi(double dpi)
Set DPI used for conversion between real world units (e.g. mm) and pixels.
static QDomElement saveSymbol(const QString &symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
static void drawText(QPainter *painter, 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 ...
QRectF sceneBoundingRect() const
QString toDegreesMinutes(int thePrecision, const bool useSuffix=true, const bool padded=false) const
Return a string representation as degrees minutes.
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...
void drawLine(const QLineF &line)
AnnotationDirection
Direction of grid annotations.
AnnotationPosition annotationPosition(const BorderSide border) const
Gets the position for the grid annotations on a specified side of the map frame.
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.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
void update(const QRectF &rect)
An item which is drawn inside a QgsComposerMap, eg a grid or map overview.
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...
double y() const
Get the y value of the point.
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.
QDomElement toElement() const
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
void setCapStyle(Qt::PenCapStyle style)
void drawRect(const QRectF &rectangle)
void setColor(const QColor &color)
static double fontHeightCharacterMM(const QFont &font, QChar character)
Calculate font height in millimeters of a single character, including workarounds for QT font renderi...
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)
void setOutputSize(QSize size)
Set the size of the resulting map image.
virtual ~QgsComposerMapGridStack()
void updateBoundingRect()
Updates the bounding rect of this item.
void startRender(QgsRenderContext &context, const QgsFields *fields=nullptr)
bool fromString(const QString &descrip)
bool mEnabled
True if item is to be displayed on map.
bool writeXML(QDomElement &elem, QDomDocument &doc) const override
Stores grid state in DOM element.
static QgsLineSymbolV2 * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
bool readXML(const QDomNode &theNode)
Restores state from the given Dom node.
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
QRectF mapRectFromScene(const QRectF &rect) const
void removeItem(const QString &itemId)
Removes an item from the stack and deletes the corresponding QgsComposerMapItem.
const QgsComposerMapItem * constItem(const QString &itemId) const
Returns a const reference to an item within the stack.
int toInt(bool *ok, int base) const
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
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.
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
GridStyle style() const
Gets the grid's style, which controls how the grid is drawn over the map's contents.
void setWidthF(qreal width)
void setBrush(const QBrush &brush)
void setPainter(QPainter *p)
FrameSideFlags frameSideFlags() const
Returns the flags which control which sides of the map item the grid frame is drawn on...
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.
QString toDegreesMinutesSeconds(int thePrecision, const bool useSuffix=true, const bool padded=false) const
Return a string representation as degrees minutes seconds.
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.
AnnotationDirection annotationDirection(const BorderSide border) const
Gets the direction for drawing frame annotations.
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.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setGridLineWidth(const double width)
Sets width of grid lines.
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.
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
Object representing map window.
void moveItemDown(const QString &itemId)
Moves an item up the stack, causing it to be rendered above other items.
virtual QgsExpressionContext * createExpressionContext() const override
Creates an expression context relating to the objects' current state.
void setX(double x)
Sets the x value of the point.
BorderSide
Border sides for annotations.
QList< QgsGeometry * > asGeometryCollection() const
Return contents of the geometry as a list of geometries.
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.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
QgsExpressionContext & expressionContext()
Gets the expression context.
double xMaximum() const
Get the x maximum value (right side of rectangle)
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset) ...
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...
const T & at(int i) const
QVariant value(const QString &key, const QVariant &defaultValue) const
const_iterator constBegin() const
Contains information about the context of a rendering operation.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QRectF boundingRect() const
void stopRender(QgsRenderContext &context)
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
DisplayMode frameDivisions(const BorderSide border) const
Gets the type of grid divisions which are used for frames on a specified side of the map...
const QgsComposition * composition() const
Returns the composition the item is attached to.
QList< QgsComposerMapGrid *> asList() const
Returns a list of QgsComposerMapGrids contained by the stack.
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.
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 setMarkerSymbol(QgsMarkerSymbolV2 *symbol)
Sets the marker symbol used for drawing grid points.
DisplayMode annotationDisplay(const BorderSide border) const
Gets the display mode for the grid annotations on a specified side of the map frame.
bool sortByDistance(QPair< qreal, QgsComposerMapGrid::BorderSide > a, QPair< qreal, QgsComposerMapGrid::BorderSide > b)
QgsGeometry * intersection(const QgsGeometry *geometry) const
Returns a geometry representing the points shared by this geometry and other.
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 renderPoint(QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
void translate(const QPointF &offset)
double xMinimum() const
Get the x minimum value (left side of rectangle)
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.
virtual bool readXML(const QDomElement &itemElem, const QDomDocument &doc) override
Sets map item state from a DOM document.
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsComposerMap's item rect...
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
double yMaximum() const
Get the y maximum value (top side of rectangle)
static QColor decodeColor(const QString &str)
iterator insert(const Key &key, const T &value)
bool hasFrame() const
Whether this item has a frame or not.
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.
bool testFrameSideFlag(const FrameSideFlag flag) const
Tests whether the grid frame should be drawn on a specified side of the map item. ...
const_iterator constEnd() const
bool writeXML(QDomNode &theNode, QDomDocument &theDoc) const
Stores state to the given Dom node in the given document.
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. ...
double mapRotation(QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the composer item.
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const override
Stores map item state in DOM element.
GridUnit
Unit for grid values.
void setIntervalX(const double interval)
Sets the interval between grid lines in the x-direction.
const QgsRectangle * currentMapExtent() const
Returns a pointer to the current map extent, which is either the original user specified extent or th...
QgsCoordinateReferenceSystem crs() const
Retrieves the CRS for the grid.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
QgsComposerMapGrid * grid(const QString &gridId) const
Returns a reference to a grid within the stack.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
void setOffsetX(const double offset)
Sets the offset for grid lines in the x-direction.
AnnotationCoordinate
Annotation coordinate type.
double x() const
Get the x value of the point.
virtual QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the objects' current state.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QDomNode at(int index) const
bool geographicFlag() const
Returns whether the CRS is a geographic CRS.
QgsComposerMap * mComposerMap
uint toUInt(bool *ok, int base) const
bool isValid() const
Returns whether this CRS is correctly initialized and usable.