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 );
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 );
334 mGroupLayers.clear();
336 QList<QgsMapLayer *> layersCopy {
layers };
341 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
343 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
345 auto existingIt = mGroupLayers.find( groupLayer->id() );
346 if ( existingIt != mGroupLayers.end( ) )
348 *it = ( *existingIt ).second.get();
352 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
353 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
354 *it = mGroupLayers[ groupLayer->id() ].get();
358 mLayers = _qgis_listRawToRef( layersCopy );
363 if ( overrides == mLayerStyleOverrides )
366 mLayerStyleOverrides = overrides;
373 mLayerStyleOverrides.clear();
380 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
387 if ( mFollowVisibilityPreset == follow )
390 mFollowVisibilityPreset = follow;
392 if ( !mFollowVisibilityPresetName.isEmpty() )
393 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
398 if ( name == mFollowVisibilityPresetName )
401 mFollowVisibilityPresetName = name;
402 if ( mFollowVisibilityPreset )
408 mLastRenderedImageOffsetX -= dx;
409 mLastRenderedImageOffsetY -= dy;
412 transformShift( dx, dy );
436 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
442 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
443 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
445 double newIntervalX, newIntervalY;
462 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
469 calculator.
setDpi( 25.4 );
470 double scaleRatio =
scale() / calculator.
calculate( mExtent, rect().width() );
471 mExtent.
scale( scaleRatio );
487 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
521 if ( mOverviewStack->containsAdvancedEffects() )
527 if ( mGridStack->containsAdvancedEffects() )
539 mMapRotation = rotation;
540 mEvaluatedMapRotation = mMapRotation;
554 mAtlasDriven = enabled;
571 double margin = mAtlasMargin;
579 margin = ddMargin / 100;
591 if ( mGridStack->size() < 1 )
594 mGridStack->addGrid(
grid );
596 return mGridStack->grid( 0 );
601 if ( mOverviewStack->size() < 1 )
604 mOverviewStack->addOverview(
overview );
606 return mOverviewStack->overview( 0 );
616 for (
int i = 0; i < mGridStack->size(); ++i )
619 if (
grid->mEvaluatedEnabled )
622 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
638 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
642 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
645 if ( mDrawAnnotations )
647 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
651 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
655 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
660 mapElem.appendChild( extentElem );
664 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
666 mapElem.appendChild( crsElem );
670 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
671 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
674 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
677 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
682 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
684 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
686 return groupLayer.second.get() == layerRef.get();
689 if ( it != mGroupLayers.end() )
695 layerId = layerRef.layerId;
698 QDomText layerIdText = doc.createTextNode( layerId );
699 layerElem.appendChild( layerIdText );
701 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
702 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
703 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
705 if ( it != mGroupLayers.end() )
707 const auto childLayers { it->second->childLayers() };
708 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
709 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
711 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
712 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
713 childLayersElement.appendChild( childElement );
715 layerElem.appendChild( childLayersElement );
717 layerSetElem.appendChild( layerElem );
719 mapElem.appendChild( layerSetElem );
722 if ( mKeepLayerStyles )
724 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
725 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
727 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
732 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
733 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
734 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
735 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
739 stylesElem.appendChild( styleElem );
741 mapElem.appendChild( stylesElem );
745 mGridStack->writeXml( mapElem, doc, context );
748 mOverviewStack->writeXml( mapElem, doc, context );
751 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
752 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
753 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
754 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
755 mapElem.appendChild( atlasElem );
757 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
758 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
760 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
761 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
766 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
767 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
768 labelBlockingItemsElem.appendChild( blockingItemElem );
770 mapElem.appendChild( labelBlockingItemsElem );
773 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
776 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
777 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
780 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
781 mItemClippingSettings->
writeXml( mapElem, doc, context );
788 mUpdatesEnabled =
false;
791 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
792 if ( !extentNodeList.isEmpty() )
794 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
795 double xmin, xmax, ymin, ymax;
796 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
797 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
798 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
799 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
803 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
805 if ( !crsNodeList.isEmpty() )
807 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
813 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
814 mEvaluatedMapRotation = mMapRotation;
817 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
818 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
821 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
822 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
824 mKeepLayerSet =
true;
828 mKeepLayerSet =
false;
831 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
832 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
834 mDrawAnnotations =
true;
838 mDrawAnnotations =
false;
841 mLayerStyleOverrides.clear();
843 QList<QgsMapLayerRef> layerSet;
844 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
845 if ( !layerSetNodeList.isEmpty() )
847 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
848 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
849 layerSet.reserve( layerIdNodeList.size() );
850 for (
int i = 0; i < layerIdNodeList.size(); ++i )
852 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
853 QString layerId = layerElem.text();
854 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
855 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
856 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
858 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
866 setLayers( _qgis_listRefToRaw( layerSet ) );
869 if ( !layerSetNodeList.isEmpty() )
871 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
872 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
873 for (
int i = 0; i < layerIdNodeList.size(); ++i )
875 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
876 const QString layerId = layerElem.text();
877 const auto it = mGroupLayers.find( layerId );
878 if ( it != mGroupLayers.cend() )
880 QList<QgsMapLayerRef> childSet;
881 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
882 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
883 for (
int i = 0; i < children.size(); ++i )
885 const QDomElement childElement = children.at( i ).toElement();
886 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
888 if ( layerRef.resolveWeakly(
mLayout->project() ) )
890 childSet.push_back( layerRef );
893 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
900 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
901 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
902 if ( mKeepLayerStyles )
904 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
905 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
906 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
908 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
909 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
910 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
911 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
912 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
913 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
917 style.
readXml( layerStyleElement );
923 mNumCachedLayers = 0;
924 mCacheInvalidated =
true;
927 mOverviewStack->readXml( itemElem, doc, context );
930 mGridStack->readXml( itemElem, doc, context );
933 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
934 if ( !atlasNodeList.isEmpty() )
936 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
937 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
938 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
940 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
942 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
944 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
946 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
951 mMapFlags =
static_cast< MapItemFlags
>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
954 mBlockingLabelItems.clear();
955 mBlockingLabelItemUuids.clear();
956 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
957 if ( !labelBlockingNodeList.isEmpty() )
959 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
960 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
961 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
963 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
964 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
965 mBlockingLabelItemUuids << itemUuid;
969 mAtlasClippingSettings->
readXml( itemElem, doc, context );
970 mItemClippingSettings->
readXml( itemElem, doc, context );
975 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
978 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
979 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
983 mUpdatesEnabled =
true;
989 if ( mItemClippingSettings->
isActive() )
1000 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1009 QRectF thisPaintRect = rect();
1015 if (
mLayout->renderContext().isPreviewRender() )
1017 bool renderInProgress =
false;
1020 painter->setClipRect( thisPaintRect );
1021 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1024 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1025 painter->drawRect( thisPaintRect );
1026 painter->setBrush( Qt::NoBrush );
1028 messageFont.setPointSize( 12 );
1029 painter->setFont( messageFont );
1030 painter->setPen( QColor( 255, 255, 255, 255 ) );
1031 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1032 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1036 mBackgroundUpdateTimer->start( 1 );
1038 else if ( !mPainterJob && !mDrawingPreview )
1042 mBackgroundUpdateTimer->start( 1 );
1044 renderInProgress =
true;
1048 if ( mCacheInvalidated && !mDrawingPreview )
1052 mBackgroundUpdateTimer->start( 1 );
1053 renderInProgress =
true;
1058 double imagePixelWidth = mCacheFinalImage->width();
1059 double scale = rect().width() / imagePixelWidth;
1063 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1065 painter->drawImage( 0, 0, *mCacheFinalImage );
1070 painter->setClipRect( thisPaintRect, Qt::NoClip );
1072 mOverviewStack->drawItems( painter,
false );
1073 mGridStack->drawItems( painter );
1075 drawMapFrame( painter );
1077 if ( renderInProgress )
1088 QPaintDevice *paintDevice = painter->device();
1096 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1103 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1104 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1105 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1107 image.fill( Qt::transparent );
1108 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1109 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1110 double dotsPerMM = destinationDpi / 25.4;
1111 QPainter p( &image );
1114 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1115 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1116 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1117 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1118 p.setClipRect( imagePaintRect );
1120 p.translate( imagePaintRect.topLeft() );
1124 if ( shouldDrawPart( Background ) )
1126 p.scale( dotsPerMM, dotsPerMM );
1127 drawMapBackground( &p );
1128 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1131 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1136 p.scale( dotsPerMM, dotsPerMM );
1138 if ( shouldDrawPart( OverviewMapExtent ) )
1140 mOverviewStack->drawItems( &p,
false );
1142 if ( shouldDrawPart( Grid ) )
1144 mGridStack->drawItems( &p );
1149 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1150 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1151 painter->scale( dotsPerMM, dotsPerMM );
1156 if ( shouldDrawPart( Background ) )
1158 drawMapBackground( painter );
1162 painter->setClipRect( thisPaintRect );
1167 painter->translate( mXOffset, mYOffset );
1169 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1171 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1173 if ( mCurrentExportPart != NotLayered )
1175 if ( !mStagedRendererJob )
1177 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1180 mStagedRendererJob->renderCurrentPart( painter );
1184 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1188 painter->setClipRect( thisPaintRect, Qt::NoClip );
1190 if ( shouldDrawPart( OverviewMapExtent ) )
1192 mOverviewStack->drawItems( painter,
false );
1194 if ( shouldDrawPart( Grid ) )
1196 mGridStack->drawItems( painter );
1201 if ( shouldDrawPart( Frame ) )
1203 drawMapFrame( painter );
1214 + ( layerCount + ( layerCount ? 1 : 0 ) )
1215 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1216 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1222 mCurrentExportPart = Start;
1224 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1225 mExportThemeIt = mExportThemes.begin();
1230 mCurrentExportPart = NotLayered;
1231 mExportThemes.clear();
1232 mExportThemeIt = mExportThemes.begin();
1237 switch ( mCurrentExportPart )
1242 mCurrentExportPart = Background;
1248 mCurrentExportPart = Layer;
1252 if ( mStagedRendererJob )
1254 if ( mStagedRendererJob->nextPart() )
1258 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1259 mStagedRendererJob.reset();
1263 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1269 if ( mGridStack->hasEnabledItems() )
1271 mCurrentExportPart = Grid;
1277 for (
int i = 0; i < mOverviewStack->size(); ++i )
1282 mCurrentExportPart = OverviewMapExtent;
1288 case OverviewMapExtent:
1291 mCurrentExportPart = Frame;
1298 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1300 mCurrentExportPart = SelectionBoxes;
1305 case SelectionBoxes:
1306 mCurrentExportPart = End;
1327 switch ( mCurrentExportPart )
1337 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1340 if ( mStagedRendererJob )
1342 switch ( mStagedRendererJob->currentStage() )
1346 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1347 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1348 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1354 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1356 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1362 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1367 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1373 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1376 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1378 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1387 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1393 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1428 case OverviewMapExtent:
1436 case SelectionBoxes:
1451void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1465 if ( shouldDrawPart( OverviewMapExtent ) )
1467 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1471#ifdef HAVE_SERVER_PYTHON_PLUGINS
1472 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1478 job.renderSynchronously();
1480 mExportLabelingResults.reset( job.takeLabelingResults() );
1482 mRenderingErrors = job.errors();
1485void QgsLayoutItemMap::recreateCachedImageInBackground()
1491 QPainter *oldPainter = mPainter.release();
1492 QImage *oldImage = mCacheRenderingImage.release();
1495 oldJob->deleteLater();
1503 mCacheRenderingImage.reset(
nullptr );
1507 Q_ASSERT( !mPainterJob );
1508 Q_ASSERT( !mPainter );
1509 Q_ASSERT( !mCacheRenderingImage );
1515 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1516 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1519 if ( w > 5000 || h > 5000 )
1524 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1529 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1533 if ( w <= 0 || h <= 0 )
1536 mCacheRenderingImage.reset(
new QImage( w, h, QImage::Format_ARGB32 ) );
1539 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1540 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1543 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1548 if ( mItemClippingSettings->
isActive() )
1550 QPainter p( mCacheRenderingImage.get() );
1552 p.setPen( Qt::NoPen );
1554 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1564 mCacheInvalidated =
false;
1565 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1568 if ( shouldDrawPart( OverviewMapExtent ) )
1570 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1575 mPainterJob->start();
1587 mDrawingPreview =
false;
1610 if (
layout()->renderContext().isPreviewRender() )
1613 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1620 if ( includeLayerSettings )
1625 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1628 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1635 if ( !
mLayout->renderContext().isPreviewRender() )
1678 if ( mEvaluatedLabelMargin.
length() > 0 )
1681 visiblePoly.append( visiblePoly.at( 0 ) );
1682 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1683 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1685 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1686 labelBoundary = mapBoundaryGeom;
1689 if ( !mBlockingLabelItems.isEmpty() )
1702 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1713 if ( !labelBoundary.
isEmpty() )
1715 labelBoundary = clipGeom.
intersection( labelBoundary );
1719 labelBoundary = clipGeom;
1724 if ( mItemClippingSettings->
isActive() )
1733 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1734 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1736 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1737 if ( !labelBoundary.
isEmpty() )
1739 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1743 labelBoundary = mapBoundaryGeom;
1749 if ( !labelBoundary.
isNull() )
1752 return jobMapSettings;
1759 mBlockingLabelItems.clear();
1760 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1769 mOverviewStack->finalizeRestoreFromXml();
1770 mGridStack->finalizeRestoreFromXml();
1782 return mCurrentRectangle;
1796 const double mapScale =
scale();
1820 QVariantList layersIds;
1830 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1832 layersIds.reserve( layersInMap.count() );
1833 layers.reserve( layersInMap.count() );
1836 layersIds << layer->id();
1842 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1861 if ( extentWidth <= 0 )
1865 return rect().width() / extentWidth;
1870 double dx = mXOffset;
1871 double dy = mYOffset;
1872 transformShift( dx, dy );
1873 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1874 poly.translate( -dx, -dy );
1880 if ( !mBlockingLabelItems.contains( item ) )
1881 mBlockingLabelItems.append( item );
1888 mBlockingLabelItems.removeAll( item );
1895 return mBlockingLabelItems.contains( item );
1900 return mPreviewLabelingResults.get();
1909 if ( mOverviewStack )
1911 for (
int i = 0; i < mOverviewStack->size(); ++i )
1913 if ( mOverviewStack->item( i )->accept( visitor ) )
1920 for (
int i = 0; i < mGridStack->size(); ++i )
1922 if ( mGridStack->item( i )->accept( visitor ) )
1935 mRenderedFeatureHandlers.append( handler );
1940 mRenderedFeatureHandlers.removeAll( handler );
1946 if ( mapPoly.empty() )
1948 return QPointF( 0, 0 );
1953 double dx = mapCoords.x() - rotationPoint.
x();
1954 double dy = mapCoords.y() - rotationPoint.
y();
1956 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
1959 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
1960 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
1961 return QPointF( xItem, yItem );
1975 mapPolygon( newExtent, poly );
1976 QRectF bRect = poly.boundingRect();
1990 mCacheInvalidated =
true;
1996 QRectF rectangle = rect();
1997 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
1999 double topExtension = 0.0;
2000 double rightExtension = 0.0;
2001 double bottomExtension = 0.0;
2002 double leftExtension = 0.0;
2005 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2007 topExtension = std::max( topExtension, frameExtension );
2008 rightExtension = std::max( rightExtension, frameExtension );
2009 bottomExtension = std::max( bottomExtension, frameExtension );
2010 leftExtension = std::max( leftExtension, frameExtension );
2012 rectangle.setLeft( rectangle.left() - leftExtension );
2013 rectangle.setRight( rectangle.right() + rightExtension );
2014 rectangle.setTop( rectangle.top() - topExtension );
2015 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2016 if ( rectangle != mCurrentRectangle )
2018 prepareGeometryChange();
2019 mCurrentRectangle = rectangle;
2047 refreshMapExtents( &context );
2049 if ( mExtent != beforeExtent )
2056 refreshLabelMargin(
false );
2060 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2062 if ( mLastEvaluatedThemeName != previousTheme )
2080 mCacheInvalidated =
true;
2085void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2088 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2092 mLayerStyleOverrides.remove( layer->id() );
2094 _qgis_removeLayers( mLayers,
layers );
2100 if ( mGroupLayers.erase( layer->id() ) == 0 )
2103 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2106 if ( groupLayer->
childLayers().contains( layer ) )
2108 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2109 childLayers.removeAll( layer );
2117void QgsLayoutItemMap::painterJobFinished()
2120 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2121 mPainterJob.reset(
nullptr );
2122 mPainter.reset(
nullptr );
2123 mCacheFinalImage = std::move( mCacheRenderingImage );
2124 mLastRenderedImageOffsetX = 0;
2125 mLastRenderedImageOffsetY = 0;
2131void QgsLayoutItemMap::shapeChanged()
2136 double w = rect().width();
2137 double h = rect().height();
2140 double newWidth = mExtent.
width();
2142 double newHeight = newWidth * h / w;
2147 refreshMapExtents();
2154void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2156 if ( theme == mCachedLayerStyleOverridesPresetName )
2157 mCachedLayerStyleOverridesPresetName.clear();
2160void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2162 if ( theme == mFollowVisibilityPresetName )
2164 mFollowVisibilityPresetName = newTheme;
2168void QgsLayoutItemMap::connectUpdateSlot()
2176 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2180 if ( layers().isEmpty() )
2209 if ( mAtlasScalingMode == Predefined )
2210 updateAtlasFeature();
2216 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2217 QTransform mapTransform;
2218 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2220 thisRectPoly.pop_back();
2221 thisExtent.pop_back();
2223 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2226 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2227 return mapTransform;
2230QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2233 QList< QgsLabelBlockingRegion > blockers;
2234 blockers.reserve( mBlockingLabelItems.count() );
2235 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2242 if ( item->property(
"wasVisible" ).isValid() )
2244 if ( !item->property(
"wasVisible" ).toBool() )
2247 else if ( !item->isVisible() )
2250 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2251 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2260 return mLabelMargin;
2265 mLabelMargin = margin;
2266 refreshLabelMargin(
false );
2269void QgsLayoutItemMap::updateToolTip()
2278 if ( mFollowVisibilityPreset )
2280 presetName = mFollowVisibilityPresetName;
2284 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2285 presetName = *mExportThemeIt;
2296 QList<QgsMapLayer *> renderLayers;
2298 QString presetName = themeToRender( *evalContext );
2299 if ( !presetName.isEmpty() )
2301 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2302 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2304 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2306 else if ( !
layers().isEmpty() )
2312 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2319 renderLayers.clear();
2321 const QStringList layerNames = ddLayers.split(
'|' );
2323 for (
const QString &name : layerNames )
2325 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2328 renderLayers << layer;
2337 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2338 if ( removeAt != -1 )
2340 renderLayers.removeAt( removeAt );
2345 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2347 return !layer || !layer->isValid();
2348 } ), renderLayers.end() );
2350 return renderLayers;
2353QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2355 QString presetName = themeToRender( context );
2356 if ( !presetName.isEmpty() )
2358 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2360 if ( presetName != mCachedLayerStyleOverridesPresetName )
2363 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2364 mCachedLayerStyleOverridesPresetName = presetName;
2367 return mCachedPresetLayerStyleOverrides;
2370 return QMap<QString, QString>();
2372 else if ( mFollowVisibilityPreset )
2374 QString presetName = mFollowVisibilityPresetName;
2377 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2379 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2382 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2383 mCachedLayerStyleOverridesPresetName = presetName;
2386 return mCachedPresetLayerStyleOverrides;
2389 return QMap<QString, QString>();
2391 else if ( mKeepLayerStyles )
2393 return mLayerStyleOverrides;
2397 return QMap<QString, QString>();
2401QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2403 double dx = mXOffset;
2404 double dy = mYOffset;
2405 transformShift( dx, dy );
2409void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2419 poly << QPointF( poly.at( 0 ) );
2431 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2437 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2443 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2449 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2452 poly << QPointF( poly.at( 0 ) );
2455void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2458 double dxScaled = xShift * mmToMapUnits;
2459 double dyScaled = - yShift * mmToMapUnits;
2474 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2475 if ( annotations.isEmpty() )
2485 if ( !annotation || !annotation->isVisible() )
2489 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2492 drawAnnotation( annotation, rc );
2506 double itemX, itemY;
2509 QPointF mapPos = layoutMapPosForItem( annotation );
2518 context.
painter()->translate( itemX, itemY );
2521 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2522 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2524 annotation->
render( context );
2527QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2530 return QPointF( 0, 0 );
2539 if ( annotationCrs !=
crs() )
2546 t.transformInPlace( mapX, mapY, z );
2556void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2567void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2578bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2580 if ( mCurrentExportPart == NotLayered )
2598 return mCurrentExportPart == Layer;
2601 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2603 case OverviewMapExtent:
2604 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2609 case SelectionBoxes:
2610 return mCurrentExportPart == SelectionBoxes && isSelected();
2631 bool useDdXMin =
false;
2632 bool useDdXMax =
false;
2633 bool useDdYMin =
false;
2634 bool useDdYMax =
false;
2665 if ( newExtent != mExtent )
2671 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2672 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2674 if ( currentWidthHeightRatio < newWidthHeightRatio )
2677 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2678 double deltaHeight = newHeight - newExtent.
height();
2685 double newWidth = currentWidthHeightRatio * newExtent.
height();
2686 double deltaWidth = newWidth - newExtent.
width();
2691 mExtent = newExtent;
2701 newExtent = mExtent;
2704 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2708 if ( useDdXMin && !useDdXMax )
2714 else if ( !useDdXMin && useDdXMax )
2720 if ( useDdYMin && !useDdYMax )
2726 else if ( !useDdYMin && useDdYMax )
2733 if ( newExtent != mExtent )
2735 mExtent = newExtent;
2752void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2765void QgsLayoutItemMap::updateAtlasFeature()
2784 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2789 double originalScale = calc.
calculate( originalExtent, rect().width() );
2790 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2791 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2792 QVector<qreal> scales;
2794 if ( !
mLayout->reportContext().predefinedScales().empty() )
2795 scales =
mLayout->reportContext().predefinedScales();
2797 scales =
mLayout->renderContext().predefinedScales();
2799 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2802 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2803 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2806 xMin + originalExtent.
width(),
2807 yMin + originalExtent.
height() );
2811 double newScale = calc.
calculate( newExtent, rect().width() );
2812 newExtent.
scale( originalScale / newScale );
2817 double newWidth = originalExtent.
width();
2818 double newHeight = originalExtent.
height();
2819 for (
int i = 0; i < scales.size(); i++ )
2821 double ratio = scales[i] / originalScale;
2822 newWidth = originalExtent.
width() * ratio;
2823 newHeight = originalExtent.
height() * ratio;
2826 double xMin = geomCenterX - newWidth / 2.0;
2827 double yMin = geomCenterY - newHeight / 2.0;
2835 double newScale = calc.
calculate( newExtent, rect().width() );
2836 newExtent.
scale( scales[i] / newScale );
2846 else if ( mAtlasScalingMode ==
Auto )
2850 double geomRatio = bounds.
width() / bounds.
height();
2851 double mapRatio = originalExtent.
width() / originalExtent.
height();
2854 if ( geomRatio < mapRatio )
2857 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
2862 else if ( geomRatio > mapRatio )
2865 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
2871 const double evaluatedAtlasMargin =
atlasMargin();
2872 if ( evaluatedAtlasMargin > 0.0 )
2874 newExtent.
scale( 1 + evaluatedAtlasMargin );
2890 if ( mEvaluatedMapRotation != 0.0 )
2900 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
2901 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
2902 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
2903 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
2906 center.
x() + dx, center.
y() + dy );
2914void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
2917 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
2919 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
2923 mStagedRendererJob->start();
2939 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
2945 return mClipToAtlasFeature;
2950 if (
enabled == mClipToAtlasFeature )
2953 mClipToAtlasFeature =
enabled;
2959 return mFeatureClippingType;
2964 if ( mFeatureClippingType == type )
2967 mFeatureClippingType = type;
2973 return mForceLabelsInsideFeature;
2978 if ( forceInside == mForceLabelsInsideFeature )
2981 mForceLabelsInsideFeature = forceInside;
2987 return mRestrictToLayers;
2992 if ( mRestrictToLayers ==
enabled )
3001 return _qgis_listRefToRaw( mLayersToClip );
3012 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3013 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3014 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3015 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3016 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3019 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3024 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3025 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3026 layerElem.appendChild( layerIdText );
3028 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3029 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3030 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3032 layerSetElem.appendChild( layerElem );
3034 settingsElem.appendChild( layerSetElem );
3036 element.appendChild( settingsElem );
3042 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3044 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3045 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3047 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3049 mLayersToClip.clear();
3050 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3051 if ( !layerSetNodeList.isEmpty() )
3053 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3054 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3055 mLayersToClip.reserve( layerIdNodeList.size() );
3056 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3058 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3059 QString layerId = layerElem.text();
3060 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3061 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3062 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3064 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3067 mLayersToClip << ref;
3074void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3076 if ( !mLayersToClip.isEmpty() )
3078 _qgis_removeLayers( mLayersToClip, layers );
3093 return mEnabled && mClipPathSource;
3108 if ( mClipPathSource )
3111 mClipPathSource->refresh();
3120 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3131 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3132 clipGeom.
transform( mMap->sceneTransform().inverted() );
3147 if ( mClipPathSource == item )
3150 if ( mClipPathSource )
3159 mClipPathSource = item;
3161 if ( mClipPathSource )
3170 mClipPathSource->refresh();
3184 return mClipPathSource;
3189 return mFeatureClippingType;
3194 if ( mFeatureClippingType == type )
3197 mFeatureClippingType = type;
3203 return mForceLabelsInsideClipPath;
3208 if ( forceInside == mForceLabelsInsideClipPath )
3211 mForceLabelsInsideClipPath = forceInside;
3217 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3218 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3219 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3220 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3221 if ( mClipPathSource )
3222 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3224 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3226 element.appendChild( settingsElem );
3232 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3234 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3235 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3237 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3244 if ( !mClipPathUuid.isEmpty() )
@ Millimeters
Millimeters.
@ 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.
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,...
Qgis::DistanceUnit mapUnits
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.
QPolygonF asQPolygonF() const
Returns contents of the geometry as a QPolygonF.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
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 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.
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.
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.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
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.
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
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).
Render job implementation that renders maps in stages, allowing different stages (e....
@ 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,...
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
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 xMinimum() const
Returns the x minimum value (left side of rectangle).
void setYMinimum(double y)
Set the minimum y value.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
void setXMinimum(double x)
Set the minimum x value.
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
void setYMaximum(double y)
Set the maximum y value.
QgsPointXY center() const
Returns the center point of the rectangle.
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.
double height() const
Returns the height 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.
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.
@ 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)
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.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
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.