Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions src/core/layout/qgslayoutitemmapgrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@

using namespace Qt::StringLiterals;

#define MAX_GRID_LINES 1000 //maximum number of horizontal or vertical grid lines to draw

QgsLayoutItemMapGridStack::QgsLayoutItemMapGridStack( QgsLayoutItemMap *map )
: QgsLayoutItemMapItemStack( map )
{}
Expand Down Expand Up @@ -752,8 +754,8 @@ void QgsLayoutItemMapGrid::drawGridNoTransform( QgsRenderContext &context, doubl
{
//get line positions
mGridLines.clear();
yGridLines();
xGridLines();
calculateYGridLines();
calculateXGridLines();

if ( calculateLinesOnly || mGridLines.empty() )
return;
Expand Down Expand Up @@ -1591,17 +1593,22 @@ void QgsLayoutItemMapGrid::drawCoordinateAnnotation(
facingLeft = !facingLeft;
facingRight = !facingRight;
}
const QRectF mapRect = mMap->rect();
if ( annot.border == Qgis::MapGridBorderSide::Top
&& ( ( facingLeft && annot.position.x() < mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.x() > mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) ) )
&& ( ( facingLeft && !qgsDoubleGreaterThanOrNear( annot.position.x(),mRotatedAnnotationsMarginToCorner,ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM) )
|| ( facingRight && !qgsDoubleLessThanOrNear( annot.position.x(), mapRect.width() - mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) ) ) )
return;
if ( annot.border == Qgis::MapGridBorderSide::Bottom
&& ( ( facingLeft && annot.position.x() > mMap->rect().width() - mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.x() < mRotatedAnnotationsMarginToCorner ) ) )
&& ( ( facingLeft && !qgsDoubleLessThanOrNear( annot.position.x(), mapRect.width() - mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) )
|| ( facingRight && !qgsDoubleGreaterThanOrNear( annot.position.x(), mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) ) ) )
return;
if ( annot.border == Qgis::MapGridBorderSide::Left
&& ( ( facingLeft && annot.position.y() > mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.y() < mRotatedAnnotationsMarginToCorner ) ) )
&& ( ( facingLeft && !qgsDoubleLessThanOrNear( annot.position.y(), mapRect.height() - mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) )
|| ( facingRight && !qgsDoubleGreaterThanOrNear( annot.position.y(), mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) ) ) )
return;
if ( annot.border == Qgis::MapGridBorderSide::Right
&& ( ( facingLeft && annot.position.y() < mRotatedAnnotationsMarginToCorner ) || ( facingRight && annot.position.y() > mMap->rect().height() - mRotatedAnnotationsMarginToCorner ) ) )
&& ( ( facingLeft && !qgsDoubleGreaterThanOrNear( annot.position.y(), mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) )
|| ( facingRight && !qgsDoubleLessThanOrNear( annot.position.y(), mapRect.height() - mRotatedAnnotationsMarginToCorner, ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM ) ) ) )
return;

// adjust to account for text alignment -- for left/right borders the alignment
Expand Down Expand Up @@ -1848,11 +1855,11 @@ QString QgsLayoutItemMapGrid::gridAnnotationString( const double value, Qgis::Ma
return QString(); // no warnings
}

int QgsLayoutItemMapGrid::xGridLines() const
void QgsLayoutItemMapGrid::calculateXGridLines() const
{
if ( !mMap || mEvaluatedIntervalY <= 0.0 )
{
return 1;
return;
}

QPolygonF mapPolygon = mMap->transformedMapPolygon();
Expand Down Expand Up @@ -1881,17 +1888,17 @@ int QgsLayoutItemMapGrid::xGridLines() const
break;
}

//consider to round up to the next step in case the left boundary is > 0
const double roundCorrection = mapBoundingRect.top() > gridOffsetY ? 1.0 : 0.0;
double currentLevel = static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
double currentLevel = static_cast< int >( ( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY ) * gridIntervalY + gridOffsetY;
if ( !qgsDoubleGreaterThanOrNear( currentLevel, mapBoundingRect.top(), GRID_LINE_CLOSE_TO_EDGE_TOLERANCE_MAP_UNITS ) )
currentLevel += gridIntervalY;

int gridLineCount = 0;
if ( qgsDoubleNear( mMap->mapRotation(), 0.0 ) || ( mGridUnit != Qgis::MapGridUnit::MapUnits && mGridUnit != Qgis::MapGridUnit::DynamicPageSizeBased ) )
{
//no rotation. Do it 'the easy way'

double yCanvasCoord;
while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < MAX_GRID_OBJECTS )
while ( qgsDoubleLessThanOrNear( currentLevel, mapBoundingRect.bottom(), GRID_LINE_CLOSE_TO_EDGE_TOLERANCE_MAP_UNITS ) && gridLineCount < MAX_GRID_OBJECTS )
{
yCanvasCoord = mMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
GridLine newLine;
Expand All @@ -1902,7 +1909,7 @@ int QgsLayoutItemMapGrid::xGridLines() const
currentLevel += gridIntervalY;
gridLineCount++;
}
return 0;
return;
}

//the four border lines
Expand Down Expand Up @@ -1944,16 +1951,13 @@ int QgsLayoutItemMapGrid::xGridLines() const
}
currentLevel += gridIntervalY;
}


return 0;
}

int QgsLayoutItemMapGrid::yGridLines() const
void QgsLayoutItemMapGrid::calculateYGridLines() const
{
if ( !mMap || mEvaluatedIntervalX <= 0.0 )
{
return 1;
return;
}

QPolygonF mapPolygon = mMap->transformedMapPolygon();
Expand Down Expand Up @@ -1982,16 +1986,16 @@ int QgsLayoutItemMapGrid::yGridLines() const
break;
}

//consider to round up to the next step in case the left boundary is > 0
const double roundCorrection = mapBoundingRect.left() > gridOffsetX ? 1.0 : 0.0;
double currentLevel = static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
double currentLevel = static_cast< int >( ( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX ) * gridIntervalX + gridOffsetX;
if ( !qgsDoubleGreaterThanOrNear( currentLevel, mapBoundingRect.left(), GRID_LINE_CLOSE_TO_EDGE_TOLERANCE_MAP_UNITS ) )
currentLevel += gridIntervalX;

int gridLineCount = 0;
if ( qgsDoubleNear( mMap->mapRotation(), 0.0 ) || ( mGridUnit != Qgis::MapGridUnit::MapUnits && mGridUnit != Qgis::MapGridUnit::DynamicPageSizeBased ) )
{
//no rotation. Do it 'the easy way'
double xCanvasCoord;
while ( currentLevel <= mapBoundingRect.right() && gridLineCount < MAX_GRID_OBJECTS )
while ( qgsDoubleLessThanOrNear( currentLevel, mapBoundingRect.right(), GRID_LINE_CLOSE_TO_EDGE_TOLERANCE_MAP_UNITS ) && gridLineCount < MAX_GRID_OBJECTS )
{
xCanvasCoord = mMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();

Expand All @@ -2003,7 +2007,7 @@ int QgsLayoutItemMapGrid::yGridLines() const
currentLevel += gridIntervalX;
gridLineCount++;
}
return 0;
return;
}

//the four border lines
Expand Down Expand Up @@ -2045,8 +2049,6 @@ int QgsLayoutItemMapGrid::yGridLines() const
}
currentLevel += gridIntervalX;
}

return 0;
}

int QgsLayoutItemMapGrid::xGridLinesCrsTransform( const QgsRectangle &bbox, const QgsCoordinateTransform &t ) const
Expand Down
14 changes: 9 additions & 5 deletions src/core/layout/qgslayoutitemmapgrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,12 @@ class CORE_EXPORT QgsLayoutItemMapGrid : public QgsLayoutItemMapItem
}
};

static constexpr double GRID_LINE_CLOSE_TO_EDGE_TOLERANCE_MAP_UNITS = 0.00001;

// we need a little bit of tolerance for showing annotations right at the extremities of their edges,
// as we don't want to omit annotations right at the map edges if rounding errors have occurred in the position math
static constexpr double ANNOTATION_CLOSE_TO_EDGE_TOLERANCE_MM = 0.01;

struct GridLineAnnotation
{
Qgis::MapGridBorderSide border = Qgis::MapGridBorderSide::Left; // border on which the annotation is
Expand Down Expand Up @@ -1135,16 +1141,14 @@ class CORE_EXPORT QgsLayoutItemMapGrid : public QgsLayoutItemMapItem
QString gridAnnotationString( double value, Qgis::MapGridAnnotationType coord, QgsExpressionContext &expressionContext, bool isGeographic ) const;

/**
* Computes the grid lines with associated coordinate value
* \returns 0 in case of success
* Computes the grid lines for the x-coordinates.
*/
int xGridLines() const;
void calculateXGridLines() const;

/**
* Computes the grid lines for the y-coordinates. Not vertical in case of rotation
* \returns 0 in case of success
*/
int yGridLines() const;
void calculateYGridLines() const;

int xGridLinesCrsTransform( const QgsRectangle &bbox, const QgsCoordinateTransform &t ) const;

Expand Down
Loading