44#include <QStyleOptionGraphicsItem>
52 mBackgroundUpdateTimer =
new QTimer(
this );
53 mBackgroundUpdateTimer->setSingleShot(
true );
54 connect( mBackgroundUpdateTimer, &QTimer::timeout,
this, &QgsLayoutItemMap::recreateCachedImageInBackground );
58 setCacheMode( QGraphicsItem::NoCache );
65 mGridStack = std::make_unique< QgsLayoutItemMapGridStack >(
this );
66 mOverviewStack = std::make_unique< QgsLayoutItemMapOverviewStack >(
this );
99 mPainterJob->cancel();
124 QList<QgsLayoutItemMap *> mapsList;
125 mLayout->layoutItems( mapsList );
134 if ( map->mMapId == mMapId )
137 maxId = std::max( maxId, map->mMapId );
142 mLayout->itemsModel()->updateItemDisplayName(
this );
154 return tr(
"Map %1" ).arg( mMapId );
166 mCachedLayerStyleOverridesPresetName.clear();
170 updateAtlasFeature();
175 if ( rect().isEmpty() )
180 calculator.
setDpi( 25.4 );
181 double widthInMm =
mLayout->convertFromLayoutUnits( rect().width(), Qgis::LayoutUnit::Millimeters ).length();
187 double currentScaleDenominator =
scale();
194 double scaleRatio = scaleDenominator / currentScaleDenominator;
195 mExtent.
scale( scaleRatio );
197 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
204 calculator.
setDpi( 25.4 );
205 scaleRatio = scaleDenominator / calculator.
calculate( mExtent, rect().width() );
206 mExtent.
scale( scaleRatio );
230 QRectF currentRect = rect();
232 double newHeight = currentRect.width() * mExtent.
height() / mExtent.
width();
244 double currentWidthHeightRatio = 1.0;
245 if ( !currentExtent.
isNull() )
246 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
248 currentWidthHeightRatio = rect().width() / rect().height();
249 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
251 if ( currentWidthHeightRatio < newWidthHeightRatio )
254 double newHeight = newExtent.
width() / currentWidthHeightRatio;
255 double deltaHeight = newHeight - newExtent.
height();
262 double newWidth = currentWidthHeightRatio * newExtent.
height();
263 double deltaWidth = newWidth - newExtent.
width();
268 if ( mExtent == newExtent )
287QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
290 mapPolygon( mExtent, poly );
292 if ( includeClipping && mItemClippingSettings->
isActive() )
306 return calculateVisibleExtentPolygon(
true );
314 return mLayout->project()->crs();
329 return _qgis_listRefToRaw( mLayers );
335 mGroupLayers.clear();
337 QList<QgsMapLayer *> layersCopy {
layers };
342 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
344 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
346 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
347 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
348 *it = mGroupLayers[ groupLayer->id() ].get();
351 mLayers = _qgis_listRawToRef( layersCopy );
356 if ( overrides == mLayerStyleOverrides )
359 mLayerStyleOverrides = overrides;
366 mLayerStyleOverrides.clear();
373 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
380 if ( mFollowVisibilityPreset == follow )
383 mFollowVisibilityPreset = follow;
385 if ( !mFollowVisibilityPresetName.isEmpty() )
386 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
391 if ( name == mFollowVisibilityPresetName )
394 mFollowVisibilityPresetName = name;
395 if ( mFollowVisibilityPreset )
401 mLastRenderedImageOffsetX -= dx;
402 mLastRenderedImageOffsetY -= dy;
405 transformShift( dx, dy );
429 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
435 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
436 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
438 double newIntervalX, newIntervalY;
455 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
462 calculator.
setDpi( 25.4 );
463 double scaleRatio =
scale() / calculator.
calculate( mExtent, rect().width() );
464 mExtent.
scale( scaleRatio );
480 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
514 if ( mOverviewStack->containsAdvancedEffects() )
520 if ( mGridStack->containsAdvancedEffects() )
532 mMapRotation = rotation;
533 mEvaluatedMapRotation = mMapRotation;
547 mAtlasDriven = enabled;
564 double margin = mAtlasMargin;
572 margin = ddMargin / 100;
584 if ( mGridStack->size() < 1 )
587 mGridStack->addGrid(
grid );
589 return mGridStack->grid( 0 );
594 if ( mOverviewStack->size() < 1 )
597 mOverviewStack->addOverview(
overview );
599 return mOverviewStack->overview( 0 );
610 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
614 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
617 if ( mDrawAnnotations )
619 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
623 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
627 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
632 mapElem.appendChild( extentElem );
636 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
638 mapElem.appendChild( crsElem );
642 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
643 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
646 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
649 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
654 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
656 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
658 return groupLayer.second.get() == layerRef.get();
661 if ( it != mGroupLayers.end() )
667 layerId = layerRef.layerId;
670 QDomText layerIdText = doc.createTextNode( layerId );
671 layerElem.appendChild( layerIdText );
673 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
674 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
675 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
677 if ( it != mGroupLayers.end() )
679 const auto childLayers { it->second->childLayers() };
680 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
681 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
683 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
684 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
685 childLayersElement.appendChild( childElement );
687 layerElem.appendChild( childLayersElement );
689 layerSetElem.appendChild( layerElem );
691 mapElem.appendChild( layerSetElem );
694 if ( mKeepLayerStyles )
696 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
697 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
699 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
704 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
705 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
706 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
707 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
711 stylesElem.appendChild( styleElem );
713 mapElem.appendChild( stylesElem );
717 mGridStack->writeXml( mapElem, doc, context );
720 mOverviewStack->writeXml( mapElem, doc, context );
723 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
724 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
725 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
726 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
727 mapElem.appendChild( atlasElem );
729 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
730 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
732 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
733 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
738 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
739 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
740 labelBlockingItemsElem.appendChild( blockingItemElem );
742 mapElem.appendChild( labelBlockingItemsElem );
745 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
748 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().begin().toString( Qt::ISODate ) );
749 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().end().toString( Qt::ISODate ) );
752 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
753 mItemClippingSettings->
writeXml( mapElem, doc, context );
760 mUpdatesEnabled =
false;
763 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
764 if ( !extentNodeList.isEmpty() )
766 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
767 double xmin, xmax, ymin, ymax;
768 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
769 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
770 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
771 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
775 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
777 if ( !crsNodeList.isEmpty() )
779 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
785 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
786 mEvaluatedMapRotation = mMapRotation;
789 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
790 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
793 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
794 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
796 mKeepLayerSet =
true;
800 mKeepLayerSet =
false;
803 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
804 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
806 mDrawAnnotations =
true;
810 mDrawAnnotations =
false;
813 mLayerStyleOverrides.clear();
815 QList<QgsMapLayerRef> layerSet;
816 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
817 if ( !layerSetNodeList.isEmpty() )
819 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
820 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
821 layerSet.reserve( layerIdNodeList.size() );
822 for (
int i = 0; i < layerIdNodeList.size(); ++i )
824 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
825 QString layerId = layerElem.text();
826 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
827 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
828 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
830 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
838 setLayers( _qgis_listRefToRaw( layerSet ) );
841 if ( !layerSetNodeList.isEmpty() )
843 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
844 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
845 for (
int i = 0; i < layerIdNodeList.size(); ++i )
847 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
848 const QString layerId = layerElem.text();
849 const auto it = mGroupLayers.find( layerId );
850 if ( it != mGroupLayers.cend() )
852 QList<QgsMapLayerRef> childSet;
853 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
854 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
855 for (
int i = 0; i < children.size(); ++i )
857 const QDomElement childElement = children.at( i ).toElement();
858 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
860 if ( layerRef.resolveWeakly(
mLayout->project() ) )
862 childSet.push_back( layerRef );
865 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
872 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
873 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
874 if ( mKeepLayerStyles )
876 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
877 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
878 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
880 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
881 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
882 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
883 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
884 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
885 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
889 style.
readXml( layerStyleElement );
895 mNumCachedLayers = 0;
896 mCacheInvalidated =
true;
899 mOverviewStack->readXml( itemElem, doc, context );
902 mGridStack->readXml( itemElem, doc, context );
905 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
906 if ( !atlasNodeList.isEmpty() )
908 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
909 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
910 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
912 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
914 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
916 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
918 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
923 mMapFlags =
static_cast< MapItemFlags
>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
926 mBlockingLabelItems.clear();
927 mBlockingLabelItemUuids.clear();
928 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
929 if ( !labelBlockingNodeList.isEmpty() )
931 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
932 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
933 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
935 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
936 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
937 mBlockingLabelItemUuids << itemUuid;
941 mAtlasClippingSettings->
readXml( itemElem, doc, context );
942 mItemClippingSettings->
readXml( itemElem, doc, context );
947 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
950 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
951 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
955 mUpdatesEnabled =
true;
961 if ( mItemClippingSettings->
isActive() )
972 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
981 QRectF thisPaintRect = rect();
987 if (
mLayout->renderContext().isPreviewRender() )
989 bool renderInProgress =
false;
992 painter->setClipRect( thisPaintRect );
993 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
996 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
997 painter->drawRect( thisPaintRect );
998 painter->setBrush( Qt::NoBrush );
1000 messageFont.setPointSize( 12 );
1001 painter->setFont( messageFont );
1002 painter->setPen( QColor( 255, 255, 255, 255 ) );
1003 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1004 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1008 mBackgroundUpdateTimer->start( 1 );
1010 else if ( !mPainterJob && !mDrawingPreview )
1014 mBackgroundUpdateTimer->start( 1 );
1016 renderInProgress =
true;
1020 if ( mCacheInvalidated && !mDrawingPreview )
1024 mBackgroundUpdateTimer->start( 1 );
1025 renderInProgress =
true;
1030 double imagePixelWidth = mCacheFinalImage->width();
1031 double scale = rect().width() / imagePixelWidth;
1035 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1037 painter->drawImage( 0, 0, *mCacheFinalImage );
1042 painter->setClipRect( thisPaintRect, Qt::NoClip );
1044 mOverviewStack->drawItems( painter,
false );
1045 mGridStack->drawItems( painter );
1047 drawMapFrame( painter );
1049 if ( renderInProgress )
1060 QPaintDevice *paintDevice = painter->device();
1068 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1074 double layoutUnitsInInches =
mLayout ?
mLayout->convertFromLayoutUnits( 1, Qgis::LayoutUnit::Inches ).length() : 1;
1075 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1076 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1077 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1079 image.fill( Qt::transparent );
1080 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1081 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1082 double dotsPerMM = destinationDpi / 25.4;
1083 QPainter p( &image );
1086 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1087 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1088 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1089 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1090 p.setClipRect( imagePaintRect );
1092 p.translate( imagePaintRect.topLeft() );
1096 if ( shouldDrawPart( Background ) )
1098 p.scale( dotsPerMM, dotsPerMM );
1099 drawMapBackground( &p );
1100 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1103 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1108 p.scale( dotsPerMM, dotsPerMM );
1110 if ( shouldDrawPart( OverviewMapExtent ) )
1112 mOverviewStack->drawItems( &p,
false );
1114 if ( shouldDrawPart( Grid ) )
1116 mGridStack->drawItems( &p );
1121 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1122 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1123 painter->scale( dotsPerMM, dotsPerMM );
1128 if ( shouldDrawPart( Background ) )
1130 drawMapBackground( painter );
1134 painter->setClipRect( thisPaintRect );
1139 painter->translate( mXOffset, mYOffset );
1141 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1143 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1145 if ( mCurrentExportPart != NotLayered )
1147 if ( !mStagedRendererJob )
1149 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1152 mStagedRendererJob->renderCurrentPart( painter );
1156 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1160 painter->setClipRect( thisPaintRect, Qt::NoClip );
1162 if ( shouldDrawPart( OverviewMapExtent ) )
1164 mOverviewStack->drawItems( painter,
false );
1166 if ( shouldDrawPart( Grid ) )
1168 mGridStack->drawItems( painter );
1173 if ( shouldDrawPart( Frame ) )
1175 drawMapFrame( painter );
1186 + ( layerCount + ( layerCount ? 1 : 0 ) )
1187 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1188 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1194 mCurrentExportPart = Start;
1196 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1197 mExportThemeIt = mExportThemes.begin();
1202 mCurrentExportPart = NotLayered;
1203 mExportThemes.clear();
1204 mExportThemeIt = mExportThemes.begin();
1209 switch ( mCurrentExportPart )
1214 mCurrentExportPart = Background;
1220 mCurrentExportPart = Layer;
1224 if ( mStagedRendererJob )
1226 if ( mStagedRendererJob->nextPart() )
1230 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1231 mStagedRendererJob.reset();
1235 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1241 if ( mGridStack->hasEnabledItems() )
1243 mCurrentExportPart = Grid;
1249 for (
int i = 0; i < mOverviewStack->size(); ++i )
1254 mCurrentExportPart = OverviewMapExtent;
1260 case OverviewMapExtent:
1263 mCurrentExportPart = Frame;
1270 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1272 mCurrentExportPart = SelectionBoxes;
1277 case SelectionBoxes:
1278 mCurrentExportPart = End;
1299 switch ( mCurrentExportPart )
1309 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1312 if ( mStagedRendererJob )
1314 switch ( mStagedRendererJob->currentStage() )
1318 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1319 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1320 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1326 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1328 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1334 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1339 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1345 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1348 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1350 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1359 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1365 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1400 case OverviewMapExtent:
1408 case SelectionBoxes:
1423void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1437 if ( shouldDrawPart( OverviewMapExtent ) )
1439 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1443#ifdef HAVE_SERVER_PYTHON_PLUGINS
1444 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1450 job.renderSynchronously();
1452 mExportLabelingResults.reset( job.takeLabelingResults() );
1454 mRenderingErrors = job.errors();
1457void QgsLayoutItemMap::recreateCachedImageInBackground()
1463 QPainter *oldPainter = mPainter.release();
1464 QImage *oldImage = mCacheRenderingImage.release();
1467 oldJob->deleteLater();
1475 mCacheRenderingImage.reset(
nullptr );
1479 Q_ASSERT( !mPainterJob );
1480 Q_ASSERT( !mPainter );
1481 Q_ASSERT( !mCacheRenderingImage );
1487 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1488 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1491 if ( w > 5000 || h > 5000 )
1496 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1501 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1505 if ( w <= 0 || h <= 0 )
1508 mCacheRenderingImage.reset(
new QImage( w, h, QImage::Format_ARGB32 ) );
1511 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1512 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1515 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1520 if ( mItemClippingSettings->
isActive() )
1522 QPainter p( mCacheRenderingImage.get() );
1524 p.setPen( Qt::NoPen );
1526 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1536 mCacheInvalidated =
false;
1537 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1540 if ( shouldDrawPart( OverviewMapExtent ) )
1542 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1547 mPainterJob->start();
1559 mDrawingPreview =
false;
1582 if (
layout()->renderContext().isPreviewRender() )
1585 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1592 if ( includeLayerSettings )
1597 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1600 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1607 if ( !
mLayout->renderContext().isPreviewRender() )
1650 if ( mEvaluatedLabelMargin.
length() > 0 )
1653 visiblePoly.append( visiblePoly.at( 0 ) );
1654 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1655 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1657 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1658 labelBoundary = mapBoundaryGeom;
1661 if ( !mBlockingLabelItems.isEmpty() )
1674 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1685 if ( !labelBoundary.
isEmpty() )
1687 labelBoundary = clipGeom.
intersection( labelBoundary );
1691 labelBoundary = clipGeom;
1696 if ( mItemClippingSettings->
isActive() )
1705 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1706 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1708 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1709 if ( !labelBoundary.
isEmpty() )
1711 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1715 labelBoundary = mapBoundaryGeom;
1721 if ( !labelBoundary.
isNull() )
1724 return jobMapSettings;
1731 mBlockingLabelItems.clear();
1732 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1741 mOverviewStack->finalizeRestoreFromXml();
1742 mGridStack->finalizeRestoreFromXml();
1754 return mCurrentRectangle;
1768 const double mapScale =
scale();
1792 QVariantList layersIds;
1802 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1804 layersIds.reserve( layersInMap.count() );
1805 layers.reserve( layersInMap.count() );
1808 layersIds << layer->id();
1814 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1833 if ( extentWidth <= 0 )
1837 return rect().width() / extentWidth;
1842 double dx = mXOffset;
1843 double dy = mYOffset;
1844 transformShift( dx, dy );
1845 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1846 poly.translate( -dx, -dy );
1852 if ( !mBlockingLabelItems.contains( item ) )
1853 mBlockingLabelItems.append( item );
1860 mBlockingLabelItems.removeAll( item );
1867 return mBlockingLabelItems.contains( item );
1872 return mPreviewLabelingResults.get();
1881 if ( mOverviewStack )
1883 for (
int i = 0; i < mOverviewStack->size(); ++i )
1885 if ( mOverviewStack->item( i )->accept( visitor ) )
1892 for (
int i = 0; i < mGridStack->size(); ++i )
1894 if ( mGridStack->item( i )->accept( visitor ) )
1907 mRenderedFeatureHandlers.append( handler );
1912 mRenderedFeatureHandlers.removeAll( handler );
1918 if ( mapPoly.empty() )
1920 return QPointF( 0, 0 );
1925 double dx = mapCoords.x() - rotationPoint.
x();
1926 double dy = mapCoords.y() - rotationPoint.
y();
1928 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
1931 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
1932 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
1933 return QPointF( xItem, yItem );
1947 mapPolygon( newExtent, poly );
1948 QRectF bRect = poly.boundingRect();
1962 mCacheInvalidated =
true;
1968 QRectF rectangle = rect();
1969 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
1971 double topExtension = 0.0;
1972 double rightExtension = 0.0;
1973 double bottomExtension = 0.0;
1974 double leftExtension = 0.0;
1977 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
1979 topExtension = std::max( topExtension, frameExtension );
1980 rightExtension = std::max( rightExtension, frameExtension );
1981 bottomExtension = std::max( bottomExtension, frameExtension );
1982 leftExtension = std::max( leftExtension, frameExtension );
1984 rectangle.setLeft( rectangle.left() - leftExtension );
1985 rectangle.setRight( rectangle.right() + rightExtension );
1986 rectangle.setTop( rectangle.top() - topExtension );
1987 rectangle.setBottom( rectangle.bottom() + bottomExtension );
1988 if ( rectangle != mCurrentRectangle )
1990 prepareGeometryChange();
1991 mCurrentRectangle = rectangle;
2019 refreshMapExtents( &context );
2021 if ( mExtent != beforeExtent )
2028 refreshLabelMargin(
false );
2032 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2034 if ( mLastEvaluatedThemeName != previousTheme )
2052 mCacheInvalidated =
true;
2057void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2060 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2064 mLayerStyleOverrides.remove( layer->id() );
2066 _qgis_removeLayers( mLayers,
layers );
2072 if ( mGroupLayers.erase( layer->id() ) == 0 )
2075 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2078 if ( groupLayer->
childLayers().contains( layer ) )
2080 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2081 childLayers.removeAll( layer );
2089void QgsLayoutItemMap::painterJobFinished()
2092 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2093 mPainterJob.reset(
nullptr );
2094 mPainter.reset(
nullptr );
2095 mCacheFinalImage = std::move( mCacheRenderingImage );
2096 mLastRenderedImageOffsetX = 0;
2097 mLastRenderedImageOffsetY = 0;
2103void QgsLayoutItemMap::shapeChanged()
2108 double w = rect().width();
2109 double h = rect().height();
2112 double newWidth = mExtent.
width();
2114 double newHeight = newWidth * h / w;
2119 refreshMapExtents();
2126void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2128 if ( theme == mCachedLayerStyleOverridesPresetName )
2129 mCachedLayerStyleOverridesPresetName.clear();
2132void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2134 if ( theme == mFollowVisibilityPresetName )
2136 mFollowVisibilityPresetName = newTheme;
2140void QgsLayoutItemMap::connectUpdateSlot()
2148 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2152 if ( layers().isEmpty() )
2181 if ( mAtlasScalingMode == Predefined )
2182 updateAtlasFeature();
2188 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2189 QTransform mapTransform;
2190 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2192 thisRectPoly.pop_back();
2193 thisExtent.pop_back();
2195 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2198 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2199 return mapTransform;
2202QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2205 QList< QgsLabelBlockingRegion > blockers;
2206 blockers.reserve( mBlockingLabelItems.count() );
2207 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2214 if ( item->property(
"wasVisible" ).isValid() )
2216 if ( !item->property(
"wasVisible" ).toBool() )
2219 else if ( !item->isVisible() )
2222 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2223 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2232 return mLabelMargin;
2237 mLabelMargin = margin;
2238 refreshLabelMargin(
false );
2241void QgsLayoutItemMap::updateToolTip()
2250 if ( mFollowVisibilityPreset )
2252 presetName = mFollowVisibilityPresetName;
2256 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2257 presetName = *mExportThemeIt;
2268 QList<QgsMapLayer *> renderLayers;
2270 QString presetName = themeToRender( *evalContext );
2271 if ( !presetName.isEmpty() )
2273 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2274 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2276 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2278 else if ( !
layers().isEmpty() )
2284 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2291 renderLayers.clear();
2293 const QStringList layerNames = ddLayers.split(
'|' );
2295 for (
const QString &name : layerNames )
2297 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2300 renderLayers << layer;
2309 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2310 if ( removeAt != -1 )
2312 renderLayers.removeAt( removeAt );
2317 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2319 return !layer || !layer->isValid();
2320 } ), renderLayers.end() );
2322 return renderLayers;
2325QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2327 QString presetName = themeToRender( context );
2328 if ( !presetName.isEmpty() )
2330 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2332 if ( presetName != mCachedLayerStyleOverridesPresetName )
2335 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2336 mCachedLayerStyleOverridesPresetName = presetName;
2339 return mCachedPresetLayerStyleOverrides;
2342 return QMap<QString, QString>();
2344 else if ( mFollowVisibilityPreset )
2346 QString presetName = mFollowVisibilityPresetName;
2349 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2351 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2354 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2355 mCachedLayerStyleOverridesPresetName = presetName;
2358 return mCachedPresetLayerStyleOverrides;
2361 return QMap<QString, QString>();
2363 else if ( mKeepLayerStyles )
2365 return mLayerStyleOverrides;
2369 return QMap<QString, QString>();
2373QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2375 double dx = mXOffset;
2376 double dy = mYOffset;
2377 transformShift( dx, dy );
2381void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2391 poly << QPointF( poly.at( 0 ) );
2403 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2409 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2415 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2421 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2424 poly << QPointF( poly.at( 0 ) );
2427void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2430 double dxScaled = xShift * mmToMapUnits;
2431 double dyScaled = - yShift * mmToMapUnits;
2446 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2447 if ( annotations.isEmpty() )
2457 if ( !annotation || !annotation->isVisible() )
2461 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2464 drawAnnotation( annotation, rc );
2478 double itemX, itemY;
2481 QPointF mapPos = layoutMapPosForItem( annotation );
2490 context.
painter()->translate( itemX, itemY );
2493 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2494 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2496 annotation->
render( context );
2499QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2502 return QPointF( 0, 0 );
2511 if ( annotationCrs !=
crs() )
2518 t.transformInPlace( mapX, mapY, z );
2528void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2539void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2550bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2552 if ( mCurrentExportPart == NotLayered )
2570 return mCurrentExportPart == Layer;
2573 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2575 case OverviewMapExtent:
2576 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2581 case SelectionBoxes:
2582 return mCurrentExportPart == SelectionBoxes && isSelected();
2603 bool useDdXMin =
false;
2604 bool useDdXMax =
false;
2605 bool useDdYMin =
false;
2606 bool useDdYMax =
false;
2637 if ( newExtent != mExtent )
2643 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2644 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2646 if ( currentWidthHeightRatio < newWidthHeightRatio )
2649 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2650 double deltaHeight = newHeight - newExtent.
height();
2657 double newWidth = currentWidthHeightRatio * newExtent.
height();
2658 double deltaWidth = newWidth - newExtent.
width();
2663 mExtent = newExtent;
2673 newExtent = mExtent;
2676 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2680 if ( useDdXMin && !useDdXMax )
2686 else if ( !useDdXMin && useDdXMax )
2692 if ( useDdYMin && !useDdYMax )
2698 else if ( !useDdYMin && useDdYMax )
2705 if ( newExtent != mExtent )
2707 mExtent = newExtent;
2724void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2737void QgsLayoutItemMap::updateAtlasFeature()
2756 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2761 double originalScale = calc.
calculate( originalExtent, rect().width() );
2762 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2763 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2764 QVector<qreal> scales;
2766 if ( !
mLayout->reportContext().predefinedScales().empty() )
2767 scales =
mLayout->reportContext().predefinedScales();
2769 scales =
mLayout->renderContext().predefinedScales();
2771 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2774 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2775 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2778 xMin + originalExtent.
width(),
2779 yMin + originalExtent.
height() );
2783 double newScale = calc.
calculate( newExtent, rect().width() );
2784 newExtent.
scale( originalScale / newScale );
2789 double newWidth = originalExtent.
width();
2790 double newHeight = originalExtent.
height();
2791 for (
int i = 0; i < scales.size(); i++ )
2793 double ratio = scales[i] / originalScale;
2794 newWidth = originalExtent.
width() * ratio;
2795 newHeight = originalExtent.
height() * ratio;
2798 double xMin = geomCenterX - newWidth / 2.0;
2799 double yMin = geomCenterY - newHeight / 2.0;
2807 double newScale = calc.
calculate( newExtent, rect().width() );
2808 newExtent.
scale( scales[i] / newScale );
2818 else if ( mAtlasScalingMode ==
Auto )
2822 double geomRatio = bounds.
width() / bounds.
height();
2823 double mapRatio = originalExtent.
width() / originalExtent.
height();
2826 if ( geomRatio < mapRatio )
2829 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
2834 else if ( geomRatio > mapRatio )
2837 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
2843 const double evaluatedAtlasMargin =
atlasMargin();
2844 if ( evaluatedAtlasMargin > 0.0 )
2846 newExtent.
scale( 1 + evaluatedAtlasMargin );
2862 if ( mEvaluatedMapRotation != 0.0 )
2872 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
2873 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
2874 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
2875 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
2878 center.
x() + dx, center.
y() + dy );
2886void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
2889 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
2891 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
2894 : QgsMapRendererStagedRenderJob::Flags() );
2895 mStagedRendererJob->start();
2911 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
2917 return mClipToAtlasFeature;
2922 if (
enabled == mClipToAtlasFeature )
2925 mClipToAtlasFeature =
enabled;
2931 return mFeatureClippingType;
2936 if ( mFeatureClippingType == type )
2939 mFeatureClippingType = type;
2945 return mForceLabelsInsideFeature;
2950 if ( forceInside == mForceLabelsInsideFeature )
2953 mForceLabelsInsideFeature = forceInside;
2959 return mRestrictToLayers;
2964 if ( mRestrictToLayers ==
enabled )
2973 return _qgis_listRefToRaw( mLayersToClip );
2984 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
2985 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2986 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2987 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
2988 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2991 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
2996 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
2997 QDomText layerIdText = document.createTextNode( layerRef.layerId );
2998 layerElem.appendChild( layerIdText );
3000 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3001 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3002 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3004 layerSetElem.appendChild( layerElem );
3006 settingsElem.appendChild( layerSetElem );
3008 element.appendChild( settingsElem );
3014 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3016 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3017 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3019 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3021 mLayersToClip.clear();
3022 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3023 if ( !layerSetNodeList.isEmpty() )
3025 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3026 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3027 mLayersToClip.reserve( layerIdNodeList.size() );
3028 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3030 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3031 QString layerId = layerElem.text();
3032 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3033 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3034 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3036 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3039 mLayersToClip << ref;
3046void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3048 if ( !mLayersToClip.isEmpty() )
3050 _qgis_removeLayers( mLayersToClip, layers );
3065 return mEnabled && mClipPathSource;
3080 if ( mClipPathSource )
3083 mClipPathSource->refresh();
3092 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3103 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3104 clipGeom.
transform( mMap->sceneTransform().inverted() );
3119 if ( mClipPathSource == item )
3122 if ( mClipPathSource )
3131 mClipPathSource = item;
3133 if ( mClipPathSource )
3142 mClipPathSource->refresh();
3156 return mClipPathSource;
3161 return mFeatureClippingType;
3166 if ( mFeatureClippingType == type )
3169 mFeatureClippingType = type;
3175 return mForceLabelsInsideClipPath;
3180 if ( forceInside == mForceLabelsInsideClipPath )
3183 mForceLabelsInsideClipPath = forceInside;
3189 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3190 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3191 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3192 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3193 if ( mClipPathSource )
3194 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3196 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3198 element.appendChild( settingsElem );
3204 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3206 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3207 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3209 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3216 if ( !mClipPathUuid.isEmpty() )
@ 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.
@ DrawEditingInfo
Enable drawing of vertex markers for layers in editing mode.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ ForceVectorOutput
Vector graphics should not be cached and drawn as raster images.
@ 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...
@ DrawSelection
Whether vector selections should be shown in the rendered map.
@ Antialiasing
Enable anti-aliasing for map rendering.
@ UseAdvancedEffects
Enable layer opacity and blending effects.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
QDateTime valueAsDateTime(int key, const QgsExpressionContext &context, const QDateTime &defaultDateTime=QDateTime(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a datetime.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
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.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Q_GADGET Qgis::DistanceUnit mapUnits
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
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.
void updateDefinition()
Updates the definition and parameters of the coordinate reference system to their latest values.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
QString toWkt(WktVariant variant=WKT1_GDAL, 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,...
Custom exception class for Coordinate Reference System related exceptions.
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.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
QPolygonF asQPolygonF() const SIP_HOLDGIL
Returns contents of the geometry as a QPolygonF.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QgsGeometry buffer(double distance, int segments) 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.
A representation of the interval between two datetime values.
Label blocking region (in map coordinates and CRS).
Stores global configuration for labeling engine.
void setFlag(Qgis::LabelingFlag f, bool enabled=true)
Sets whether a particual flag is enabled.
Class that 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 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.
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.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
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.
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
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 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
Returns the number of layers that this item requires for exporting during layered exports (e....
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.
QgsLayoutItemMapGrid * grid()
Returns the map item's first grid.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
int type() const override
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
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 refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties) override
void zoomContent(double factor, QPointF point) override
Zooms content of item.
QList< QgsMapLayer * > layersToRender(const QgsExpressionContext *context=nullptr) const
Returns a list of the layers which will be rendered within this map item, considering any locked laye...
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 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.
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.
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.
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...
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 setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
void rotationChanged(double newRotation)
Emitted on item rotation change.
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.
virtual bool requiresRasterization() const
Returns true if the item is drawn in such a way that forces the whole layout to be rasterized when ex...
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
@ FlagOverridesPaint
Item overrides the default layout item painting method.
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.
void backgroundTaskCountChanged(int count)
Emitted whenever the number of background tasks an item is executing changes.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
void setLength(const double length)
Sets the length of the measurement.
static QgsLayoutMeasurement decodeMeasurement(const QString &string)
Decodes a measurement from a string.
QString encodeMeasurement() const
Encodes the layout measurement to a string.
Qgis::LayoutUnit units() const
Returns the units for the measurement.
void setUnits(const Qgis::LayoutUnit units)
Sets the units for the measurement.
double length() const
Returns the length of the measurement.
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.
@ MapStylePreset
Layer and style map theme.
@ MapXMax
Map extent x maximum.
@ StartDateTime
Temporal range's start DateTime.
@ AllProperties
All properties for item.
@ EndDateTime
Temporal range's end DateTime.
@ MapAtlasMargin
Map atlas margin.
@ MapYMax
Map extent y maximum.
@ MapXMin
Map extent x minimum.
@ MapLabelMargin
Map label margin.
@ MapLayers
Map layer set.
@ MapRotation
Map rotation.
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.
@ FlagRenderLabelsByMapLayer
When rendering map items to multi-layered exports, render labels belonging to different layers into s...
@ FlagUseAdvancedEffects
Enable advanced effects such as blend modes.
@ FlagDrawSelection
Draw selection.
@ FlagLosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ FlagAntialiasing
Use antialiasing when drawing items.
@ FlagForceVectorOutput
Force output in vector format where possible, even if items require rasterization to keep their corre...
@ FlagHideCoverageLayer
Hide coverage layer in outputs.
@ FlagDisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
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.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
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.
QgsProject * project() const
The project associated with the layout.
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.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Job implementation that renders everything sequentially using a custom painter.
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.
The QgsMapSettings class contains configuration for rendering of the map.
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 setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
long long currentFrame() const
Returns the current frame number of the map, for maps which are part of an animation.
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.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
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.
double frameRate() const
Returns the frame rate of the map (in frames per second), for maps which are part of an animation.
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.
A class to represent a 2D point.
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.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
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 setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
An interface for classes which provider 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.
Scoped object for saving and restoring a QPainter object's state.
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.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
@ NoSimplification
No simplification can be applied.
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) SIP_HOLDGIL
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)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
const QgsCoordinateReferenceSystem & crs
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.