49#include <QApplication>
53#include <QStyleOptionGraphicsItem>
56#include "moc_qgslayoutitemmap.cpp"
58using namespace Qt::StringLiterals;
68 mBackgroundUpdateTimer =
new QTimer(
this );
69 mBackgroundUpdateTimer->setSingleShot(
true );
70 connect( mBackgroundUpdateTimer, &QTimer::timeout,
this, &QgsLayoutItemMap::recreateCachedImageInBackground );
74 setCacheMode( QGraphicsItem::NoCache );
78 mGridStack = std::make_unique< QgsLayoutItemMapGridStack >(
this );
79 mOverviewStack = std::make_unique< QgsLayoutItemMapOverviewStack >(
this );
87 crs.updateDefinition();
105 mPainterJob->cancel();
130 QList<QgsLayoutItemMap *> mapsList;
131 mLayout->layoutItems( mapsList );
140 if ( map->mMapId == mMapId )
143 maxId = std::max( maxId, map->mMapId );
148 mLayout->itemsModel()->updateItemDisplayName(
this );
160 return tr(
"Map %1" ).arg( mMapId );
172 mCachedLayerStyleOverridesPresetName.clear();
176 updateAtlasFeature();
181 if ( rect().isEmpty() || !
mLayout )
186 calculator.
setDpi( 25.4 );
190 calculator.
setMethod( project->scaleMethod() );
198 double currentScaleDenominator =
scale();
205 double scaleRatio = scaleDenominator / currentScaleDenominator;
206 mExtent.scale( scaleRatio );
208 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
215 calculator.
setDpi( 25.4 );
221 calculator.
setMethod( project->scaleMethod() );
225 const double newScale = calculator.
calculate( mExtent, rect().width() );
228 scaleRatio = scaleDenominator / newScale;
229 mExtent.scale( scaleRatio );
254 if ( mExtent.isFinite() && !mExtent.isEmpty() )
256 const QRectF currentRect = rect();
257 const double newHeight = mExtent.width() == 0 ? 0 : currentRect.width() * mExtent.height() / mExtent.width();
269 double currentWidthHeightRatio = 1.0;
270 if ( !currentExtent.
isEmpty() )
271 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
273 currentWidthHeightRatio = rect().width() / rect().height();
275 if ( currentWidthHeightRatio != 0 && !std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
277 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
279 if ( currentWidthHeightRatio < newWidthHeightRatio )
282 double newHeight = newExtent.
width() / currentWidthHeightRatio;
283 double deltaHeight = newHeight - newExtent.
height();
290 double newWidth = currentWidthHeightRatio * newExtent.
height();
291 double deltaWidth = newWidth - newExtent.
width();
297 if ( mExtent == newExtent )
316QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
319 mapPolygon( mExtent, poly );
321 if ( includeClipping )
328 poly = poly.intersected( geom.asQPolygonF() );
332 if ( mItemClippingSettings->isActive() )
334 const QgsGeometry geom = mItemClippingSettings->clippedMapExtent();
347 return calculateVisibleExtentPolygon(
true );
352 if ( mCrs.isValid() )
355 return mLayout->project()->crs();
370 return _qgis_listRefToRaw( mLayers );
375 mGroupLayers.clear();
377 QList<QgsMapLayer *> layersCopy {
layers };
382 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
384 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
386 auto existingIt = mGroupLayers.find( groupLayer->id() );
387 if ( existingIt != mGroupLayers.end() )
389 *it = ( *existingIt ).second.get();
393 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
396 groupLayerClone->setId( groupLayer->id() );
397 mGroupLayers[groupLayer->id()] = std::move( groupLayerClone );
398 *it = mGroupLayers[groupLayer->id()].get();
402 mLayers = _qgis_listRawToRef( layersCopy );
407 if ( overrides == mLayerStyleOverrides )
410 mLayerStyleOverrides = overrides;
416 mLayerStyleOverrides.clear();
423 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
430 if ( mFollowVisibilityPreset == follow )
433 mFollowVisibilityPreset = follow;
435 if ( !mFollowVisibilityPresetName.isEmpty() )
436 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
441 if ( name == mFollowVisibilityPresetName )
444 mFollowVisibilityPresetName = name;
445 if ( mFollowVisibilityPreset )
451 mLastRenderedImageOffsetX -= dx;
452 mLastRenderedImageOffsetY -= dy;
455 transformShift( dx, dy );
456 if ( !mExtent.isNull() )
458 mExtent.setXMinimum( mExtent.xMinimum() + dx );
459 mExtent.setXMaximum( mExtent.xMaximum() + dx );
460 mExtent.setYMinimum( mExtent.yMinimum() + dy );
461 mExtent.setYMaximum( mExtent.yMaximum() + dy );
475 if ( mDrawing || mExtent.isNull() )
481 double mapX = mExtent.xMinimum() + ( point.x() / rect().width() ) * ( mExtent.xMaximum() - mExtent.xMinimum() );
482 double mapY = mExtent.yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.yMaximum() - mExtent.yMinimum() );
485 double centerX = ( mExtent.xMaximum() + mExtent.xMinimum() ) / 2;
486 double centerY = ( mExtent.yMaximum() + mExtent.yMinimum() ) / 2;
488 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
489 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
491 double newIntervalX, newIntervalY;
495 newIntervalX = ( mExtent.xMaximum() - mExtent.xMinimum() ) / factor;
496 newIntervalY = ( mExtent.yMaximum() - mExtent.yMinimum() ) / factor;
503 mExtent.setXMaximum( centerX + newIntervalX / 2 );
504 mExtent.setXMinimum( centerX - newIntervalX / 2 );
505 mExtent.setYMaximum( centerY + newIntervalY / 2 );
506 mExtent.setYMinimum( centerY - newIntervalY / 2 );
508 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
515 calculator.
setDpi( 25.4 );
520 calculator.
setMethod( project->scaleMethod() );
524 const double newScale = calculator.
calculate( mExtent, rect().width() );
527 const double scaleRatio =
scale() / newScale;
528 mExtent.scale( scaleRatio );
545 if ( layer->dataProvider() && layer->providerType() ==
"wms"_L1 )
555 if (
blendMode() != QPainter::CompositionMode_SourceOver )
574 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]() ->
bool {
583 if ( mOverviewStack->containsAdvancedEffects() )
591 if ( mGridStack->containsAdvancedEffects() )
604 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
625 if ( mOverviewStack->containsAdvancedEffects() )
633 if ( mGridStack->containsAdvancedEffects() )
648 mMapRotation = rotation;
649 mEvaluatedMapRotation = mMapRotation;
662 mAtlasDriven = enabled;
679 double margin = mAtlasMargin;
687 margin = ddMargin / 100;
699 if ( mGridStack->size() < 1 )
702 mGridStack->addGrid(
grid );
704 return mGridStack->grid( 0 );
709 if ( mOverviewStack->size() < 1 )
712 mOverviewStack->addOverview(
overview );
714 return mOverviewStack->overview( 0 );
724 for (
int i = 0; i < mGridStack->size(); ++i )
727 if (
grid->mEvaluatedEnabled )
730 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
745 mapElem.setAttribute( u
"keepLayerSet"_s, u
"true"_s );
749 mapElem.setAttribute( u
"keepLayerSet"_s, u
"false"_s );
752 if ( mDrawAnnotations )
754 mapElem.setAttribute( u
"drawCanvasItems"_s, u
"true"_s );
758 mapElem.setAttribute( u
"drawCanvasItems"_s, u
"false"_s );
762 QDomElement extentElem = doc.createElement( u
"Extent"_s );
767 mapElem.appendChild( extentElem );
769 if ( mCrs.isValid() )
771 QDomElement crsElem = doc.createElement( u
"crs"_s );
772 mCrs.writeXml( crsElem, doc );
773 mapElem.appendChild( crsElem );
777 mapElem.setAttribute( u
"followPreset"_s, mFollowVisibilityPreset ? u
"true"_s : u
"false"_s );
778 mapElem.setAttribute( u
"followPresetName"_s, mFollowVisibilityPresetName );
781 mapElem.setAttribute( u
"mapRotation"_s, QString::number( mMapRotation ) );
784 QDomElement layerSetElem = doc.createElement( u
"LayerSet"_s );
789 QDomElement layerElem = doc.createElement( u
"Layer"_s );
791 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [&layerRef](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool {
792 return groupLayer.second.get() == layerRef.get();
795 if ( it != mGroupLayers.end() )
801 layerId = layerRef.layerId;
804 QDomText layerIdText = doc.createTextNode( layerId );
805 layerElem.appendChild( layerIdText );
807 layerElem.setAttribute( u
"name"_s, layerRef.name );
808 layerElem.setAttribute( u
"source"_s, layerRef.source );
809 layerElem.setAttribute( u
"provider"_s, layerRef.provider );
811 if ( it != mGroupLayers.end() )
813 const auto childLayers { it->second->childLayers() };
814 QDomElement childLayersElement = doc.createElement( u
"childLayers"_s );
815 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
817 QDomElement childElement = doc.createElement( u
"child"_s );
818 childElement.setAttribute( u
"layerid"_s, childLayer->id() );
819 childLayersElement.appendChild( childElement );
821 layerElem.appendChild( childLayersElement );
823 layerSetElem.appendChild( layerElem );
825 mapElem.appendChild( layerSetElem );
828 if ( mKeepLayerStyles )
830 QDomElement stylesElem = doc.createElement( u
"LayerStyles"_s );
831 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
833 QDomElement styleElem = doc.createElement( u
"LayerStyle"_s );
838 styleElem.setAttribute( u
"layerid"_s, ref.
layerId );
839 styleElem.setAttribute( u
"name"_s, ref.
name );
840 styleElem.setAttribute( u
"source"_s, ref.
source );
841 styleElem.setAttribute( u
"provider"_s, ref.
provider );
845 stylesElem.appendChild( styleElem );
847 mapElem.appendChild( stylesElem );
851 mGridStack->writeXml( mapElem, doc, context );
854 mOverviewStack->writeXml( mapElem, doc, context );
857 QDomElement atlasElem = doc.createElement( u
"AtlasMap"_s );
858 atlasElem.setAttribute( u
"atlasDriven"_s, mAtlasDriven );
859 atlasElem.setAttribute( u
"scalingMode"_s, mAtlasScalingMode );
861 mapElem.appendChild( atlasElem );
863 mapElem.setAttribute( u
"labelMargin"_s, mLabelMargin.encodeMeasurement() );
864 mapElem.setAttribute( u
"mapFlags"_s,
static_cast< int>( mMapFlags ) );
866 QDomElement labelBlockingItemsElem = doc.createElement( u
"labelBlockingItems"_s );
867 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
872 QDomElement blockingItemElem = doc.createElement( u
"item"_s );
873 blockingItemElem.setAttribute( u
"uuid"_s, item->uuid() );
874 labelBlockingItemsElem.appendChild( blockingItemElem );
876 mapElem.appendChild( labelBlockingItemsElem );
879 mapElem.setAttribute( u
"isTemporal"_s,
isTemporal() ? 1 : 0 );
882 mapElem.setAttribute( u
"temporalRangeBegin"_s,
temporalRange().begin().toString( Qt::ISODate ) );
883 mapElem.setAttribute( u
"temporalRangeEnd"_s,
temporalRange().end().toString( Qt::ISODate ) );
886 mapElem.setAttribute( u
"enableZRange"_s, mZRangeEnabled ? 1 : 0 );
887 if ( mZRange.lower() != std::numeric_limits< double >::lowest() )
889 if ( mZRange.upper() != std::numeric_limits< double >::max() )
892 mAtlasClippingSettings->writeXml( mapElem, doc, context );
893 mItemClippingSettings->writeXml( mapElem, doc, context );
900 mUpdatesEnabled =
false;
903 QDomNodeList extentNodeList = itemElem.elementsByTagName( u
"Extent"_s );
904 if ( !extentNodeList.isEmpty() )
906 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
907 double xmin, xmax, ymin, ymax;
908 xmin = extentElem.attribute( u
"xmin"_s ).toDouble();
909 xmax = extentElem.attribute( u
"xmax"_s ).toDouble();
910 ymin = extentElem.attribute( u
"ymin"_s ).toDouble();
911 ymax = extentElem.attribute( u
"ymax"_s ).toDouble();
915 QDomNodeList crsNodeList = itemElem.elementsByTagName( u
"crs"_s );
917 if ( !crsNodeList.isEmpty() )
919 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
920 crs.readXml( crsElem );
925 mMapRotation = itemElem.attribute( u
"mapRotation"_s, u
"0"_s ).toDouble();
926 mEvaluatedMapRotation = mMapRotation;
929 mFollowVisibilityPreset = itemElem.attribute( u
"followPreset"_s ).compare(
"true"_L1 ) == 0;
930 mFollowVisibilityPresetName = itemElem.attribute( u
"followPresetName"_s );
933 QString keepLayerSetFlag = itemElem.attribute( u
"keepLayerSet"_s );
934 if ( keepLayerSetFlag.compare(
"true"_L1, Qt::CaseInsensitive ) == 0 )
936 mKeepLayerSet =
true;
940 mKeepLayerSet =
false;
943 QString drawCanvasItemsFlag = itemElem.attribute( u
"drawCanvasItems"_s, u
"true"_s );
944 if ( drawCanvasItemsFlag.compare(
"true"_L1, Qt::CaseInsensitive ) == 0 )
946 mDrawAnnotations =
true;
950 mDrawAnnotations =
false;
953 mLayerStyleOverrides.clear();
955 QList<QgsMapLayerRef> layerSet;
956 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( u
"LayerSet"_s );
957 if ( !layerSetNodeList.isEmpty() )
959 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
960 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( u
"Layer"_s );
961 layerSet.reserve( layerIdNodeList.size() );
962 for (
int i = 0; i < layerIdNodeList.size(); ++i )
964 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
965 QString layerId = layerElem.text();
966 QString layerName = layerElem.attribute( u
"name"_s );
967 QString layerSource = layerElem.attribute( u
"source"_s );
968 QString layerProvider = layerElem.attribute( u
"provider"_s );
970 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
978 setLayers( _qgis_listRefToRaw( layerSet ) );
981 if ( !layerSetNodeList.isEmpty() )
983 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
984 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( u
"Layer"_s );
985 for (
int i = 0; i < layerIdNodeList.size(); ++i )
987 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
988 const QString layerId = layerElem.text();
989 const auto it = mGroupLayers.find( layerId );
990 if ( it != mGroupLayers.cend() )
992 QList<QgsMapLayerRef> childSet;
993 const QDomNodeList childLayersElements = layerElem.elementsByTagName( u
"childLayers"_s );
994 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
995 for (
int i = 0; i < children.size(); ++i )
997 const QDomElement childElement = children.at( i ).toElement();
998 const QString
id = childElement.attribute( u
"layerid"_s );
1002 childSet.push_back( layerRef );
1005 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
1012 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( u
"LayerStyles"_s );
1013 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
1014 if ( mKeepLayerStyles )
1016 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
1017 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( u
"LayerStyle"_s );
1018 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
1020 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
1021 QString layerId = layerStyleElement.attribute( u
"layerid"_s );
1022 QString layerName = layerStyleElement.attribute( u
"name"_s );
1023 QString layerSource = layerStyleElement.attribute( u
"source"_s );
1024 QString layerProvider = layerStyleElement.attribute( u
"provider"_s );
1025 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
1029 style.
readXml( layerStyleElement );
1035 mNumCachedLayers = 0;
1036 mCacheInvalidated =
true;
1039 mOverviewStack->readXml( itemElem, doc, context );
1042 mGridStack->readXml( itemElem, doc, context );
1045 QDomNodeList atlasNodeList = itemElem.elementsByTagName( u
"AtlasMap"_s );
1046 if ( !atlasNodeList.isEmpty() )
1048 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1049 mAtlasDriven = ( atlasElem.attribute( u
"atlasDriven"_s, u
"0"_s ) !=
"0"_L1 );
1050 if ( atlasElem.hasAttribute( u
"fixedScale"_s ) )
1052 mAtlasScalingMode = ( atlasElem.attribute( u
"fixedScale"_s, u
"0"_s ) !=
"0"_L1 ) ?
Fixed :
Auto;
1054 else if ( atlasElem.hasAttribute( u
"scalingMode"_s ) )
1056 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( u
"scalingMode"_s ).toInt() );
1058 mAtlasMargin = atlasElem.attribute( u
"margin"_s, u
"0.1"_s ).toDouble();
1063 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( u
"mapFlags"_s,
nullptr ).toInt() );
1066 mBlockingLabelItems.clear();
1067 mBlockingLabelItemUuids.clear();
1068 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( u
"labelBlockingItems"_s );
1069 if ( !labelBlockingNodeList.isEmpty() )
1071 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1072 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1073 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1075 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1076 const QString itemUuid = itemBlockingElement.attribute( u
"uuid"_s );
1077 mBlockingLabelItemUuids << itemUuid;
1081 mAtlasClippingSettings->readXml( itemElem, doc, context );
1082 mItemClippingSettings->readXml( itemElem, doc, context );
1087 setIsTemporal( itemElem.attribute( u
"isTemporal"_s ).toInt() );
1090 const QDateTime begin = QDateTime::fromString( itemElem.attribute( u
"temporalRangeBegin"_s ), Qt::ISODate );
1091 const QDateTime end = QDateTime::fromString( itemElem.attribute( u
"temporalRangeEnd"_s ), Qt::ISODate );
1095 mZRangeEnabled = itemElem.attribute( u
"enableZRange"_s ).toInt();
1097 double zLower = itemElem.attribute( u
"zRangeLower"_s ).toDouble( &ok );
1100 zLower = std::numeric_limits< double >::lowest();
1102 double zUpper = itemElem.attribute( u
"zRangeUpper"_s ).toDouble( &ok );
1105 zUpper = std::numeric_limits< double >::max();
1109 mUpdatesEnabled =
true;
1113bool QgsLayoutItemMap::hasCustomFramePath()
const
1124 return mItemClippingSettings->isActive();
1129 QPainterPath customFramePath;
1130 if ( mAtlasClippingSettings->enabled() && mAtlasClippingSettings->clipItemShape() )
1135 QPolygonF visibleExtent = calculateVisibleExtentPolygon(
false );
1136 QPolygonF rectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
1139 visibleExtent.pop_back();
1140 rectPoly.pop_back();
1143 QTransform transform;
1144 QTransform::quadToQuad( visibleExtent, rectPoly, transform );
1154 if ( mItemClippingSettings->isActive() )
1156 const QgsGeometry g = mItemClippingSettings->clipPathInMapItemCoordinates();
1159 if ( !customFramePath.isEmpty() )
1162 customFramePath.closeSubpath();
1176 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1185 QRectF thisPaintRect = rect();
1191 if (
mLayout->renderContext().isPreviewRender() )
1193 bool renderInProgress =
false;
1194 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1197 painter->setClipRect( thisPaintRect );
1198 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1201 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1202 painter->drawRect( thisPaintRect );
1203 painter->setBrush( Qt::NoBrush );
1205 messageFont.setPointSize( 12 );
1206 painter->setFont( messageFont );
1207 painter->setPen( QColor( 255, 255, 255, 255 ) );
1208 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1209 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1213 mBackgroundUpdateTimer->start( 100 );
1215 else if ( !mPainterJob && !mDrawingPreview )
1219 mBackgroundUpdateTimer->start( 100 );
1221 renderInProgress =
true;
1225 if ( mCacheInvalidated && !mDrawingPreview )
1229 mBackgroundUpdateTimer->start( 100 );
1230 renderInProgress =
true;
1235 double imagePixelWidth = mCacheFinalImage->width();
1236 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1240 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1241 painter->setCompositionMode( blendModeForRender() );
1243 painter->drawImage( 0, 0, *mCacheFinalImage );
1248 painter->setClipRect( thisPaintRect, Qt::NoClip );
1250 mOverviewStack->drawItems( painter,
false );
1251 mGridStack->drawItems( painter );
1253 drawMapFrame( painter );
1255 if ( renderInProgress )
1266 QPaintDevice *paintDevice = painter->device();
1274 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1283 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1284 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1285 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1287 image.fill( Qt::transparent );
1288 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1289 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1290 double dotsPerMM = destinationDpi / 25.4;
1291 QPainter p( &image );
1294 QRect imagePaintRect(
1295 static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1296 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1297 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1298 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) )
1300 p.setClipRect( imagePaintRect );
1302 p.translate( imagePaintRect.topLeft() );
1306 if ( shouldDrawPart( Background ) )
1308 p.scale( dotsPerMM, dotsPerMM );
1309 drawMapBackground( &p );
1310 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1313 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1318 p.scale( dotsPerMM, dotsPerMM );
1320 if ( shouldDrawPart( OverviewMapExtent ) )
1322 mOverviewStack->drawItems( &p,
false );
1324 if ( shouldDrawPart( Grid ) )
1326 mGridStack->drawItems( &p );
1331 painter->setCompositionMode( blendModeForRender() );
1332 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1333 painter->drawImage( QPointF( -tl.x() * dotsPerMM, -tl.y() * dotsPerMM ), image );
1334 painter->scale( dotsPerMM, dotsPerMM );
1339 if ( shouldDrawPart( Background ) )
1341 drawMapBackground( painter );
1345 painter->setClipRect( thisPaintRect );
1350 painter->translate( mXOffset, mYOffset );
1352 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1354 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1356 if ( mCurrentExportPart != NotLayered )
1358 if ( !mStagedRendererJob )
1360 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1363 mStagedRendererJob->renderCurrentPart( painter );
1367 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1371 painter->setClipRect( thisPaintRect, Qt::NoClip );
1373 if ( shouldDrawPart( OverviewMapExtent ) )
1375 mOverviewStack->drawItems( painter,
false );
1377 if ( shouldDrawPart( Grid ) )
1379 mGridStack->drawItems( painter );
1384 if ( shouldDrawPart( Frame ) )
1386 drawMapFrame( painter );
1397 + ( layerCount + ( layerCount ? 1 : 0 ) )
1398 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1399 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1405 mCurrentExportPart = Start;
1407 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1408 mExportThemeIt = mExportThemes.begin();
1413 mCurrentExportPart = NotLayered;
1414 mExportThemes.clear();
1415 mExportThemeIt = mExportThemes.begin();
1420 switch ( mCurrentExportPart )
1425 mCurrentExportPart = Background;
1431 mCurrentExportPart = Layer;
1435 if ( mStagedRendererJob )
1437 if ( mStagedRendererJob->nextPart() )
1441 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1442 mStagedRendererJob.reset();
1446 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1452 if ( mGridStack->hasEnabledItems() )
1454 mCurrentExportPart = Grid;
1460 for (
int i = 0; i < mOverviewStack->size(); ++i )
1465 mCurrentExportPart = OverviewMapExtent;
1471 case OverviewMapExtent:
1474 mCurrentExportPart = Frame;
1481 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1483 mCurrentExportPart = SelectionBoxes;
1488 case SelectionBoxes:
1489 mCurrentExportPart = End;
1510 switch ( mCurrentExportPart )
1520 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1523 if ( mStagedRendererJob )
1525 switch ( mStagedRendererJob->currentStage() )
1529 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1530 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1531 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1539 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1550 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1556 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1561 detail.
name = u
"%1: %2"_s.arg(
displayName(), item->mapLayer()->name() );
1570 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1576 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1611 case OverviewMapExtent:
1619 case SelectionBoxes:
1634void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1640 if ( std::isnan( size.width() ) || std::isnan( size.height() ) ||
qgsDoubleNear( size.width(), 0.0 ) ||
qgsDoubleNear( size.height(), 0.0 ) )
1642 QgsDebugError( u
"Trying to draw a map with invalid size (%1, %2)"_s.arg( size.width() ).arg( size.height() ) );
1649 if ( shouldDrawPart( OverviewMapExtent ) )
1651 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1654 QgsMapRendererCustomPainterJob job( ms, painter );
1655#ifdef HAVE_SERVER_PYTHON_PLUGINS
1656 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1659 QgsGroupedFeatureFilterProvider jobFeatureFilter;
1662 jobFeatureFilter.
addProvider( mAtlasFeatureFilterProvider.get() );
1663 if ( job.featureFilterProvider() )
1665 jobFeatureFilter.
addProvider( job.featureFilterProvider() );
1667 job.setFeatureFilterProvider( &jobFeatureFilter );
1673 job.renderSynchronously();
1675 mExportLabelingResults.reset( job.takeLabelingResults() );
1677 mRenderingErrors = job.errors();
1681 mRenderingErrors.append( QgsMapRendererJob::Error( QString(), u
"Invalid layer(s)"_s ) );
1685void QgsLayoutItemMap::recreateCachedImageInBackground()
1690 QgsMapRendererCustomPainterJob *oldJob = mPainterJob.release();
1691 QPainter *oldPainter = mPainter.release();
1692 QImage *oldImage = mCacheRenderingImage.release();
1694 oldJob->deleteLater();
1702 mCacheRenderingImage.reset(
nullptr );
1706 Q_ASSERT( !mPainterJob );
1707 Q_ASSERT( !mPainter );
1708 Q_ASSERT( !mCacheRenderingImage );
1710 QgsRectangle ext =
extent();
1714 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1715 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1718 if ( w > 5000 || h > 5000 )
1723 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1728 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1732 if ( w <= 0 || h <= 0 )
1735 mCacheRenderingImage = std::make_unique<QImage>( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 );
1738 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1739 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1740 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1743 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1748 if ( hasCustomFramePath() )
1750 QPainter p( mCacheRenderingImage.get() );
1752 p.setPen( Qt::NoPen );
1754 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1764 mCacheInvalidated =
false;
1765 mPainter = std::make_unique<QPainter>( mCacheRenderingImage.get() );
1766 QgsMapSettings settings(
mapSettings( ext, QSizeF( w, h ), mCacheRenderingImage->logicalDpiX(),
true ) );
1768 if ( shouldDrawPart( OverviewMapExtent ) )
1770 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1773 mPainterJob = std::make_unique<QgsMapRendererCustomPainterJob>( settings, mPainter.get() );
1776 mPainterJob->setFeatureFilterProvider( mAtlasFeatureFilterProvider.get() );
1779 mPainterJob->start();
1791 mDrawingPreview =
false;
1814 if (
layout()->renderContext().isPreviewRender() )
1817 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1820 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1828 if ( includeLayerSettings )
1833 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1836 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1843 if ( !
mLayout->renderContext().isPreviewRender() )
1892 if ( mEvaluatedLabelMargin.length() > 0 )
1895 visiblePoly.append( visiblePoly.at( 0 ) );
1896 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1897 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1899 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1900 labelBoundary = mapBoundaryGeom;
1903 if ( !mBlockingLabelItems.isEmpty() )
1916 if ( mZRangeEnabled )
1921 if ( mAtlasClippingSettings->enabled() &&
mLayout->reportContext().feature().isValid() )
1925 region.
setFeatureClip( mAtlasClippingSettings->featureClippingType() );
1930 if ( mAtlasClippingSettings->forceLabelsInsideFeature() )
1932 if ( !labelBoundary.
isEmpty() )
1934 labelBoundary = clipGeom.
intersection( labelBoundary );
1938 labelBoundary = clipGeom;
1943 if ( mItemClippingSettings->isActive() )
1945 const QgsGeometry clipGeom = mItemClippingSettings->clippedMapExtent();
1948 jobMapSettings.
addClippingRegion( mItemClippingSettings->toMapClippingRegion() );
1950 if ( mItemClippingSettings->forceLabelsInsideClipPath() )
1952 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1953 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1955 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1956 if ( !labelBoundary.
isEmpty() )
1958 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1962 labelBoundary = mapBoundaryGeom;
1968 if ( !labelBoundary.
isNull() )
1971 return jobMapSettings;
1978 mBlockingLabelItems.clear();
1979 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1988 mOverviewStack->finalizeRestoreFromXml();
1989 mGridStack->finalizeRestoreFromXml();
1990 mItemClippingSettings->finalizeRestoreFromXml();
2001 return mCurrentRectangle;
2015 const double mapScale =
scale();
2039 QVariantList layersIds;
2049 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
2051 layersIds.reserve( layersInMap.count() );
2052 layers.reserve( layersInMap.count() );
2055 layersIds << layer->id();
2061 scope->
addFunction( u
"is_layer_visible"_s,
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
2083 if ( extentWidth <= 0 )
2087 return rect().width() / extentWidth;
2092 double dx = mXOffset;
2093 double dy = mYOffset;
2094 transformShift( dx, dy );
2095 QPolygonF poly = calculateVisibleExtentPolygon(
false );
2096 poly.translate( -dx, -dy );
2102 if ( !mBlockingLabelItems.contains( item ) )
2103 mBlockingLabelItems.append( item );
2110 mBlockingLabelItems.removeAll( item );
2117 return mBlockingLabelItems.contains( item );
2122 return mPreviewLabelingResults.get();
2131 if ( mOverviewStack )
2133 for (
int i = 0; i < mOverviewStack->size(); ++i )
2135 if ( mOverviewStack->item( i )->accept( visitor ) )
2142 for (
int i = 0; i < mGridStack->size(); ++i )
2144 if ( mGridStack->item( i )->accept( visitor ) )
2157 mRenderedFeatureHandlers.append( handler );
2162 mRenderedFeatureHandlers.removeAll( handler );
2168 if ( mapPoly.empty() )
2170 return QPointF( 0, 0 );
2175 double dx = mapCoords.x() - rotationPoint.
x();
2176 double dy = mapCoords.y() - rotationPoint.
y();
2178 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2181 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2182 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2183 return QPointF( xItem, yItem );
2197 mapPolygon( newExtent, poly );
2198 QRectF bRect = poly.boundingRect();
2199 extent.setXMinimum( bRect.left() );
2200 extent.setXMaximum( bRect.right() );
2201 extent.setYMinimum( bRect.top() );
2202 extent.setYMaximum( bRect.bottom() );
2212 mCacheInvalidated =
true;
2218 QRectF rectangle = rect();
2219 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2221 double topExtension = 0.0;
2222 double rightExtension = 0.0;
2223 double bottomExtension = 0.0;
2224 double leftExtension = 0.0;
2227 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2229 topExtension = std::max( topExtension, frameExtension );
2230 rightExtension = std::max( rightExtension, frameExtension );
2231 bottomExtension = std::max( bottomExtension, frameExtension );
2232 leftExtension = std::max( leftExtension, frameExtension );
2234 rectangle.setLeft( rectangle.left() - leftExtension );
2235 rectangle.setRight( rectangle.right() + rightExtension );
2236 rectangle.setTop( rectangle.top() - topExtension );
2237 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2238 if ( rectangle != mCurrentRectangle )
2240 prepareGeometryChange();
2241 mCurrentRectangle = rectangle;
2272 refreshMapExtents( &context );
2274 if ( mExtent != beforeExtent )
2281 refreshLabelMargin(
false );
2285 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2287 if ( mLastEvaluatedThemeName != previousTheme )
2308 double zLower = mZRange.lower();
2309 double zUpper = mZRange.upper();
2320 mCacheInvalidated =
true;
2325void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2327 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2331 mLayerStyleOverrides.remove( layer->id() );
2333 _qgis_removeLayers( mLayers,
layers );
2336 for ( QgsMapLayer *layer : std::as_const(
layers ) )
2339 if ( mGroupLayers.erase( layer->id() ) == 0 )
2342 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2344 QgsGroupLayer *groupLayer = it->second.get();
2345 if ( groupLayer->
childLayers().contains( layer ) )
2347 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2348 childLayers.removeAll( layer );
2356void QgsLayoutItemMap::painterJobFinished()
2359 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2360 mPainterJob.reset(
nullptr );
2361 mPainter.reset(
nullptr );
2362 mCacheFinalImage = std::move( mCacheRenderingImage );
2363 mLastRenderedImageOffsetX = 0;
2364 mLastRenderedImageOffsetY = 0;
2370void QgsLayoutItemMap::shapeChanged()
2373 if ( !mExtent.isNull() )
2375 QgsPointXY oldCenter = mExtent.center();
2377 double w = rect().width();
2378 double h = rect().height();
2381 double newWidth = mExtent.width();
2383 double newHeight = newWidth * h / w;
2389 refreshMapExtents();
2396void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2398 if ( theme == mCachedLayerStyleOverridesPresetName )
2399 mCachedLayerStyleOverridesPresetName.clear();
2402void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2404 if ( theme == mFollowVisibilityPresetName )
2406 mFollowVisibilityPresetName = newTheme;
2410void QgsLayoutItemMap::connectUpdateSlot()
2413 QgsProject *project =
mLayout->project();
2417 connect( project,
static_cast< void ( QgsProject::* )(
const QList<QgsMapLayer *> &
layers )
>( &
QgsProject::layersWillBeRemoved ),
this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2420 if ( layers().isEmpty() )
2428 if ( !mCrs.isValid() )
2444 if ( mAtlasScalingMode == Predefined )
2445 updateAtlasFeature();
2451 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2452 QTransform mapTransform;
2453 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2455 thisRectPoly.pop_back();
2456 thisExtent.pop_back();
2458 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2461 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2462 return mapTransform;
2467 mZRangeEnabled = enabled;
2472 return mZRangeEnabled;
2485QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2488 QList< QgsLabelBlockingRegion > blockers;
2489 blockers.reserve( mBlockingLabelItems.count() );
2490 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2497 if ( item->property(
"wasVisible" ).isValid() )
2499 if ( !item->property(
"wasVisible" ).toBool() )
2502 else if ( !item->isVisible() )
2505 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2506 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2508 blockers << QgsLabelBlockingRegion( blockingRegion );
2515 return mLabelMargin;
2520 mLabelMargin = margin;
2521 refreshLabelMargin(
false );
2524void QgsLayoutItemMap::updateToolTip()
2533 if ( mFollowVisibilityPreset )
2535 presetName = mFollowVisibilityPresetName;
2539 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2540 presetName = *mExportThemeIt;
2551 QList<QgsMapLayer *> renderLayers;
2553 QString presetName = themeToRender( *evalContext );
2554 if ( !presetName.isEmpty() )
2556 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2557 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2559 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2561 else if ( !
layers().isEmpty() )
2567 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2574 renderLayers.clear();
2576 const QStringList layerNames = ddLayers.split(
'|' );
2578 for (
const QString &name : layerNames )
2580 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2583 renderLayers << layer;
2592 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2593 if ( removeAt != -1 )
2595 renderLayers.removeAt( removeAt );
2600 if ( !includeInvalidLayers )
2602 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer *layer ) { return !layer || !layer->isValid(); } ), renderLayers.end() );
2605 return renderLayers;
2608QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2610 QString presetName = themeToRender( context );
2611 if ( !presetName.isEmpty() )
2613 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2615 if ( presetName != mCachedLayerStyleOverridesPresetName )
2618 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2619 mCachedLayerStyleOverridesPresetName = presetName;
2622 return mCachedPresetLayerStyleOverrides;
2625 return QMap<QString, QString>();
2627 else if ( mFollowVisibilityPreset )
2629 QString presetName = mFollowVisibilityPresetName;
2632 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2634 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2637 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2638 mCachedLayerStyleOverridesPresetName = presetName;
2641 return mCachedPresetLayerStyleOverrides;
2644 return QMap<QString, QString>();
2646 else if ( mKeepLayerStyles )
2648 return mLayerStyleOverrides;
2652 return QMap<QString, QString>();
2656QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2658 double dx = mXOffset;
2659 double dy = mYOffset;
2660 transformShift( dx, dy );
2661 return QgsRectangle( mExtent.xMinimum() - dx, mExtent.yMinimum() - dy, mExtent.xMaximum() - dx, mExtent.yMaximum() - dy );
2664void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2669 poly << QPointF(
extent.xMinimum(),
extent.yMaximum() );
2670 poly << QPointF(
extent.xMaximum(),
extent.yMaximum() );
2671 poly << QPointF(
extent.xMaximum(),
extent.yMinimum() );
2672 poly << QPointF(
extent.xMinimum(),
extent.yMinimum() );
2674 poly << QPointF( poly.at( 0 ) );
2679 QgsPointXY rotationPoint( (
extent.xMaximum() +
extent.xMinimum() ) / 2.0, (
extent.yMaximum() +
extent.yMinimum() ) / 2.0 );
2683 dx = rotationPoint.x() -
extent.xMinimum();
2684 dy = rotationPoint.y() -
extent.yMaximum();
2686 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2689 dx = rotationPoint.x() -
extent.xMaximum();
2690 dy = rotationPoint.y() -
extent.yMaximum();
2692 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2695 dx = rotationPoint.x() -
extent.xMaximum();
2696 dy = rotationPoint.y() -
extent.yMinimum();
2698 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2701 dx = rotationPoint.x() -
extent.xMinimum();
2702 dy = rotationPoint.y() -
extent.yMinimum();
2704 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2707 poly << QPointF( poly.at( 0 ) );
2710void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2713 double dxScaled = xShift * mmToMapUnits;
2714 double dyScaled = -yShift * mmToMapUnits;
2729 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2730 if ( annotations.isEmpty() )
2739 for ( QgsAnnotation *annotation : annotations )
2741 if ( !annotation || !annotation->isVisible() )
2745 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2748 drawAnnotation( annotation, rc );
2759 QgsScopedQPainterState painterState( context.
painter() );
2762 double itemX, itemY;
2765 QPointF mapPos = layoutMapPosForItem( annotation );
2774 context.
painter()->translate( itemX, itemY );
2777 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2778 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2780 annotation->
render( context );
2783QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2786 return QPointF( 0, 0 );
2793 QgsCoordinateReferenceSystem annotationCrs = annotation->
mapPositionCrs();
2795 if ( annotationCrs !=
crs() )
2798 QgsCoordinateTransform t( annotationCrs,
crs(),
mLayout->project() );
2802 t.transformInPlace( mapX, mapY, z );
2804 catch (
const QgsCsException & )
2811void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2822void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2833bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2835 if ( mCurrentExportPart == NotLayered )
2853 return mCurrentExportPart == Layer;
2856 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2858 case OverviewMapExtent:
2859 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2864 case SelectionBoxes:
2865 return mCurrentExportPart == SelectionBoxes && isSelected();
2876 QgsExpressionContext scopedContext;
2881 const QgsExpressionContext *evalContext = context ? context : &scopedContext;
2885 QgsRectangle newExtent =
extent();
2886 bool useDdXMin =
false;
2887 bool useDdXMax =
false;
2888 bool useDdYMin =
false;
2889 bool useDdYMax =
false;
2920 if ( newExtent != mExtent )
2926 double currentWidthHeightRatio = mExtent.width() / mExtent.height();
2927 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2929 if ( currentWidthHeightRatio < newWidthHeightRatio )
2932 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2933 double deltaHeight = newHeight - newExtent.
height();
2940 double newWidth = currentWidthHeightRatio * newExtent.
height();
2941 double deltaWidth = newWidth - newExtent.
width();
2946 mExtent = newExtent;
2956 newExtent = mExtent;
2959 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2963 if ( useDdXMin && !useDdXMax )
2965 double xMax = mExtent.xMaximum() - ( mExtent.xMinimum() - minXD );
2969 else if ( !useDdXMin && useDdXMax )
2971 double xMin = mExtent.xMinimum() - ( mExtent.xMaximum() - maxXD );
2975 if ( useDdYMin && !useDdYMax )
2977 double yMax = mExtent.yMaximum() - ( mExtent.yMinimum() - minYD );
2981 else if ( !useDdYMin && useDdYMax )
2983 double yMin = mExtent.yMinimum() - ( mExtent.yMaximum() - maxYD );
2988 if ( newExtent != mExtent )
2990 mExtent = newExtent;
3007void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
3012 mEvaluatedLabelMargin.setUnits( mLabelMargin.units() );
3020void QgsLayoutItemMap::updateAtlasFeature()
3022 if ( !
mLayout->reportContext().layer() || !
mLayout->reportContext().feature().isValid() )
3025 QgsFeatureExpressionFilterProvider *filter =
new QgsFeatureExpressionFilterProvider();
3026 filter->
setFilter(
mLayout->reportContext().layer()->id(), QgsExpression( u
"@id = %1"_s.arg(
mLayout->reportContext().feature().id() ) ) );
3027 mAtlasFeatureFilterProvider = std::make_unique<QgsGroupedFeatureFilterProvider>();
3028 mAtlasFeatureFilterProvider->addProvider( filter );
3033 QgsRectangle bounds = computeAtlasRectangle();
3041 QgsRectangle newExtent = bounds;
3042 QgsRectangle originalExtent = mExtent;
3047 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
3049 QgsScaleCalculator calc;
3052 if ( QgsProject *project =
mLayout->project() )
3057 double originalScale = calc.
calculate( originalExtent, rect().width() );
3058 double geomCenterX = ( xa1 + xa2 ) / 2.0;
3059 double geomCenterY = ( ya1 + ya2 ) / 2.0;
3060 QVector<qreal> scales;
3062 if ( !
mLayout->reportContext().predefinedScales().empty() )
3063 scales =
mLayout->reportContext().predefinedScales();
3065 scales =
mLayout->renderContext().predefinedScales();
3067 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
3070 double xMin = geomCenterX - originalExtent.
width() / 2.0;
3071 double yMin = geomCenterY - originalExtent.
height() / 2.0;
3072 newExtent = QgsRectangle( xMin, yMin, xMin + originalExtent.
width(), yMin + originalExtent.
height() );
3076 double newScale = calc.
calculate( newExtent, rect().width() );
3079 newExtent.
scale( originalScale / newScale );
3085 double newWidth = originalExtent.
width();
3086 double newHeight = originalExtent.
height();
3087 for (
int i = 0; i < scales.size(); i++ )
3089 double ratio = scales[i] / originalScale;
3090 newWidth = originalExtent.
width() * ratio;
3091 newHeight = originalExtent.
height() * ratio;
3094 double xMin = geomCenterX - newWidth / 2.0;
3095 double yMin = geomCenterY - newHeight / 2.0;
3096 newExtent = QgsRectangle( xMin, yMin, xMin + newWidth, yMin + newHeight );
3100 const double newScale = calc.
calculate( newExtent, rect().width() );
3104 newExtent.
scale( scales[i] / newScale );
3114 else if ( mAtlasScalingMode ==
Auto )
3118 double geomRatio = bounds.
width() / bounds.
height();
3119 double mapRatio = originalExtent.
width() / originalExtent.
height();
3122 if ( geomRatio < mapRatio )
3125 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
3130 else if ( geomRatio > mapRatio )
3133 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
3137 newExtent = QgsRectangle( xa1, ya1, xa2, ya2 );
3139 const double evaluatedAtlasMargin =
atlasMargin();
3140 if ( evaluatedAtlasMargin > 0.0 )
3142 newExtent.
scale( 1 + evaluatedAtlasMargin );
3156 QgsGeometry g =
mLayout->reportContext().currentGeometry(
crs() );
3168 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ), std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3169 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ), std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3171 return QgsRectangle( center.
x() - dx, center.
y() - dy, center.
x() + dx, center.
y() + dy );
3179void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3182 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3184 mStagedRendererJob = std::make_unique<
3186 mStagedRendererJob->start();
3198 if ( mMap->layout() && mMap->layout()->project() )
3200 connect( mMap->layout()->project(), static_cast< void ( QgsProject::* )( const QList<QgsMapLayer *> &layers ) >( &QgsProject::layersWillBeRemoved ), this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3206 return mClipToAtlasFeature;
3211 if (
enabled == mClipToAtlasFeature )
3214 mClipToAtlasFeature =
enabled;
3220 return mFeatureClippingType;
3225 if ( mFeatureClippingType == type )
3228 mFeatureClippingType = type;
3234 return mForceLabelsInsideFeature;
3239 if ( forceInside == mForceLabelsInsideFeature )
3242 mForceLabelsInsideFeature = forceInside;
3248 return mClipItemShape;
3262 return mRestrictToLayers;
3267 if ( mRestrictToLayers ==
enabled )
3276 return _qgis_listRefToRaw( mLayersToClip );
3287 QDomElement settingsElem = document.createElement( u
"atlasClippingSettings"_s );
3288 settingsElem.setAttribute( u
"enabled"_s, mClipToAtlasFeature ? u
"1"_s : u
"0"_s );
3289 settingsElem.setAttribute( u
"forceLabelsInside"_s, mForceLabelsInsideFeature ? u
"1"_s : u
"0"_s );
3290 if ( mClipItemShape )
3292 settingsElem.setAttribute( u
"clipItemShape"_s, u
"1"_s );
3294 settingsElem.setAttribute( u
"clippingType"_s, QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3295 settingsElem.setAttribute( u
"restrictLayers"_s, mRestrictToLayers ? u
"1"_s : u
"0"_s );
3298 QDomElement layerSetElem = document.createElement( u
"layersToClip"_s );
3303 QDomElement layerElem = document.createElement( u
"Layer"_s );
3304 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3305 layerElem.appendChild( layerIdText );
3307 layerElem.setAttribute( u
"name"_s, layerRef.name );
3308 layerElem.setAttribute( u
"source"_s, layerRef.source );
3309 layerElem.setAttribute( u
"provider"_s, layerRef.provider );
3311 layerSetElem.appendChild( layerElem );
3313 settingsElem.appendChild( layerSetElem );
3315 element.appendChild( settingsElem );
3321 const QDomElement settingsElem = element.firstChildElement( u
"atlasClippingSettings"_s );
3323 mClipToAtlasFeature = settingsElem.attribute( u
"enabled"_s, u
"0"_s ).toInt();
3324 mForceLabelsInsideFeature = settingsElem.attribute( u
"forceLabelsInside"_s, u
"0"_s ).toInt();
3325 mClipItemShape = settingsElem.attribute( u
"clipItemShape"_s, u
"0"_s ).toInt();
3327 mRestrictToLayers = settingsElem.attribute( u
"restrictLayers"_s, u
"0"_s ).toInt();
3329 mLayersToClip.clear();
3330 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( u
"layersToClip"_s );
3331 if ( !layerSetNodeList.isEmpty() )
3333 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3334 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( u
"Layer"_s );
3335 mLayersToClip.reserve( layerIdNodeList.size() );
3336 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3338 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3339 QString layerId = layerElem.text();
3340 QString layerName = layerElem.attribute( u
"name"_s );
3341 QString layerSource = layerElem.attribute( u
"source"_s );
3342 QString layerProvider = layerElem.attribute( u
"provider"_s );
3344 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3345 if ( mMap->layout() && mMap->layout()->project() )
3347 mLayersToClip << ref;
3354void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3356 if ( !mLayersToClip.isEmpty() )
3358 _qgis_removeLayers( mLayersToClip, layers );
3372 return mEnabled && mClipPathSource;
3387 if ( mClipPathSource )
3390 mClipPathSource->refresh();
3399 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3400 clipGeom.
transform( mMap->layoutToMapCoordsTransform() );
3410 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3411 clipGeom.
transform( mMap->sceneTransform().inverted() );
3426 if ( mClipPathSource == item )
3429 if ( mClipPathSource )
3438 mClipPathSource = item;
3440 if ( mClipPathSource )
3449 mClipPathSource->refresh();
3463 return mClipPathSource;
3468 return mFeatureClippingType;
3473 if ( mFeatureClippingType == type )
3476 mFeatureClippingType = type;
3482 return mForceLabelsInsideClipPath;
3487 if ( forceInside == mForceLabelsInsideClipPath )
3490 mForceLabelsInsideClipPath = forceInside;
3496 QDomElement settingsElem = document.createElement( u
"itemClippingSettings"_s );
3497 settingsElem.setAttribute( u
"enabled"_s, mEnabled ? u
"1"_s : u
"0"_s );
3498 settingsElem.setAttribute( u
"forceLabelsInside"_s, mForceLabelsInsideClipPath ? u
"1"_s : u
"0"_s );
3499 settingsElem.setAttribute( u
"clippingType"_s, QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3500 if ( mClipPathSource )
3501 settingsElem.setAttribute( u
"clipSource"_s, mClipPathSource->uuid() );
3503 settingsElem.setAttribute( u
"clipSource"_s, QString() );
3505 element.appendChild( settingsElem );
3511 const QDomElement settingsElem = element.firstChildElement( u
"itemClippingSettings"_s );
3513 mEnabled = settingsElem.attribute( u
"enabled"_s, u
"0"_s ).toInt();
3514 mForceLabelsInsideClipPath = settingsElem.attribute( u
"forceLabelsInside"_s, u
"0"_s ).toInt();
3516 mClipPathUuid = settingsElem.attribute( u
"clipSource"_s );
3523 if ( !mClipPathUuid.isEmpty() )
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ ForceVector
Always force vector-based rendering, even when the result will be visually different to a raster-base...
QFlags< VectorRenderingSimplificationFlag > VectorRenderingSimplificationFlags
Simplification flags for vector feature rendering.
@ Millimeters
Millimeters.
@ NoSimplification
No simplification can be applied.
@ CollectUnplacedLabels
Whether unplaced labels should be collected in the labeling results (regardless of whether they are b...
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
@ UsePartialCandidates
Whether to use also label candidates that are partially outside of the map view.
@ Export
Renderer used for printing or exporting to a file.
@ View
Renderer used for displaying on screen.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
@ DrawEditingInfo
Enable drawing of vertex markers for layers in editing mode.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
@ ForceRasterMasks
Force symbol masking to be applied using a raster method. This is considerably faster when compared t...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ AlwaysUseGlobalMasks
When applying clipping paths for selective masking, always use global ("entire map") paths,...
@ DrawSelection
Whether vector selections should be shown in the rendered map.
@ Antialiasing
Enable anti-aliasing for map rendering.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ DisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
@ LimitCoverageLayerRenderToCurrentFeature
Limit coverage layer rendering to the current atlas feature.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ AlwaysUseGlobalMasks
When applying clipping paths for selective masking, always use global ("entire map") paths,...
@ DrawSelection
Draw selection.
@ Antialiasing
Use antialiasing when drawing items.
@ RenderLabelsByMapLayer
When rendering map items to multi-layered exports, render labels belonging to different layers into s...
@ HideCoverageLayer
Hide coverage layer in outputs.
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
Abstract base class for annotation items which are drawn over a map.
QgsCoordinateReferenceSystem mapPositionCrs() const
Returns the CRS of the map position, or an invalid CRS if the annotation does not have a fixed map po...
void render(QgsRenderContext &context) const
Renders the annotation to a target render context.
bool isVisible() const
Returns true if the annotation is visible and should be rendered.
QPointF relativePosition() const
Returns the relative position of the annotation, if it is not attached to a fixed map position.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
Qgis::DistanceUnit mapUnits
QgsRange which stores a range of double values.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFilter(const QString &layerId, const QgsExpression &expression)
Set a filter for the given layer.
A geometry is the spatial representation of a feature.
QPolygonF asQPolygonF() const
Returns contents of the geometry as a QPolygonF.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points shared by this geometry and other.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
QgsGeometry buffer(double distance, int segments, QgsFeedback *feedback=nullptr) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
QList< QgsMapLayer * > childLayers() const
Returns the child layers contained by the group.
void setChildLayers(const QList< QgsMapLayer * > &layers)
Sets the child layers contained by the group.
QgsGroupedFeatureFilterProvider & addProvider(const QgsFeatureFilterProvider *provider)
Add another filter provider to the group.
A representation of the interval between two datetime values.
Stores global configuration for labeling engine.
void setFlag(Qgis::LabelingFlag f, bool enabled=true)
Sets whether a particual flag is enabled.
Stores computed placement from labeling engine.
void layerOrderChanged()
Emitted when the layer order has changed.
Contains settings relating to clipping a layout map by the current atlas feature.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the current atlas feature.
bool restrictToLayers() const
Returns true if clipping should be restricted to a subset of layers.
QgsLayoutItemMapAtlasClippingSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapAtlasClippingSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
bool clipItemShape() const
Returns true if the map item shape will be clipped to the atlas feature geometry.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
void setLayersToClip(const QList< QgsMapLayer * > &layers)
Sets the list of map layers to clip to the atlas feature.
QList< QgsMapLayer * > layersToClip() const
Returns the list of map layers to clip to the atlas feature.
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the current atlas feature.
void changed()
Emitted when the atlas clipping settings are changed.
void setClipItemShape(bool clipItemShape)
Sets whether the map item shape will be clipped to the atlas feature geometry.
bool forceLabelsInsideFeature() const
Returns true if labels should only be placed inside the atlas feature geometry.
bool enabled() const
Returns true if the map content should be clipped to the current atlas feature.
void setForceLabelsInsideFeature(bool forceInside)
Sets whether labels should only be placed inside the atlas feature geometry.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the current atlas feature.
Contains settings relating to clipping a layout map by another layout item.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setForceLabelsInsideClipPath(bool forceInside)
Sets whether labels should only be placed inside the clip path geometry.
void setSourceItem(QgsLayoutItem *item)
Sets the source item which will provide the clipping path for the map.
QgsLayoutItemMapItemClipPathSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapItemClipPathSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
QgsGeometry clipPathInMapItemCoordinates() const
Returns the clipping path geometry, in the map item's coordinate space.
QgsGeometry clippedMapExtent() const
Returns the geometry to use for clipping the parent map, in the map item's CRS.
QgsLayoutItem * sourceItem()
Returns the source item which will provide the clipping path for the map, or nullptr if no item is se...
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the associated item.
bool forceLabelsInsideClipPath() const
Returns true if labels should only be placed inside the clip path geometry.
void finalizeRestoreFromXml()
To be called after all pending items have been restored from XML.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the associated item.
bool enabled() const
Returns true if the map content should be clipped to the associated item.
QgsMapClippingRegion toMapClippingRegion() const
Returns the clip path as a map clipping region.
void changed()
Emitted when the item clipping settings are changed.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the associated item.
bool isActive() const
Returns true if the item clipping is enabled and set to a valid source item.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
@ StackAboveMapLabels
Render above all map layers and labels.
StackingPosition stackingPosition() const
Returns the item's stacking position, which specifies where the in the map's stack the item should be...
bool enabled() const
Returns whether the item will be drawn.
Layout graphical items for displaying a map.
void setFollowVisibilityPreset(bool follow)
Sets whether the map should follow a map theme.
bool nextExportPart() override
Moves to the next export part for a multi-layered export item, during a multi-layered export.
void removeRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Removes a previously added rendered feature handler.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset).
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
~QgsLayoutItemMap() override
QIcon icon() const override
Returns the item's icon.
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties) override
void preparedForAtlas()
Emitted when the map has been prepared for atlas rendering, just before actual rendering.
void setFollowVisibilityPresetName(const QString &name)
Sets preset name for map rendering.
QTransform layoutToMapCoordsTransform() const
Creates a transform from layout coordinates to map coordinates.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
bool isLabelBlockingItem(QgsLayoutItem *item) const
Returns true if the specified item is a "label blocking item".
void storeCurrentLayerStyles()
Stores the current project layer styles into style overrides.
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
QgsLayoutMeasurement labelMargin() const
Returns the margin from the map edges in which no labels may be placed.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas).
@ Predefined
A scale is chosen from the predefined scales.
@ Auto
The extent is adjusted so that each feature is fully visible.
@ Fixed
The current scale of the map is used for each feature of the atlas.
bool requiresRasterization() const override
Returns true if the item is drawn in such a way that forces the whole layout to be rasterized when ex...
Q_DECL_DEPRECATED int numberExportLayers() const override
void layerStyleOverridesChanged()
Emitted when layer style overrides are changed... a means to let associated legend items know they sh...
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void moveContent(double dx, double dy) override
Moves the content of the item, by a specified dx and dy in layout units.
void setZRangeEnabled(bool enabled)
Sets whether the z range is enabled (i.e.
QgsLayoutItemMapGrid * grid()
Returns the map item's first grid.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
int type() const override
QList< QgsMapLayer * > layersToRender(const QgsExpressionContext *context=nullptr, bool includeInvalidLayers=false) const
Returns a list of the layers which will be rendered within this map item, considering any locked laye...
void previewRefreshed()
Emitted whenever the item's map preview has been refreshed.
friend class QgsLayoutItemMapOverview
void setExtent(const QgsRectangle &extent)
Sets a new extent for the map.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
QFlags< MapItemFlag > MapItemFlags
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
QPolygonF visibleExtentPolygon() const
Returns a polygon representing the current visible map extent, considering map extents and rotation.
QgsRectangle requestedExtent() const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
QgsLayoutItemMap(QgsLayout *layout)
Constructor for QgsLayoutItemMap, with the specified parent layout.
void setMapFlags(QgsLayoutItemMap::MapItemFlags flags)
Sets the map item's flags, which control how the map content is drawn.
void zoomContent(double factor, QPointF point) override
Zooms content of item.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the stored layers set.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
static QgsLayoutItemMap * create(QgsLayout *layout)
Returns a new map item for the specified layout.
QRectF boundingRect() const override
QString displayName() const override
Gets item display name.
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
void setZRange(const QgsDoubleRange &range)
Sets the map's z range, which is used to filter the map's content to only display features within the...
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for layers.
void stopLayeredExport() override
Stops a multi-layer export operation.
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map.
double estimatedFrameBleed() const override
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainterPath framePath() const override
Returns the path to use when drawing the item's frame or background.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void startLayeredExport() override
Starts a multi-layer export operation.
bool containsWmsLayer() const
Returns true if the map contains a WMS layer.
void setScale(double scale, bool forceUpdate=true)
Sets new map scale and changes only the map extent.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
double mapUnitsToLayoutUnits() const
Returns the conversion factor from map units to layout units.
QgsLayoutItemMap::MapItemFlags mapFlags() const
Returns the map item's flags, which control how the map content is drawn.
bool zRangeEnabled() const
Returns whether the z range is enabled (i.e.
void setLabelMargin(const QgsLayoutMeasurement &margin)
Sets the margin from the map edges in which no labels may be placed.
void themeChanged(const QString &theme)
Emitted when the map's associated theme is changed.
QgsLayoutItem::ExportLayerDetail exportLayerDetails() const override
Returns the details for the specified current export layer.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
double scale() const
Returns the map scale.
@ ShowPartialLabels
Whether to draw labels which are partially outside of the map view.
@ ShowUnplacedLabels
Whether to render unplaced labels in the map view.
bool drawAnnotations() const
Returns whether annotations are drawn within the map.
QgsDoubleRange zRange() const
Returns the map's z range, which is used to filter the map's content to only display features within ...
void removeLabelBlockingItem(QgsLayoutItem *item)
Removes the specified layout item from the map's "label blocking items".
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the map's preset crs (coordinate reference system).
void invalidateCache() override
QgsRectangle extent() const
Returns the current map extent.
QgsLayoutItemMapOverview * overview()
Returns the map item's first overview.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setFrameStrokeWidth(QgsLayoutMeasurement width) override
Sets the frame stroke width.
bool containsAdvancedEffects() const override
Returns true if the item contains contents with blend modes or transparency effects which can only be...
friend class QgsLayoutItemMapGrid
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
void setMoveContentPreviewOffset(double dx, double dy) override
Sets temporary offset for the item, by a specified dx and dy in layout units.
void setMapRotation(double rotation)
Sets the rotation for the map - this does not affect the layout item shape, only the way the map is d...
static const QgsSettingsEntryBool * settingForceRasterMasks
Settings entry - Whether to force rasterized clipping masks, regardless of output format.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
double atlasMargin(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue)
Returns the margin size (percentage) used when the map is in atlas mode.
void addLabelBlockingItem(QgsLayoutItem *item)
Sets the specified layout item as a "label blocking item" for this map.
void assignFreeId()
Sets the map id() to a number not yet used in the layout.
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
QgsLabelingResults * previewLabelingResults() const
Returns the labeling results of the most recent preview map render.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Base class for graphical items within a QgsLayout.
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
virtual QPainterPath framePath() const
Returns the path to use when drawing the item's frame or background.
QColor backgroundColor(bool useDataDefined=true) const
Returns the background color for this item.
void drawRefreshingOverlay(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle)
Draws a "refreshing" overlay icon on the item.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
QgsLayoutItem(QgsLayout *layout, bool manageZValue=true)
Constructor for QgsLayoutItem, with the specified parent layout.
void rotationChanged(double newRotation)
Emitted on item rotation change.
friend class QgsLayoutItemMap
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void drawBackground(QgsRenderContext &context)
Draws the background for the item.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
@ FlagOverridesPaint
Item overrides the default layout item painting method.
@ FlagDisableSceneCaching
Item should not have QGraphicsItem caching enabled.
virtual bool containsAdvancedEffects() const
Returns true if the item contains contents with blend modes or transparency effects which can only be...
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
QString id() const
Returns the item's ID name.
bool frameEnabled() const
Returns true if the item includes a frame.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ ItemContainsSubLayers
Item contains multiple sublayers which must be individually exported.
void clipPathChanged()
Emitted when the item's clipping path has changed.
bool hasBackground() const
Returns true if the item has a background.
void refresh() override
Refreshes the item, causing a recalculation of any property overrides and recalculation of its positi...
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
void backgroundTaskCountChanged(int count)
Emitted whenever the number of background tasks an item is executing changes.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
static QgsLayoutMeasurement decodeMeasurement(const QString &string)
Decodes a measurement from a string.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
DataDefinedProperty
Data defined properties for different item types.
@ MapYMin
Map extent y minimum.
@ MapZRangeUpper
Map frame Z-range lower value.
@ StartDateTime
Temporal range's start DateTime.
@ MapLayers
Map layer set.
@ MapZRangeLower
Map frame Z-range lower value.
@ MapRotation
Map rotation.
@ MapXMax
Map extent x maximum.
@ MapStylePreset
Layer and style map theme.
@ MapYMax
Map extent y maximum.
@ MapAtlasMargin
Map atlas margin.
@ EndDateTime
Temporal range's end DateTime.
@ MapXMin
Map extent x minimum.
@ MapLabelMargin
Map label margin.
@ AllProperties
All properties for item.
PropertyValueType
Specifies whether the value returned by a function should be the original, user set value,...
@ EvaluatedValue
Return the current evaluated value for the property.
void predefinedScalesChanged()
Emitted when the list of predefined scales changes.
static QgsRenderContext createRenderContextForMap(QgsLayoutItemMap *map, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout map and painter destination.
static void rotate(double angle, double &x, double &y)
Rotates a point / vector around the origin.
static Q_DECL_DEPRECATED double scaleFactorFromItemStyle(const QStyleOptionGraphicsItem *style)
Extracts the scale factor from an item style.
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
void refreshed()
Emitted when the layout has been refreshed and items should also be refreshed and updated.
A map clipping region (in map coordinates and CRS).
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
FeatureClippingType
Feature clipping behavior, which controls how features from vector layers will be clipped.
void setFeatureClip(FeatureClippingType type)
Sets the feature clipping type.
void setRestrictedLayers(const QList< QgsMapLayer * > &layers)
Sets a list of layers to restrict the clipping region effects to.
Stores style information (renderer, opacity, labeling, diagrams etc.) applicable to a map layer.
void readXml(const QDomElement &styleElement)
Read style configuration (for project file reading).
void readFromLayer(QgsMapLayer *layer)
Store layer's active style information in the instance.
void writeXml(QDomElement &styleElement) const
Write style configuration (for project file writing).
QString xmlData() const
Returns XML content of the style.
Base class for all map layer types.
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
void finished()
emitted when asynchronous rendering is finished (or canceled).
@ RenderLabelsByMapLayer
Labels should be rendered in individual stages by map layer. This allows separation of labels belongi...
@ Finished
Rendering is finished.
@ Symbology
Rendering layer symbology.
@ Labels
Rendering labels.
static QStringList containsAdvancedEffects(const QgsMapSettings &mapSettings, EffectsCheckFlags flags=QgsMapSettingsUtils::EffectsCheckFlags())
Checks whether any of the layers attached to a map settings object contain advanced effects.
Contains configuration for rendering maps.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &renderer)
Sets the shading renderer used to render shading on the entire map.
void addClippingRegion(const QgsMapClippingRegion ®ion)
Adds a new clipping region to the map settings.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setSimplifyMethod(const QgsVectorSimplifyMethod &method)
Sets the simplification setting to use when rendering vector layers.
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated).
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map settings.
void setTextRenderFormat(Qgis::TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
void setDevicePixelRatio(float dpr)
Sets the device pixel ratio.
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which will be visible in the map.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
void setRendererUsage(Qgis::RendererUsage rendererUsage)
Sets the rendering usage.
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setMaskSettings(const QgsMaskRenderSettings &settings)
Sets the mask render settings, which control how masks are drawn and behave during the map render.
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
void setLabelBoundaryGeometry(const QgsGeometry &boundary)
Sets the label boundary geometry, which restricts where in the rendered map labels are permitted to b...
void setLabelBlockingRegions(const QList< QgsLabelBlockingRegion > ®ions)
Sets a list of regions to avoid placing labels within.
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
void mapThemeRenamed(const QString &name, const QString &newName)
Emitted when a map theme within the collection is renamed.
void mapThemeChanged(const QString &theme)
Emitted when a map theme changes definition.
QString description() const
Description.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
void crsChanged()
Emitted when the crs() of the project has changed.
QgsMapThemeCollection * mapThemeCollection
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
Qgis::ScaleCalculationMethod scaleMethod
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
Qgis::RasterizedRenderingPolicy rasterizedRenderingPolicy() const
Returns the policy controlling when rasterisation of content during renders is permitted.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
An interface for classes which provide custom handlers for features rendered as part of a map render ...
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the output resolution, to be used in scale calculations.
void setMapUnits(Qgis::DistanceUnit mapUnits)
Set the map units.
void setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for map scale calculations.
Scoped object for saving and restoring a QPainter object's state.
A boolean settings entry.
static QgsSettingsTreeNode * sTreeLayout
An interface for classes which can visit style entity (e.g.
@ LayoutItem
Individual item in a print layout.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static double scaleToZoom(double mapScale, double z0Scale=559082264.0287178)
Finds zoom level given map scale denominator.
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale=559082264.0287178)
Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
_LayerRef< QgsMapLayer > QgsMapLayerRef
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
Single variable definition for use within a QgsExpressionContextScope.
Contains details of a particular export layer relating to a layout item.
QPainter::CompositionMode compositionMode
Associated composition mode if this layer is associated with a map layer.
QString mapLayerId
Associated map layer ID, or an empty string if this export layer is not associated with a map layer.
double opacity
Associated opacity, if this layer is associated with a map layer.
QString name
User-friendly name for the export layer.
QString mapTheme
Associated map theme, or an empty string if this export layer does not need to be associated with a m...
Contains information relating to a node (i.e.
TYPE * resolveWeakly(const QgsProject *project, MatchType matchType=MatchType::All)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
QString source
Weak reference to layer public source.
QString name
Weak reference to layer name.
QString provider
Weak reference to layer provider.
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
QString layerId
Original layer ID.