18#include "moc_qgslayoutitemmap.cpp"
44#include <QApplication>
47#include <QStyleOptionGraphicsItem>
55 mBackgroundUpdateTimer =
new QTimer(
this );
56 mBackgroundUpdateTimer->setSingleShot(
true );
57 connect( mBackgroundUpdateTimer, &QTimer::timeout,
this, &QgsLayoutItemMap::recreateCachedImageInBackground );
61 setCacheMode( QGraphicsItem::NoCache );
68 mGridStack = std::make_unique< QgsLayoutItemMapGridStack >(
this );
69 mOverviewStack = std::make_unique< QgsLayoutItemMapOverviewStack >(
this );
102 mPainterJob->cancel();
127 QList<QgsLayoutItemMap *> mapsList;
128 mLayout->layoutItems( mapsList );
137 if ( map->mMapId == mMapId )
140 maxId = std::max( maxId, map->mMapId );
145 mLayout->itemsModel()->updateItemDisplayName(
this );
157 return tr(
"Map %1" ).arg( mMapId );
169 mCachedLayerStyleOverridesPresetName.clear();
173 updateAtlasFeature();
178 if ( rect().isEmpty() )
183 calculator.
setDpi( 25.4 );
190 double currentScaleDenominator =
scale();
197 double scaleRatio = scaleDenominator / currentScaleDenominator;
198 mExtent.
scale( scaleRatio );
200 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
207 calculator.
setDpi( 25.4 );
208 scaleRatio = scaleDenominator / calculator.
calculate( mExtent, rect().width() );
209 mExtent.
scale( scaleRatio );
235 const QRectF currentRect = rect();
236 const double newHeight = mExtent.
width() == 0 ? 0
237 : currentRect.width() * mExtent.
height() / mExtent.
width();
249 double currentWidthHeightRatio = 1.0;
250 if ( !currentExtent.
isEmpty() )
251 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
253 currentWidthHeightRatio = rect().width() / rect().height();
255 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
257 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
259 if ( currentWidthHeightRatio < newWidthHeightRatio )
262 double newHeight = newExtent.
width() / currentWidthHeightRatio;
263 double deltaHeight = newHeight - newExtent.
height();
270 double newWidth = currentWidthHeightRatio * newExtent.
height();
271 double deltaWidth = newWidth - newExtent.
width();
277 if ( mExtent == newExtent )
296QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
299 mapPolygon( mExtent, poly );
301 if ( includeClipping && mItemClippingSettings->
isActive() )
315 return calculateVisibleExtentPolygon(
true );
323 return mLayout->project()->crs();
338 return _qgis_listRefToRaw( mLayers );
343 mGroupLayers.clear();
345 QList<QgsMapLayer *> layersCopy {
layers };
350 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
352 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
354 auto existingIt = mGroupLayers.find( groupLayer->id() );
355 if ( existingIt != mGroupLayers.end( ) )
357 *it = ( *existingIt ).second.get();
361 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
362 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
363 *it = mGroupLayers[ groupLayer->id() ].get();
367 mLayers = _qgis_listRawToRef( layersCopy );
372 if ( overrides == mLayerStyleOverrides )
375 mLayerStyleOverrides = overrides;
382 mLayerStyleOverrides.clear();
389 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
396 if ( mFollowVisibilityPreset == follow )
399 mFollowVisibilityPreset = follow;
401 if ( !mFollowVisibilityPresetName.isEmpty() )
402 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
407 if ( name == mFollowVisibilityPresetName )
410 mFollowVisibilityPresetName = name;
411 if ( mFollowVisibilityPreset )
417 mLastRenderedImageOffsetX -= dx;
418 mLastRenderedImageOffsetY -= dy;
421 transformShift( dx, dy );
445 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
451 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
452 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
454 double newIntervalX, newIntervalY;
471 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
478 calculator.
setDpi( 25.4 );
479 double scaleRatio =
scale() / calculator.
calculate( mExtent, rect().width() );
480 mExtent.
scale( scaleRatio );
496 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
506 if (
blendMode() != QPainter::CompositionMode_SourceOver )
525 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]()->
bool
535 if ( mOverviewStack->containsAdvancedEffects() )
543 if ( mGridStack->containsAdvancedEffects() )
556 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
577 if ( mOverviewStack->containsAdvancedEffects() )
585 if ( mGridStack->containsAdvancedEffects() )
600 mMapRotation = rotation;
601 mEvaluatedMapRotation = mMapRotation;
614 mAtlasDriven = enabled;
631 double margin = mAtlasMargin;
639 margin = ddMargin / 100;
651 if ( mGridStack->size() < 1 )
654 mGridStack->addGrid(
grid );
656 return mGridStack->grid( 0 );
661 if ( mOverviewStack->size() < 1 )
664 mOverviewStack->addOverview(
overview );
666 return mOverviewStack->overview( 0 );
676 for (
int i = 0; i < mGridStack->size(); ++i )
679 if (
grid->mEvaluatedEnabled )
682 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
698 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
702 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
705 if ( mDrawAnnotations )
707 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
711 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
715 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
720 mapElem.appendChild( extentElem );
724 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
726 mapElem.appendChild( crsElem );
730 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
731 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
734 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
737 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
742 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
744 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
746 return groupLayer.second.get() == layerRef.get();
749 if ( it != mGroupLayers.end() )
755 layerId = layerRef.layerId;
758 QDomText layerIdText = doc.createTextNode( layerId );
759 layerElem.appendChild( layerIdText );
761 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
762 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
763 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
765 if ( it != mGroupLayers.end() )
767 const auto childLayers { it->second->childLayers() };
768 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
769 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
771 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
772 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
773 childLayersElement.appendChild( childElement );
775 layerElem.appendChild( childLayersElement );
777 layerSetElem.appendChild( layerElem );
779 mapElem.appendChild( layerSetElem );
782 if ( mKeepLayerStyles )
784 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
785 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
787 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
792 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
793 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
794 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
795 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
799 stylesElem.appendChild( styleElem );
801 mapElem.appendChild( stylesElem );
805 mGridStack->writeXml( mapElem, doc, context );
808 mOverviewStack->writeXml( mapElem, doc, context );
811 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
812 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
813 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
814 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
815 mapElem.appendChild( atlasElem );
817 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
818 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
820 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
821 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
826 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
827 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
828 labelBlockingItemsElem.appendChild( blockingItemElem );
830 mapElem.appendChild( labelBlockingItemsElem );
833 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
836 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
837 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
840 mapElem.setAttribute( QStringLiteral(
"enableZRange" ), mZRangeEnabled ? 1 : 0 );
841 if ( mZRange.
lower() != std::numeric_limits< double >::lowest() )
843 if ( mZRange.
upper() != std::numeric_limits< double >::max() )
846 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
847 mItemClippingSettings->
writeXml( mapElem, doc, context );
854 mUpdatesEnabled =
false;
857 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
858 if ( !extentNodeList.isEmpty() )
860 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
861 double xmin, xmax, ymin, ymax;
862 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
863 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
864 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
865 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
869 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
871 if ( !crsNodeList.isEmpty() )
873 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
879 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
880 mEvaluatedMapRotation = mMapRotation;
883 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
884 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
887 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
888 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
890 mKeepLayerSet =
true;
894 mKeepLayerSet =
false;
897 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
898 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
900 mDrawAnnotations =
true;
904 mDrawAnnotations =
false;
907 mLayerStyleOverrides.clear();
909 QList<QgsMapLayerRef> layerSet;
910 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
911 if ( !layerSetNodeList.isEmpty() )
913 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
914 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
915 layerSet.reserve( layerIdNodeList.size() );
916 for (
int i = 0; i < layerIdNodeList.size(); ++i )
918 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
919 QString layerId = layerElem.text();
920 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
921 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
922 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
924 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
932 setLayers( _qgis_listRefToRaw( layerSet ) );
935 if ( !layerSetNodeList.isEmpty() )
937 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
938 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
939 for (
int i = 0; i < layerIdNodeList.size(); ++i )
941 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
942 const QString layerId = layerElem.text();
943 const auto it = mGroupLayers.find( layerId );
944 if ( it != mGroupLayers.cend() )
946 QList<QgsMapLayerRef> childSet;
947 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
948 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
949 for (
int i = 0; i < children.size(); ++i )
951 const QDomElement childElement = children.at( i ).toElement();
952 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
954 if ( layerRef.resolveWeakly(
mLayout->project() ) )
956 childSet.push_back( layerRef );
959 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
966 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
967 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
968 if ( mKeepLayerStyles )
970 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
971 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
972 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
974 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
975 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
976 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
977 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
978 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
979 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
983 style.
readXml( layerStyleElement );
989 mNumCachedLayers = 0;
990 mCacheInvalidated =
true;
993 mOverviewStack->readXml( itemElem, doc, context );
996 mGridStack->readXml( itemElem, doc, context );
999 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
1000 if ( !atlasNodeList.isEmpty() )
1002 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1003 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
1004 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
1006 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
1008 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1010 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1012 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1017 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1020 mBlockingLabelItems.clear();
1021 mBlockingLabelItemUuids.clear();
1022 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1023 if ( !labelBlockingNodeList.isEmpty() )
1025 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1026 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1027 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1029 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1030 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1031 mBlockingLabelItemUuids << itemUuid;
1035 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1036 mItemClippingSettings->
readXml( itemElem, doc, context );
1041 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1044 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1045 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1049 mZRangeEnabled = itemElem.attribute( QStringLiteral(
"enableZRange" ) ).toInt();
1051 double zLower = itemElem.attribute( QStringLiteral(
"zRangeLower" ) ).toDouble( &ok );
1054 zLower = std::numeric_limits< double >::lowest();
1056 double zUpper = itemElem.attribute( QStringLiteral(
"zRangeUpper" ) ).toDouble( &ok );
1059 zUpper = std::numeric_limits< double >::max();
1063 mUpdatesEnabled =
true;
1069 if ( mItemClippingSettings->
isActive() )
1080 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1089 QRectF thisPaintRect = rect();
1095 if (
mLayout->renderContext().isPreviewRender() )
1097 bool renderInProgress =
false;
1098 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1101 painter->setClipRect( thisPaintRect );
1102 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1105 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1106 painter->drawRect( thisPaintRect );
1107 painter->setBrush( Qt::NoBrush );
1109 messageFont.setPointSize( 12 );
1110 painter->setFont( messageFont );
1111 painter->setPen( QColor( 255, 255, 255, 255 ) );
1112 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1113 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1117 mBackgroundUpdateTimer->start( 1 );
1119 else if ( !mPainterJob && !mDrawingPreview )
1123 mBackgroundUpdateTimer->start( 1 );
1125 renderInProgress =
true;
1129 if ( mCacheInvalidated && !mDrawingPreview )
1133 mBackgroundUpdateTimer->start( 1 );
1134 renderInProgress =
true;
1139 double imagePixelWidth = mCacheFinalImage->width();
1140 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1144 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1145 painter->setCompositionMode( blendModeForRender() );
1147 painter->drawImage( 0, 0, *mCacheFinalImage );
1152 painter->setClipRect( thisPaintRect, Qt::NoClip );
1154 mOverviewStack->drawItems( painter,
false );
1155 mGridStack->drawItems( painter );
1157 drawMapFrame( painter );
1159 if ( renderInProgress )
1170 QPaintDevice *paintDevice = painter->device();
1178 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1186 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1187 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1188 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1190 image.fill( Qt::transparent );
1191 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1192 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1193 double dotsPerMM = destinationDpi / 25.4;
1194 QPainter p( &image );
1197 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1198 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1199 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1200 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1201 p.setClipRect( imagePaintRect );
1203 p.translate( imagePaintRect.topLeft() );
1207 if ( shouldDrawPart( Background ) )
1209 p.scale( dotsPerMM, dotsPerMM );
1210 drawMapBackground( &p );
1211 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1214 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1219 p.scale( dotsPerMM, dotsPerMM );
1221 if ( shouldDrawPart( OverviewMapExtent ) )
1223 mOverviewStack->drawItems( &p,
false );
1225 if ( shouldDrawPart( Grid ) )
1227 mGridStack->drawItems( &p );
1232 painter->setCompositionMode( blendModeForRender() );
1233 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1234 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1235 painter->scale( dotsPerMM, dotsPerMM );
1240 if ( shouldDrawPart( Background ) )
1242 drawMapBackground( painter );
1246 painter->setClipRect( thisPaintRect );
1251 painter->translate( mXOffset, mYOffset );
1253 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1255 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1257 if ( mCurrentExportPart != NotLayered )
1259 if ( !mStagedRendererJob )
1261 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1264 mStagedRendererJob->renderCurrentPart( painter );
1268 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1272 painter->setClipRect( thisPaintRect, Qt::NoClip );
1274 if ( shouldDrawPart( OverviewMapExtent ) )
1276 mOverviewStack->drawItems( painter,
false );
1278 if ( shouldDrawPart( Grid ) )
1280 mGridStack->drawItems( painter );
1285 if ( shouldDrawPart( Frame ) )
1287 drawMapFrame( painter );
1298 + ( layerCount + ( layerCount ? 1 : 0 ) )
1299 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1300 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1306 mCurrentExportPart = Start;
1308 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1309 mExportThemeIt = mExportThemes.begin();
1314 mCurrentExportPart = NotLayered;
1315 mExportThemes.clear();
1316 mExportThemeIt = mExportThemes.begin();
1321 switch ( mCurrentExportPart )
1326 mCurrentExportPart = Background;
1332 mCurrentExportPart = Layer;
1336 if ( mStagedRendererJob )
1338 if ( mStagedRendererJob->nextPart() )
1342 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1343 mStagedRendererJob.reset();
1347 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1353 if ( mGridStack->hasEnabledItems() )
1355 mCurrentExportPart = Grid;
1361 for (
int i = 0; i < mOverviewStack->size(); ++i )
1366 mCurrentExportPart = OverviewMapExtent;
1372 case OverviewMapExtent:
1375 mCurrentExportPart = Frame;
1382 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1384 mCurrentExportPart = SelectionBoxes;
1389 case SelectionBoxes:
1390 mCurrentExportPart = End;
1411 switch ( mCurrentExportPart )
1421 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1424 if ( mStagedRendererJob )
1426 switch ( mStagedRendererJob->currentStage() )
1430 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1431 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1432 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1438 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1440 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1446 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1451 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1457 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1460 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1462 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1471 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1477 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1512 case OverviewMapExtent:
1520 case SelectionBoxes:
1535void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1549 if ( shouldDrawPart( OverviewMapExtent ) )
1551 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1555#ifdef HAVE_SERVER_PYTHON_PLUGINS
1556 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1562 job.renderSynchronously();
1564 mExportLabelingResults.reset( job.takeLabelingResults() );
1566 mRenderingErrors = job.errors();
1569void QgsLayoutItemMap::recreateCachedImageInBackground()
1575 QPainter *oldPainter = mPainter.release();
1576 QImage *oldImage = mCacheRenderingImage.release();
1579 oldJob->deleteLater();
1587 mCacheRenderingImage.reset(
nullptr );
1591 Q_ASSERT( !mPainterJob );
1592 Q_ASSERT( !mPainter );
1593 Q_ASSERT( !mCacheRenderingImage );
1599 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1600 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1603 if ( w > 5000 || h > 5000 )
1608 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1613 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1617 if ( w <= 0 || h <= 0 )
1620 mCacheRenderingImage.reset(
new QImage( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 ) );
1623 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1624 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1625 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1628 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1633 if ( mItemClippingSettings->
isActive() )
1635 QPainter p( mCacheRenderingImage.get() );
1637 p.setPen( Qt::NoPen );
1639 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1649 mCacheInvalidated =
false;
1650 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1653 if ( shouldDrawPart( OverviewMapExtent ) )
1655 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1660 mPainterJob->start();
1672 mDrawingPreview =
false;
1695 if (
layout()->renderContext().isPreviewRender() )
1698 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1701 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1708 if ( includeLayerSettings )
1713 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1716 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1723 if ( !
mLayout->renderContext().isPreviewRender() )
1768 if ( mEvaluatedLabelMargin.
length() > 0 )
1771 visiblePoly.append( visiblePoly.at( 0 ) );
1772 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1773 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1775 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1776 labelBoundary = mapBoundaryGeom;
1779 if ( !mBlockingLabelItems.isEmpty() )
1792 if ( mZRangeEnabled )
1797 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1808 if ( !labelBoundary.
isEmpty() )
1810 labelBoundary = clipGeom.
intersection( labelBoundary );
1814 labelBoundary = clipGeom;
1819 if ( mItemClippingSettings->
isActive() )
1828 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1829 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1831 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1832 if ( !labelBoundary.
isEmpty() )
1834 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1838 labelBoundary = mapBoundaryGeom;
1844 if ( !labelBoundary.
isNull() )
1847 return jobMapSettings;
1854 mBlockingLabelItems.clear();
1855 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1864 mOverviewStack->finalizeRestoreFromXml();
1865 mGridStack->finalizeRestoreFromXml();
1877 return mCurrentRectangle;
1891 const double mapScale =
scale();
1915 QVariantList layersIds;
1925 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1927 layersIds.reserve( layersInMap.count() );
1928 layers.reserve( layersInMap.count() );
1931 layersIds << layer->id();
1937 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1959 if ( extentWidth <= 0 )
1963 return rect().width() / extentWidth;
1968 double dx = mXOffset;
1969 double dy = mYOffset;
1970 transformShift( dx, dy );
1971 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1972 poly.translate( -dx, -dy );
1978 if ( !mBlockingLabelItems.contains( item ) )
1979 mBlockingLabelItems.append( item );
1986 mBlockingLabelItems.removeAll( item );
1993 return mBlockingLabelItems.contains( item );
1998 return mPreviewLabelingResults.get();
2007 if ( mOverviewStack )
2009 for (
int i = 0; i < mOverviewStack->size(); ++i )
2011 if ( mOverviewStack->item( i )->accept( visitor ) )
2018 for (
int i = 0; i < mGridStack->size(); ++i )
2020 if ( mGridStack->item( i )->accept( visitor ) )
2033 mRenderedFeatureHandlers.append( handler );
2038 mRenderedFeatureHandlers.removeAll( handler );
2044 if ( mapPoly.empty() )
2046 return QPointF( 0, 0 );
2051 double dx = mapCoords.x() - rotationPoint.
x();
2052 double dy = mapCoords.y() - rotationPoint.
y();
2054 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2057 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2058 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2059 return QPointF( xItem, yItem );
2073 mapPolygon( newExtent, poly );
2074 QRectF bRect = poly.boundingRect();
2088 mCacheInvalidated =
true;
2094 QRectF rectangle = rect();
2095 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2097 double topExtension = 0.0;
2098 double rightExtension = 0.0;
2099 double bottomExtension = 0.0;
2100 double leftExtension = 0.0;
2103 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2105 topExtension = std::max( topExtension, frameExtension );
2106 rightExtension = std::max( rightExtension, frameExtension );
2107 bottomExtension = std::max( bottomExtension, frameExtension );
2108 leftExtension = std::max( leftExtension, frameExtension );
2110 rectangle.setLeft( rectangle.left() - leftExtension );
2111 rectangle.setRight( rectangle.right() + rightExtension );
2112 rectangle.setTop( rectangle.top() - topExtension );
2113 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2114 if ( rectangle != mCurrentRectangle )
2116 prepareGeometryChange();
2117 mCurrentRectangle = rectangle;
2145 refreshMapExtents( &context );
2147 if ( mExtent != beforeExtent )
2154 refreshLabelMargin(
false );
2158 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2160 if ( mLastEvaluatedThemeName != previousTheme )
2179 double zLower = mZRange.
lower();
2180 double zUpper = mZRange.
upper();
2191 mCacheInvalidated =
true;
2196void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2199 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2203 mLayerStyleOverrides.remove( layer->id() );
2205 _qgis_removeLayers( mLayers,
layers );
2211 if ( mGroupLayers.erase( layer->id() ) == 0 )
2214 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2217 if ( groupLayer->
childLayers().contains( layer ) )
2219 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2220 childLayers.removeAll( layer );
2228void QgsLayoutItemMap::painterJobFinished()
2231 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2232 mPainterJob.reset(
nullptr );
2233 mPainter.reset(
nullptr );
2234 mCacheFinalImage = std::move( mCacheRenderingImage );
2235 mLastRenderedImageOffsetX = 0;
2236 mLastRenderedImageOffsetY = 0;
2242void QgsLayoutItemMap::shapeChanged()
2247 double w = rect().width();
2248 double h = rect().height();
2251 double newWidth = mExtent.
width();
2253 double newHeight = newWidth * h / w;
2258 refreshMapExtents();
2265void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2267 if ( theme == mCachedLayerStyleOverridesPresetName )
2268 mCachedLayerStyleOverridesPresetName.clear();
2271void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2273 if ( theme == mFollowVisibilityPresetName )
2275 mFollowVisibilityPresetName = newTheme;
2279void QgsLayoutItemMap::connectUpdateSlot()
2287 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2291 if ( layers().isEmpty() )
2320 if ( mAtlasScalingMode == Predefined )
2321 updateAtlasFeature();
2327 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2328 QTransform mapTransform;
2329 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2331 thisRectPoly.pop_back();
2332 thisExtent.pop_back();
2334 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2337 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2338 return mapTransform;
2343 mZRangeEnabled = enabled;
2348 return mZRangeEnabled;
2361QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2364 QList< QgsLabelBlockingRegion > blockers;
2365 blockers.reserve( mBlockingLabelItems.count() );
2366 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2373 if ( item->property(
"wasVisible" ).isValid() )
2375 if ( !item->property(
"wasVisible" ).toBool() )
2378 else if ( !item->isVisible() )
2381 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2382 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2391 return mLabelMargin;
2396 mLabelMargin = margin;
2397 refreshLabelMargin(
false );
2400void QgsLayoutItemMap::updateToolTip()
2409 if ( mFollowVisibilityPreset )
2411 presetName = mFollowVisibilityPresetName;
2415 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2416 presetName = *mExportThemeIt;
2427 QList<QgsMapLayer *> renderLayers;
2429 QString presetName = themeToRender( *evalContext );
2430 if ( !presetName.isEmpty() )
2432 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2433 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2435 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2437 else if ( !
layers().isEmpty() )
2443 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2450 renderLayers.clear();
2452 const QStringList layerNames = ddLayers.split(
'|' );
2454 for (
const QString &name : layerNames )
2456 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2459 renderLayers << layer;
2468 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2469 if ( removeAt != -1 )
2471 renderLayers.removeAt( removeAt );
2476 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2478 return !layer || !layer->isValid();
2479 } ), renderLayers.end() );
2481 return renderLayers;
2484QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2486 QString presetName = themeToRender( context );
2487 if ( !presetName.isEmpty() )
2489 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2491 if ( presetName != mCachedLayerStyleOverridesPresetName )
2494 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2495 mCachedLayerStyleOverridesPresetName = presetName;
2498 return mCachedPresetLayerStyleOverrides;
2501 return QMap<QString, QString>();
2503 else if ( mFollowVisibilityPreset )
2505 QString presetName = mFollowVisibilityPresetName;
2508 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2510 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2513 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2514 mCachedLayerStyleOverridesPresetName = presetName;
2517 return mCachedPresetLayerStyleOverrides;
2520 return QMap<QString, QString>();
2522 else if ( mKeepLayerStyles )
2524 return mLayerStyleOverrides;
2528 return QMap<QString, QString>();
2532QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2534 double dx = mXOffset;
2535 double dy = mYOffset;
2536 transformShift( dx, dy );
2540void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2550 poly << QPointF( poly.at( 0 ) );
2562 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2568 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2574 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2580 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2583 poly << QPointF( poly.at( 0 ) );
2586void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2589 double dxScaled = xShift * mmToMapUnits;
2590 double dyScaled = - yShift * mmToMapUnits;
2605 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2606 if ( annotations.isEmpty() )
2616 if ( !annotation || !annotation->isVisible() )
2620 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2623 drawAnnotation( annotation, rc );
2637 double itemX, itemY;
2640 QPointF mapPos = layoutMapPosForItem( annotation );
2649 context.
painter()->translate( itemX, itemY );
2652 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2653 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2655 annotation->
render( context );
2658QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2661 return QPointF( 0, 0 );
2670 if ( annotationCrs !=
crs() )
2677 t.transformInPlace( mapX, mapY, z );
2687void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2698void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2709bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2711 if ( mCurrentExportPart == NotLayered )
2729 return mCurrentExportPart == Layer;
2732 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2734 case OverviewMapExtent:
2735 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2740 case SelectionBoxes:
2741 return mCurrentExportPart == SelectionBoxes && isSelected();
2762 bool useDdXMin =
false;
2763 bool useDdXMax =
false;
2764 bool useDdYMin =
false;
2765 bool useDdYMax =
false;
2796 if ( newExtent != mExtent )
2802 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2803 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2805 if ( currentWidthHeightRatio < newWidthHeightRatio )
2808 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2809 double deltaHeight = newHeight - newExtent.
height();
2816 double newWidth = currentWidthHeightRatio * newExtent.
height();
2817 double deltaWidth = newWidth - newExtent.
width();
2822 mExtent = newExtent;
2832 newExtent = mExtent;
2835 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2839 if ( useDdXMin && !useDdXMax )
2845 else if ( !useDdXMin && useDdXMax )
2851 if ( useDdYMin && !useDdYMax )
2857 else if ( !useDdYMin && useDdYMax )
2864 if ( newExtent != mExtent )
2866 mExtent = newExtent;
2883void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2896void QgsLayoutItemMap::updateAtlasFeature()
2915 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2920 double originalScale = calc.
calculate( originalExtent, rect().width() );
2921 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2922 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2923 QVector<qreal> scales;
2925 if ( !
mLayout->reportContext().predefinedScales().empty() )
2926 scales =
mLayout->reportContext().predefinedScales();
2928 scales =
mLayout->renderContext().predefinedScales();
2930 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2933 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2934 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2937 xMin + originalExtent.
width(),
2938 yMin + originalExtent.
height() );
2942 double newScale = calc.
calculate( newExtent, rect().width() );
2943 newExtent.
scale( originalScale / newScale );
2948 double newWidth = originalExtent.
width();
2949 double newHeight = originalExtent.
height();
2950 for (
int i = 0; i < scales.size(); i++ )
2952 double ratio = scales[i] / originalScale;
2953 newWidth = originalExtent.
width() * ratio;
2954 newHeight = originalExtent.
height() * ratio;
2957 double xMin = geomCenterX - newWidth / 2.0;
2958 double yMin = geomCenterY - newHeight / 2.0;
2966 double newScale = calc.
calculate( newExtent, rect().width() );
2967 newExtent.
scale( scales[i] / newScale );
2977 else if ( mAtlasScalingMode ==
Auto )
2981 double geomRatio = bounds.
width() / bounds.
height();
2982 double mapRatio = originalExtent.
width() / originalExtent.
height();
2985 if ( geomRatio < mapRatio )
2988 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
2993 else if ( geomRatio > mapRatio )
2996 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
3002 const double evaluatedAtlasMargin =
atlasMargin();
3003 if ( evaluatedAtlasMargin > 0.0 )
3005 newExtent.
scale( 1 + evaluatedAtlasMargin );
3031 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
3032 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3033 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
3034 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3037 center.
x() + dx, center.
y() + dy );
3045void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3048 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3050 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
3054 mStagedRendererJob->start();
3070 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3076 return mClipToAtlasFeature;
3081 if (
enabled == mClipToAtlasFeature )
3084 mClipToAtlasFeature =
enabled;
3090 return mFeatureClippingType;
3095 if ( mFeatureClippingType == type )
3098 mFeatureClippingType = type;
3104 return mForceLabelsInsideFeature;
3109 if ( forceInside == mForceLabelsInsideFeature )
3112 mForceLabelsInsideFeature = forceInside;
3118 return mRestrictToLayers;
3123 if ( mRestrictToLayers ==
enabled )
3132 return _qgis_listRefToRaw( mLayersToClip );
3143 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3144 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3145 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3146 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3147 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3150 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3155 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3156 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3157 layerElem.appendChild( layerIdText );
3159 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3160 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3161 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3163 layerSetElem.appendChild( layerElem );
3165 settingsElem.appendChild( layerSetElem );
3167 element.appendChild( settingsElem );
3173 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3175 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3176 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3178 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3180 mLayersToClip.clear();
3181 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3182 if ( !layerSetNodeList.isEmpty() )
3184 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3185 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3186 mLayersToClip.reserve( layerIdNodeList.size() );
3187 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3189 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3190 QString layerId = layerElem.text();
3191 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3192 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3193 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3195 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3198 mLayersToClip << ref;
3205void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3207 if ( !mLayersToClip.isEmpty() )
3209 _qgis_removeLayers( mLayersToClip, layers );
3224 return mEnabled && mClipPathSource;
3239 if ( mClipPathSource )
3242 mClipPathSource->refresh();
3251 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3262 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3263 clipGeom.
transform( mMap->sceneTransform().inverted() );
3278 if ( mClipPathSource == item )
3281 if ( mClipPathSource )
3290 mClipPathSource = item;
3292 if ( mClipPathSource )
3301 mClipPathSource->refresh();
3315 return mClipPathSource;
3320 return mFeatureClippingType;
3325 if ( mFeatureClippingType == type )
3328 mFeatureClippingType = type;
3334 return mForceLabelsInsideClipPath;
3339 if ( forceInside == mForceLabelsInsideClipPath )
3342 mForceLabelsInsideClipPath = forceInside;
3348 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3349 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3350 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3351 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3352 if ( mClipPathSource )
3353 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3355 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3357 element.appendChild( settingsElem );
3363 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3365 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3366 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3368 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3375 if ( !mClipPathUuid.isEmpty() )
QFlags< VectorRenderingSimplificationFlag > VectorRenderingSimplificationFlags
Simplification flags for vector feature rendering.
@ Millimeters
Millimeters.
@ NoSimplification
No simplification can be applied.
@ CollectUnplacedLabels
Whether unplaced labels should be collected in the labeling results (regardless of whether they are b...
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
@ UsePartialCandidates
Whether to use also label candidates that are partially outside of the map view.
@ Export
Renderer used for printing or exporting to a file.
@ View
Renderer used for displaying on screen.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
@ DrawEditingInfo
Enable drawing of vertex markers for layers in editing mode.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ ForceVectorOutput
Vector graphics should not be cached and drawn as raster images.
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
@ ForceRasterMasks
Force symbol masking to be applied using a raster method. This is considerably faster when compared t...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ AlwaysUseGlobalMasks
When applying clipping paths for selective masking, always use global ("entire map") paths,...
@ DrawSelection
Whether vector selections should be shown in the rendered map.
@ Antialiasing
Enable anti-aliasing for map rendering.
@ UseAdvancedEffects
Enable layer opacity and blending effects.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
QDateTime valueAsDateTime(int key, const QgsExpressionContext &context, const QDateTime &defaultDateTime=QDateTime(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a datetime.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
Abstract base class for annotation items which are drawn over a map.
QgsCoordinateReferenceSystem mapPositionCrs() const
Returns the CRS of the map position, or an invalid CRS if the annotation does not have a fixed map po...
void render(QgsRenderContext &context) const
Renders the annotation to a target render context.
bool isVisible() const
Returns true if the annotation is visible and should be rendered.
QPointF relativePosition() const
Returns the relative position of the annotation, if it is not attached to a fixed map position.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
void updateDefinition()
Updates the definition and parameters of the coordinate reference system to their latest values.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
Qgis::DistanceUnit mapUnits
Custom exception class for Coordinate Reference System related exceptions.
QgsRange which stores a range of double values.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
A geometry is the spatial representation of a feature.
QPolygonF asQPolygonF() const
Returns contents of the geometry as a QPolygonF.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
QList< QgsMapLayer * > childLayers() const
Returns the child layers contained by the group.
void setChildLayers(const QList< QgsMapLayer * > &layers)
Sets the child layers contained by the group.
A representation of the interval between two datetime values.
Label blocking region (in map coordinates and CRS).
Stores global configuration for labeling engine.
void setFlag(Qgis::LabelingFlag f, bool enabled=true)
Sets whether a particual flag is enabled.
Class that stores computed placement from labeling engine.
void layerOrderChanged()
Emitted when the layer order has changed.
Contains settings relating to clipping a layout map by the current atlas feature.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the current atlas feature.
bool restrictToLayers() const
Returns true if clipping should be restricted to a subset of layers.
QgsLayoutItemMapAtlasClippingSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapAtlasClippingSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
void setLayersToClip(const QList< QgsMapLayer * > &layers)
Sets the list of map layers to clip to the atlas feature.
QList< QgsMapLayer * > layersToClip() const
Returns the list of map layers to clip to the atlas feature.
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the current atlas feature.
void changed()
Emitted when the atlas clipping settings are changed.
bool forceLabelsInsideFeature() const
Returns true if labels should only be placed inside the atlas feature geometry.
bool enabled() const
Returns true if the map content should be clipped to the current atlas feature.
void setForceLabelsInsideFeature(bool forceInside)
Sets whether labels should only be placed inside the atlas feature geometry.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the current atlas feature.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
Contains settings relating to clipping a layout map by another layout item.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setForceLabelsInsideClipPath(bool forceInside)
Sets whether labels should only be placed inside the clip path geometry.
void setSourceItem(QgsLayoutItem *item)
Sets the source item which will provide the clipping path for the map.
QgsLayoutItemMapItemClipPathSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapItemClipPathSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
QgsGeometry clipPathInMapItemCoordinates() const
Returns the clipping path geometry, in the map item's coordinate space.
QgsGeometry clippedMapExtent() const
Returns the geometry to use for clipping the parent map, in the map item's CRS.
QgsLayoutItem * sourceItem()
Returns the source item which will provide the clipping path for the map, or nullptr if no item is se...
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the associated item.
bool forceLabelsInsideClipPath() const
Returns true if labels should only be placed inside the clip path geometry.
void finalizeRestoreFromXml()
To be called after all pending items have been restored from XML.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the associated item.
bool enabled() const
Returns true if the map content should be clipped to the associated item.
QgsMapClippingRegion toMapClippingRegion() const
Returns the clip path as a map clipping region.
void changed()
Emitted when the item clipping settings are changed.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the associated item.
bool isActive() const
Returns true if the item clipping is enabled and set to a valid source item.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
@ StackAboveMapLabels
Render above all map layers and labels.
StackingPosition stackingPosition() const
Returns the item's stacking position, which specifies where the in the map's stack the item should be...
bool enabled() const
Returns whether the item will be drawn.
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
Layout graphical items for displaying a map.
void setFollowVisibilityPreset(bool follow)
Sets whether the map should follow a map theme.
bool nextExportPart() override
Moves to the next export part for a multi-layered export item, during a multi-layered export.
void removeRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Removes a previously added rendered feature handler.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
~QgsLayoutItemMap() override
QIcon icon() const override
Returns the item's icon.
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties) override
void preparedForAtlas()
Emitted when the map has been prepared for atlas rendering, just before actual rendering.
void setFollowVisibilityPresetName(const QString &name)
Sets preset name for map rendering.
QTransform layoutToMapCoordsTransform() const
Creates a transform from layout coordinates to map coordinates.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
bool isLabelBlockingItem(QgsLayoutItem *item) const
Returns true if the specified item is a "label blocking item".
void storeCurrentLayerStyles()
Stores the current project layer styles into style overrides.
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
QgsLayoutMeasurement labelMargin() const
Returns the margin from the map edges in which no labels may be placed.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
@ Predefined
A scale is chosen from the predefined scales.
@ Auto
The extent is adjusted so that each feature is fully visible.
@ Fixed
The current scale of the map is used for each feature of the atlas.
bool requiresRasterization() const override
Returns true if the item is drawn in such a way that forces the whole layout to be rasterized when ex...
Q_DECL_DEPRECATED int numberExportLayers() const override
Returns the number of layers that this item requires for exporting during layered exports (e....
void layerStyleOverridesChanged()
Emitted when layer style overrides are changed... a means to let associated legend items know they sh...
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void moveContent(double dx, double dy) override
Moves the content of the item, by a specified dx and dy in layout units.
void setZRangeEnabled(bool enabled)
Sets whether the z range is enabled (i.e.
QgsLayoutItemMapGrid * grid()
Returns the map item's first grid.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
int type() const override
void previewRefreshed()
Emitted whenever the item's map preview has been refreshed.
friend class QgsLayoutItemMapOverview
void setExtent(const QgsRectangle &extent)
Sets a new extent for the map.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
QFlags< MapItemFlag > MapItemFlags
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
QPolygonF visibleExtentPolygon() const
Returns a polygon representing the current visible map extent, considering map extents and rotation.
QgsRectangle requestedExtent() const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
void setMapFlags(QgsLayoutItemMap::MapItemFlags flags)
Sets the map item's flags, which control how the map content is drawn.
void zoomContent(double factor, QPointF point) override
Zooms content of item.
QList< QgsMapLayer * > layersToRender(const QgsExpressionContext *context=nullptr) const
Returns a list of the layers which will be rendered within this map item, considering any locked laye...
void crsChanged()
Emitted when the map's coordinate reference system is changed.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the stored layers set.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
static QgsLayoutItemMap * create(QgsLayout *layout)
Returns a new map item for the specified layout.
QRectF boundingRect() const override
QString displayName() const override
Gets item display name.
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
void setZRange(const QgsDoubleRange &range)
Sets the map's z range, which is used to filter the map's content to only display features within the...
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for layers.
void stopLayeredExport() override
Stops a multi-layer export operation.
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map.
double estimatedFrameBleed() const override
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainterPath framePath() const override
Returns the path to use when drawing the item's frame or background.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void startLayeredExport() override
Starts a multi-layer export operation.
bool containsWmsLayer() const
Returns true if the map contains a WMS layer.
void setScale(double scale, bool forceUpdate=true)
Sets new map scale and changes only the map extent.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
double mapUnitsToLayoutUnits() const
Returns the conversion factor from map units to layout units.
QgsLayoutItemMap::MapItemFlags mapFlags() const
Returns the map item's flags, which control how the map content is drawn.
bool zRangeEnabled() const
Returns whether the z range is enabled (i.e.
void setLabelMargin(const QgsLayoutMeasurement &margin)
Sets the margin from the map edges in which no labels may be placed.
void themeChanged(const QString &theme)
Emitted when the map's associated theme is changed.
QgsLayoutItem::ExportLayerDetail exportLayerDetails() const override
Returns the details for the specified current export layer.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
double scale() const
Returns the map scale.
@ ShowPartialLabels
Whether to draw labels which are partially outside of the map view.
@ ShowUnplacedLabels
Whether to render unplaced labels in the map view.
bool drawAnnotations() const
Returns whether annotations are drawn within the map.
QgsDoubleRange zRange() const
Returns the map's z range, which is used to filter the map's content to only display features within ...
void removeLabelBlockingItem(QgsLayoutItem *item)
Removes the specified layout item from the map's "label blocking items".
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the map's preset crs (coordinate reference system).
void invalidateCache() override
QgsRectangle extent() const
Returns the current map extent.
QgsLayoutItemMapOverview * overview()
Returns the map item's first overview.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setFrameStrokeWidth(QgsLayoutMeasurement width) override
Sets the frame stroke width.
bool containsAdvancedEffects() const override
Returns true if the item contains contents with blend modes or transparency effects which can only be...
friend class QgsLayoutItemMapGrid
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
void setMoveContentPreviewOffset(double dx, double dy) override
Sets temporary offset for the item, by a specified dx and dy in layout units.
void setMapRotation(double rotation)
Sets the rotation for the map - this does not affect the layout item shape, only the way the map is d...
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
double atlasMargin(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue)
Returns the margin size (percentage) used when the map is in atlas mode.
void addLabelBlockingItem(QgsLayoutItem *item)
Sets the specified layout item as a "label blocking item" for this map.
void assignFreeId()
Sets the map id() to a number not yet used in the layout.
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
QgsLabelingResults * previewLabelingResults() const
Returns the labeling results of the most recent preview map render.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Base class for graphical items within a QgsLayout.
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
virtual QPainterPath framePath() const
Returns the path to use when drawing the item's frame or background.
QColor backgroundColor(bool useDataDefined=true) const
Returns the background color for this item.
void drawRefreshingOverlay(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle)
Draws a "refreshing" overlay icon on the item.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
void rotationChanged(double newRotation)
Emitted on item rotation change.
friend class QgsLayoutItemMap
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void drawBackground(QgsRenderContext &context)
Draws the background for the item.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
@ FlagOverridesPaint
Item overrides the default layout item painting method.
@ FlagDisableSceneCaching
Item should not have QGraphicsItem caching enabled.
virtual bool containsAdvancedEffects() const
Returns true if the item contains contents with blend modes or transparency effects which can only be...
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
QString id() const
Returns the item's ID name.
bool frameEnabled() const
Returns true if the item includes a frame.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ ItemContainsSubLayers
Item contains multiple sublayers which must be individually exported.
void clipPathChanged()
Emitted when the item's clipping path has changed.
bool hasBackground() const
Returns true if the item has a background.
void refresh() override
Refreshes the item, causing a recalculation of any property overrides and recalculation of its positi...
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
void backgroundTaskCountChanged(int count)
Emitted whenever the number of background tasks an item is executing changes.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
void setLength(const double length)
Sets the length of the measurement.
static QgsLayoutMeasurement decodeMeasurement(const QString &string)
Decodes a measurement from a string.
QString encodeMeasurement() const
Encodes the layout measurement to a string.
Qgis::LayoutUnit units() const
Returns the units for the measurement.
void setUnits(const Qgis::LayoutUnit units)
Sets the units for the measurement.
double length() const
Returns the length of the measurement.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
DataDefinedProperty
Data defined properties for different item types.
@ MapYMin
Map extent y minimum.
@ MapZRangeUpper
Map frame Z-range lower value.
@ StartDateTime
Temporal range's start DateTime.
@ MapLayers
Map layer set.
@ MapZRangeLower
Map frame Z-range lower value.
@ MapRotation
Map rotation.
@ MapXMax
Map extent x maximum.
@ MapStylePreset
Layer and style map theme.
@ MapYMax
Map extent y maximum.
@ MapAtlasMargin
Map atlas margin.
@ EndDateTime
Temporal range's end DateTime.
@ MapXMin
Map extent x minimum.
@ MapLabelMargin
Map label margin.
@ AllProperties
All properties for item.
PropertyValueType
Specifies whether the value returned by a function should be the original, user set value,...
@ EvaluatedValue
Return the current evaluated value for the property.
void predefinedScalesChanged()
Emitted when the list of predefined scales changes.
@ FlagRenderLabelsByMapLayer
When rendering map items to multi-layered exports, render labels belonging to different layers into s...
@ FlagAlwaysUseGlobalMasks
When applying clipping paths for selective masking, always use global ("entire map") paths,...
@ FlagUseAdvancedEffects
Enable advanced effects such as blend modes.
@ FlagDrawSelection
Draw selection.
@ FlagLosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ FlagAntialiasing
Use antialiasing when drawing items.
@ FlagForceVectorOutput
Force output in vector format where possible, even if items require rasterization to keep their corre...
@ FlagHideCoverageLayer
Hide coverage layer in outputs.
@ FlagDisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
static QgsRenderContext createRenderContextForMap(QgsLayoutItemMap *map, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout map and painter destination.
static void rotate(double angle, double &x, double &y)
Rotates a point / vector around the origin.
static Q_DECL_DEPRECATED double scaleFactorFromItemStyle(const QStyleOptionGraphicsItem *style)
Extracts the scale factor from an item style.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
void refreshed()
Emitted when the layout has been refreshed and items should also be refreshed and updated.
QgsProject * project() const
The project associated with the layout.
A map clipping region (in map coordinates and CRS).
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
FeatureClippingType
Feature clipping behavior, which controls how features from vector layers will be clipped.
void setFeatureClip(FeatureClippingType type)
Sets the feature clipping type.
void setRestrictedLayers(const QList< QgsMapLayer * > &layers)
Sets a list of layers to restrict the clipping region effects to.
Stores style information (renderer, opacity, labeling, diagrams etc.) applicable to a map layer.
void readXml(const QDomElement &styleElement)
Read style configuration (for project file reading)
void readFromLayer(QgsMapLayer *layer)
Store layer's active style information in the instance.
void writeXml(QDomElement &styleElement) const
Write style configuration (for project file writing)
QString xmlData() const
Returns XML content of the style.
Base class for all map layer types.
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
Job implementation that renders everything sequentially using a custom painter.
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
void finished()
emitted when asynchronous rendering is finished (or canceled).
Render job implementation that renders maps in stages, allowing different stages (e....
@ RenderLabelsByMapLayer
Labels should be rendered in individual stages by map layer. This allows separation of labels belongi...
@ Finished
Rendering is finished.
@ Symbology
Rendering layer symbology.
@ Labels
Rendering labels.
static QStringList containsAdvancedEffects(const QgsMapSettings &mapSettings, EffectsCheckFlags flags=QgsMapSettingsUtils::EffectsCheckFlags())
Checks whether any of the layers attached to a map settings object contain advanced effects.
The QgsMapSettings class contains configuration for rendering of the map.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &renderer)
Sets the shading renderer used to render shading on the entire map.
void addClippingRegion(const QgsMapClippingRegion ®ion)
Adds a new clipping region to the map settings.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setSimplifyMethod(const QgsVectorSimplifyMethod &method)
Sets the simplification setting to use when rendering vector layers.
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated)
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map settings.
void setTextRenderFormat(Qgis::TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
void setDevicePixelRatio(float dpr)
Sets the device pixel ratio.
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which will be visible in the map.
long long currentFrame() const
Returns the current frame number of the map, for maps which are part of an animation.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
void setRendererUsage(Qgis::RendererUsage rendererUsage)
Sets the rendering usage.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setMaskSettings(const QgsMaskRenderSettings &settings)
Sets the mask render settings, which control how masks are drawn and behave during the map render.
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
double frameRate() const
Returns the frame rate of the map (in frames per second), for maps which are part of an animation.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
void setLabelBoundaryGeometry(const QgsGeometry &boundary)
Sets the label boundary geometry, which restricts where in the rendered map labels are permitted to b...
void setLabelBlockingRegions(const QList< QgsLabelBlockingRegion > ®ions)
Sets a list of regions to avoid placing labels within.
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
void mapThemeRenamed(const QString &name, const QString &newName)
Emitted when a map theme within the collection is renamed.
void mapThemeChanged(const QString &theme)
Emitted when a map theme changes definition.
A class to represent a 2D point.
QString description() const
Description.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
void crsChanged()
Emitted when the crs() of the project has changed.
QgsMapThemeCollection * mapThemeCollection
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
T lower() const
Returns the lower bound of the range.
T upper() const
Returns the upper bound of the range.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
void setYMinimum(double y)
Set the minimum y value.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
void setXMinimum(double x)
Set the minimum x value.
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
bool isNull() const
Test if the rectangle is null (holding no spatial information).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
void setYMaximum(double y)
Set the maximum y value.
QgsPointXY center() const
Returns the center point of the rectangle.
void setXMaximum(double x)
Set the maximum x value.
bool isEmpty() const
Returns true if the rectangle has no area.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
double height() const
Returns the height of the rectangle.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
An interface for classes which provider custom handlers for features rendered as part of a map render...
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the output resolution, to be used in scale calculations.
void setMapUnits(Qgis::DistanceUnit mapUnits)
Set the map units.
Scoped object for saving and restoring a QPainter object's state.
An interface for classes which can visit style entity (e.g.
@ LayoutItem
Individual item in a print layout.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static double scaleToZoom(double mapScale, double z0Scale=559082264.0287178)
Finds zoom level given map scale denominator.
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale=559082264.0287178)
Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
const QgsCoordinateReferenceSystem & crs
Single variable definition for use within a QgsExpressionContextScope.
Contains details of a particular export layer relating to a layout item.
QPainter::CompositionMode compositionMode
Associated composition mode if this layer is associated with a map layer.
QString mapLayerId
Associated map layer ID, or an empty string if this export layer is not associated with a map layer.
double opacity
Associated opacity, if this layer is associated with a map layer.
QString name
User-friendly name for the export layer.
QString mapTheme
Associated map theme, or an empty string if this export layer does not need to be associated with a m...
Contains information relating to a node (i.e.
TYPE * resolveWeakly(const QgsProject *project, MatchType matchType=MatchType::All)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
QString source
Weak reference to layer public source.
QString name
Weak reference to layer name.
QString provider
Weak reference to layer provider.
TYPE * resolve(const QgsProject *project)
Resolves the map layer by attempting to find a layer with matching ID within a project.
QString layerId
Original layer ID.