18#include "moc_qgslayoutitemmap.cpp"
47#include <QApplication>
50#include <QStyleOptionGraphicsItem>
60 mBackgroundUpdateTimer =
new QTimer(
this );
61 mBackgroundUpdateTimer->setSingleShot(
true );
62 connect( mBackgroundUpdateTimer, &QTimer::timeout,
this, &QgsLayoutItemMap::recreateCachedImageInBackground );
66 setCacheMode( QGraphicsItem::NoCache );
73 mGridStack = std::make_unique< QgsLayoutItemMapGridStack >(
this );
74 mOverviewStack = std::make_unique< QgsLayoutItemMapOverviewStack >(
this );
107 mPainterJob->cancel();
132 QList<QgsLayoutItemMap *> mapsList;
133 mLayout->layoutItems( mapsList );
142 if ( map->mMapId == mMapId )
145 maxId = std::max( maxId, map->mMapId );
150 mLayout->itemsModel()->updateItemDisplayName(
this );
162 return tr(
"Map %1" ).arg( mMapId );
174 mCachedLayerStyleOverridesPresetName.clear();
178 updateAtlasFeature();
183 if ( rect().isEmpty() || !
mLayout )
188 calculator.
setDpi( 25.4 );
191 calculator.
setMethod( project->scaleMethod() );
199 double currentScaleDenominator =
scale();
206 double scaleRatio = scaleDenominator / currentScaleDenominator;
207 mExtent.
scale( scaleRatio );
209 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
216 calculator.
setDpi( 25.4 );
222 const double newScale = calculator.
calculate( mExtent, rect().width() );
225 scaleRatio = scaleDenominator / newScale;
226 mExtent.
scale( scaleRatio );
253 const QRectF currentRect = rect();
254 const double newHeight = mExtent.
width() == 0 ? 0
255 : currentRect.width() * mExtent.
height() / mExtent.
width();
267 double currentWidthHeightRatio = 1.0;
268 if ( !currentExtent.
isEmpty() )
269 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
271 currentWidthHeightRatio = rect().width() / rect().height();
273 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
275 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
277 if ( currentWidthHeightRatio < newWidthHeightRatio )
280 double newHeight = newExtent.
width() / currentWidthHeightRatio;
281 double deltaHeight = newHeight - newExtent.
height();
288 double newWidth = currentWidthHeightRatio * newExtent.
height();
289 double deltaWidth = newWidth - newExtent.
width();
295 if ( mExtent == newExtent )
314QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
317 mapPolygon( mExtent, poly );
319 if ( includeClipping && mItemClippingSettings->
isActive() )
333 return calculateVisibleExtentPolygon(
true );
341 return mLayout->project()->crs();
356 return _qgis_listRefToRaw( mLayers );
361 mGroupLayers.clear();
363 QList<QgsMapLayer *> layersCopy {
layers };
368 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
370 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
372 auto existingIt = mGroupLayers.find( groupLayer->id() );
373 if ( existingIt != mGroupLayers.end( ) )
375 *it = ( *existingIt ).second.get();
379 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
380 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
381 *it = mGroupLayers[ groupLayer->id() ].get();
385 mLayers = _qgis_listRawToRef( layersCopy );
390 if ( overrides == mLayerStyleOverrides )
393 mLayerStyleOverrides = overrides;
400 mLayerStyleOverrides.clear();
407 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
414 if ( mFollowVisibilityPreset == follow )
417 mFollowVisibilityPreset = follow;
419 if ( !mFollowVisibilityPresetName.isEmpty() )
420 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
425 if ( name == mFollowVisibilityPresetName )
428 mFollowVisibilityPresetName = name;
429 if ( mFollowVisibilityPreset )
435 mLastRenderedImageOffsetX -= dx;
436 mLastRenderedImageOffsetY -= dy;
439 transformShift( dx, dy );
463 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
469 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
470 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
472 double newIntervalX, newIntervalY;
489 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
496 calculator.
setDpi( 25.4 );
501 const double newScale = calculator.
calculate( mExtent, rect().
width() );
504 const double scaleRatio =
scale() / newScale ;
505 mExtent.
scale( scaleRatio );
522 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
532 if (
blendMode() != QPainter::CompositionMode_SourceOver )
551 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]()->
bool
561 if ( mOverviewStack->containsAdvancedEffects() )
569 if ( mGridStack->containsAdvancedEffects() )
582 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
603 if ( mOverviewStack->containsAdvancedEffects() )
611 if ( mGridStack->containsAdvancedEffects() )
626 mMapRotation = rotation;
627 mEvaluatedMapRotation = mMapRotation;
640 mAtlasDriven = enabled;
657 double margin = mAtlasMargin;
665 margin = ddMargin / 100;
677 if ( mGridStack->size() < 1 )
680 mGridStack->addGrid(
grid );
682 return mGridStack->grid( 0 );
687 if ( mOverviewStack->size() < 1 )
690 mOverviewStack->addOverview(
overview );
692 return mOverviewStack->overview( 0 );
702 for (
int i = 0; i < mGridStack->size(); ++i )
705 if (
grid->mEvaluatedEnabled )
708 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
724 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
728 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
731 if ( mDrawAnnotations )
733 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
737 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
741 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
746 mapElem.appendChild( extentElem );
750 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
752 mapElem.appendChild( crsElem );
756 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
757 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
760 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
763 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
768 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
770 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
772 return groupLayer.second.get() == layerRef.get();
775 if ( it != mGroupLayers.end() )
781 layerId = layerRef.layerId;
784 QDomText layerIdText = doc.createTextNode( layerId );
785 layerElem.appendChild( layerIdText );
787 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
788 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
789 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
791 if ( it != mGroupLayers.end() )
793 const auto childLayers { it->second->childLayers() };
794 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
795 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
797 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
798 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
799 childLayersElement.appendChild( childElement );
801 layerElem.appendChild( childLayersElement );
803 layerSetElem.appendChild( layerElem );
805 mapElem.appendChild( layerSetElem );
808 if ( mKeepLayerStyles )
810 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
811 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
813 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
818 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
819 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
820 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
821 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
825 stylesElem.appendChild( styleElem );
827 mapElem.appendChild( stylesElem );
831 mGridStack->writeXml( mapElem, doc, context );
834 mOverviewStack->writeXml( mapElem, doc, context );
837 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
838 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
839 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
840 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
841 mapElem.appendChild( atlasElem );
843 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
844 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
846 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
847 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
852 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
853 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
854 labelBlockingItemsElem.appendChild( blockingItemElem );
856 mapElem.appendChild( labelBlockingItemsElem );
859 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
862 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
863 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
866 mapElem.setAttribute( QStringLiteral(
"enableZRange" ), mZRangeEnabled ? 1 : 0 );
867 if ( mZRange.
lower() != std::numeric_limits< double >::lowest() )
869 if ( mZRange.
upper() != std::numeric_limits< double >::max() )
872 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
873 mItemClippingSettings->
writeXml( mapElem, doc, context );
880 mUpdatesEnabled =
false;
883 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
884 if ( !extentNodeList.isEmpty() )
886 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
887 double xmin, xmax, ymin, ymax;
888 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
889 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
890 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
891 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
895 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
897 if ( !crsNodeList.isEmpty() )
899 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
905 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
906 mEvaluatedMapRotation = mMapRotation;
909 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
910 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
913 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
914 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
916 mKeepLayerSet =
true;
920 mKeepLayerSet =
false;
923 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
924 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
926 mDrawAnnotations =
true;
930 mDrawAnnotations =
false;
933 mLayerStyleOverrides.clear();
935 QList<QgsMapLayerRef> layerSet;
936 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
937 if ( !layerSetNodeList.isEmpty() )
939 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
940 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
941 layerSet.reserve( layerIdNodeList.size() );
942 for (
int i = 0; i < layerIdNodeList.size(); ++i )
944 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
945 QString layerId = layerElem.text();
946 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
947 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
948 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
950 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
958 setLayers( _qgis_listRefToRaw( layerSet ) );
961 if ( !layerSetNodeList.isEmpty() )
963 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
964 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
965 for (
int i = 0; i < layerIdNodeList.size(); ++i )
967 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
968 const QString layerId = layerElem.text();
969 const auto it = mGroupLayers.find( layerId );
970 if ( it != mGroupLayers.cend() )
972 QList<QgsMapLayerRef> childSet;
973 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
974 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
975 for (
int i = 0; i < children.size(); ++i )
977 const QDomElement childElement = children.at( i ).toElement();
978 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
980 if ( layerRef.resolveWeakly(
mLayout->project() ) )
982 childSet.push_back( layerRef );
985 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
992 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
993 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
994 if ( mKeepLayerStyles )
996 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
997 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
998 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
1000 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
1001 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
1002 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
1003 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
1004 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
1005 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
1009 style.
readXml( layerStyleElement );
1015 mNumCachedLayers = 0;
1016 mCacheInvalidated =
true;
1019 mOverviewStack->readXml( itemElem, doc, context );
1022 mGridStack->readXml( itemElem, doc, context );
1025 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
1026 if ( !atlasNodeList.isEmpty() )
1028 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1029 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
1030 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
1032 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
1034 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1036 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1038 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1043 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1046 mBlockingLabelItems.clear();
1047 mBlockingLabelItemUuids.clear();
1048 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1049 if ( !labelBlockingNodeList.isEmpty() )
1051 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1052 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1053 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1055 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1056 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1057 mBlockingLabelItemUuids << itemUuid;
1061 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1062 mItemClippingSettings->
readXml( itemElem, doc, context );
1067 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1070 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1071 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1075 mZRangeEnabled = itemElem.attribute( QStringLiteral(
"enableZRange" ) ).toInt();
1077 double zLower = itemElem.attribute( QStringLiteral(
"zRangeLower" ) ).toDouble( &ok );
1080 zLower = std::numeric_limits< double >::lowest();
1082 double zUpper = itemElem.attribute( QStringLiteral(
"zRangeUpper" ) ).toDouble( &ok );
1085 zUpper = std::numeric_limits< double >::max();
1089 mUpdatesEnabled =
true;
1095 if ( mItemClippingSettings->
isActive() )
1106 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1115 QRectF thisPaintRect = rect();
1121 if (
mLayout->renderContext().isPreviewRender() )
1123 bool renderInProgress =
false;
1124 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1127 painter->setClipRect( thisPaintRect );
1128 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1131 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1132 painter->drawRect( thisPaintRect );
1133 painter->setBrush( Qt::NoBrush );
1135 messageFont.setPointSize( 12 );
1136 painter->setFont( messageFont );
1137 painter->setPen( QColor( 255, 255, 255, 255 ) );
1138 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1139 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1143 mBackgroundUpdateTimer->start( 100 );
1145 else if ( !mPainterJob && !mDrawingPreview )
1149 mBackgroundUpdateTimer->start( 100 );
1151 renderInProgress =
true;
1155 if ( mCacheInvalidated && !mDrawingPreview )
1159 mBackgroundUpdateTimer->start( 100 );
1160 renderInProgress =
true;
1165 double imagePixelWidth = mCacheFinalImage->width();
1166 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1170 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1171 painter->setCompositionMode( blendModeForRender() );
1173 painter->drawImage( 0, 0, *mCacheFinalImage );
1178 painter->setClipRect( thisPaintRect, Qt::NoClip );
1180 mOverviewStack->drawItems( painter,
false );
1181 mGridStack->drawItems( painter );
1183 drawMapFrame( painter );
1185 if ( renderInProgress )
1196 QPaintDevice *paintDevice = painter->device();
1204 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1209 && ( !
mLayout || !forceVector ) )
1214 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1215 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1216 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1218 image.fill( Qt::transparent );
1219 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1220 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1221 double dotsPerMM = destinationDpi / 25.4;
1222 QPainter p( &image );
1225 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1226 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1227 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1228 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1229 p.setClipRect( imagePaintRect );
1231 p.translate( imagePaintRect.topLeft() );
1235 if ( shouldDrawPart( Background ) )
1237 p.scale( dotsPerMM, dotsPerMM );
1238 drawMapBackground( &p );
1239 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1242 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1247 p.scale( dotsPerMM, dotsPerMM );
1249 if ( shouldDrawPart( OverviewMapExtent ) )
1251 mOverviewStack->drawItems( &p,
false );
1253 if ( shouldDrawPart( Grid ) )
1255 mGridStack->drawItems( &p );
1260 painter->setCompositionMode( blendModeForRender() );
1261 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1262 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1263 painter->scale( dotsPerMM, dotsPerMM );
1268 if ( shouldDrawPart( Background ) )
1270 drawMapBackground( painter );
1274 painter->setClipRect( thisPaintRect );
1279 painter->translate( mXOffset, mYOffset );
1281 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1283 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1285 if ( mCurrentExportPart != NotLayered )
1287 if ( !mStagedRendererJob )
1289 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1292 mStagedRendererJob->renderCurrentPart( painter );
1296 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1300 painter->setClipRect( thisPaintRect, Qt::NoClip );
1302 if ( shouldDrawPart( OverviewMapExtent ) )
1304 mOverviewStack->drawItems( painter,
false );
1306 if ( shouldDrawPart( Grid ) )
1308 mGridStack->drawItems( painter );
1313 if ( shouldDrawPart( Frame ) )
1315 drawMapFrame( painter );
1326 + ( layerCount + ( layerCount ? 1 : 0 ) )
1327 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1328 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1334 mCurrentExportPart = Start;
1336 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1337 mExportThemeIt = mExportThemes.begin();
1342 mCurrentExportPart = NotLayered;
1343 mExportThemes.clear();
1344 mExportThemeIt = mExportThemes.begin();
1349 switch ( mCurrentExportPart )
1354 mCurrentExportPart = Background;
1360 mCurrentExportPart = Layer;
1364 if ( mStagedRendererJob )
1366 if ( mStagedRendererJob->nextPart() )
1370 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1371 mStagedRendererJob.reset();
1375 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1381 if ( mGridStack->hasEnabledItems() )
1383 mCurrentExportPart = Grid;
1389 for (
int i = 0; i < mOverviewStack->size(); ++i )
1394 mCurrentExportPart = OverviewMapExtent;
1400 case OverviewMapExtent:
1403 mCurrentExportPart = Frame;
1410 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1412 mCurrentExportPart = SelectionBoxes;
1417 case SelectionBoxes:
1418 mCurrentExportPart = End;
1439 switch ( mCurrentExportPart )
1449 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1452 if ( mStagedRendererJob )
1454 switch ( mStagedRendererJob->currentStage() )
1458 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1459 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1460 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1466 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1468 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1474 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1479 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1485 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1488 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1490 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1499 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1505 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1540 case OverviewMapExtent:
1548 case SelectionBoxes:
1563void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1577 if ( shouldDrawPart( OverviewMapExtent ) )
1579 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1583#ifdef HAVE_SERVER_PYTHON_PLUGINS
1584 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1590 jobFeatureFilter.
addProvider( mAtlasFeatureFilterProvider.get() );
1591 if ( job.featureFilterProvider() )
1593 jobFeatureFilter.
addProvider( job.featureFilterProvider() );
1595 job.setFeatureFilterProvider( &jobFeatureFilter );
1601 job.renderSynchronously();
1603 mExportLabelingResults.reset( job.takeLabelingResults() );
1605 mRenderingErrors = job.errors();
1608void QgsLayoutItemMap::recreateCachedImageInBackground()
1614 QPainter *oldPainter = mPainter.release();
1615 QImage *oldImage = mCacheRenderingImage.release();
1618 oldJob->deleteLater();
1626 mCacheRenderingImage.reset(
nullptr );
1630 Q_ASSERT( !mPainterJob );
1631 Q_ASSERT( !mPainter );
1632 Q_ASSERT( !mCacheRenderingImage );
1638 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1639 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1642 if ( w > 5000 || h > 5000 )
1647 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1652 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1656 if ( w <= 0 || h <= 0 )
1659 mCacheRenderingImage.reset(
new QImage( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 ) );
1662 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1663 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1664 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1667 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1672 if ( mItemClippingSettings->
isActive() )
1674 QPainter p( mCacheRenderingImage.get() );
1676 p.setPen( Qt::NoPen );
1678 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1688 mCacheInvalidated =
false;
1689 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1692 if ( shouldDrawPart( OverviewMapExtent ) )
1694 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1700 mPainterJob->setFeatureFilterProvider( mAtlasFeatureFilterProvider.get() );
1703 mPainterJob->start();
1715 mDrawingPreview =
false;
1738 if (
layout()->renderContext().isPreviewRender() )
1741 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1744 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1752 if ( includeLayerSettings )
1757 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1760 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1767 if ( !
mLayout->renderContext().isPreviewRender() )
1815 if ( mEvaluatedLabelMargin.
length() > 0 )
1818 visiblePoly.append( visiblePoly.at( 0 ) );
1819 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1820 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1822 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1823 labelBoundary = mapBoundaryGeom;
1826 if ( !mBlockingLabelItems.isEmpty() )
1839 if ( mZRangeEnabled )
1844 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1855 if ( !labelBoundary.
isEmpty() )
1857 labelBoundary = clipGeom.
intersection( labelBoundary );
1861 labelBoundary = clipGeom;
1866 if ( mItemClippingSettings->
isActive() )
1875 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1876 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1878 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1879 if ( !labelBoundary.
isEmpty() )
1881 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1885 labelBoundary = mapBoundaryGeom;
1891 if ( !labelBoundary.
isNull() )
1894 return jobMapSettings;
1901 mBlockingLabelItems.clear();
1902 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1911 mOverviewStack->finalizeRestoreFromXml();
1912 mGridStack->finalizeRestoreFromXml();
1924 return mCurrentRectangle;
1938 const double mapScale =
scale();
1962 QVariantList layersIds;
1972 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1974 layersIds.reserve( layersInMap.count() );
1975 layers.reserve( layersInMap.count() );
1978 layersIds << layer->id();
1984 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
2006 if ( extentWidth <= 0 )
2010 return rect().width() / extentWidth;
2015 double dx = mXOffset;
2016 double dy = mYOffset;
2017 transformShift( dx, dy );
2018 QPolygonF poly = calculateVisibleExtentPolygon(
false );
2019 poly.translate( -dx, -dy );
2025 if ( !mBlockingLabelItems.contains( item ) )
2026 mBlockingLabelItems.append( item );
2033 mBlockingLabelItems.removeAll( item );
2040 return mBlockingLabelItems.contains( item );
2045 return mPreviewLabelingResults.get();
2054 if ( mOverviewStack )
2056 for (
int i = 0; i < mOverviewStack->size(); ++i )
2058 if ( mOverviewStack->item( i )->accept( visitor ) )
2065 for (
int i = 0; i < mGridStack->size(); ++i )
2067 if ( mGridStack->item( i )->accept( visitor ) )
2080 mRenderedFeatureHandlers.append( handler );
2085 mRenderedFeatureHandlers.removeAll( handler );
2091 if ( mapPoly.empty() )
2093 return QPointF( 0, 0 );
2098 double dx = mapCoords.x() - rotationPoint.
x();
2099 double dy = mapCoords.y() - rotationPoint.
y();
2101 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2104 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2105 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2106 return QPointF( xItem, yItem );
2120 mapPolygon( newExtent, poly );
2121 QRectF bRect = poly.boundingRect();
2135 mCacheInvalidated =
true;
2141 QRectF rectangle = rect();
2142 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2144 double topExtension = 0.0;
2145 double rightExtension = 0.0;
2146 double bottomExtension = 0.0;
2147 double leftExtension = 0.0;
2150 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2152 topExtension = std::max( topExtension, frameExtension );
2153 rightExtension = std::max( rightExtension, frameExtension );
2154 bottomExtension = std::max( bottomExtension, frameExtension );
2155 leftExtension = std::max( leftExtension, frameExtension );
2157 rectangle.setLeft( rectangle.left() - leftExtension );
2158 rectangle.setRight( rectangle.right() + rightExtension );
2159 rectangle.setTop( rectangle.top() - topExtension );
2160 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2161 if ( rectangle != mCurrentRectangle )
2163 prepareGeometryChange();
2164 mCurrentRectangle = rectangle;
2192 refreshMapExtents( &context );
2194 if ( mExtent != beforeExtent )
2201 refreshLabelMargin(
false );
2205 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2207 if ( mLastEvaluatedThemeName != previousTheme )
2226 double zLower = mZRange.
lower();
2227 double zUpper = mZRange.
upper();
2238 mCacheInvalidated =
true;
2243void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2246 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2250 mLayerStyleOverrides.remove( layer->id() );
2252 _qgis_removeLayers( mLayers,
layers );
2258 if ( mGroupLayers.erase( layer->id() ) == 0 )
2261 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2264 if ( groupLayer->
childLayers().contains( layer ) )
2266 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2267 childLayers.removeAll( layer );
2275void QgsLayoutItemMap::painterJobFinished()
2278 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2279 mPainterJob.reset(
nullptr );
2280 mPainter.reset(
nullptr );
2281 mCacheFinalImage = std::move( mCacheRenderingImage );
2282 mLastRenderedImageOffsetX = 0;
2283 mLastRenderedImageOffsetY = 0;
2289void QgsLayoutItemMap::shapeChanged()
2294 double w = rect().width();
2295 double h = rect().height();
2298 double newWidth = mExtent.
width();
2300 double newHeight = newWidth * h / w;
2305 refreshMapExtents();
2312void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2314 if ( theme == mCachedLayerStyleOverridesPresetName )
2315 mCachedLayerStyleOverridesPresetName.clear();
2318void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2320 if ( theme == mFollowVisibilityPresetName )
2322 mFollowVisibilityPresetName = newTheme;
2326void QgsLayoutItemMap::connectUpdateSlot()
2334 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2338 if ( layers().isEmpty() )
2367 if ( mAtlasScalingMode == Predefined )
2368 updateAtlasFeature();
2374 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2375 QTransform mapTransform;
2376 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2378 thisRectPoly.pop_back();
2379 thisExtent.pop_back();
2381 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2384 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2385 return mapTransform;
2390 mZRangeEnabled = enabled;
2395 return mZRangeEnabled;
2408QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2411 QList< QgsLabelBlockingRegion > blockers;
2412 blockers.reserve( mBlockingLabelItems.count() );
2413 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2420 if ( item->property(
"wasVisible" ).isValid() )
2422 if ( !item->property(
"wasVisible" ).toBool() )
2425 else if ( !item->isVisible() )
2428 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2429 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2438 return mLabelMargin;
2443 mLabelMargin = margin;
2444 refreshLabelMargin(
false );
2447void QgsLayoutItemMap::updateToolTip()
2456 if ( mFollowVisibilityPreset )
2458 presetName = mFollowVisibilityPresetName;
2462 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2463 presetName = *mExportThemeIt;
2474 QList<QgsMapLayer *> renderLayers;
2476 QString presetName = themeToRender( *evalContext );
2477 if ( !presetName.isEmpty() )
2479 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2480 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2482 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2484 else if ( !
layers().isEmpty() )
2490 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2497 renderLayers.clear();
2499 const QStringList layerNames = ddLayers.split(
'|' );
2501 for (
const QString &name : layerNames )
2503 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2506 renderLayers << layer;
2515 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2516 if ( removeAt != -1 )
2518 renderLayers.removeAt( removeAt );
2523 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2525 return !layer || !layer->isValid();
2526 } ), renderLayers.end() );
2528 return renderLayers;
2531QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2533 QString presetName = themeToRender( context );
2534 if ( !presetName.isEmpty() )
2536 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2538 if ( presetName != mCachedLayerStyleOverridesPresetName )
2541 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2542 mCachedLayerStyleOverridesPresetName = presetName;
2545 return mCachedPresetLayerStyleOverrides;
2548 return QMap<QString, QString>();
2550 else if ( mFollowVisibilityPreset )
2552 QString presetName = mFollowVisibilityPresetName;
2555 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2557 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2560 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2561 mCachedLayerStyleOverridesPresetName = presetName;
2564 return mCachedPresetLayerStyleOverrides;
2567 return QMap<QString, QString>();
2569 else if ( mKeepLayerStyles )
2571 return mLayerStyleOverrides;
2575 return QMap<QString, QString>();
2579QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2581 double dx = mXOffset;
2582 double dy = mYOffset;
2583 transformShift( dx, dy );
2587void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2597 poly << QPointF( poly.at( 0 ) );
2609 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2615 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2621 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2627 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2630 poly << QPointF( poly.at( 0 ) );
2633void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2636 double dxScaled = xShift * mmToMapUnits;
2637 double dyScaled = - yShift * mmToMapUnits;
2652 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2653 if ( annotations.isEmpty() )
2664 if ( !annotation || !annotation->isVisible() )
2668 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2671 drawAnnotation( annotation, rc );
2685 double itemX, itemY;
2688 QPointF mapPos = layoutMapPosForItem( annotation );
2697 context.
painter()->translate( itemX, itemY );
2700 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2701 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2703 annotation->
render( context );
2706QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2709 return QPointF( 0, 0 );
2718 if ( annotationCrs !=
crs() )
2725 t.transformInPlace( mapX, mapY, z );
2735void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2746void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2757bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2759 if ( mCurrentExportPart == NotLayered )
2777 return mCurrentExportPart == Layer;
2780 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2782 case OverviewMapExtent:
2783 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2788 case SelectionBoxes:
2789 return mCurrentExportPart == SelectionBoxes && isSelected();
2810 bool useDdXMin =
false;
2811 bool useDdXMax =
false;
2812 bool useDdYMin =
false;
2813 bool useDdYMax =
false;
2844 if ( newExtent != mExtent )
2850 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2851 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2853 if ( currentWidthHeightRatio < newWidthHeightRatio )
2856 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2857 double deltaHeight = newHeight - newExtent.
height();
2864 double newWidth = currentWidthHeightRatio * newExtent.
height();
2865 double deltaWidth = newWidth - newExtent.
width();
2870 mExtent = newExtent;
2880 newExtent = mExtent;
2883 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2887 if ( useDdXMin && !useDdXMax )
2893 else if ( !useDdXMin && useDdXMax )
2899 if ( useDdYMin && !useDdYMax )
2905 else if ( !useDdYMin && useDdYMax )
2912 if ( newExtent != mExtent )
2914 mExtent = newExtent;
2931void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2944void QgsLayoutItemMap::updateAtlasFeature()
2946 if ( !
mLayout->reportContext().layer() || !
mLayout->reportContext().feature().isValid() )
2952 mAtlasFeatureFilterProvider->addProvider( filter );
2971 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2980 double originalScale = calc.
calculate( originalExtent, rect().width() );
2981 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2982 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2983 QVector<qreal> scales;
2985 if ( !
mLayout->reportContext().predefinedScales().empty() )
2986 scales =
mLayout->reportContext().predefinedScales();
2988 scales =
mLayout->renderContext().predefinedScales();
2990 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2993 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2994 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2997 xMin + originalExtent.
width(),
2998 yMin + originalExtent.
height() );
3002 double newScale = calc.
calculate( newExtent, rect().width() );
3003 newExtent.
scale( originalScale / newScale );
3008 double newWidth = originalExtent.
width();
3009 double newHeight = originalExtent.
height();
3010 for (
int i = 0; i < scales.size(); i++ )
3012 double ratio = scales[i] / originalScale;
3013 newWidth = originalExtent.
width() * ratio;
3014 newHeight = originalExtent.
height() * ratio;
3017 double xMin = geomCenterX - newWidth / 2.0;
3018 double yMin = geomCenterY - newHeight / 2.0;
3026 const double newScale = calc.
calculate( newExtent, rect().width() );
3030 newExtent.
scale( scales[i] / newScale );
3040 else if ( mAtlasScalingMode ==
Auto )
3044 double geomRatio = bounds.
width() / bounds.
height();
3045 double mapRatio = originalExtent.
width() / originalExtent.
height();
3048 if ( geomRatio < mapRatio )
3051 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
3056 else if ( geomRatio > mapRatio )
3059 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
3065 const double evaluatedAtlasMargin =
atlasMargin();
3066 if ( evaluatedAtlasMargin > 0.0 )
3068 newExtent.
scale( 1 + evaluatedAtlasMargin );
3094 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
3095 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3096 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
3097 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3100 center.
x() + dx, center.
y() + dy );
3108void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3111 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3113 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
3117 mStagedRendererJob->start();
3133 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3139 return mClipToAtlasFeature;
3144 if (
enabled == mClipToAtlasFeature )
3147 mClipToAtlasFeature =
enabled;
3153 return mFeatureClippingType;
3158 if ( mFeatureClippingType == type )
3161 mFeatureClippingType = type;
3167 return mForceLabelsInsideFeature;
3172 if ( forceInside == mForceLabelsInsideFeature )
3175 mForceLabelsInsideFeature = forceInside;
3181 return mRestrictToLayers;
3186 if ( mRestrictToLayers ==
enabled )
3195 return _qgis_listRefToRaw( mLayersToClip );
3206 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3207 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3208 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3209 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3210 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3213 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3218 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3219 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3220 layerElem.appendChild( layerIdText );
3222 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3223 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3224 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3226 layerSetElem.appendChild( layerElem );
3228 settingsElem.appendChild( layerSetElem );
3230 element.appendChild( settingsElem );
3236 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3238 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3239 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3241 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3243 mLayersToClip.clear();
3244 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3245 if ( !layerSetNodeList.isEmpty() )
3247 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3248 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3249 mLayersToClip.reserve( layerIdNodeList.size() );
3250 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3252 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3253 QString layerId = layerElem.text();
3254 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3255 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3256 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3258 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3261 mLayersToClip << ref;
3268void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3270 if ( !mLayersToClip.isEmpty() )
3272 _qgis_removeLayers( mLayersToClip, layers );
3287 return mEnabled && mClipPathSource;
3302 if ( mClipPathSource )
3305 mClipPathSource->refresh();
3314 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3325 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3326 clipGeom.
transform( mMap->sceneTransform().inverted() );
3341 if ( mClipPathSource == item )
3344 if ( mClipPathSource )
3353 mClipPathSource = item;
3355 if ( mClipPathSource )
3364 mClipPathSource->refresh();
3378 return mClipPathSource;
3383 return mFeatureClippingType;
3388 if ( mFeatureClippingType == type )
3391 mFeatureClippingType = type;
3397 return mForceLabelsInsideClipPath;
3402 if ( forceInside == mForceLabelsInsideClipPath )
3405 mForceLabelsInsideClipPath = forceInside;
3411 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3412 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3413 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3414 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3415 if ( mClipPathSource )
3416 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3418 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3420 element.appendChild( settingsElem );
3426 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3428 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3429 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3431 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3438 if ( !mClipPathUuid.isEmpty() )
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ ForceVector
Always force vector-based rendering, even when the result will be visually different to a raster-base...
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.
@ 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.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ DisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
@ LimitCoverageLayerRenderToCurrentFeature
Limit coverage layer rendering to the current atlas feature.
@ 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
Draw selection.
@ Antialiasing
Use antialiasing when drawing items.
@ RenderLabelsByMapLayer
When rendering map items to multi-layered exports, render labels belonging to different layers into s...
@ HideCoverageLayer
Hide coverage layer in outputs.
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.
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.
Handles parsing and evaluation of expressions (formerly called "search strings").
A feature filter provider allowing to set filter expressions on a per-layer basis.
void setFilter(const QString &layerId, const QgsExpression &expression)
Set a filter for the given layer.
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 filter filter provider grouping several filter providers.
QgsGroupedFeatureFilterProvider & addProvider(const QgsFeatureFilterProvider *provider)
Add another filter provider to 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.
Stores computed placement from labeling engine.
void layerOrderChanged()
Emitted when the layer order has changed.
Contains settings relating to clipping a layout map by the current atlas feature.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the current atlas feature.
bool restrictToLayers() const
Returns true if clipping should be restricted to a subset of layers.
QgsLayoutItemMapAtlasClippingSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapAtlasClippingSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
void setLayersToClip(const QList< QgsMapLayer * > &layers)
Sets the list of map layers to clip to the atlas feature.
QList< QgsMapLayer * > layersToClip() const
Returns the list of map layers to clip to the atlas feature.
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the current atlas feature.
void changed()
Emitted when the atlas clipping settings are changed.
bool forceLabelsInsideFeature() const
Returns true if labels should only be placed inside the atlas feature geometry.
bool enabled() const
Returns true if the map content should be clipped to the current atlas feature.
void setForceLabelsInsideFeature(bool forceInside)
Sets whether labels should only be placed inside the atlas feature geometry.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the current atlas feature.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
Contains settings relating to clipping a layout map by another layout item.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setForceLabelsInsideClipPath(bool forceInside)
Sets whether labels should only be placed inside the clip path geometry.
void setSourceItem(QgsLayoutItem *item)
Sets the source item which will provide the clipping path for the map.
QgsLayoutItemMapItemClipPathSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapItemClipPathSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
QgsGeometry clipPathInMapItemCoordinates() const
Returns the clipping path geometry, in the map item's coordinate space.
QgsGeometry clippedMapExtent() const
Returns the geometry to use for clipping the parent map, in the map item's CRS.
QgsLayoutItem * sourceItem()
Returns the source item which will provide the clipping path for the map, or nullptr if no item is se...
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the associated item.
bool forceLabelsInsideClipPath() const
Returns true if labels should only be placed inside the clip path geometry.
void finalizeRestoreFromXml()
To be called after all pending items have been restored from XML.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the associated item.
bool enabled() const
Returns true if the map content should be clipped to the associated item.
QgsMapClippingRegion toMapClippingRegion() const
Returns the clip path as a map clipping region.
void changed()
Emitted when the item clipping settings are changed.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the associated item.
bool isActive() const
Returns true if the item clipping is enabled and set to a valid source item.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
@ StackAboveMapLabels
Render above all map layers and labels.
StackingPosition stackingPosition() const
Returns the item's stacking position, which specifies where the in the map's stack the item should be...
bool enabled() const
Returns whether the item will be drawn.
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
Layout graphical items for displaying a map.
void setFollowVisibilityPreset(bool follow)
Sets whether the map should follow a map theme.
bool nextExportPart() override
Moves to the next export part for a multi-layered export item, during a multi-layered export.
void removeRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Removes a previously added rendered feature handler.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
~QgsLayoutItemMap() override
QIcon icon() const override
Returns the item's icon.
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties) override
void preparedForAtlas()
Emitted when the map has been prepared for atlas rendering, just before actual rendering.
void setFollowVisibilityPresetName(const QString &name)
Sets preset name for map rendering.
QTransform layoutToMapCoordsTransform() const
Creates a transform from layout coordinates to map coordinates.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
bool isLabelBlockingItem(QgsLayoutItem *item) const
Returns true if the specified item is a "label blocking item".
void storeCurrentLayerStyles()
Stores the current project layer styles into style overrides.
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
QgsLayoutMeasurement labelMargin() const
Returns the margin from the map edges in which no labels may be placed.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
@ Predefined
A scale is chosen from the predefined scales.
@ Auto
The extent is adjusted so that each feature is fully visible.
@ Fixed
The current scale of the map is used for each feature of the atlas.
bool requiresRasterization() const override
Returns true if the item is drawn in such a way that forces the whole layout to be rasterized when ex...
Q_DECL_DEPRECATED int numberExportLayers() const override
void layerStyleOverridesChanged()
Emitted when layer style overrides are changed... a means to let associated legend items know they sh...
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void moveContent(double dx, double dy) override
Moves the content of the item, by a specified dx and dy in layout units.
void setZRangeEnabled(bool enabled)
Sets whether the z range is enabled (i.e.
QgsLayoutItemMapGrid * grid()
Returns the map item's first grid.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
int type() const override
void previewRefreshed()
Emitted whenever the item's map preview has been refreshed.
friend class QgsLayoutItemMapOverview
void setExtent(const QgsRectangle &extent)
Sets a new extent for the map.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
QFlags< MapItemFlag > MapItemFlags
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
QPolygonF visibleExtentPolygon() const
Returns a polygon representing the current visible map extent, considering map extents and rotation.
QgsRectangle requestedExtent() const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
void setMapFlags(QgsLayoutItemMap::MapItemFlags flags)
Sets the map item's flags, which control how the map content is drawn.
void zoomContent(double factor, QPointF point) override
Zooms content of item.
QList< QgsMapLayer * > layersToRender(const QgsExpressionContext *context=nullptr) const
Returns a list of the layers which will be rendered within this map item, considering any locked laye...
void crsChanged()
Emitted when the map's coordinate reference system is changed.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the stored layers set.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
static QgsLayoutItemMap * create(QgsLayout *layout)
Returns a new map item for the specified layout.
QRectF boundingRect() const override
QString displayName() const override
Gets item display name.
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
void setZRange(const QgsDoubleRange &range)
Sets the map's z range, which is used to filter the map's content to only display features within the...
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for layers.
void stopLayeredExport() override
Stops a multi-layer export operation.
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map.
double estimatedFrameBleed() const override
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainterPath framePath() const override
Returns the path to use when drawing the item's frame or background.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void startLayeredExport() override
Starts a multi-layer export operation.
bool containsWmsLayer() const
Returns true if the map contains a WMS layer.
void setScale(double scale, bool forceUpdate=true)
Sets new map scale and changes only the map extent.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
double mapUnitsToLayoutUnits() const
Returns the conversion factor from map units to layout units.
QgsLayoutItemMap::MapItemFlags mapFlags() const
Returns the map item's flags, which control how the map content is drawn.
bool zRangeEnabled() const
Returns whether the z range is enabled (i.e.
void setLabelMargin(const QgsLayoutMeasurement &margin)
Sets the margin from the map edges in which no labels may be placed.
void themeChanged(const QString &theme)
Emitted when the map's associated theme is changed.
QgsLayoutItem::ExportLayerDetail exportLayerDetails() const override
Returns the details for the specified current export layer.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
double scale() const
Returns the map scale.
@ ShowPartialLabels
Whether to draw labels which are partially outside of the map view.
@ ShowUnplacedLabels
Whether to render unplaced labels in the map view.
bool drawAnnotations() const
Returns whether annotations are drawn within the map.
QgsDoubleRange zRange() const
Returns the map's z range, which is used to filter the map's content to only display features within ...
void removeLabelBlockingItem(QgsLayoutItem *item)
Removes the specified layout item from the map's "label blocking items".
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the map's preset crs (coordinate reference system).
void invalidateCache() override
QgsRectangle extent() const
Returns the current map extent.
QgsLayoutItemMapOverview * overview()
Returns the map item's first overview.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setFrameStrokeWidth(QgsLayoutMeasurement width) override
Sets the frame stroke width.
bool containsAdvancedEffects() const override
Returns true if the item contains contents with blend modes or transparency effects which can only be...
friend class QgsLayoutItemMapGrid
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
void setMoveContentPreviewOffset(double dx, double dy) override
Sets temporary offset for the item, by a specified dx and dy in layout units.
void setMapRotation(double rotation)
Sets the rotation for the map - this does not affect the layout item shape, only the way the map is d...
static const QgsSettingsEntryBool * settingForceRasterMasks
Settings entry - Whether to force rasterised clipping masks, regardless of output format.
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.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
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.
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.
Contains configuration for rendering maps.
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 setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
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.
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
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.
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.
Qgis::ScaleCalculationMethod scaleMethod
T lower() const
Returns the lower bound of the range.
T upper() const
Returns the upper bound of the range.
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Contains information about the context of a rendering operation.
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 setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
Qgis::RasterizedRenderingPolicy rasterizedRenderingPolicy() const
Returns the policy controlling when rasterisation of content during renders is permitted.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
An interface for classes which provide 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.
void setMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for map scale calculations.
Scoped object for saving and restoring a QPainter object's state.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
A boolean settings entry.
static QgsSettingsTreeNode * sTreeLayout
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.