@@ -610,6 +610,18 @@ bool QgsLayoutItemMap::writePropertiesToElement( QDomElement &mapElem, QDomDocum
610
610
mapElem.setAttribute ( QStringLiteral ( " labelMargin" ), mLabelMargin .encodeMeasurement () );
611
611
mapElem.setAttribute ( QStringLiteral ( " mapFlags" ), static_cast < int >( mMapFlags ) );
612
612
613
+ QDomElement labelBlockingItemsElem = doc.createElement ( QStringLiteral ( " labelBlockingItems" ) );
614
+ for ( const auto &item : qgis::as_const ( mBlockingLabelItems ) )
615
+ {
616
+ if ( !item )
617
+ continue ;
618
+
619
+ QDomElement blockingItemElem = doc.createElement ( QStringLiteral ( " item" ) );
620
+ blockingItemElem.setAttribute ( QStringLiteral ( " uuid" ), item->uuid () );
621
+ labelBlockingItemsElem.appendChild ( blockingItemElem );
622
+ }
623
+ mapElem.appendChild ( labelBlockingItemsElem );
624
+
613
625
return true ;
614
626
}
615
627
@@ -747,6 +759,22 @@ bool QgsLayoutItemMap::readPropertiesFromElement( const QDomElement &itemElem, c
747
759
748
760
mMapFlags = static_cast < MapItemFlags>( itemElem.attribute ( QStringLiteral ( " mapFlags" ), nullptr ).toInt () );
749
761
762
+ // label blocking items
763
+ mBlockingLabelItems .clear ();
764
+ mBlockingLabelItemUuids .clear ();
765
+ QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName ( QStringLiteral ( " labelBlockingItems" ) );
766
+ if ( !labelBlockingNodeList.isEmpty () )
767
+ {
768
+ QDomElement blockingItems = labelBlockingNodeList.at ( 0 ).toElement ();
769
+ QDomNodeList labelBlockingNodeList = blockingItems.childNodes ();
770
+ for ( int i = 0 ; i < labelBlockingNodeList.size (); ++i )
771
+ {
772
+ const QDomElement &itemBlockingElement = labelBlockingNodeList.at ( i ).toElement ();
773
+ const QString itemUuid = itemBlockingElement.attribute ( QStringLiteral ( " uuid" ) );
774
+ mBlockingLabelItemUuids << itemUuid;
775
+ }
776
+ }
777
+
750
778
updateBoundingRect ();
751
779
752
780
mUpdatesEnabled = true ;
@@ -1160,13 +1188,28 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF
1160
1188
jobMapSettings.setLabelBoundaryGeometry ( mapBoundaryGeom );
1161
1189
}
1162
1190
1191
+ if ( !mBlockingLabelItems .isEmpty () )
1192
+ {
1193
+ jobMapSettings.setLabelBlockingRegions ( createLabelBlockingRegions ( jobMapSettings ) );
1194
+ }
1195
+
1163
1196
return jobMapSettings;
1164
1197
}
1165
1198
1166
1199
void QgsLayoutItemMap::finalizeRestoreFromXml ()
1167
1200
{
1168
1201
assignFreeId ();
1169
1202
1203
+ mBlockingLabelItems .clear ();
1204
+ for ( const QString &uuid : qgis::as_const ( mBlockingLabelItemUuids ) )
1205
+ {
1206
+ QgsLayoutItem *item = mLayout ->itemByUuid ( uuid, true );
1207
+ if ( item )
1208
+ {
1209
+ addLabelBlockingItem ( item );
1210
+ }
1211
+ }
1212
+
1170
1213
mOverviewStack ->finalizeRestoreFromXml ();
1171
1214
mGridStack ->finalizeRestoreFromXml ();
1172
1215
}
@@ -1254,6 +1297,26 @@ QPolygonF QgsLayoutItemMap::transformedMapPolygon() const
1254
1297
return poly;
1255
1298
}
1256
1299
1300
+ void QgsLayoutItemMap::addLabelBlockingItem ( QgsLayoutItem *item )
1301
+ {
1302
+ if ( !mBlockingLabelItems .contains ( item ) )
1303
+ mBlockingLabelItems .append ( item );
1304
+
1305
+ connect ( item, &QgsLayoutItem::sizePositionChanged, this , &QgsLayoutItemMap::invalidateCache, Qt::UniqueConnection );
1306
+ }
1307
+
1308
+ void QgsLayoutItemMap::removeLabelBlockingItem ( QgsLayoutItem *item )
1309
+ {
1310
+ mBlockingLabelItems .removeAll ( item );
1311
+ if ( item )
1312
+ disconnect ( item, &QgsLayoutItem::sizePositionChanged, this , &QgsLayoutItemMap::invalidateCache );
1313
+ }
1314
+
1315
+ bool QgsLayoutItemMap::isLabelBlockingItem ( QgsLayoutItem *item ) const
1316
+ {
1317
+ return mBlockingLabelItems .contains ( item );
1318
+ }
1319
+
1257
1320
QPointF QgsLayoutItemMap::mapToItemCoords ( QPointF mapCoords ) const
1258
1321
{
1259
1322
QPolygonF mapPoly = transformedMapPolygon ();
@@ -1450,6 +1513,43 @@ void QgsLayoutItemMap::connectUpdateSlot()
1450
1513
connect ( project->mapThemeCollection (), &QgsMapThemeCollection::mapThemeChanged, this , &QgsLayoutItemMap::mapThemeChanged );
1451
1514
}
1452
1515
1516
+ QTransform QgsLayoutItemMap::layoutToMapCoordsTransform () const
1517
+ {
1518
+ QPolygonF thisExtent = visibleExtentPolygon ();
1519
+ QTransform mapTransform;
1520
+ QPolygonF thisRectPoly = QPolygonF ( QRectF ( 0 , 0 , rect ().width (), rect ().height () ) );
1521
+ // workaround QT Bug #21329
1522
+ thisRectPoly.pop_back ();
1523
+ thisExtent.pop_back ();
1524
+
1525
+ QPolygonF thisItemPolyInLayout = mapToScene ( thisRectPoly );
1526
+
1527
+ // create transform from layout coordinates to map coordinates
1528
+ QTransform::quadToQuad ( thisItemPolyInLayout, thisExtent, mapTransform );
1529
+ return mapTransform;
1530
+ }
1531
+
1532
+ QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions ( const QgsMapSettings &mapSettings ) const
1533
+ {
1534
+ const QTransform mapTransform = layoutToMapCoordsTransform ();
1535
+ QList< QgsLabelBlockingRegion > blockers;
1536
+ blockers.reserve ( mBlockingLabelItems .count () );
1537
+ for ( const auto &item : qgis::as_const ( mBlockingLabelItems ) )
1538
+ {
1539
+ if ( !item || !item->isVisible () ) // invisible items don't block labels!
1540
+ continue ;
1541
+
1542
+ QPolygonF itemRectInMapCoordinates = mapTransform.map ( item->mapToScene ( item->rect () ) );
1543
+ itemRectInMapCoordinates.append ( itemRectInMapCoordinates.at ( 0 ) ); // close polygon
1544
+ QgsGeometry blockingRegion = QgsGeometry::fromQPolygonF ( itemRectInMapCoordinates );
1545
+ const double labelMargin = mLayout ->convertToLayoutUnits ( mEvaluatedLabelMargin );
1546
+ const double labelMarginInMapUnits = labelMargin / rect ().width () * mapSettings.extent ().width ();
1547
+ blockingRegion = blockingRegion.buffer ( labelMarginInMapUnits, 0 , QgsGeometry::CapSquare, QgsGeometry::JoinStyleMiter, 2 );
1548
+ blockers << QgsLabelBlockingRegion ( blockingRegion );
1549
+ }
1550
+ return blockers;
1551
+ }
1552
+
1453
1553
QgsLayoutMeasurement QgsLayoutItemMap::labelMargin () const
1454
1554
{
1455
1555
return mLabelMargin ;
0 commit comments