18#include "moc_qgslayoutitemmap.cpp"
44#include <QApplication>
47#include <QStyleOptionGraphicsItem>
55 mBackgroundUpdateTimer =
new QTimer(
this );
56 mBackgroundUpdateTimer->setSingleShot(
true );
57 connect( mBackgroundUpdateTimer, &QTimer::timeout,
this, &QgsLayoutItemMap::recreateCachedImageInBackground );
61 setCacheMode( QGraphicsItem::NoCache );
68 mGridStack = std::make_unique< QgsLayoutItemMapGridStack >(
this );
69 mOverviewStack = std::make_unique< QgsLayoutItemMapOverviewStack >(
this );
102 mPainterJob->cancel();
127 QList<QgsLayoutItemMap *> mapsList;
128 mLayout->layoutItems( mapsList );
137 if ( map->mMapId == mMapId )
140 maxId = std::max( maxId, map->mMapId );
145 mLayout->itemsModel()->updateItemDisplayName(
this );
157 return tr(
"Map %1" ).arg( mMapId );
169 mCachedLayerStyleOverridesPresetName.clear();
173 updateAtlasFeature();
178 if ( rect().isEmpty() )
183 calculator.
setDpi( 25.4 );
190 double currentScaleDenominator =
scale();
197 double scaleRatio = scaleDenominator / currentScaleDenominator;
198 mExtent.
scale( scaleRatio );
200 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
207 calculator.
setDpi( 25.4 );
208 const double newScale = calculator.
calculate( mExtent, rect().width() );
211 scaleRatio = scaleDenominator / newScale;
212 mExtent.
scale( scaleRatio );
239 const QRectF currentRect = rect();
240 const double newHeight = mExtent.
width() == 0 ? 0
241 : currentRect.width() * mExtent.
height() / mExtent.
width();
253 double currentWidthHeightRatio = 1.0;
254 if ( !currentExtent.
isEmpty() )
255 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
257 currentWidthHeightRatio = rect().width() / rect().height();
259 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
261 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
263 if ( currentWidthHeightRatio < newWidthHeightRatio )
266 double newHeight = newExtent.
width() / currentWidthHeightRatio;
267 double deltaHeight = newHeight - newExtent.
height();
274 double newWidth = currentWidthHeightRatio * newExtent.
height();
275 double deltaWidth = newWidth - newExtent.
width();
281 if ( mExtent == newExtent )
300QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
303 mapPolygon( mExtent, poly );
305 if ( includeClipping && mItemClippingSettings->
isActive() )
319 return calculateVisibleExtentPolygon(
true );
327 return mLayout->project()->crs();
342 return _qgis_listRefToRaw( mLayers );
347 mGroupLayers.clear();
349 QList<QgsMapLayer *> layersCopy {
layers };
354 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
356 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
358 auto existingIt = mGroupLayers.find( groupLayer->id() );
359 if ( existingIt != mGroupLayers.end( ) )
361 *it = ( *existingIt ).second.get();
365 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
366 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
367 *it = mGroupLayers[ groupLayer->id() ].get();
371 mLayers = _qgis_listRawToRef( layersCopy );
376 if ( overrides == mLayerStyleOverrides )
379 mLayerStyleOverrides = overrides;
386 mLayerStyleOverrides.clear();
393 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
400 if ( mFollowVisibilityPreset == follow )
403 mFollowVisibilityPreset = follow;
405 if ( !mFollowVisibilityPresetName.isEmpty() )
406 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
411 if ( name == mFollowVisibilityPresetName )
414 mFollowVisibilityPresetName = name;
415 if ( mFollowVisibilityPreset )
421 mLastRenderedImageOffsetX -= dx;
422 mLastRenderedImageOffsetY -= dy;
425 transformShift( dx, dy );
449 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
455 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
456 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
458 double newIntervalX, newIntervalY;
475 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
482 calculator.
setDpi( 25.4 );
483 const double newScale = calculator.
calculate( mExtent, rect().
width() );
486 const double scaleRatio =
scale() / newScale ;
487 mExtent.
scale( scaleRatio );
504 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
514 if (
blendMode() != QPainter::CompositionMode_SourceOver )
533 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]()->
bool
543 if ( mOverviewStack->containsAdvancedEffects() )
551 if ( mGridStack->containsAdvancedEffects() )
564 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
585 if ( mOverviewStack->containsAdvancedEffects() )
593 if ( mGridStack->containsAdvancedEffects() )
608 mMapRotation = rotation;
609 mEvaluatedMapRotation = mMapRotation;
622 mAtlasDriven = enabled;
639 double margin = mAtlasMargin;
647 margin = ddMargin / 100;
659 if ( mGridStack->size() < 1 )
662 mGridStack->addGrid(
grid );
664 return mGridStack->grid( 0 );
669 if ( mOverviewStack->size() < 1 )
672 mOverviewStack->addOverview(
overview );
674 return mOverviewStack->overview( 0 );
684 for (
int i = 0; i < mGridStack->size(); ++i )
687 if (
grid->mEvaluatedEnabled )
690 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
706 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
710 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
713 if ( mDrawAnnotations )
715 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
719 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
723 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
728 mapElem.appendChild( extentElem );
732 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
734 mapElem.appendChild( crsElem );
738 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
739 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
742 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
745 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
750 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
752 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
754 return groupLayer.second.get() == layerRef.get();
757 if ( it != mGroupLayers.end() )
763 layerId = layerRef.layerId;
766 QDomText layerIdText = doc.createTextNode( layerId );
767 layerElem.appendChild( layerIdText );
769 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
770 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
771 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
773 if ( it != mGroupLayers.end() )
775 const auto childLayers { it->second->childLayers() };
776 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
777 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
779 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
780 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
781 childLayersElement.appendChild( childElement );
783 layerElem.appendChild( childLayersElement );
785 layerSetElem.appendChild( layerElem );
787 mapElem.appendChild( layerSetElem );
790 if ( mKeepLayerStyles )
792 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
793 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
795 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
800 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
801 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
802 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
803 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
807 stylesElem.appendChild( styleElem );
809 mapElem.appendChild( stylesElem );
813 mGridStack->writeXml( mapElem, doc, context );
816 mOverviewStack->writeXml( mapElem, doc, context );
819 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
820 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
821 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
822 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
823 mapElem.appendChild( atlasElem );
825 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
826 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
828 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
829 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
834 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
835 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
836 labelBlockingItemsElem.appendChild( blockingItemElem );
838 mapElem.appendChild( labelBlockingItemsElem );
841 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
844 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
845 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
848 mapElem.setAttribute( QStringLiteral(
"enableZRange" ), mZRangeEnabled ? 1 : 0 );
849 if ( mZRange.
lower() != std::numeric_limits< double >::lowest() )
851 if ( mZRange.
upper() != std::numeric_limits< double >::max() )
854 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
855 mItemClippingSettings->
writeXml( mapElem, doc, context );
862 mUpdatesEnabled =
false;
865 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
866 if ( !extentNodeList.isEmpty() )
868 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
869 double xmin, xmax, ymin, ymax;
870 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
871 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
872 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
873 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
877 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
879 if ( !crsNodeList.isEmpty() )
881 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
887 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
888 mEvaluatedMapRotation = mMapRotation;
891 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
892 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
895 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
896 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
898 mKeepLayerSet =
true;
902 mKeepLayerSet =
false;
905 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
906 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
908 mDrawAnnotations =
true;
912 mDrawAnnotations =
false;
915 mLayerStyleOverrides.clear();
917 QList<QgsMapLayerRef> layerSet;
918 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
919 if ( !layerSetNodeList.isEmpty() )
921 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
922 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
923 layerSet.reserve( layerIdNodeList.size() );
924 for (
int i = 0; i < layerIdNodeList.size(); ++i )
926 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
927 QString layerId = layerElem.text();
928 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
929 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
930 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
932 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
940 setLayers( _qgis_listRefToRaw( layerSet ) );
943 if ( !layerSetNodeList.isEmpty() )
945 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
946 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
947 for (
int i = 0; i < layerIdNodeList.size(); ++i )
949 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
950 const QString layerId = layerElem.text();
951 const auto it = mGroupLayers.find( layerId );
952 if ( it != mGroupLayers.cend() )
954 QList<QgsMapLayerRef> childSet;
955 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
956 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
957 for (
int i = 0; i < children.size(); ++i )
959 const QDomElement childElement = children.at( i ).toElement();
960 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
962 if ( layerRef.resolveWeakly(
mLayout->project() ) )
964 childSet.push_back( layerRef );
967 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
974 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
975 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
976 if ( mKeepLayerStyles )
978 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
979 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
980 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
982 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
983 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
984 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
985 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
986 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
987 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
991 style.
readXml( layerStyleElement );
997 mNumCachedLayers = 0;
998 mCacheInvalidated =
true;
1001 mOverviewStack->readXml( itemElem, doc, context );
1004 mGridStack->readXml( itemElem, doc, context );
1007 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
1008 if ( !atlasNodeList.isEmpty() )
1010 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1011 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
1012 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
1014 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
1016 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1018 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1020 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1025 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1028 mBlockingLabelItems.clear();
1029 mBlockingLabelItemUuids.clear();
1030 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1031 if ( !labelBlockingNodeList.isEmpty() )
1033 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1034 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1035 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1037 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1038 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1039 mBlockingLabelItemUuids << itemUuid;
1043 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1044 mItemClippingSettings->
readXml( itemElem, doc, context );
1049 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1052 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1053 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1057 mZRangeEnabled = itemElem.attribute( QStringLiteral(
"enableZRange" ) ).toInt();
1059 double zLower = itemElem.attribute( QStringLiteral(
"zRangeLower" ) ).toDouble( &ok );
1062 zLower = std::numeric_limits< double >::lowest();
1064 double zUpper = itemElem.attribute( QStringLiteral(
"zRangeUpper" ) ).toDouble( &ok );
1067 zUpper = std::numeric_limits< double >::max();
1071 mUpdatesEnabled =
true;
1077 if ( mItemClippingSettings->
isActive() )
1088 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1097 QRectF thisPaintRect = rect();
1103 if (
mLayout->renderContext().isPreviewRender() )
1105 bool renderInProgress =
false;
1106 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1109 painter->setClipRect( thisPaintRect );
1110 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1113 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1114 painter->drawRect( thisPaintRect );
1115 painter->setBrush( Qt::NoBrush );
1117 messageFont.setPointSize( 12 );
1118 painter->setFont( messageFont );
1119 painter->setPen( QColor( 255, 255, 255, 255 ) );
1120 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1121 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1125 mBackgroundUpdateTimer->start( 1 );
1127 else if ( !mPainterJob && !mDrawingPreview )
1131 mBackgroundUpdateTimer->start( 1 );
1133 renderInProgress =
true;
1137 if ( mCacheInvalidated && !mDrawingPreview )
1141 mBackgroundUpdateTimer->start( 1 );
1142 renderInProgress =
true;
1147 double imagePixelWidth = mCacheFinalImage->width();
1148 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1152 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1153 painter->setCompositionMode( blendModeForRender() );
1155 painter->drawImage( 0, 0, *mCacheFinalImage );
1160 painter->setClipRect( thisPaintRect, Qt::NoClip );
1162 mOverviewStack->drawItems( painter,
false );
1163 mGridStack->drawItems( painter );
1165 drawMapFrame( painter );
1167 if ( renderInProgress )
1178 QPaintDevice *paintDevice = painter->device();
1186 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1194 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1195 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1196 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1198 image.fill( Qt::transparent );
1199 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1200 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1201 double dotsPerMM = destinationDpi / 25.4;
1202 QPainter p( &image );
1205 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1206 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1207 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1208 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1209 p.setClipRect( imagePaintRect );
1211 p.translate( imagePaintRect.topLeft() );
1215 if ( shouldDrawPart( Background ) )
1217 p.scale( dotsPerMM, dotsPerMM );
1218 drawMapBackground( &p );
1219 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1222 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1227 p.scale( dotsPerMM, dotsPerMM );
1229 if ( shouldDrawPart( OverviewMapExtent ) )
1231 mOverviewStack->drawItems( &p,
false );
1233 if ( shouldDrawPart( Grid ) )
1235 mGridStack->drawItems( &p );
1240 painter->setCompositionMode( blendModeForRender() );
1241 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1242 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1243 painter->scale( dotsPerMM, dotsPerMM );
1248 if ( shouldDrawPart( Background ) )
1250 drawMapBackground( painter );
1254 painter->setClipRect( thisPaintRect );
1259 painter->translate( mXOffset, mYOffset );
1261 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1263 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1265 if ( mCurrentExportPart != NotLayered )
1267 if ( !mStagedRendererJob )
1269 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1272 mStagedRendererJob->renderCurrentPart( painter );
1276 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1280 painter->setClipRect( thisPaintRect, Qt::NoClip );
1282 if ( shouldDrawPart( OverviewMapExtent ) )
1284 mOverviewStack->drawItems( painter,
false );
1286 if ( shouldDrawPart( Grid ) )
1288 mGridStack->drawItems( painter );
1293 if ( shouldDrawPart( Frame ) )
1295 drawMapFrame( painter );
1306 + ( layerCount + ( layerCount ? 1 : 0 ) )
1307 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1308 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1314 mCurrentExportPart = Start;
1316 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1317 mExportThemeIt = mExportThemes.begin();
1322 mCurrentExportPart = NotLayered;
1323 mExportThemes.clear();
1324 mExportThemeIt = mExportThemes.begin();
1329 switch ( mCurrentExportPart )
1334 mCurrentExportPart = Background;
1340 mCurrentExportPart = Layer;
1344 if ( mStagedRendererJob )
1346 if ( mStagedRendererJob->nextPart() )
1350 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1351 mStagedRendererJob.reset();
1355 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1361 if ( mGridStack->hasEnabledItems() )
1363 mCurrentExportPart = Grid;
1369 for (
int i = 0; i < mOverviewStack->size(); ++i )
1374 mCurrentExportPart = OverviewMapExtent;
1380 case OverviewMapExtent:
1383 mCurrentExportPart = Frame;
1390 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1392 mCurrentExportPart = SelectionBoxes;
1397 case SelectionBoxes:
1398 mCurrentExportPart = End;
1419 switch ( mCurrentExportPart )
1429 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1432 if ( mStagedRendererJob )
1434 switch ( mStagedRendererJob->currentStage() )
1438 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1439 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1440 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1446 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1448 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1454 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1459 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1465 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1468 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1470 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1479 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1485 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1520 case OverviewMapExtent:
1528 case SelectionBoxes:
1543void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1557 if ( shouldDrawPart( OverviewMapExtent ) )
1559 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1563#ifdef HAVE_SERVER_PYTHON_PLUGINS
1564 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1570 job.renderSynchronously();
1572 mExportLabelingResults.reset( job.takeLabelingResults() );
1574 mRenderingErrors = job.errors();
1577void QgsLayoutItemMap::recreateCachedImageInBackground()
1583 QPainter *oldPainter = mPainter.release();
1584 QImage *oldImage = mCacheRenderingImage.release();
1587 oldJob->deleteLater();
1595 mCacheRenderingImage.reset(
nullptr );
1599 Q_ASSERT( !mPainterJob );
1600 Q_ASSERT( !mPainter );
1601 Q_ASSERT( !mCacheRenderingImage );
1607 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1608 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1611 if ( w > 5000 || h > 5000 )
1616 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1621 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1625 if ( w <= 0 || h <= 0 )
1628 mCacheRenderingImage.reset(
new QImage( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 ) );
1631 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1632 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1633 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1636 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1641 if ( mItemClippingSettings->
isActive() )
1643 QPainter p( mCacheRenderingImage.get() );
1645 p.setPen( Qt::NoPen );
1647 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1657 mCacheInvalidated =
false;
1658 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1661 if ( shouldDrawPart( OverviewMapExtent ) )
1663 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1668 mPainterJob->start();
1680 mDrawingPreview =
false;
1703 if (
layout()->renderContext().isPreviewRender() )
1706 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1709 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1716 if ( includeLayerSettings )
1721 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1724 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1731 if ( !
mLayout->renderContext().isPreviewRender() )
1776 if ( mEvaluatedLabelMargin.
length() > 0 )
1779 visiblePoly.append( visiblePoly.at( 0 ) );
1780 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1781 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1783 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1784 labelBoundary = mapBoundaryGeom;
1787 if ( !mBlockingLabelItems.isEmpty() )
1800 if ( mZRangeEnabled )
1805 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1816 if ( !labelBoundary.
isEmpty() )
1818 labelBoundary = clipGeom.
intersection( labelBoundary );
1822 labelBoundary = clipGeom;
1827 if ( mItemClippingSettings->
isActive() )
1836 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1837 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1839 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1840 if ( !labelBoundary.
isEmpty() )
1842 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1846 labelBoundary = mapBoundaryGeom;
1852 if ( !labelBoundary.
isNull() )
1855 return jobMapSettings;
1862 mBlockingLabelItems.clear();
1863 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1872 mOverviewStack->finalizeRestoreFromXml();
1873 mGridStack->finalizeRestoreFromXml();
1885 return mCurrentRectangle;
1899 const double mapScale =
scale();
1923 QVariantList layersIds;
1933 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1935 layersIds.reserve( layersInMap.count() );
1936 layers.reserve( layersInMap.count() );
1939 layersIds << layer->id();
1945 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1967 if ( extentWidth <= 0 )
1971 return rect().width() / extentWidth;
1976 double dx = mXOffset;
1977 double dy = mYOffset;
1978 transformShift( dx, dy );
1979 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1980 poly.translate( -dx, -dy );
1986 if ( !mBlockingLabelItems.contains( item ) )
1987 mBlockingLabelItems.append( item );
1994 mBlockingLabelItems.removeAll( item );
2001 return mBlockingLabelItems.contains( item );
2006 return mPreviewLabelingResults.get();
2015 if ( mOverviewStack )
2017 for (
int i = 0; i < mOverviewStack->size(); ++i )
2019 if ( mOverviewStack->item( i )->accept( visitor ) )
2026 for (
int i = 0; i < mGridStack->size(); ++i )
2028 if ( mGridStack->item( i )->accept( visitor ) )
2041 mRenderedFeatureHandlers.append( handler );
2046 mRenderedFeatureHandlers.removeAll( handler );
2052 if ( mapPoly.empty() )
2054 return QPointF( 0, 0 );
2059 double dx = mapCoords.x() - rotationPoint.
x();
2060 double dy = mapCoords.y() - rotationPoint.
y();
2062 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2065 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2066 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2067 return QPointF( xItem, yItem );
2081 mapPolygon( newExtent, poly );
2082 QRectF bRect = poly.boundingRect();
2096 mCacheInvalidated =
true;
2102 QRectF rectangle = rect();
2103 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2105 double topExtension = 0.0;
2106 double rightExtension = 0.0;
2107 double bottomExtension = 0.0;
2108 double leftExtension = 0.0;
2111 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2113 topExtension = std::max( topExtension, frameExtension );
2114 rightExtension = std::max( rightExtension, frameExtension );
2115 bottomExtension = std::max( bottomExtension, frameExtension );
2116 leftExtension = std::max( leftExtension, frameExtension );
2118 rectangle.setLeft( rectangle.left() - leftExtension );
2119 rectangle.setRight( rectangle.right() + rightExtension );
2120 rectangle.setTop( rectangle.top() - topExtension );
2121 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2122 if ( rectangle != mCurrentRectangle )
2124 prepareGeometryChange();
2125 mCurrentRectangle = rectangle;
2153 refreshMapExtents( &context );
2155 if ( mExtent != beforeExtent )
2162 refreshLabelMargin(
false );
2166 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2168 if ( mLastEvaluatedThemeName != previousTheme )
2187 double zLower = mZRange.
lower();
2188 double zUpper = mZRange.
upper();
2199 mCacheInvalidated =
true;
2204void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2207 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2211 mLayerStyleOverrides.remove( layer->id() );
2213 _qgis_removeLayers( mLayers,
layers );
2219 if ( mGroupLayers.erase( layer->id() ) == 0 )
2222 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2225 if ( groupLayer->
childLayers().contains( layer ) )
2227 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2228 childLayers.removeAll( layer );
2236void QgsLayoutItemMap::painterJobFinished()
2239 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2240 mPainterJob.reset(
nullptr );
2241 mPainter.reset(
nullptr );
2242 mCacheFinalImage = std::move( mCacheRenderingImage );
2243 mLastRenderedImageOffsetX = 0;
2244 mLastRenderedImageOffsetY = 0;
2250void QgsLayoutItemMap::shapeChanged()
2255 double w = rect().width();
2256 double h = rect().height();
2259 double newWidth = mExtent.
width();
2261 double newHeight = newWidth * h / w;
2266 refreshMapExtents();
2273void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2275 if ( theme == mCachedLayerStyleOverridesPresetName )
2276 mCachedLayerStyleOverridesPresetName.clear();
2279void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2281 if ( theme == mFollowVisibilityPresetName )
2283 mFollowVisibilityPresetName = newTheme;
2287void QgsLayoutItemMap::connectUpdateSlot()
2295 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2299 if ( layers().isEmpty() )
2328 if ( mAtlasScalingMode == Predefined )
2329 updateAtlasFeature();
2335 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2336 QTransform mapTransform;
2337 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2339 thisRectPoly.pop_back();
2340 thisExtent.pop_back();
2342 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2345 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2346 return mapTransform;
2351 mZRangeEnabled = enabled;
2356 return mZRangeEnabled;
2369QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2372 QList< QgsLabelBlockingRegion > blockers;
2373 blockers.reserve( mBlockingLabelItems.count() );
2374 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2381 if ( item->property(
"wasVisible" ).isValid() )
2383 if ( !item->property(
"wasVisible" ).toBool() )
2386 else if ( !item->isVisible() )
2389 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2390 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2399 return mLabelMargin;
2404 mLabelMargin = margin;
2405 refreshLabelMargin(
false );
2408void QgsLayoutItemMap::updateToolTip()
2417 if ( mFollowVisibilityPreset )
2419 presetName = mFollowVisibilityPresetName;
2423 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2424 presetName = *mExportThemeIt;
2435 QList<QgsMapLayer *> renderLayers;
2437 QString presetName = themeToRender( *evalContext );
2438 if ( !presetName.isEmpty() )
2440 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2441 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2443 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2445 else if ( !
layers().isEmpty() )
2451 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2458 renderLayers.clear();
2460 const QStringList layerNames = ddLayers.split(
'|' );
2462 for (
const QString &name : layerNames )
2464 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2467 renderLayers << layer;
2476 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2477 if ( removeAt != -1 )
2479 renderLayers.removeAt( removeAt );
2484 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2486 return !layer || !layer->isValid();
2487 } ), renderLayers.end() );
2489 return renderLayers;
2492QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2494 QString presetName = themeToRender( context );
2495 if ( !presetName.isEmpty() )
2497 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2499 if ( presetName != mCachedLayerStyleOverridesPresetName )
2502 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2503 mCachedLayerStyleOverridesPresetName = presetName;
2506 return mCachedPresetLayerStyleOverrides;
2509 return QMap<QString, QString>();
2511 else if ( mFollowVisibilityPreset )
2513 QString presetName = mFollowVisibilityPresetName;
2516 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2518 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2521 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2522 mCachedLayerStyleOverridesPresetName = presetName;
2525 return mCachedPresetLayerStyleOverrides;
2528 return QMap<QString, QString>();
2530 else if ( mKeepLayerStyles )
2532 return mLayerStyleOverrides;
2536 return QMap<QString, QString>();
2540QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2542 double dx = mXOffset;
2543 double dy = mYOffset;
2544 transformShift( dx, dy );
2548void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2558 poly << QPointF( poly.at( 0 ) );
2570 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2576 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2582 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2588 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2591 poly << QPointF( poly.at( 0 ) );
2594void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2597 double dxScaled = xShift * mmToMapUnits;
2598 double dyScaled = - yShift * mmToMapUnits;
2613 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2614 if ( annotations.isEmpty() )
2624 if ( !annotation || !annotation->isVisible() )
2628 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2631 drawAnnotation( annotation, rc );
2645 double itemX, itemY;
2648 QPointF mapPos = layoutMapPosForItem( annotation );
2657 context.
painter()->translate( itemX, itemY );
2660 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2661 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2663 annotation->
render( context );
2666QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2669 return QPointF( 0, 0 );
2678 if ( annotationCrs !=
crs() )
2685 t.transformInPlace( mapX, mapY, z );
2695void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2706void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2717bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2719 if ( mCurrentExportPart == NotLayered )
2737 return mCurrentExportPart == Layer;
2740 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2742 case OverviewMapExtent:
2743 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2748 case SelectionBoxes:
2749 return mCurrentExportPart == SelectionBoxes && isSelected();
2770 bool useDdXMin =
false;
2771 bool useDdXMax =
false;
2772 bool useDdYMin =
false;
2773 bool useDdYMax =
false;
2804 if ( newExtent != mExtent )
2810 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2811 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2813 if ( currentWidthHeightRatio < newWidthHeightRatio )
2816 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2817 double deltaHeight = newHeight - newExtent.
height();
2824 double newWidth = currentWidthHeightRatio * newExtent.
height();
2825 double deltaWidth = newWidth - newExtent.
width();
2830 mExtent = newExtent;
2840 newExtent = mExtent;
2843 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2847 if ( useDdXMin && !useDdXMax )
2853 else if ( !useDdXMin && useDdXMax )
2859 if ( useDdYMin && !useDdYMax )
2865 else if ( !useDdYMin && useDdYMax )
2872 if ( newExtent != mExtent )
2874 mExtent = newExtent;
2891void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2904void QgsLayoutItemMap::updateAtlasFeature()
2923 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2928 double originalScale = calc.
calculate( originalExtent, rect().width() );
2929 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2930 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2931 QVector<qreal> scales;
2933 if ( !
mLayout->reportContext().predefinedScales().empty() )
2934 scales =
mLayout->reportContext().predefinedScales();
2936 scales =
mLayout->renderContext().predefinedScales();
2938 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2941 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2942 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2945 xMin + originalExtent.
width(),
2946 yMin + originalExtent.
height() );
2950 double newScale = calc.
calculate( newExtent, rect().width() );
2951 newExtent.
scale( originalScale / newScale );
2956 double newWidth = originalExtent.
width();
2957 double newHeight = originalExtent.
height();
2958 for (
int i = 0; i < scales.size(); i++ )
2960 double ratio = scales[i] / originalScale;
2961 newWidth = originalExtent.
width() * ratio;
2962 newHeight = originalExtent.
height() * ratio;
2965 double xMin = geomCenterX - newWidth / 2.0;
2966 double yMin = geomCenterY - newHeight / 2.0;
2974 const double newScale = calc.
calculate( newExtent, rect().width() );
2978 newExtent.
scale( scales[i] / newScale );
2988 else if ( mAtlasScalingMode ==
Auto )
2992 double geomRatio = bounds.
width() / bounds.
height();
2993 double mapRatio = originalExtent.
width() / originalExtent.
height();
2996 if ( geomRatio < mapRatio )
2999 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
3004 else if ( geomRatio > mapRatio )
3007 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
3013 const double evaluatedAtlasMargin =
atlasMargin();
3014 if ( evaluatedAtlasMargin > 0.0 )
3016 newExtent.
scale( 1 + evaluatedAtlasMargin );
3042 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
3043 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3044 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
3045 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3048 center.
x() + dx, center.
y() + dy );
3056void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3059 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3061 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
3065 mStagedRendererJob->start();
3081 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3087 return mClipToAtlasFeature;
3092 if (
enabled == mClipToAtlasFeature )
3095 mClipToAtlasFeature =
enabled;
3101 return mFeatureClippingType;
3106 if ( mFeatureClippingType == type )
3109 mFeatureClippingType = type;
3115 return mForceLabelsInsideFeature;
3120 if ( forceInside == mForceLabelsInsideFeature )
3123 mForceLabelsInsideFeature = forceInside;
3129 return mRestrictToLayers;
3134 if ( mRestrictToLayers ==
enabled )
3143 return _qgis_listRefToRaw( mLayersToClip );
3154 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3155 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3156 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3157 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3158 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3161 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3166 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3167 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3168 layerElem.appendChild( layerIdText );
3170 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3171 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3172 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3174 layerSetElem.appendChild( layerElem );
3176 settingsElem.appendChild( layerSetElem );
3178 element.appendChild( settingsElem );
3184 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3186 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3187 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3189 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3191 mLayersToClip.clear();
3192 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3193 if ( !layerSetNodeList.isEmpty() )
3195 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3196 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3197 mLayersToClip.reserve( layerIdNodeList.size() );
3198 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3200 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3201 QString layerId = layerElem.text();
3202 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3203 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3204 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3206 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3209 mLayersToClip << ref;
3216void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3218 if ( !mLayersToClip.isEmpty() )
3220 _qgis_removeLayers( mLayersToClip, layers );
3235 return mEnabled && mClipPathSource;
3250 if ( mClipPathSource )
3253 mClipPathSource->refresh();
3262 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3273 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3274 clipGeom.
transform( mMap->sceneTransform().inverted() );
3289 if ( mClipPathSource == item )
3292 if ( mClipPathSource )
3301 mClipPathSource = item;
3303 if ( mClipPathSource )
3312 mClipPathSource->refresh();
3326 return mClipPathSource;
3331 return mFeatureClippingType;
3336 if ( mFeatureClippingType == type )
3339 mFeatureClippingType = type;
3345 return mForceLabelsInsideClipPath;
3350 if ( forceInside == mForceLabelsInsideClipPath )
3353 mForceLabelsInsideClipPath = forceInside;
3359 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3360 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3361 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3362 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3363 if ( mClipPathSource )
3364 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3366 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3368 element.appendChild( settingsElem );
3374 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3376 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3377 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3379 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3386 if ( !mClipPathUuid.isEmpty() )
QFlags< VectorRenderingSimplificationFlag > VectorRenderingSimplificationFlags
Simplification flags for vector feature rendering.
@ Millimeters
Millimeters.
@ NoSimplification
No simplification can be applied.
@ CollectUnplacedLabels
Whether unplaced labels should be collected in the labeling results (regardless of whether they are b...
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
@ UsePartialCandidates
Whether to use also label candidates that are partially outside of the map view.
@ Export
Renderer used for printing or exporting to a file.
@ View
Renderer used for displaying on screen.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
@ DrawEditingInfo
Enable drawing of vertex markers for layers in editing mode.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ 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...
@ AlwaysUseGlobalMasks
When applying clipping paths for selective masking, always use global ("entire map") paths,...
@ DrawSelection
Whether vector selections should be shown in the rendered map.
@ Antialiasing
Enable anti-aliasing for map rendering.
@ 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.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
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.
QgsRange which stores a range of double values.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
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 refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties) override
void preparedForAtlas()
Emitted when the map has been prepared for atlas rendering, just before actual rendering.
void setFollowVisibilityPresetName(const QString &name)
Sets preset name for map rendering.
QTransform layoutToMapCoordsTransform() const
Creates a transform from layout coordinates to map coordinates.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
bool isLabelBlockingItem(QgsLayoutItem *item) const
Returns true if the specified item is a "label blocking item".
void storeCurrentLayerStyles()
Stores the current project layer styles into style overrides.
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
QgsLayoutMeasurement labelMargin() const
Returns the margin from the map edges in which no labels may be placed.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
@ Predefined
A scale is chosen from the predefined scales.
@ Auto
The extent is adjusted so that each feature is fully visible.
@ Fixed
The current scale of the map is used for each feature of the atlas.
bool requiresRasterization() const override
Returns true if the item is drawn in such a way that forces the whole layout to be rasterized when ex...
Q_DECL_DEPRECATED int numberExportLayers() const override
void layerStyleOverridesChanged()
Emitted when layer style overrides are changed... a means to let associated legend items know they sh...
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void moveContent(double dx, double dy) override
Moves the content of the item, by a specified dx and dy in layout units.
void setZRangeEnabled(bool enabled)
Sets whether the z range is enabled (i.e.
QgsLayoutItemMapGrid * grid()
Returns the map item's first grid.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
int type() const override
void previewRefreshed()
Emitted whenever the item's map preview has been refreshed.
friend class QgsLayoutItemMapOverview
void setExtent(const QgsRectangle &extent)
Sets a new extent for the map.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
QFlags< MapItemFlag > MapItemFlags
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
QPolygonF visibleExtentPolygon() const
Returns a polygon representing the current visible map extent, considering map extents and rotation.
QgsRectangle requestedExtent() const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
void setMapFlags(QgsLayoutItemMap::MapItemFlags flags)
Sets the map item's flags, which control how the map content is drawn.
void zoomContent(double factor, QPointF point) override
Zooms content of item.
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 setZRange(const QgsDoubleRange &range)
Sets the map's z range, which is used to filter the map's content to only display features within the...
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for layers.
void stopLayeredExport() override
Stops a multi-layer export operation.
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map.
double estimatedFrameBleed() const override
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainterPath framePath() const override
Returns the path to use when drawing the item's frame or background.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void startLayeredExport() override
Starts a multi-layer export operation.
bool containsWmsLayer() const
Returns true if the map contains a WMS layer.
void setScale(double scale, bool forceUpdate=true)
Sets new map scale and changes only the map extent.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
double mapUnitsToLayoutUnits() const
Returns the conversion factor from map units to layout units.
QgsLayoutItemMap::MapItemFlags mapFlags() const
Returns the map item's flags, which control how the map content is drawn.
bool zRangeEnabled() const
Returns whether the z range is enabled (i.e.
void setLabelMargin(const QgsLayoutMeasurement &margin)
Sets the margin from the map edges in which no labels may be placed.
void themeChanged(const QString &theme)
Emitted when the map's associated theme is changed.
QgsLayoutItem::ExportLayerDetail exportLayerDetails() const override
Returns the details for the specified current export layer.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
double scale() const
Returns the map scale.
@ ShowPartialLabels
Whether to draw labels which are partially outside of the map view.
@ ShowUnplacedLabels
Whether to render unplaced labels in the map view.
bool drawAnnotations() const
Returns whether annotations are drawn within the map.
QgsDoubleRange zRange() const
Returns the map's z range, which is used to filter the map's content to only display features within ...
void removeLabelBlockingItem(QgsLayoutItem *item)
Removes the specified layout item from the map's "label blocking items".
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the map's preset crs (coordinate reference system).
void invalidateCache() override
QgsRectangle extent() const
Returns the current map extent.
QgsLayoutItemMapOverview * overview()
Returns the map item's first overview.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setFrameStrokeWidth(QgsLayoutMeasurement width) override
Sets the frame stroke width.
bool containsAdvancedEffects() const override
Returns true if the item contains contents with blend modes or transparency effects which can only be...
friend class QgsLayoutItemMapGrid
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
void setMoveContentPreviewOffset(double dx, double dy) override
Sets temporary offset for the item, by a specified dx and dy in layout units.
void setMapRotation(double rotation)
Sets the rotation for the map - this does not affect the layout item shape, only the way the map is d...
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
double atlasMargin(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue)
Returns the margin size (percentage) used when the map is in atlas mode.
void addLabelBlockingItem(QgsLayoutItem *item)
Sets the specified layout item as a "label blocking item" for this map.
void assignFreeId()
Sets the map id() to a number not yet used in the layout.
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
QgsLabelingResults * previewLabelingResults() const
Returns the labeling results of the most recent preview map render.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Base class for graphical items within a QgsLayout.
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
virtual QPainterPath framePath() const
Returns the path to use when drawing the item's frame or background.
QColor backgroundColor(bool useDataDefined=true) const
Returns the background color for this item.
void drawRefreshingOverlay(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle)
Draws a "refreshing" overlay icon on the item.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
void rotationChanged(double newRotation)
Emitted on item rotation change.
friend class QgsLayoutItemMap
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void drawBackground(QgsRenderContext &context)
Draws the background for the item.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
@ FlagOverridesPaint
Item overrides the default layout item painting method.
@ FlagDisableSceneCaching
Item should not have QGraphicsItem caching enabled.
virtual bool containsAdvancedEffects() const
Returns true if the item contains contents with blend modes or transparency effects which can only be...
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
QString id() const
Returns the item's ID name.
bool frameEnabled() const
Returns true if the item includes a frame.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ ItemContainsSubLayers
Item contains multiple sublayers which must be individually exported.
void clipPathChanged()
Emitted when the item's clipping path has changed.
bool hasBackground() const
Returns true if the item has a background.
void refresh() override
Refreshes the item, causing a recalculation of any property overrides and recalculation of its positi...
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
void backgroundTaskCountChanged(int count)
Emitted whenever the number of background tasks an item is executing changes.
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.
@ MapZRangeUpper
Map frame Z-range lower value.
@ StartDateTime
Temporal range's start DateTime.
@ MapLayers
Map layer set.
@ MapZRangeLower
Map frame Z-range lower value.
@ MapRotation
Map rotation.
@ MapXMax
Map extent x maximum.
@ MapStylePreset
Layer and style map theme.
@ MapYMax
Map extent y maximum.
@ MapAtlasMargin
Map atlas margin.
@ EndDateTime
Temporal range's end DateTime.
@ MapXMin
Map extent x minimum.
@ MapLabelMargin
Map label margin.
@ AllProperties
All properties for item.
PropertyValueType
Specifies whether the value returned by a function should be the original, user set value,...
@ EvaluatedValue
Return the current evaluated value for the property.
void predefinedScalesChanged()
Emitted when the list of predefined scales changes.
@ FlagRenderLabelsByMapLayer
When rendering map items to multi-layered exports, render labels belonging to different layers into s...
@ FlagAlwaysUseGlobalMasks
When applying clipping paths for selective masking, always use global ("entire map") paths,...
@ 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.
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.
void setDevicePixelRatio(float dpr)
Sets the device pixel ratio.
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which will be visible in the map.
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 setMaskSettings(const QgsMaskRenderSettings &settings)
Sets the mask render settings, which control how masks are drawn and behave during the map render.
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
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.
T lower() const
Returns the lower bound of the range.
T upper() const
Returns the upper bound of the range.
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.
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
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.
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.