43#include <QApplication>
46#include <QStyleOptionGraphicsItem>
54 mBackgroundUpdateTimer =
new QTimer(
this );
55 mBackgroundUpdateTimer->setSingleShot(
true );
56 connect( mBackgroundUpdateTimer, &QTimer::timeout,
this, &QgsLayoutItemMap::recreateCachedImageInBackground );
60 setCacheMode( QGraphicsItem::NoCache );
67 mGridStack = std::make_unique< QgsLayoutItemMapGridStack >(
this );
68 mOverviewStack = std::make_unique< QgsLayoutItemMapOverviewStack >(
this );
101 mPainterJob->cancel();
126 QList<QgsLayoutItemMap *> mapsList;
127 mLayout->layoutItems( mapsList );
136 if ( map->mMapId == mMapId )
139 maxId = std::max( maxId, map->mMapId );
144 mLayout->itemsModel()->updateItemDisplayName(
this );
156 return tr(
"Map %1" ).arg( mMapId );
168 mCachedLayerStyleOverridesPresetName.clear();
172 updateAtlasFeature();
177 if ( rect().isEmpty() )
182 calculator.
setDpi( 25.4 );
189 double currentScaleDenominator =
scale();
196 double scaleRatio = scaleDenominator / currentScaleDenominator;
197 mExtent.
scale( scaleRatio );
199 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
206 calculator.
setDpi( 25.4 );
207 scaleRatio = scaleDenominator / calculator.
calculate( mExtent, rect().width() );
208 mExtent.
scale( scaleRatio );
234 const QRectF currentRect = rect();
235 const double newHeight = mExtent.
width() == 0 ? 0
236 : currentRect.width() * mExtent.
height() / mExtent.
width();
248 double currentWidthHeightRatio = 1.0;
249 if ( !currentExtent.
isEmpty() )
250 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
252 currentWidthHeightRatio = rect().width() / rect().height();
254 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
256 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
258 if ( currentWidthHeightRatio < newWidthHeightRatio )
261 double newHeight = newExtent.
width() / currentWidthHeightRatio;
262 double deltaHeight = newHeight - newExtent.
height();
269 double newWidth = currentWidthHeightRatio * newExtent.
height();
270 double deltaWidth = newWidth - newExtent.
width();
276 if ( mExtent == newExtent )
295QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
298 mapPolygon( mExtent, poly );
300 if ( includeClipping && mItemClippingSettings->
isActive() )
314 return calculateVisibleExtentPolygon(
true );
322 return mLayout->project()->crs();
337 return _qgis_listRefToRaw( mLayers );
342 mGroupLayers.clear();
344 QList<QgsMapLayer *> layersCopy {
layers };
349 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
351 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
353 auto existingIt = mGroupLayers.find( groupLayer->id() );
354 if ( existingIt != mGroupLayers.end( ) )
356 *it = ( *existingIt ).second.get();
360 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
361 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
362 *it = mGroupLayers[ groupLayer->id() ].get();
366 mLayers = _qgis_listRawToRef( layersCopy );
371 if ( overrides == mLayerStyleOverrides )
374 mLayerStyleOverrides = overrides;
381 mLayerStyleOverrides.clear();
388 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
395 if ( mFollowVisibilityPreset == follow )
398 mFollowVisibilityPreset = follow;
400 if ( !mFollowVisibilityPresetName.isEmpty() )
401 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
406 if ( name == mFollowVisibilityPresetName )
409 mFollowVisibilityPresetName = name;
410 if ( mFollowVisibilityPreset )
416 mLastRenderedImageOffsetX -= dx;
417 mLastRenderedImageOffsetY -= dy;
420 transformShift( dx, dy );
444 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
450 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
451 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
453 double newIntervalX, newIntervalY;
470 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
477 calculator.
setDpi( 25.4 );
478 double scaleRatio =
scale() / calculator.
calculate( mExtent, rect().width() );
479 mExtent.
scale( scaleRatio );
495 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
505 if (
blendMode() != QPainter::CompositionMode_SourceOver )
524 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]()->
bool
534 if ( mOverviewStack->containsAdvancedEffects() )
542 if ( mGridStack->containsAdvancedEffects() )
555 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
576 if ( mOverviewStack->containsAdvancedEffects() )
584 if ( mGridStack->containsAdvancedEffects() )
599 mMapRotation = rotation;
600 mEvaluatedMapRotation = mMapRotation;
613 mAtlasDriven = enabled;
630 double margin = mAtlasMargin;
638 margin = ddMargin / 100;
650 if ( mGridStack->size() < 1 )
653 mGridStack->addGrid(
grid );
655 return mGridStack->grid( 0 );
660 if ( mOverviewStack->size() < 1 )
663 mOverviewStack->addOverview(
overview );
665 return mOverviewStack->overview( 0 );
675 for (
int i = 0; i < mGridStack->size(); ++i )
678 if (
grid->mEvaluatedEnabled )
681 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
697 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
701 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
704 if ( mDrawAnnotations )
706 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
710 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
714 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
719 mapElem.appendChild( extentElem );
723 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
725 mapElem.appendChild( crsElem );
729 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
730 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
733 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
736 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
741 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
743 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
745 return groupLayer.second.get() == layerRef.get();
748 if ( it != mGroupLayers.end() )
754 layerId = layerRef.layerId;
757 QDomText layerIdText = doc.createTextNode( layerId );
758 layerElem.appendChild( layerIdText );
760 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
761 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
762 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
764 if ( it != mGroupLayers.end() )
766 const auto childLayers { it->second->childLayers() };
767 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
768 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
770 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
771 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
772 childLayersElement.appendChild( childElement );
774 layerElem.appendChild( childLayersElement );
776 layerSetElem.appendChild( layerElem );
778 mapElem.appendChild( layerSetElem );
781 if ( mKeepLayerStyles )
783 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
784 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
786 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
791 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
792 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
793 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
794 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
798 stylesElem.appendChild( styleElem );
800 mapElem.appendChild( stylesElem );
804 mGridStack->writeXml( mapElem, doc, context );
807 mOverviewStack->writeXml( mapElem, doc, context );
810 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
811 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
812 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
813 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
814 mapElem.appendChild( atlasElem );
816 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
817 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
819 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
820 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
825 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
826 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
827 labelBlockingItemsElem.appendChild( blockingItemElem );
829 mapElem.appendChild( labelBlockingItemsElem );
832 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
835 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
836 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
839 mapElem.setAttribute( QStringLiteral(
"enableZRange" ), mZRangeEnabled ? 1 : 0 );
840 if ( mZRange.
lower() != std::numeric_limits< double >::lowest() )
842 if ( mZRange.
upper() != std::numeric_limits< double >::max() )
845 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
846 mItemClippingSettings->
writeXml( mapElem, doc, context );
853 mUpdatesEnabled =
false;
856 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
857 if ( !extentNodeList.isEmpty() )
859 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
860 double xmin, xmax, ymin, ymax;
861 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
862 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
863 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
864 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
868 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
870 if ( !crsNodeList.isEmpty() )
872 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
878 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
879 mEvaluatedMapRotation = mMapRotation;
882 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
883 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
886 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
887 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
889 mKeepLayerSet =
true;
893 mKeepLayerSet =
false;
896 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
897 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
899 mDrawAnnotations =
true;
903 mDrawAnnotations =
false;
906 mLayerStyleOverrides.clear();
908 QList<QgsMapLayerRef> layerSet;
909 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
910 if ( !layerSetNodeList.isEmpty() )
912 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
913 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
914 layerSet.reserve( layerIdNodeList.size() );
915 for (
int i = 0; i < layerIdNodeList.size(); ++i )
917 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
918 QString layerId = layerElem.text();
919 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
920 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
921 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
923 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
931 setLayers( _qgis_listRefToRaw( layerSet ) );
934 if ( !layerSetNodeList.isEmpty() )
936 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
937 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
938 for (
int i = 0; i < layerIdNodeList.size(); ++i )
940 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
941 const QString layerId = layerElem.text();
942 const auto it = mGroupLayers.find( layerId );
943 if ( it != mGroupLayers.cend() )
945 QList<QgsMapLayerRef> childSet;
946 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
947 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
948 for (
int i = 0; i < children.size(); ++i )
950 const QDomElement childElement = children.at( i ).toElement();
951 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
953 if ( layerRef.resolveWeakly(
mLayout->project() ) )
955 childSet.push_back( layerRef );
958 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
965 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
966 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
967 if ( mKeepLayerStyles )
969 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
970 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
971 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
973 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
974 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
975 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
976 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
977 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
978 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
982 style.
readXml( layerStyleElement );
988 mNumCachedLayers = 0;
989 mCacheInvalidated =
true;
992 mOverviewStack->readXml( itemElem, doc, context );
995 mGridStack->readXml( itemElem, doc, context );
998 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
999 if ( !atlasNodeList.isEmpty() )
1001 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1002 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
1003 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
1005 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
1007 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1009 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1011 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1016 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1019 mBlockingLabelItems.clear();
1020 mBlockingLabelItemUuids.clear();
1021 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1022 if ( !labelBlockingNodeList.isEmpty() )
1024 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1025 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1026 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1028 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1029 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1030 mBlockingLabelItemUuids << itemUuid;
1034 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1035 mItemClippingSettings->
readXml( itemElem, doc, context );
1040 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1043 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1044 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1048 mZRangeEnabled = itemElem.attribute( QStringLiteral(
"enableZRange" ) ).toInt();
1050 double zLower = itemElem.attribute( QStringLiteral(
"zRangeLower" ) ).toDouble( &ok );
1053 zLower = std::numeric_limits< double >::lowest();
1055 double zUpper = itemElem.attribute( QStringLiteral(
"zRangeUpper" ) ).toDouble( &ok );
1058 zUpper = std::numeric_limits< double >::max();
1062 mUpdatesEnabled =
true;
1068 if ( mItemClippingSettings->
isActive() )
1079 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1088 QRectF thisPaintRect = rect();
1094 if (
mLayout->renderContext().isPreviewRender() )
1096 bool renderInProgress =
false;
1097 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1100 painter->setClipRect( thisPaintRect );
1101 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1104 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1105 painter->drawRect( thisPaintRect );
1106 painter->setBrush( Qt::NoBrush );
1108 messageFont.setPointSize( 12 );
1109 painter->setFont( messageFont );
1110 painter->setPen( QColor( 255, 255, 255, 255 ) );
1111 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1112 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1116 mBackgroundUpdateTimer->start( 1 );
1118 else if ( !mPainterJob && !mDrawingPreview )
1122 mBackgroundUpdateTimer->start( 1 );
1124 renderInProgress =
true;
1128 if ( mCacheInvalidated && !mDrawingPreview )
1132 mBackgroundUpdateTimer->start( 1 );
1133 renderInProgress =
true;
1138 double imagePixelWidth = mCacheFinalImage->width();
1139 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1143 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1144 painter->setCompositionMode( blendModeForRender() );
1146 painter->drawImage( 0, 0, *mCacheFinalImage );
1151 painter->setClipRect( thisPaintRect, Qt::NoClip );
1153 mOverviewStack->drawItems( painter,
false );
1154 mGridStack->drawItems( painter );
1156 drawMapFrame( painter );
1158 if ( renderInProgress )
1169 QPaintDevice *paintDevice = painter->device();
1177 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1185 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1186 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1187 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1189 image.fill( Qt::transparent );
1190 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1191 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1192 double dotsPerMM = destinationDpi / 25.4;
1193 QPainter p( &image );
1196 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1197 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1198 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1199 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1200 p.setClipRect( imagePaintRect );
1202 p.translate( imagePaintRect.topLeft() );
1206 if ( shouldDrawPart( Background ) )
1208 p.scale( dotsPerMM, dotsPerMM );
1209 drawMapBackground( &p );
1210 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1213 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1218 p.scale( dotsPerMM, dotsPerMM );
1220 if ( shouldDrawPart( OverviewMapExtent ) )
1222 mOverviewStack->drawItems( &p,
false );
1224 if ( shouldDrawPart( Grid ) )
1226 mGridStack->drawItems( &p );
1231 painter->setCompositionMode( blendModeForRender() );
1232 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1233 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1234 painter->scale( dotsPerMM, dotsPerMM );
1239 if ( shouldDrawPart( Background ) )
1241 drawMapBackground( painter );
1245 painter->setClipRect( thisPaintRect );
1250 painter->translate( mXOffset, mYOffset );
1252 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1254 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1256 if ( mCurrentExportPart != NotLayered )
1258 if ( !mStagedRendererJob )
1260 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1263 mStagedRendererJob->renderCurrentPart( painter );
1267 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1271 painter->setClipRect( thisPaintRect, Qt::NoClip );
1273 if ( shouldDrawPart( OverviewMapExtent ) )
1275 mOverviewStack->drawItems( painter,
false );
1277 if ( shouldDrawPart( Grid ) )
1279 mGridStack->drawItems( painter );
1284 if ( shouldDrawPart( Frame ) )
1286 drawMapFrame( painter );
1297 + ( layerCount + ( layerCount ? 1 : 0 ) )
1298 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1299 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1305 mCurrentExportPart = Start;
1307 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1308 mExportThemeIt = mExportThemes.begin();
1313 mCurrentExportPart = NotLayered;
1314 mExportThemes.clear();
1315 mExportThemeIt = mExportThemes.begin();
1320 switch ( mCurrentExportPart )
1325 mCurrentExportPart = Background;
1331 mCurrentExportPart = Layer;
1335 if ( mStagedRendererJob )
1337 if ( mStagedRendererJob->nextPart() )
1341 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1342 mStagedRendererJob.reset();
1346 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1352 if ( mGridStack->hasEnabledItems() )
1354 mCurrentExportPart = Grid;
1360 for (
int i = 0; i < mOverviewStack->size(); ++i )
1365 mCurrentExportPart = OverviewMapExtent;
1371 case OverviewMapExtent:
1374 mCurrentExportPart = Frame;
1381 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1383 mCurrentExportPart = SelectionBoxes;
1388 case SelectionBoxes:
1389 mCurrentExportPart = End;
1410 switch ( mCurrentExportPart )
1420 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1423 if ( mStagedRendererJob )
1425 switch ( mStagedRendererJob->currentStage() )
1429 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1430 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1431 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1437 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1439 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1445 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1450 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1456 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1459 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1461 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1470 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1476 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1511 case OverviewMapExtent:
1519 case SelectionBoxes:
1534void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1548 if ( shouldDrawPart( OverviewMapExtent ) )
1550 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1554#ifdef HAVE_SERVER_PYTHON_PLUGINS
1555 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1561 job.renderSynchronously();
1563 mExportLabelingResults.reset( job.takeLabelingResults() );
1565 mRenderingErrors = job.errors();
1568void QgsLayoutItemMap::recreateCachedImageInBackground()
1574 QPainter *oldPainter = mPainter.release();
1575 QImage *oldImage = mCacheRenderingImage.release();
1578 oldJob->deleteLater();
1586 mCacheRenderingImage.reset(
nullptr );
1590 Q_ASSERT( !mPainterJob );
1591 Q_ASSERT( !mPainter );
1592 Q_ASSERT( !mCacheRenderingImage );
1598 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1599 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1602 if ( w > 5000 || h > 5000 )
1607 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1612 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1616 if ( w <= 0 || h <= 0 )
1619 mCacheRenderingImage.reset(
new QImage( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 ) );
1622 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1623 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1624 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1627 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1632 if ( mItemClippingSettings->
isActive() )
1634 QPainter p( mCacheRenderingImage.get() );
1636 p.setPen( Qt::NoPen );
1638 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1648 mCacheInvalidated =
false;
1649 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1652 if ( shouldDrawPart( OverviewMapExtent ) )
1654 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1659 mPainterJob->start();
1671 mDrawingPreview =
false;
1694 if (
layout()->renderContext().isPreviewRender() )
1697 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1700 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1707 if ( includeLayerSettings )
1712 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1715 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1722 if ( !
mLayout->renderContext().isPreviewRender() )
1767 if ( mEvaluatedLabelMargin.
length() > 0 )
1770 visiblePoly.append( visiblePoly.at( 0 ) );
1771 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1772 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1774 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1775 labelBoundary = mapBoundaryGeom;
1778 if ( !mBlockingLabelItems.isEmpty() )
1791 if ( mZRangeEnabled )
1796 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1807 if ( !labelBoundary.
isEmpty() )
1809 labelBoundary = clipGeom.
intersection( labelBoundary );
1813 labelBoundary = clipGeom;
1818 if ( mItemClippingSettings->
isActive() )
1827 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1828 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1830 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1831 if ( !labelBoundary.
isEmpty() )
1833 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1837 labelBoundary = mapBoundaryGeom;
1843 if ( !labelBoundary.
isNull() )
1846 return jobMapSettings;
1853 mBlockingLabelItems.clear();
1854 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1863 mOverviewStack->finalizeRestoreFromXml();
1864 mGridStack->finalizeRestoreFromXml();
1876 return mCurrentRectangle;
1890 const double mapScale =
scale();
1914 QVariantList layersIds;
1924 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1926 layersIds.reserve( layersInMap.count() );
1927 layers.reserve( layersInMap.count() );
1930 layersIds << layer->id();
1936 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1958 if ( extentWidth <= 0 )
1962 return rect().width() / extentWidth;
1967 double dx = mXOffset;
1968 double dy = mYOffset;
1969 transformShift( dx, dy );
1970 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1971 poly.translate( -dx, -dy );
1977 if ( !mBlockingLabelItems.contains( item ) )
1978 mBlockingLabelItems.append( item );
1985 mBlockingLabelItems.removeAll( item );
1992 return mBlockingLabelItems.contains( item );
1997 return mPreviewLabelingResults.get();
2006 if ( mOverviewStack )
2008 for (
int i = 0; i < mOverviewStack->size(); ++i )
2010 if ( mOverviewStack->item( i )->accept( visitor ) )
2017 for (
int i = 0; i < mGridStack->size(); ++i )
2019 if ( mGridStack->item( i )->accept( visitor ) )
2032 mRenderedFeatureHandlers.append( handler );
2037 mRenderedFeatureHandlers.removeAll( handler );
2043 if ( mapPoly.empty() )
2045 return QPointF( 0, 0 );
2050 double dx = mapCoords.x() - rotationPoint.
x();
2051 double dy = mapCoords.y() - rotationPoint.
y();
2053 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2056 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2057 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2058 return QPointF( xItem, yItem );
2072 mapPolygon( newExtent, poly );
2073 QRectF bRect = poly.boundingRect();
2087 mCacheInvalidated =
true;
2093 QRectF rectangle = rect();
2094 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2096 double topExtension = 0.0;
2097 double rightExtension = 0.0;
2098 double bottomExtension = 0.0;
2099 double leftExtension = 0.0;
2102 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2104 topExtension = std::max( topExtension, frameExtension );
2105 rightExtension = std::max( rightExtension, frameExtension );
2106 bottomExtension = std::max( bottomExtension, frameExtension );
2107 leftExtension = std::max( leftExtension, frameExtension );
2109 rectangle.setLeft( rectangle.left() - leftExtension );
2110 rectangle.setRight( rectangle.right() + rightExtension );
2111 rectangle.setTop( rectangle.top() - topExtension );
2112 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2113 if ( rectangle != mCurrentRectangle )
2115 prepareGeometryChange();
2116 mCurrentRectangle = rectangle;
2144 refreshMapExtents( &context );
2146 if ( mExtent != beforeExtent )
2153 refreshLabelMargin(
false );
2157 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2159 if ( mLastEvaluatedThemeName != previousTheme )
2178 double zLower = mZRange.
lower();
2179 double zUpper = mZRange.
upper();
2190 mCacheInvalidated =
true;
2195void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2198 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2202 mLayerStyleOverrides.remove( layer->id() );
2204 _qgis_removeLayers( mLayers,
layers );
2210 if ( mGroupLayers.erase( layer->id() ) == 0 )
2213 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2216 if ( groupLayer->
childLayers().contains( layer ) )
2218 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2219 childLayers.removeAll( layer );
2227void QgsLayoutItemMap::painterJobFinished()
2230 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2231 mPainterJob.reset(
nullptr );
2232 mPainter.reset(
nullptr );
2233 mCacheFinalImage = std::move( mCacheRenderingImage );
2234 mLastRenderedImageOffsetX = 0;
2235 mLastRenderedImageOffsetY = 0;
2241void QgsLayoutItemMap::shapeChanged()
2246 double w = rect().width();
2247 double h = rect().height();
2250 double newWidth = mExtent.
width();
2252 double newHeight = newWidth * h / w;
2257 refreshMapExtents();
2264void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2266 if ( theme == mCachedLayerStyleOverridesPresetName )
2267 mCachedLayerStyleOverridesPresetName.clear();
2270void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2272 if ( theme == mFollowVisibilityPresetName )
2274 mFollowVisibilityPresetName = newTheme;
2278void QgsLayoutItemMap::connectUpdateSlot()
2286 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2290 if ( layers().isEmpty() )
2319 if ( mAtlasScalingMode == Predefined )
2320 updateAtlasFeature();
2326 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2327 QTransform mapTransform;
2328 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2330 thisRectPoly.pop_back();
2331 thisExtent.pop_back();
2333 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2336 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2337 return mapTransform;
2342 mZRangeEnabled = enabled;
2347 return mZRangeEnabled;
2360QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2363 QList< QgsLabelBlockingRegion > blockers;
2364 blockers.reserve( mBlockingLabelItems.count() );
2365 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2372 if ( item->property(
"wasVisible" ).isValid() )
2374 if ( !item->property(
"wasVisible" ).toBool() )
2377 else if ( !item->isVisible() )
2380 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2381 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2390 return mLabelMargin;
2395 mLabelMargin = margin;
2396 refreshLabelMargin(
false );
2399void QgsLayoutItemMap::updateToolTip()
2408 if ( mFollowVisibilityPreset )
2410 presetName = mFollowVisibilityPresetName;
2414 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2415 presetName = *mExportThemeIt;
2426 QList<QgsMapLayer *> renderLayers;
2428 QString presetName = themeToRender( *evalContext );
2429 if ( !presetName.isEmpty() )
2431 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2432 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2434 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2436 else if ( !
layers().isEmpty() )
2442 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2449 renderLayers.clear();
2451 const QStringList layerNames = ddLayers.split(
'|' );
2453 for (
const QString &name : layerNames )
2455 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2458 renderLayers << layer;
2467 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2468 if ( removeAt != -1 )
2470 renderLayers.removeAt( removeAt );
2475 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2477 return !layer || !layer->isValid();
2478 } ), renderLayers.end() );
2480 return renderLayers;
2483QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2485 QString presetName = themeToRender( context );
2486 if ( !presetName.isEmpty() )
2488 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2490 if ( presetName != mCachedLayerStyleOverridesPresetName )
2493 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2494 mCachedLayerStyleOverridesPresetName = presetName;
2497 return mCachedPresetLayerStyleOverrides;
2500 return QMap<QString, QString>();
2502 else if ( mFollowVisibilityPreset )
2504 QString presetName = mFollowVisibilityPresetName;
2507 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2509 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2512 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2513 mCachedLayerStyleOverridesPresetName = presetName;
2516 return mCachedPresetLayerStyleOverrides;
2519 return QMap<QString, QString>();
2521 else if ( mKeepLayerStyles )
2523 return mLayerStyleOverrides;
2527 return QMap<QString, QString>();
2531QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2533 double dx = mXOffset;
2534 double dy = mYOffset;
2535 transformShift( dx, dy );
2539void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2549 poly << QPointF( poly.at( 0 ) );
2561 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2567 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2573 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2579 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2582 poly << QPointF( poly.at( 0 ) );
2585void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2588 double dxScaled = xShift * mmToMapUnits;
2589 double dyScaled = - yShift * mmToMapUnits;
2604 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2605 if ( annotations.isEmpty() )
2615 if ( !annotation || !annotation->isVisible() )
2619 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2622 drawAnnotation( annotation, rc );
2636 double itemX, itemY;
2639 QPointF mapPos = layoutMapPosForItem( annotation );
2648 context.
painter()->translate( itemX, itemY );
2651 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2652 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2654 annotation->
render( context );
2657QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2660 return QPointF( 0, 0 );
2669 if ( annotationCrs !=
crs() )
2676 t.transformInPlace( mapX, mapY, z );
2686void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2697void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2708bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2710 if ( mCurrentExportPart == NotLayered )
2728 return mCurrentExportPart == Layer;
2731 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2733 case OverviewMapExtent:
2734 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2739 case SelectionBoxes:
2740 return mCurrentExportPart == SelectionBoxes && isSelected();
2761 bool useDdXMin =
false;
2762 bool useDdXMax =
false;
2763 bool useDdYMin =
false;
2764 bool useDdYMax =
false;
2795 if ( newExtent != mExtent )
2801 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2802 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2804 if ( currentWidthHeightRatio < newWidthHeightRatio )
2807 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2808 double deltaHeight = newHeight - newExtent.
height();
2815 double newWidth = currentWidthHeightRatio * newExtent.
height();
2816 double deltaWidth = newWidth - newExtent.
width();
2821 mExtent = newExtent;
2831 newExtent = mExtent;
2834 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2838 if ( useDdXMin && !useDdXMax )
2844 else if ( !useDdXMin && useDdXMax )
2850 if ( useDdYMin && !useDdYMax )
2856 else if ( !useDdYMin && useDdYMax )
2863 if ( newExtent != mExtent )
2865 mExtent = newExtent;
2882void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2895void QgsLayoutItemMap::updateAtlasFeature()
2914 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2919 double originalScale = calc.
calculate( originalExtent, rect().width() );
2920 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2921 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2922 QVector<qreal> scales;
2924 if ( !
mLayout->reportContext().predefinedScales().empty() )
2925 scales =
mLayout->reportContext().predefinedScales();
2927 scales =
mLayout->renderContext().predefinedScales();
2929 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2932 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2933 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2936 xMin + originalExtent.
width(),
2937 yMin + originalExtent.
height() );
2941 double newScale = calc.
calculate( newExtent, rect().width() );
2942 newExtent.
scale( originalScale / newScale );
2947 double newWidth = originalExtent.
width();
2948 double newHeight = originalExtent.
height();
2949 for (
int i = 0; i < scales.size(); i++ )
2951 double ratio = scales[i] / originalScale;
2952 newWidth = originalExtent.
width() * ratio;
2953 newHeight = originalExtent.
height() * ratio;
2956 double xMin = geomCenterX - newWidth / 2.0;
2957 double yMin = geomCenterY - newHeight / 2.0;
2965 double newScale = calc.
calculate( newExtent, rect().width() );
2966 newExtent.
scale( scales[i] / newScale );
2976 else if ( mAtlasScalingMode ==
Auto )
2980 double geomRatio = bounds.
width() / bounds.
height();
2981 double mapRatio = originalExtent.
width() / originalExtent.
height();
2984 if ( geomRatio < mapRatio )
2987 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
2992 else if ( geomRatio > mapRatio )
2995 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
3001 const double evaluatedAtlasMargin =
atlasMargin();
3002 if ( evaluatedAtlasMargin > 0.0 )
3004 newExtent.
scale( 1 + evaluatedAtlasMargin );
3030 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
3031 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3032 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
3033 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3036 center.
x() + dx, center.
y() + dy );
3044void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3047 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3049 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
3053 mStagedRendererJob->start();
3069 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3075 return mClipToAtlasFeature;
3080 if (
enabled == mClipToAtlasFeature )
3083 mClipToAtlasFeature =
enabled;
3089 return mFeatureClippingType;
3094 if ( mFeatureClippingType == type )
3097 mFeatureClippingType = type;
3103 return mForceLabelsInsideFeature;
3108 if ( forceInside == mForceLabelsInsideFeature )
3111 mForceLabelsInsideFeature = forceInside;
3117 return mRestrictToLayers;
3122 if ( mRestrictToLayers ==
enabled )
3131 return _qgis_listRefToRaw( mLayersToClip );
3142 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3143 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3144 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3145 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3146 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3149 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3154 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3155 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3156 layerElem.appendChild( layerIdText );
3158 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3159 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3160 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3162 layerSetElem.appendChild( layerElem );
3164 settingsElem.appendChild( layerSetElem );
3166 element.appendChild( settingsElem );
3172 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3174 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3175 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3177 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3179 mLayersToClip.clear();
3180 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3181 if ( !layerSetNodeList.isEmpty() )
3183 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3184 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3185 mLayersToClip.reserve( layerIdNodeList.size() );
3186 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3188 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3189 QString layerId = layerElem.text();
3190 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3191 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3192 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3194 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3197 mLayersToClip << ref;
3204void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3206 if ( !mLayersToClip.isEmpty() )
3208 _qgis_removeLayers( mLayersToClip, layers );
3223 return mEnabled && mClipPathSource;
3238 if ( mClipPathSource )
3241 mClipPathSource->refresh();
3250 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3261 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3262 clipGeom.
transform( mMap->sceneTransform().inverted() );
3277 if ( mClipPathSource == item )
3280 if ( mClipPathSource )
3289 mClipPathSource = item;
3291 if ( mClipPathSource )
3300 mClipPathSource->refresh();
3314 return mClipPathSource;
3319 return mFeatureClippingType;
3324 if ( mFeatureClippingType == type )
3327 mFeatureClippingType = type;
3333 return mForceLabelsInsideClipPath;
3338 if ( forceInside == mForceLabelsInsideClipPath )
3341 mForceLabelsInsideClipPath = forceInside;
3347 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3348 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3349 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3350 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3351 if ( mClipPathSource )
3352 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3354 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3356 element.appendChild( settingsElem );
3362 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3364 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3365 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3367 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3374 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
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.
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.
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.
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.