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.
isEmpty() )
246 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
248 currentWidthHeightRatio = rect().width() / rect().height();
250 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
252 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
254 if ( currentWidthHeightRatio < newWidthHeightRatio )
257 double newHeight = newExtent.
width() / currentWidthHeightRatio;
258 double deltaHeight = newHeight - newExtent.
height();
265 double newWidth = currentWidthHeightRatio * newExtent.
height();
266 double deltaWidth = newWidth - newExtent.
width();
272 if ( mExtent == newExtent )
291QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
294 mapPolygon( mExtent, poly );
296 if ( includeClipping && mItemClippingSettings->
isActive() )
310 return calculateVisibleExtentPolygon(
true );
318 return mLayout->project()->crs();
333 return _qgis_listRefToRaw( mLayers );
338 mGroupLayers.clear();
340 QList<QgsMapLayer *> layersCopy {
layers };
345 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
347 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
349 auto existingIt = mGroupLayers.find( groupLayer->id() );
350 if ( existingIt != mGroupLayers.end( ) )
352 *it = ( *existingIt ).second.get();
356 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
357 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
358 *it = mGroupLayers[ groupLayer->id() ].get();
362 mLayers = _qgis_listRawToRef( layersCopy );
367 if ( overrides == mLayerStyleOverrides )
370 mLayerStyleOverrides = overrides;
377 mLayerStyleOverrides.clear();
384 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
391 if ( mFollowVisibilityPreset == follow )
394 mFollowVisibilityPreset = follow;
396 if ( !mFollowVisibilityPresetName.isEmpty() )
397 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
402 if ( name == mFollowVisibilityPresetName )
405 mFollowVisibilityPresetName = name;
406 if ( mFollowVisibilityPreset )
412 mLastRenderedImageOffsetX -= dx;
413 mLastRenderedImageOffsetY -= dy;
416 transformShift( dx, dy );
440 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
446 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
447 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
449 double newIntervalX, newIntervalY;
466 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
473 calculator.
setDpi( 25.4 );
474 double scaleRatio =
scale() / calculator.
calculate( mExtent, rect().width() );
475 mExtent.
scale( scaleRatio );
491 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
501 if (
blendMode() != QPainter::CompositionMode_SourceOver )
520 auto containsAdvancedEffectsIgnoreItemOpacity = [ = ]()->
bool
530 if ( mOverviewStack->containsAdvancedEffects() )
538 if ( mGridStack->containsAdvancedEffects() )
551 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
572 if ( mOverviewStack->containsAdvancedEffects() )
580 if ( mGridStack->containsAdvancedEffects() )
595 mMapRotation = rotation;
596 mEvaluatedMapRotation = mMapRotation;
610 mAtlasDriven = enabled;
627 double margin = mAtlasMargin;
635 margin = ddMargin / 100;
647 if ( mGridStack->size() < 1 )
650 mGridStack->addGrid(
grid );
652 return mGridStack->grid( 0 );
657 if ( mOverviewStack->size() < 1 )
660 mOverviewStack->addOverview(
overview );
662 return mOverviewStack->overview( 0 );
672 for (
int i = 0; i < mGridStack->size(); ++i )
675 if (
grid->mEvaluatedEnabled )
678 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
694 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
698 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
701 if ( mDrawAnnotations )
703 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
707 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
711 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
716 mapElem.appendChild( extentElem );
720 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
722 mapElem.appendChild( crsElem );
726 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
727 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
730 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
733 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
738 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
740 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
742 return groupLayer.second.get() == layerRef.get();
745 if ( it != mGroupLayers.end() )
751 layerId = layerRef.layerId;
754 QDomText layerIdText = doc.createTextNode( layerId );
755 layerElem.appendChild( layerIdText );
757 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
758 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
759 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
761 if ( it != mGroupLayers.end() )
763 const auto childLayers { it->second->childLayers() };
764 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
765 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
767 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
768 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
769 childLayersElement.appendChild( childElement );
771 layerElem.appendChild( childLayersElement );
773 layerSetElem.appendChild( layerElem );
775 mapElem.appendChild( layerSetElem );
778 if ( mKeepLayerStyles )
780 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
781 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
783 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
788 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
789 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
790 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
791 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
795 stylesElem.appendChild( styleElem );
797 mapElem.appendChild( stylesElem );
801 mGridStack->writeXml( mapElem, doc, context );
804 mOverviewStack->writeXml( mapElem, doc, context );
807 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
808 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
809 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
810 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
811 mapElem.appendChild( atlasElem );
813 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
814 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
816 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
817 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
822 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
823 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
824 labelBlockingItemsElem.appendChild( blockingItemElem );
826 mapElem.appendChild( labelBlockingItemsElem );
829 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
832 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
833 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
836 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
837 mItemClippingSettings->
writeXml( mapElem, doc, context );
844 mUpdatesEnabled =
false;
847 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
848 if ( !extentNodeList.isEmpty() )
850 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
851 double xmin, xmax, ymin, ymax;
852 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
853 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
854 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
855 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
859 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
861 if ( !crsNodeList.isEmpty() )
863 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
869 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
870 mEvaluatedMapRotation = mMapRotation;
873 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
874 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
877 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
878 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
880 mKeepLayerSet =
true;
884 mKeepLayerSet =
false;
887 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
888 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
890 mDrawAnnotations =
true;
894 mDrawAnnotations =
false;
897 mLayerStyleOverrides.clear();
899 QList<QgsMapLayerRef> layerSet;
900 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
901 if ( !layerSetNodeList.isEmpty() )
903 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
904 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
905 layerSet.reserve( layerIdNodeList.size() );
906 for (
int i = 0; i < layerIdNodeList.size(); ++i )
908 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
909 QString layerId = layerElem.text();
910 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
911 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
912 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
914 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
922 setLayers( _qgis_listRefToRaw( layerSet ) );
925 if ( !layerSetNodeList.isEmpty() )
927 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
928 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
929 for (
int i = 0; i < layerIdNodeList.size(); ++i )
931 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
932 const QString layerId = layerElem.text();
933 const auto it = mGroupLayers.find( layerId );
934 if ( it != mGroupLayers.cend() )
936 QList<QgsMapLayerRef> childSet;
937 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
938 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
939 for (
int i = 0; i < children.size(); ++i )
941 const QDomElement childElement = children.at( i ).toElement();
942 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
944 if ( layerRef.resolveWeakly(
mLayout->project() ) )
946 childSet.push_back( layerRef );
949 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
956 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
957 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
958 if ( mKeepLayerStyles )
960 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
961 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
962 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
964 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
965 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
966 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
967 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
968 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
969 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
973 style.
readXml( layerStyleElement );
979 mNumCachedLayers = 0;
980 mCacheInvalidated =
true;
983 mOverviewStack->readXml( itemElem, doc, context );
986 mGridStack->readXml( itemElem, doc, context );
989 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
990 if ( !atlasNodeList.isEmpty() )
992 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
993 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
994 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
996 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
998 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1000 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1002 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1007 mMapFlags =
static_cast< MapItemFlags
>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1010 mBlockingLabelItems.clear();
1011 mBlockingLabelItemUuids.clear();
1012 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1013 if ( !labelBlockingNodeList.isEmpty() )
1015 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1016 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1017 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1019 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1020 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1021 mBlockingLabelItemUuids << itemUuid;
1025 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1026 mItemClippingSettings->
readXml( itemElem, doc, context );
1031 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1034 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1035 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1039 mUpdatesEnabled =
true;
1045 if ( mItemClippingSettings->
isActive() )
1056 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1065 QRectF thisPaintRect = rect();
1071 if (
mLayout->renderContext().isPreviewRender() )
1073 bool renderInProgress =
false;
1076 painter->setClipRect( thisPaintRect );
1077 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1080 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1081 painter->drawRect( thisPaintRect );
1082 painter->setBrush( Qt::NoBrush );
1084 messageFont.setPointSize( 12 );
1085 painter->setFont( messageFont );
1086 painter->setPen( QColor( 255, 255, 255, 255 ) );
1087 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1088 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1092 mBackgroundUpdateTimer->start( 1 );
1094 else if ( !mPainterJob && !mDrawingPreview )
1098 mBackgroundUpdateTimer->start( 1 );
1100 renderInProgress =
true;
1104 if ( mCacheInvalidated && !mDrawingPreview )
1108 mBackgroundUpdateTimer->start( 1 );
1109 renderInProgress =
true;
1114 double imagePixelWidth = mCacheFinalImage->width();
1115 double scale = rect().width() / imagePixelWidth;
1119 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1120 painter->setCompositionMode( blendModeForRender() );
1122 painter->drawImage( 0, 0, *mCacheFinalImage );
1127 painter->setClipRect( thisPaintRect, Qt::NoClip );
1129 mOverviewStack->drawItems( painter,
false );
1130 mGridStack->drawItems( painter );
1132 drawMapFrame( painter );
1134 if ( renderInProgress )
1145 QPaintDevice *paintDevice = painter->device();
1153 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1161 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1162 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1163 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1165 image.fill( Qt::transparent );
1166 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1167 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1168 double dotsPerMM = destinationDpi / 25.4;
1169 QPainter p( &image );
1172 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1173 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1174 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1175 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1176 p.setClipRect( imagePaintRect );
1178 p.translate( imagePaintRect.topLeft() );
1182 if ( shouldDrawPart( Background ) )
1184 p.scale( dotsPerMM, dotsPerMM );
1185 drawMapBackground( &p );
1186 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1189 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1194 p.scale( dotsPerMM, dotsPerMM );
1196 if ( shouldDrawPart( OverviewMapExtent ) )
1198 mOverviewStack->drawItems( &p,
false );
1200 if ( shouldDrawPart( Grid ) )
1202 mGridStack->drawItems( &p );
1207 painter->setCompositionMode( blendModeForRender() );
1208 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1209 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1210 painter->scale( dotsPerMM, dotsPerMM );
1215 if ( shouldDrawPart( Background ) )
1217 drawMapBackground( painter );
1221 painter->setClipRect( thisPaintRect );
1226 painter->translate( mXOffset, mYOffset );
1228 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1230 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1232 if ( mCurrentExportPart != NotLayered )
1234 if ( !mStagedRendererJob )
1236 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1239 mStagedRendererJob->renderCurrentPart( painter );
1243 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1247 painter->setClipRect( thisPaintRect, Qt::NoClip );
1249 if ( shouldDrawPart( OverviewMapExtent ) )
1251 mOverviewStack->drawItems( painter,
false );
1253 if ( shouldDrawPart( Grid ) )
1255 mGridStack->drawItems( painter );
1260 if ( shouldDrawPart( Frame ) )
1262 drawMapFrame( painter );
1273 + ( layerCount + ( layerCount ? 1 : 0 ) )
1274 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1275 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1281 mCurrentExportPart = Start;
1283 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1284 mExportThemeIt = mExportThemes.begin();
1289 mCurrentExportPart = NotLayered;
1290 mExportThemes.clear();
1291 mExportThemeIt = mExportThemes.begin();
1296 switch ( mCurrentExportPart )
1301 mCurrentExportPart = Background;
1307 mCurrentExportPart = Layer;
1311 if ( mStagedRendererJob )
1313 if ( mStagedRendererJob->nextPart() )
1317 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1318 mStagedRendererJob.reset();
1322 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1328 if ( mGridStack->hasEnabledItems() )
1330 mCurrentExportPart = Grid;
1336 for (
int i = 0; i < mOverviewStack->size(); ++i )
1341 mCurrentExportPart = OverviewMapExtent;
1347 case OverviewMapExtent:
1350 mCurrentExportPart = Frame;
1357 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1359 mCurrentExportPart = SelectionBoxes;
1364 case SelectionBoxes:
1365 mCurrentExportPart = End;
1386 switch ( mCurrentExportPart )
1396 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1399 if ( mStagedRendererJob )
1401 switch ( mStagedRendererJob->currentStage() )
1405 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1406 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1407 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1413 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1415 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1421 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1426 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1432 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1435 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1437 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1446 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1452 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1487 case OverviewMapExtent:
1495 case SelectionBoxes:
1510void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1524 if ( shouldDrawPart( OverviewMapExtent ) )
1526 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1530#ifdef HAVE_SERVER_PYTHON_PLUGINS
1531 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1537 job.renderSynchronously();
1539 mExportLabelingResults.reset( job.takeLabelingResults() );
1541 mRenderingErrors = job.errors();
1544void QgsLayoutItemMap::recreateCachedImageInBackground()
1550 QPainter *oldPainter = mPainter.release();
1551 QImage *oldImage = mCacheRenderingImage.release();
1554 oldJob->deleteLater();
1562 mCacheRenderingImage.reset(
nullptr );
1566 Q_ASSERT( !mPainterJob );
1567 Q_ASSERT( !mPainter );
1568 Q_ASSERT( !mCacheRenderingImage );
1574 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1575 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1578 if ( w > 5000 || h > 5000 )
1583 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1588 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1592 if ( w <= 0 || h <= 0 )
1595 mCacheRenderingImage.reset(
new QImage( w, h, QImage::Format_ARGB32 ) );
1598 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1599 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1602 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1607 if ( mItemClippingSettings->
isActive() )
1609 QPainter p( mCacheRenderingImage.get() );
1611 p.setPen( Qt::NoPen );
1613 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1623 mCacheInvalidated =
false;
1624 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1627 if ( shouldDrawPart( OverviewMapExtent ) )
1629 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1634 mPainterJob->start();
1646 mDrawingPreview =
false;
1669 if (
layout()->renderContext().isPreviewRender() )
1672 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1679 if ( includeLayerSettings )
1684 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1687 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1694 if ( !
mLayout->renderContext().isPreviewRender() )
1737 if ( mEvaluatedLabelMargin.
length() > 0 )
1740 visiblePoly.append( visiblePoly.at( 0 ) );
1741 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1742 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1744 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1745 labelBoundary = mapBoundaryGeom;
1748 if ( !mBlockingLabelItems.isEmpty() )
1761 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1772 if ( !labelBoundary.
isEmpty() )
1774 labelBoundary = clipGeom.
intersection( labelBoundary );
1778 labelBoundary = clipGeom;
1783 if ( mItemClippingSettings->
isActive() )
1792 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1793 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1795 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1796 if ( !labelBoundary.
isEmpty() )
1798 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1802 labelBoundary = mapBoundaryGeom;
1808 if ( !labelBoundary.
isNull() )
1811 return jobMapSettings;
1818 mBlockingLabelItems.clear();
1819 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1828 mOverviewStack->finalizeRestoreFromXml();
1829 mGridStack->finalizeRestoreFromXml();
1841 return mCurrentRectangle;
1855 const double mapScale =
scale();
1879 QVariantList layersIds;
1889 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1891 layersIds.reserve( layersInMap.count() );
1892 layers.reserve( layersInMap.count() );
1895 layersIds << layer->id();
1901 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1920 if ( extentWidth <= 0 )
1924 return rect().width() / extentWidth;
1929 double dx = mXOffset;
1930 double dy = mYOffset;
1931 transformShift( dx, dy );
1932 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1933 poly.translate( -dx, -dy );
1939 if ( !mBlockingLabelItems.contains( item ) )
1940 mBlockingLabelItems.append( item );
1947 mBlockingLabelItems.removeAll( item );
1954 return mBlockingLabelItems.contains( item );
1959 return mPreviewLabelingResults.get();
1968 if ( mOverviewStack )
1970 for (
int i = 0; i < mOverviewStack->size(); ++i )
1972 if ( mOverviewStack->item( i )->accept( visitor ) )
1979 for (
int i = 0; i < mGridStack->size(); ++i )
1981 if ( mGridStack->item( i )->accept( visitor ) )
1994 mRenderedFeatureHandlers.append( handler );
1999 mRenderedFeatureHandlers.removeAll( handler );
2005 if ( mapPoly.empty() )
2007 return QPointF( 0, 0 );
2012 double dx = mapCoords.x() - rotationPoint.
x();
2013 double dy = mapCoords.y() - rotationPoint.
y();
2015 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2018 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2019 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2020 return QPointF( xItem, yItem );
2034 mapPolygon( newExtent, poly );
2035 QRectF bRect = poly.boundingRect();
2049 mCacheInvalidated =
true;
2055 QRectF rectangle = rect();
2056 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2058 double topExtension = 0.0;
2059 double rightExtension = 0.0;
2060 double bottomExtension = 0.0;
2061 double leftExtension = 0.0;
2064 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2066 topExtension = std::max( topExtension, frameExtension );
2067 rightExtension = std::max( rightExtension, frameExtension );
2068 bottomExtension = std::max( bottomExtension, frameExtension );
2069 leftExtension = std::max( leftExtension, frameExtension );
2071 rectangle.setLeft( rectangle.left() - leftExtension );
2072 rectangle.setRight( rectangle.right() + rightExtension );
2073 rectangle.setTop( rectangle.top() - topExtension );
2074 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2075 if ( rectangle != mCurrentRectangle )
2077 prepareGeometryChange();
2078 mCurrentRectangle = rectangle;
2106 refreshMapExtents( &context );
2108 if ( mExtent != beforeExtent )
2115 refreshLabelMargin(
false );
2119 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2121 if ( mLastEvaluatedThemeName != previousTheme )
2139 mCacheInvalidated =
true;
2144void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2147 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2151 mLayerStyleOverrides.remove( layer->id() );
2153 _qgis_removeLayers( mLayers,
layers );
2159 if ( mGroupLayers.erase( layer->id() ) == 0 )
2162 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2165 if ( groupLayer->
childLayers().contains( layer ) )
2167 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2168 childLayers.removeAll( layer );
2176void QgsLayoutItemMap::painterJobFinished()
2179 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2180 mPainterJob.reset(
nullptr );
2181 mPainter.reset(
nullptr );
2182 mCacheFinalImage = std::move( mCacheRenderingImage );
2183 mLastRenderedImageOffsetX = 0;
2184 mLastRenderedImageOffsetY = 0;
2190void QgsLayoutItemMap::shapeChanged()
2195 double w = rect().width();
2196 double h = rect().height();
2199 double newWidth = mExtent.
width();
2201 double newHeight = newWidth * h / w;
2206 refreshMapExtents();
2213void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2215 if ( theme == mCachedLayerStyleOverridesPresetName )
2216 mCachedLayerStyleOverridesPresetName.clear();
2219void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2221 if ( theme == mFollowVisibilityPresetName )
2223 mFollowVisibilityPresetName = newTheme;
2227void QgsLayoutItemMap::connectUpdateSlot()
2235 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2239 if ( layers().isEmpty() )
2268 if ( mAtlasScalingMode == Predefined )
2269 updateAtlasFeature();
2275 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2276 QTransform mapTransform;
2277 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2279 thisRectPoly.pop_back();
2280 thisExtent.pop_back();
2282 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2285 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2286 return mapTransform;
2289QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2292 QList< QgsLabelBlockingRegion > blockers;
2293 blockers.reserve( mBlockingLabelItems.count() );
2294 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2301 if ( item->property(
"wasVisible" ).isValid() )
2303 if ( !item->property(
"wasVisible" ).toBool() )
2306 else if ( !item->isVisible() )
2309 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2310 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2319 return mLabelMargin;
2324 mLabelMargin = margin;
2325 refreshLabelMargin(
false );
2328void QgsLayoutItemMap::updateToolTip()
2337 if ( mFollowVisibilityPreset )
2339 presetName = mFollowVisibilityPresetName;
2343 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2344 presetName = *mExportThemeIt;
2355 QList<QgsMapLayer *> renderLayers;
2357 QString presetName = themeToRender( *evalContext );
2358 if ( !presetName.isEmpty() )
2360 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2361 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2363 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2365 else if ( !
layers().isEmpty() )
2371 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2378 renderLayers.clear();
2380 const QStringList layerNames = ddLayers.split(
'|' );
2382 for (
const QString &name : layerNames )
2384 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2387 renderLayers << layer;
2396 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2397 if ( removeAt != -1 )
2399 renderLayers.removeAt( removeAt );
2404 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2406 return !layer || !layer->isValid();
2407 } ), renderLayers.end() );
2409 return renderLayers;
2412QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2414 QString presetName = themeToRender( context );
2415 if ( !presetName.isEmpty() )
2417 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2419 if ( presetName != mCachedLayerStyleOverridesPresetName )
2422 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2423 mCachedLayerStyleOverridesPresetName = presetName;
2426 return mCachedPresetLayerStyleOverrides;
2429 return QMap<QString, QString>();
2431 else if ( mFollowVisibilityPreset )
2433 QString presetName = mFollowVisibilityPresetName;
2436 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2438 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2441 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2442 mCachedLayerStyleOverridesPresetName = presetName;
2445 return mCachedPresetLayerStyleOverrides;
2448 return QMap<QString, QString>();
2450 else if ( mKeepLayerStyles )
2452 return mLayerStyleOverrides;
2456 return QMap<QString, QString>();
2460QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2462 double dx = mXOffset;
2463 double dy = mYOffset;
2464 transformShift( dx, dy );
2468void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2478 poly << QPointF( poly.at( 0 ) );
2490 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2496 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2502 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2508 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2511 poly << QPointF( poly.at( 0 ) );
2514void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2517 double dxScaled = xShift * mmToMapUnits;
2518 double dyScaled = - yShift * mmToMapUnits;
2533 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2534 if ( annotations.isEmpty() )
2544 if ( !annotation || !annotation->isVisible() )
2548 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2551 drawAnnotation( annotation, rc );
2565 double itemX, itemY;
2568 QPointF mapPos = layoutMapPosForItem( annotation );
2577 context.
painter()->translate( itemX, itemY );
2580 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2581 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2583 annotation->
render( context );
2586QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2589 return QPointF( 0, 0 );
2598 if ( annotationCrs !=
crs() )
2605 t.transformInPlace( mapX, mapY, z );
2615void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2626void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2637bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2639 if ( mCurrentExportPart == NotLayered )
2657 return mCurrentExportPart == Layer;
2660 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2662 case OverviewMapExtent:
2663 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2668 case SelectionBoxes:
2669 return mCurrentExportPart == SelectionBoxes && isSelected();
2690 bool useDdXMin =
false;
2691 bool useDdXMax =
false;
2692 bool useDdYMin =
false;
2693 bool useDdYMax =
false;
2724 if ( newExtent != mExtent )
2730 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2731 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2733 if ( currentWidthHeightRatio < newWidthHeightRatio )
2736 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2737 double deltaHeight = newHeight - newExtent.
height();
2744 double newWidth = currentWidthHeightRatio * newExtent.
height();
2745 double deltaWidth = newWidth - newExtent.
width();
2750 mExtent = newExtent;
2760 newExtent = mExtent;
2763 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2767 if ( useDdXMin && !useDdXMax )
2773 else if ( !useDdXMin && useDdXMax )
2779 if ( useDdYMin && !useDdYMax )
2785 else if ( !useDdYMin && useDdYMax )
2792 if ( newExtent != mExtent )
2794 mExtent = newExtent;
2811void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2824void QgsLayoutItemMap::updateAtlasFeature()
2843 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2848 double originalScale = calc.
calculate( originalExtent, rect().width() );
2849 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2850 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2851 QVector<qreal> scales;
2853 if ( !
mLayout->reportContext().predefinedScales().empty() )
2854 scales =
mLayout->reportContext().predefinedScales();
2856 scales =
mLayout->renderContext().predefinedScales();
2858 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2861 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2862 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2865 xMin + originalExtent.
width(),
2866 yMin + originalExtent.
height() );
2870 double newScale = calc.
calculate( newExtent, rect().width() );
2871 newExtent.
scale( originalScale / newScale );
2876 double newWidth = originalExtent.
width();
2877 double newHeight = originalExtent.
height();
2878 for (
int i = 0; i < scales.size(); i++ )
2880 double ratio = scales[i] / originalScale;
2881 newWidth = originalExtent.
width() * ratio;
2882 newHeight = originalExtent.
height() * ratio;
2885 double xMin = geomCenterX - newWidth / 2.0;
2886 double yMin = geomCenterY - newHeight / 2.0;
2894 double newScale = calc.
calculate( newExtent, rect().width() );
2895 newExtent.
scale( scales[i] / newScale );
2905 else if ( mAtlasScalingMode ==
Auto )
2909 double geomRatio = bounds.
width() / bounds.
height();
2910 double mapRatio = originalExtent.
width() / originalExtent.
height();
2913 if ( geomRatio < mapRatio )
2916 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
2921 else if ( geomRatio > mapRatio )
2924 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
2930 const double evaluatedAtlasMargin =
atlasMargin();
2931 if ( evaluatedAtlasMargin > 0.0 )
2933 newExtent.
scale( 1 + evaluatedAtlasMargin );
2949 if ( mEvaluatedMapRotation != 0.0 )
2959 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
2960 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
2961 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
2962 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
2965 center.
x() + dx, center.
y() + dy );
2973void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
2976 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
2978 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
2982 mStagedRendererJob->start();
2998 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3004 return mClipToAtlasFeature;
3009 if (
enabled == mClipToAtlasFeature )
3012 mClipToAtlasFeature =
enabled;
3018 return mFeatureClippingType;
3023 if ( mFeatureClippingType == type )
3026 mFeatureClippingType = type;
3032 return mForceLabelsInsideFeature;
3037 if ( forceInside == mForceLabelsInsideFeature )
3040 mForceLabelsInsideFeature = forceInside;
3046 return mRestrictToLayers;
3051 if ( mRestrictToLayers ==
enabled )
3060 return _qgis_listRefToRaw( mLayersToClip );
3071 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3072 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3073 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3074 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3075 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3078 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3083 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3084 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3085 layerElem.appendChild( layerIdText );
3087 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3088 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3089 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3091 layerSetElem.appendChild( layerElem );
3093 settingsElem.appendChild( layerSetElem );
3095 element.appendChild( settingsElem );
3101 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3103 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3104 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3106 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3108 mLayersToClip.clear();
3109 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3110 if ( !layerSetNodeList.isEmpty() )
3112 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3113 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3114 mLayersToClip.reserve( layerIdNodeList.size() );
3115 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3117 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3118 QString layerId = layerElem.text();
3119 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3120 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3121 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3123 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3126 mLayersToClip << ref;
3133void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3135 if ( !mLayersToClip.isEmpty() )
3137 _qgis_removeLayers( mLayersToClip, layers );
3152 return mEnabled && mClipPathSource;
3167 if ( mClipPathSource )
3170 mClipPathSource->refresh();
3179 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3190 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3191 clipGeom.
transform( mMap->sceneTransform().inverted() );
3206 if ( mClipPathSource == item )
3209 if ( mClipPathSource )
3218 mClipPathSource = item;
3220 if ( mClipPathSource )
3229 mClipPathSource->refresh();
3243 return mClipPathSource;
3248 return mFeatureClippingType;
3253 if ( mFeatureClippingType == type )
3256 mFeatureClippingType = type;
3262 return mForceLabelsInsideClipPath;
3267 if ( forceInside == mForceLabelsInsideClipPath )
3270 mForceLabelsInsideClipPath = forceInside;
3276 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3277 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3278 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3279 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3280 if ( mClipPathSource )
3281 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3283 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3285 element.appendChild( settingsElem );
3291 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3293 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3294 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3296 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3303 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.
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.
friend class QgsLayoutItemMap
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void drawBackground(QgsRenderContext &context)
Draws the background for the item.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
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.
@ FlagDisableSceneCaching
Item should not have QGraphicsItem caching enabled.
virtual bool containsAdvancedEffects() const
Returns true if the item contains contents with blend modes or transparency effects which can only be...
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
QString id() const
Returns the item's ID name.
bool frameEnabled() const
Returns true if the item includes a frame.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ ItemContainsSubLayers
Item contains multiple sublayers which must be individually exported.
void clipPathChanged()
Emitted when the item's clipping path has changed.
bool hasBackground() const
Returns true if the item has a background.
void refresh() override
Refreshes the item, causing a recalculation of any property overrides and recalculation of its positi...
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
void backgroundTaskCountChanged(int count)
Emitted whenever the number of background tasks an item is executing changes.
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 (holding no spatial information).
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.
bool isEmpty() const
Returns true if the rectangle has no area.
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.