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 );
232 QRectF currentRect = rect();
234 double newHeight = currentRect.width() * mExtent.
height() / mExtent.
width();
246 double currentWidthHeightRatio = 1.0;
247 if ( !currentExtent.
isEmpty() )
248 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
250 currentWidthHeightRatio = rect().width() / rect().height();
252 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
254 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
256 if ( currentWidthHeightRatio < newWidthHeightRatio )
259 double newHeight = newExtent.
width() / currentWidthHeightRatio;
260 double deltaHeight = newHeight - newExtent.
height();
267 double newWidth = currentWidthHeightRatio * newExtent.
height();
268 double deltaWidth = newWidth - newExtent.
width();
274 if ( mExtent == newExtent )
293QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
296 mapPolygon( mExtent, poly );
298 if ( includeClipping && mItemClippingSettings->
isActive() )
312 return calculateVisibleExtentPolygon(
true );
320 return mLayout->project()->crs();
335 return _qgis_listRefToRaw( mLayers );
340 mGroupLayers.clear();
342 QList<QgsMapLayer *> layersCopy {
layers };
347 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
349 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
351 auto existingIt = mGroupLayers.find( groupLayer->id() );
352 if ( existingIt != mGroupLayers.end( ) )
354 *it = ( *existingIt ).second.get();
358 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
359 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
360 *it = mGroupLayers[ groupLayer->id() ].get();
364 mLayers = _qgis_listRawToRef( layersCopy );
369 if ( overrides == mLayerStyleOverrides )
372 mLayerStyleOverrides = overrides;
379 mLayerStyleOverrides.clear();
386 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
393 if ( mFollowVisibilityPreset == follow )
396 mFollowVisibilityPreset = follow;
398 if ( !mFollowVisibilityPresetName.isEmpty() )
399 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
404 if ( name == mFollowVisibilityPresetName )
407 mFollowVisibilityPresetName = name;
408 if ( mFollowVisibilityPreset )
414 mLastRenderedImageOffsetX -= dx;
415 mLastRenderedImageOffsetY -= dy;
418 transformShift( dx, dy );
442 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
448 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
449 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
451 double newIntervalX, newIntervalY;
468 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
475 calculator.
setDpi( 25.4 );
476 double scaleRatio =
scale() / calculator.
calculate( mExtent, rect().width() );
477 mExtent.
scale( scaleRatio );
493 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
503 if (
blendMode() != QPainter::CompositionMode_SourceOver )
522 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]()->
bool
532 if ( mOverviewStack->containsAdvancedEffects() )
540 if ( mGridStack->containsAdvancedEffects() )
553 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
574 if ( mOverviewStack->containsAdvancedEffects() )
582 if ( mGridStack->containsAdvancedEffects() )
597 mMapRotation = rotation;
598 mEvaluatedMapRotation = mMapRotation;
611 mAtlasDriven = enabled;
628 double margin = mAtlasMargin;
636 margin = ddMargin / 100;
648 if ( mGridStack->size() < 1 )
651 mGridStack->addGrid(
grid );
653 return mGridStack->grid( 0 );
658 if ( mOverviewStack->size() < 1 )
661 mOverviewStack->addOverview(
overview );
663 return mOverviewStack->overview( 0 );
673 for (
int i = 0; i < mGridStack->size(); ++i )
676 if (
grid->mEvaluatedEnabled )
679 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
695 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
699 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
702 if ( mDrawAnnotations )
704 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
708 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
712 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
717 mapElem.appendChild( extentElem );
721 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
723 mapElem.appendChild( crsElem );
727 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
728 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
731 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
734 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
739 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
741 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
743 return groupLayer.second.get() == layerRef.get();
746 if ( it != mGroupLayers.end() )
752 layerId = layerRef.layerId;
755 QDomText layerIdText = doc.createTextNode( layerId );
756 layerElem.appendChild( layerIdText );
758 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
759 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
760 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
762 if ( it != mGroupLayers.end() )
764 const auto childLayers { it->second->childLayers() };
765 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
766 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
768 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
769 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
770 childLayersElement.appendChild( childElement );
772 layerElem.appendChild( childLayersElement );
774 layerSetElem.appendChild( layerElem );
776 mapElem.appendChild( layerSetElem );
779 if ( mKeepLayerStyles )
781 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
782 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
784 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
789 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
790 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
791 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
792 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
796 stylesElem.appendChild( styleElem );
798 mapElem.appendChild( stylesElem );
802 mGridStack->writeXml( mapElem, doc, context );
805 mOverviewStack->writeXml( mapElem, doc, context );
808 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
809 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
810 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
811 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
812 mapElem.appendChild( atlasElem );
814 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
815 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
817 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
818 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
823 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
824 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
825 labelBlockingItemsElem.appendChild( blockingItemElem );
827 mapElem.appendChild( labelBlockingItemsElem );
830 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
833 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().begin().toString( Qt::ISODate ) );
834 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().end().toString( Qt::ISODate ) );
837 mapElem.setAttribute( QStringLiteral(
"enableZRange" ), mZRangeEnabled ? 1 : 0 );
838 if ( mZRange.
lower() != std::numeric_limits< double >::lowest() )
840 if ( mZRange.
upper() != std::numeric_limits< double >::max() )
843 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
844 mItemClippingSettings->
writeXml( mapElem, doc, context );
851 mUpdatesEnabled =
false;
854 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
855 if ( !extentNodeList.isEmpty() )
857 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
858 double xmin, xmax, ymin, ymax;
859 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
860 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
861 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
862 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
866 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
868 if ( !crsNodeList.isEmpty() )
870 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
876 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
877 mEvaluatedMapRotation = mMapRotation;
880 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
881 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
884 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
885 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
887 mKeepLayerSet =
true;
891 mKeepLayerSet =
false;
894 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
895 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
897 mDrawAnnotations =
true;
901 mDrawAnnotations =
false;
904 mLayerStyleOverrides.clear();
906 QList<QgsMapLayerRef> layerSet;
907 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
908 if ( !layerSetNodeList.isEmpty() )
910 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
911 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
912 layerSet.reserve( layerIdNodeList.size() );
913 for (
int i = 0; i < layerIdNodeList.size(); ++i )
915 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
916 QString layerId = layerElem.text();
917 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
918 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
919 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
921 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
929 setLayers( _qgis_listRefToRaw( layerSet ) );
932 if ( !layerSetNodeList.isEmpty() )
934 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
935 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
936 for (
int i = 0; i < layerIdNodeList.size(); ++i )
938 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
939 const QString layerId = layerElem.text();
940 const auto it = mGroupLayers.find( layerId );
941 if ( it != mGroupLayers.cend() )
943 QList<QgsMapLayerRef> childSet;
944 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
945 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
946 for (
int i = 0; i < children.size(); ++i )
948 const QDomElement childElement = children.at( i ).toElement();
949 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
951 if ( layerRef.resolveWeakly(
mLayout->project() ) )
953 childSet.push_back( layerRef );
956 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
963 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
964 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
965 if ( mKeepLayerStyles )
967 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
968 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
969 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
971 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
972 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
973 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
974 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
975 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
976 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
980 style.
readXml( layerStyleElement );
986 mNumCachedLayers = 0;
987 mCacheInvalidated =
true;
990 mOverviewStack->readXml( itemElem, doc, context );
993 mGridStack->readXml( itemElem, doc, context );
996 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
997 if ( !atlasNodeList.isEmpty() )
999 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1000 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
1001 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
1003 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
1005 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1007 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1009 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1014 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1017 mBlockingLabelItems.clear();
1018 mBlockingLabelItemUuids.clear();
1019 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1020 if ( !labelBlockingNodeList.isEmpty() )
1022 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1023 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1024 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1026 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1027 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1028 mBlockingLabelItemUuids << itemUuid;
1032 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1033 mItemClippingSettings->
readXml( itemElem, doc, context );
1038 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1041 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1042 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1046 mZRangeEnabled = itemElem.attribute( QStringLiteral(
"enableZRange" ) ).toInt();
1048 double zLower = itemElem.attribute( QStringLiteral(
"zRangeLower" ) ).toDouble( &ok );
1051 zLower = std::numeric_limits< double >::lowest();
1053 double zUpper = itemElem.attribute( QStringLiteral(
"zRangeUpper" ) ).toDouble( &ok );
1056 zUpper = std::numeric_limits< double >::max();
1060 mUpdatesEnabled =
true;
1066 if ( mItemClippingSettings->
isActive() )
1077 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1086 QRectF thisPaintRect = rect();
1092 if (
mLayout->renderContext().isPreviewRender() )
1094 bool renderInProgress =
false;
1095 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1098 painter->setClipRect( thisPaintRect );
1099 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1102 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1103 painter->drawRect( thisPaintRect );
1104 painter->setBrush( Qt::NoBrush );
1106 messageFont.setPointSize( 12 );
1107 painter->setFont( messageFont );
1108 painter->setPen( QColor( 255, 255, 255, 255 ) );
1109 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1110 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1114 mBackgroundUpdateTimer->start( 1 );
1116 else if ( !mPainterJob && !mDrawingPreview )
1120 mBackgroundUpdateTimer->start( 1 );
1122 renderInProgress =
true;
1126 if ( mCacheInvalidated && !mDrawingPreview )
1130 mBackgroundUpdateTimer->start( 1 );
1131 renderInProgress =
true;
1136 double imagePixelWidth = mCacheFinalImage->width();
1137 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1141 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1142 painter->setCompositionMode( blendModeForRender() );
1144 painter->drawImage( 0, 0, *mCacheFinalImage );
1149 painter->setClipRect( thisPaintRect, Qt::NoClip );
1151 mOverviewStack->drawItems( painter,
false );
1152 mGridStack->drawItems( painter );
1154 drawMapFrame( painter );
1156 if ( renderInProgress )
1167 QPaintDevice *paintDevice = painter->device();
1175 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1183 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1184 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1185 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1187 image.fill( Qt::transparent );
1188 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1189 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1190 double dotsPerMM = destinationDpi / 25.4;
1191 QPainter p( &image );
1194 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1195 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1196 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1197 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1198 p.setClipRect( imagePaintRect );
1200 p.translate( imagePaintRect.topLeft() );
1204 if ( shouldDrawPart( Background ) )
1206 p.scale( dotsPerMM, dotsPerMM );
1207 drawMapBackground( &p );
1208 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1211 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1216 p.scale( dotsPerMM, dotsPerMM );
1218 if ( shouldDrawPart( OverviewMapExtent ) )
1220 mOverviewStack->drawItems( &p,
false );
1222 if ( shouldDrawPart( Grid ) )
1224 mGridStack->drawItems( &p );
1229 painter->setCompositionMode( blendModeForRender() );
1230 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1231 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1232 painter->scale( dotsPerMM, dotsPerMM );
1237 if ( shouldDrawPart( Background ) )
1239 drawMapBackground( painter );
1243 painter->setClipRect( thisPaintRect );
1248 painter->translate( mXOffset, mYOffset );
1250 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1252 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1254 if ( mCurrentExportPart != NotLayered )
1256 if ( !mStagedRendererJob )
1258 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1261 mStagedRendererJob->renderCurrentPart( painter );
1265 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1269 painter->setClipRect( thisPaintRect, Qt::NoClip );
1271 if ( shouldDrawPart( OverviewMapExtent ) )
1273 mOverviewStack->drawItems( painter,
false );
1275 if ( shouldDrawPart( Grid ) )
1277 mGridStack->drawItems( painter );
1282 if ( shouldDrawPart( Frame ) )
1284 drawMapFrame( painter );
1295 + ( layerCount + ( layerCount ? 1 : 0 ) )
1296 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1297 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1303 mCurrentExportPart = Start;
1305 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1306 mExportThemeIt = mExportThemes.begin();
1311 mCurrentExportPart = NotLayered;
1312 mExportThemes.clear();
1313 mExportThemeIt = mExportThemes.begin();
1318 switch ( mCurrentExportPart )
1323 mCurrentExportPart = Background;
1329 mCurrentExportPart = Layer;
1333 if ( mStagedRendererJob )
1335 if ( mStagedRendererJob->nextPart() )
1339 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1340 mStagedRendererJob.reset();
1344 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1350 if ( mGridStack->hasEnabledItems() )
1352 mCurrentExportPart = Grid;
1358 for (
int i = 0; i < mOverviewStack->size(); ++i )
1363 mCurrentExportPart = OverviewMapExtent;
1369 case OverviewMapExtent:
1372 mCurrentExportPart = Frame;
1379 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1381 mCurrentExportPart = SelectionBoxes;
1386 case SelectionBoxes:
1387 mCurrentExportPart = End;
1408 switch ( mCurrentExportPart )
1418 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1421 if ( mStagedRendererJob )
1423 switch ( mStagedRendererJob->currentStage() )
1427 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1428 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1429 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1435 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1437 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1443 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1448 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1454 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1457 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1459 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1468 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1474 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1509 case OverviewMapExtent:
1517 case SelectionBoxes:
1532void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1546 if ( shouldDrawPart( OverviewMapExtent ) )
1548 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1552#ifdef HAVE_SERVER_PYTHON_PLUGINS
1553 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1559 job.renderSynchronously();
1561 mExportLabelingResults.reset( job.takeLabelingResults() );
1563 mRenderingErrors = job.errors();
1566void QgsLayoutItemMap::recreateCachedImageInBackground()
1572 QPainter *oldPainter = mPainter.release();
1573 QImage *oldImage = mCacheRenderingImage.release();
1576 oldJob->deleteLater();
1584 mCacheRenderingImage.reset(
nullptr );
1588 Q_ASSERT( !mPainterJob );
1589 Q_ASSERT( !mPainter );
1590 Q_ASSERT( !mCacheRenderingImage );
1596 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1597 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1600 if ( w > 5000 || h > 5000 )
1605 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1610 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1614 if ( w <= 0 || h <= 0 )
1617 mCacheRenderingImage.reset(
new QImage( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 ) );
1620 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1621 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1622 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1625 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1630 if ( mItemClippingSettings->
isActive() )
1632 QPainter p( mCacheRenderingImage.get() );
1634 p.setPen( Qt::NoPen );
1636 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1646 mCacheInvalidated =
false;
1647 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1650 if ( shouldDrawPart( OverviewMapExtent ) )
1652 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1657 mPainterJob->start();
1669 mDrawingPreview =
false;
1692 if (
layout()->renderContext().isPreviewRender() )
1695 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1698 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1705 if ( includeLayerSettings )
1710 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1713 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1720 if ( !
mLayout->renderContext().isPreviewRender() )
1763 if ( mEvaluatedLabelMargin.
length() > 0 )
1766 visiblePoly.append( visiblePoly.at( 0 ) );
1767 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1768 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1770 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1771 labelBoundary = mapBoundaryGeom;
1774 if ( !mBlockingLabelItems.isEmpty() )
1787 if ( mZRangeEnabled )
1792 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1803 if ( !labelBoundary.
isEmpty() )
1805 labelBoundary = clipGeom.
intersection( labelBoundary );
1809 labelBoundary = clipGeom;
1814 if ( mItemClippingSettings->
isActive() )
1823 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1824 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1826 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1827 if ( !labelBoundary.
isEmpty() )
1829 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1833 labelBoundary = mapBoundaryGeom;
1839 if ( !labelBoundary.
isNull() )
1842 return jobMapSettings;
1849 mBlockingLabelItems.clear();
1850 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1859 mOverviewStack->finalizeRestoreFromXml();
1860 mGridStack->finalizeRestoreFromXml();
1872 return mCurrentRectangle;
1886 const double mapScale =
scale();
1910 QVariantList layersIds;
1920 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1922 layersIds.reserve( layersInMap.count() );
1923 layers.reserve( layersInMap.count() );
1926 layersIds << layer->id();
1932 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1954 if ( extentWidth <= 0 )
1958 return rect().width() / extentWidth;
1963 double dx = mXOffset;
1964 double dy = mYOffset;
1965 transformShift( dx, dy );
1966 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1967 poly.translate( -dx, -dy );
1973 if ( !mBlockingLabelItems.contains( item ) )
1974 mBlockingLabelItems.append( item );
1981 mBlockingLabelItems.removeAll( item );
1988 return mBlockingLabelItems.contains( item );
1993 return mPreviewLabelingResults.get();
2002 if ( mOverviewStack )
2004 for (
int i = 0; i < mOverviewStack->size(); ++i )
2006 if ( mOverviewStack->item( i )->accept( visitor ) )
2013 for (
int i = 0; i < mGridStack->size(); ++i )
2015 if ( mGridStack->item( i )->accept( visitor ) )
2028 mRenderedFeatureHandlers.append( handler );
2033 mRenderedFeatureHandlers.removeAll( handler );
2039 if ( mapPoly.empty() )
2041 return QPointF( 0, 0 );
2046 double dx = mapCoords.x() - rotationPoint.
x();
2047 double dy = mapCoords.y() - rotationPoint.
y();
2049 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2052 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2053 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2054 return QPointF( xItem, yItem );
2068 mapPolygon( newExtent, poly );
2069 QRectF bRect = poly.boundingRect();
2083 mCacheInvalidated =
true;
2089 QRectF rectangle = rect();
2090 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2092 double topExtension = 0.0;
2093 double rightExtension = 0.0;
2094 double bottomExtension = 0.0;
2095 double leftExtension = 0.0;
2098 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2100 topExtension = std::max( topExtension, frameExtension );
2101 rightExtension = std::max( rightExtension, frameExtension );
2102 bottomExtension = std::max( bottomExtension, frameExtension );
2103 leftExtension = std::max( leftExtension, frameExtension );
2105 rectangle.setLeft( rectangle.left() - leftExtension );
2106 rectangle.setRight( rectangle.right() + rightExtension );
2107 rectangle.setTop( rectangle.top() - topExtension );
2108 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2109 if ( rectangle != mCurrentRectangle )
2111 prepareGeometryChange();
2112 mCurrentRectangle = rectangle;
2140 refreshMapExtents( &context );
2142 if ( mExtent != beforeExtent )
2149 refreshLabelMargin(
false );
2153 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2155 if ( mLastEvaluatedThemeName != previousTheme )
2174 double zLower = mZRange.
lower();
2175 double zUpper = mZRange.
upper();
2186 mCacheInvalidated =
true;
2191void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2194 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2198 mLayerStyleOverrides.remove( layer->id() );
2200 _qgis_removeLayers( mLayers,
layers );
2206 if ( mGroupLayers.erase( layer->id() ) == 0 )
2209 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2212 if ( groupLayer->
childLayers().contains( layer ) )
2214 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2215 childLayers.removeAll( layer );
2223void QgsLayoutItemMap::painterJobFinished()
2226 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2227 mPainterJob.reset(
nullptr );
2228 mPainter.reset(
nullptr );
2229 mCacheFinalImage = std::move( mCacheRenderingImage );
2230 mLastRenderedImageOffsetX = 0;
2231 mLastRenderedImageOffsetY = 0;
2237void QgsLayoutItemMap::shapeChanged()
2242 double w = rect().width();
2243 double h = rect().height();
2246 double newWidth = mExtent.
width();
2248 double newHeight = newWidth * h / w;
2253 refreshMapExtents();
2260void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2262 if ( theme == mCachedLayerStyleOverridesPresetName )
2263 mCachedLayerStyleOverridesPresetName.clear();
2266void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2268 if ( theme == mFollowVisibilityPresetName )
2270 mFollowVisibilityPresetName = newTheme;
2274void QgsLayoutItemMap::connectUpdateSlot()
2282 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2286 if ( layers().isEmpty() )
2315 if ( mAtlasScalingMode == Predefined )
2316 updateAtlasFeature();
2322 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2323 QTransform mapTransform;
2324 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2326 thisRectPoly.pop_back();
2327 thisExtent.pop_back();
2329 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2332 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2333 return mapTransform;
2338 mZRangeEnabled = enabled;
2343 return mZRangeEnabled;
2356QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2359 QList< QgsLabelBlockingRegion > blockers;
2360 blockers.reserve( mBlockingLabelItems.count() );
2361 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2368 if ( item->property(
"wasVisible" ).isValid() )
2370 if ( !item->property(
"wasVisible" ).toBool() )
2373 else if ( !item->isVisible() )
2376 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2377 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2386 return mLabelMargin;
2391 mLabelMargin = margin;
2392 refreshLabelMargin(
false );
2395void QgsLayoutItemMap::updateToolTip()
2404 if ( mFollowVisibilityPreset )
2406 presetName = mFollowVisibilityPresetName;
2410 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2411 presetName = *mExportThemeIt;
2422 QList<QgsMapLayer *> renderLayers;
2424 QString presetName = themeToRender( *evalContext );
2425 if ( !presetName.isEmpty() )
2427 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2428 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2430 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2432 else if ( !
layers().isEmpty() )
2438 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2445 renderLayers.clear();
2447 const QStringList layerNames = ddLayers.split(
'|' );
2449 for (
const QString &name : layerNames )
2451 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2454 renderLayers << layer;
2463 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2464 if ( removeAt != -1 )
2466 renderLayers.removeAt( removeAt );
2471 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2473 return !layer || !layer->isValid();
2474 } ), renderLayers.end() );
2476 return renderLayers;
2479QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2481 QString presetName = themeToRender( context );
2482 if ( !presetName.isEmpty() )
2484 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2486 if ( presetName != mCachedLayerStyleOverridesPresetName )
2489 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2490 mCachedLayerStyleOverridesPresetName = presetName;
2493 return mCachedPresetLayerStyleOverrides;
2496 return QMap<QString, QString>();
2498 else if ( mFollowVisibilityPreset )
2500 QString presetName = mFollowVisibilityPresetName;
2503 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2505 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2508 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2509 mCachedLayerStyleOverridesPresetName = presetName;
2512 return mCachedPresetLayerStyleOverrides;
2515 return QMap<QString, QString>();
2517 else if ( mKeepLayerStyles )
2519 return mLayerStyleOverrides;
2523 return QMap<QString, QString>();
2527QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2529 double dx = mXOffset;
2530 double dy = mYOffset;
2531 transformShift( dx, dy );
2535void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2545 poly << QPointF( poly.at( 0 ) );
2557 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2563 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2569 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2575 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2578 poly << QPointF( poly.at( 0 ) );
2581void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2584 double dxScaled = xShift * mmToMapUnits;
2585 double dyScaled = - yShift * mmToMapUnits;
2600 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2601 if ( annotations.isEmpty() )
2611 if ( !annotation || !annotation->isVisible() )
2615 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2618 drawAnnotation( annotation, rc );
2632 double itemX, itemY;
2635 QPointF mapPos = layoutMapPosForItem( annotation );
2644 context.
painter()->translate( itemX, itemY );
2647 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2648 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2650 annotation->
render( context );
2653QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2656 return QPointF( 0, 0 );
2665 if ( annotationCrs !=
crs() )
2672 t.transformInPlace( mapX, mapY, z );
2682void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2693void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2704bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2706 if ( mCurrentExportPart == NotLayered )
2724 return mCurrentExportPart == Layer;
2727 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2729 case OverviewMapExtent:
2730 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2735 case SelectionBoxes:
2736 return mCurrentExportPart == SelectionBoxes && isSelected();
2757 bool useDdXMin =
false;
2758 bool useDdXMax =
false;
2759 bool useDdYMin =
false;
2760 bool useDdYMax =
false;
2791 if ( newExtent != mExtent )
2797 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2798 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2800 if ( currentWidthHeightRatio < newWidthHeightRatio )
2803 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2804 double deltaHeight = newHeight - newExtent.
height();
2811 double newWidth = currentWidthHeightRatio * newExtent.
height();
2812 double deltaWidth = newWidth - newExtent.
width();
2817 mExtent = newExtent;
2827 newExtent = mExtent;
2830 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2834 if ( useDdXMin && !useDdXMax )
2840 else if ( !useDdXMin && useDdXMax )
2846 if ( useDdYMin && !useDdYMax )
2852 else if ( !useDdYMin && useDdYMax )
2859 if ( newExtent != mExtent )
2861 mExtent = newExtent;
2878void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2891void QgsLayoutItemMap::updateAtlasFeature()
2910 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2915 double originalScale = calc.
calculate( originalExtent, rect().width() );
2916 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2917 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2918 QVector<qreal> scales;
2920 if ( !
mLayout->reportContext().predefinedScales().empty() )
2921 scales =
mLayout->reportContext().predefinedScales();
2923 scales =
mLayout->renderContext().predefinedScales();
2925 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2928 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2929 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2932 xMin + originalExtent.
width(),
2933 yMin + originalExtent.
height() );
2937 double newScale = calc.
calculate( newExtent, rect().width() );
2938 newExtent.
scale( originalScale / newScale );
2943 double newWidth = originalExtent.
width();
2944 double newHeight = originalExtent.
height();
2945 for (
int i = 0; i < scales.size(); i++ )
2947 double ratio = scales[i] / originalScale;
2948 newWidth = originalExtent.
width() * ratio;
2949 newHeight = originalExtent.
height() * ratio;
2952 double xMin = geomCenterX - newWidth / 2.0;
2953 double yMin = geomCenterY - newHeight / 2.0;
2961 double newScale = calc.
calculate( newExtent, rect().width() );
2962 newExtent.
scale( scales[i] / newScale );
2972 else if ( mAtlasScalingMode ==
Auto )
2976 double geomRatio = bounds.
width() / bounds.
height();
2977 double mapRatio = originalExtent.
width() / originalExtent.
height();
2980 if ( geomRatio < mapRatio )
2983 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
2988 else if ( geomRatio > mapRatio )
2991 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
2997 const double evaluatedAtlasMargin =
atlasMargin();
2998 if ( evaluatedAtlasMargin > 0.0 )
3000 newExtent.
scale( 1 + evaluatedAtlasMargin );
3016 if ( mEvaluatedMapRotation != 0.0 )
3026 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
3027 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3028 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
3029 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3032 center.
x() + dx, center.
y() + dy );
3040void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3043 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3045 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
3049 mStagedRendererJob->start();
3065 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3071 return mClipToAtlasFeature;
3076 if (
enabled == mClipToAtlasFeature )
3079 mClipToAtlasFeature =
enabled;
3085 return mFeatureClippingType;
3090 if ( mFeatureClippingType == type )
3093 mFeatureClippingType = type;
3099 return mForceLabelsInsideFeature;
3104 if ( forceInside == mForceLabelsInsideFeature )
3107 mForceLabelsInsideFeature = forceInside;
3113 return mRestrictToLayers;
3118 if ( mRestrictToLayers ==
enabled )
3127 return _qgis_listRefToRaw( mLayersToClip );
3138 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3139 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3140 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3141 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3142 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3145 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3150 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3151 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3152 layerElem.appendChild( layerIdText );
3154 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3155 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3156 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3158 layerSetElem.appendChild( layerElem );
3160 settingsElem.appendChild( layerSetElem );
3162 element.appendChild( settingsElem );
3168 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3170 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3171 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3173 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3175 mLayersToClip.clear();
3176 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3177 if ( !layerSetNodeList.isEmpty() )
3179 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3180 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3181 mLayersToClip.reserve( layerIdNodeList.size() );
3182 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3184 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3185 QString layerId = layerElem.text();
3186 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3187 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3188 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3190 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3193 mLayersToClip << ref;
3200void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3202 if ( !mLayersToClip.isEmpty() )
3204 _qgis_removeLayers( mLayersToClip, layers );
3219 return mEnabled && mClipPathSource;
3234 if ( mClipPathSource )
3237 mClipPathSource->refresh();
3246 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3257 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3258 clipGeom.
transform( mMap->sceneTransform().inverted() );
3273 if ( mClipPathSource == item )
3276 if ( mClipPathSource )
3285 mClipPathSource = item;
3287 if ( mClipPathSource )
3296 mClipPathSource->refresh();
3310 return mClipPathSource;
3315 return mFeatureClippingType;
3320 if ( mFeatureClippingType == type )
3323 mFeatureClippingType = type;
3329 return mForceLabelsInsideClipPath;
3334 if ( forceInside == mForceLabelsInsideClipPath )
3337 mForceLabelsInsideClipPath = forceInside;
3343 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3344 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3345 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3346 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3347 if ( mClipPathSource )
3348 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3350 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3352 element.appendChild( settingsElem );
3358 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3360 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3361 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3363 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3370 if ( !mClipPathUuid.isEmpty() )
@ Millimeters
Millimeters.
@ CollectUnplacedLabels
Whether unplaced labels should be collected in the labeling results (regardless of whether they are b...
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
@ UsePartialCandidates
Whether to use also label candidates that are partially outside of the map view.
@ Export
Renderer used for printing or exporting to a file.
@ View
Renderer used for displaying on screen.
@ 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...
@ DrawSelection
Whether vector selections should be shown in the rendered map.
@ Antialiasing
Enable anti-aliasing for map rendering.
@ UseAdvancedEffects
Enable layer opacity and blending effects.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
QDateTime valueAsDateTime(int key, const QgsExpressionContext &context, const QDateTime &defaultDateTime=QDateTime(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a datetime.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
Abstract base class for annotation items which are drawn over a map.
QgsCoordinateReferenceSystem mapPositionCrs() const
Returns the CRS of the map position, or an invalid CRS if the annotation does not have a fixed map po...
void render(QgsRenderContext &context) const
Renders the annotation to a target render context.
bool isVisible() const
Returns true if the annotation is visible and should be rendered.
QPointF relativePosition() const
Returns the relative position of the annotation, if it is not attached to a fixed map position.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Q_GADGET Qgis::DistanceUnit mapUnits
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
void updateDefinition()
Updates the definition and parameters of the coordinate reference system to their latest values.
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,...
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 (since QGIS 3.38)
@ StartDateTime
Temporal range's start DateTime.
@ MapLayers
Map layer set.
@ MapZRangeLower
Map frame Z-range lower value (since QGIS 3.38)
@ 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...
@ FlagUseAdvancedEffects
Enable advanced effects such as blend modes.
@ FlagDrawSelection
Draw selection.
@ FlagLosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ FlagAntialiasing
Use antialiasing when drawing items.
@ FlagForceVectorOutput
Force output in vector format where possible, even if items require rasterization to keep their corre...
@ FlagHideCoverageLayer
Hide coverage layer in outputs.
@ FlagDisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
static QgsRenderContext createRenderContextForMap(QgsLayoutItemMap *map, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout map and painter destination.
static void rotate(double angle, double &x, double &y)
Rotates a point / vector around the origin.
static Q_DECL_DEPRECATED double scaleFactorFromItemStyle(const QStyleOptionGraphicsItem *style)
Extracts the scale factor from an item style.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
void refreshed()
Emitted when the layout has been refreshed and items should also be refreshed and updated.
QgsProject * project() const
The project associated with the layout.
A map clipping region (in map coordinates and CRS).
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
FeatureClippingType
Feature clipping behavior, which controls how features from vector layers will be clipped.
void setFeatureClip(FeatureClippingType type)
Sets the feature clipping type.
void setRestrictedLayers(const QList< QgsMapLayer * > &layers)
Sets a list of layers to restrict the clipping region effects to.
Stores style information (renderer, opacity, labeling, diagrams etc.) applicable to a map layer.
void readXml(const QDomElement &styleElement)
Read style configuration (for project file reading)
void readFromLayer(QgsMapLayer *layer)
Store layer's active style information in the instance.
void writeXml(QDomElement &styleElement) const
Write style configuration (for project file writing)
QString xmlData() const
Returns XML content of the style.
Base class for all map layer types.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Job implementation that renders everything sequentially using a custom painter.
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
void finished()
emitted when asynchronous rendering is finished (or canceled).
@ RenderLabelsByMapLayer
Labels should be rendered in individual stages by map layer. This allows separation of labels belongi...
@ Finished
Rendering is finished.
@ Symbology
Rendering layer symbology.
@ Labels
Rendering labels.
static QStringList containsAdvancedEffects(const QgsMapSettings &mapSettings, EffectsCheckFlags flags=QgsMapSettingsUtils::EffectsCheckFlags())
Checks whether any of the layers attached to a map settings object contain advanced effects.
The QgsMapSettings class contains configuration for rendering of the map.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &renderer)
Sets the shading renderer used to render shading on the entire map.
void addClippingRegion(const QgsMapClippingRegion ®ion)
Adds a new clipping region to the map settings.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setSimplifyMethod(const QgsVectorSimplifyMethod &method)
Sets the simplification setting to use when rendering vector layers.
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated)
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map settings.
void setTextRenderFormat(Qgis::TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
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 setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
double frameRate() const
Returns the frame rate of the map (in frames per second), for maps which are part of an animation.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
void setLabelBoundaryGeometry(const QgsGeometry &boundary)
Sets the label boundary geometry, which restricts where in the rendered map labels are permitted to b...
void setLabelBlockingRegions(const QList< QgsLabelBlockingRegion > ®ions)
Sets a list of regions to avoid placing labels within.
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
void mapThemeRenamed(const QString &name, const QString &newName)
Emitted when a map theme within the collection is renamed.
void mapThemeChanged(const QString &theme)
Emitted when a map theme changes definition.
A class to represent a 2D point.
QString description() const
Description.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
void crsChanged()
Emitted when the CRS of the project has changed.
QgsMapThemeCollection * mapThemeCollection
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
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.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
An interface for classes which provider custom handlers for features rendered as part of a map render...
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the output resolution, to be used in scale calculations.
void setMapUnits(Qgis::DistanceUnit mapUnits)
Set the map units.
Scoped object for saving and restoring a QPainter object's state.
An interface for classes which can visit style entity (e.g.
@ LayoutItem
Individual item in a print layout.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
@ NoSimplification
No simplification can be applied.
static double scaleToZoom(double mapScale, double z0Scale=559082264.0287178)
Finds zoom level given map scale denominator.
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale=559082264.0287178)
Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
const QgsCoordinateReferenceSystem & crs
Single variable definition for use within a QgsExpressionContextScope.
Contains details of a particular export layer relating to a layout item.
QPainter::CompositionMode compositionMode
Associated composition mode if this layer is associated with a map layer.
QString mapLayerId
Associated map layer ID, or an empty string if this export layer is not associated with a map layer.
double opacity
Associated opacity, if this layer is associated with a map layer.
QString name
User-friendly name for the export layer.
QString mapTheme
Associated map theme, or an empty string if this export layer does not need to be associated with a m...
Contains information relating to a node (i.e.
TYPE * resolveWeakly(const QgsProject *project, MatchType matchType=MatchType::All)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
QString source
Weak reference to layer public source.
QString name
Weak reference to layer name.
QString provider
Weak reference to layer provider.
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
QString layerId
Original layer ID.