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() || !
mLayout )
183 calculator.
setDpi( 25.4 );
186 calculator.
setMethod( project->scaleMethod() );
194 double currentScaleDenominator =
scale();
201 double scaleRatio = scaleDenominator / currentScaleDenominator;
202 mExtent.
scale( scaleRatio );
204 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
211 calculator.
setDpi( 25.4 );
217 const double newScale = calculator.
calculate( mExtent, rect().width() );
220 scaleRatio = scaleDenominator / newScale;
221 mExtent.
scale( scaleRatio );
248 const QRectF currentRect = rect();
249 const double newHeight = mExtent.
width() == 0 ? 0
250 : currentRect.width() * mExtent.
height() / mExtent.
width();
262 double currentWidthHeightRatio = 1.0;
263 if ( !currentExtent.
isEmpty() )
264 currentWidthHeightRatio = currentExtent.
width() / currentExtent.
height();
266 currentWidthHeightRatio = rect().width() / rect().height();
268 if ( currentWidthHeightRatio != 0 && ! std::isnan( currentWidthHeightRatio ) && !newExtent.
isEmpty() )
270 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
272 if ( currentWidthHeightRatio < newWidthHeightRatio )
275 double newHeight = newExtent.
width() / currentWidthHeightRatio;
276 double deltaHeight = newHeight - newExtent.
height();
283 double newWidth = currentWidthHeightRatio * newExtent.
height();
284 double deltaWidth = newWidth - newExtent.
width();
290 if ( mExtent == newExtent )
309QPolygonF QgsLayoutItemMap::calculateVisibleExtentPolygon(
bool includeClipping )
const
312 mapPolygon( mExtent, poly );
314 if ( includeClipping && mItemClippingSettings->
isActive() )
328 return calculateVisibleExtentPolygon(
true );
336 return mLayout->project()->crs();
351 return _qgis_listRefToRaw( mLayers );
356 mGroupLayers.clear();
358 QList<QgsMapLayer *> layersCopy {
layers };
363 for (
auto it = layersCopy.begin(); it != layersCopy.end(); ++it )
365 if (
const QgsGroupLayer *groupLayer = qobject_cast<QgsGroupLayer *>( *it ) )
367 auto existingIt = mGroupLayers.find( groupLayer->id() );
368 if ( existingIt != mGroupLayers.end( ) )
370 *it = ( *existingIt ).second.get();
374 std::unique_ptr<QgsGroupLayer> groupLayerClone { groupLayer->clone() };
375 mGroupLayers[ groupLayer->id() ] = std::move( groupLayerClone );
376 *it = mGroupLayers[ groupLayer->id() ].get();
380 mLayers = _qgis_listRawToRef( layersCopy );
385 if ( overrides == mLayerStyleOverrides )
388 mLayerStyleOverrides = overrides;
395 mLayerStyleOverrides.clear();
402 mLayerStyleOverrides.insert( layer->id(), style.
xmlData() );
409 if ( mFollowVisibilityPreset == follow )
412 mFollowVisibilityPreset = follow;
414 if ( !mFollowVisibilityPresetName.isEmpty() )
415 emit
themeChanged( mFollowVisibilityPreset ? mFollowVisibilityPresetName : QString() );
420 if ( name == mFollowVisibilityPresetName )
423 mFollowVisibilityPresetName = name;
424 if ( mFollowVisibilityPreset )
430 mLastRenderedImageOffsetX -= dx;
431 mLastRenderedImageOffsetY -= dy;
434 transformShift( dx, dy );
458 double mapY = mExtent.
yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( mExtent.
yMaximum() - mExtent.
yMinimum() );
464 centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
465 centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
467 double newIntervalX, newIntervalY;
484 if ( mAtlasDriven && mAtlasScalingMode ==
Fixed )
491 calculator.
setDpi( 25.4 );
496 const double newScale = calculator.
calculate( mExtent, rect().
width() );
499 const double scaleRatio =
scale() / newScale ;
500 mExtent.
scale( scaleRatio );
517 if ( layer->dataProvider() && layer->providerType() == QLatin1String(
"wms" ) )
527 if (
blendMode() != QPainter::CompositionMode_SourceOver )
546 auto containsAdvancedEffectsIgnoreItemOpacity = [
this]()->
bool
556 if ( mOverviewStack->containsAdvancedEffects() )
564 if ( mGridStack->containsAdvancedEffects() )
577 if ( !containsAdvancedEffectsIgnoreItemOpacity() )
598 if ( mOverviewStack->containsAdvancedEffects() )
606 if ( mGridStack->containsAdvancedEffects() )
621 mMapRotation = rotation;
622 mEvaluatedMapRotation = mMapRotation;
635 mAtlasDriven = enabled;
652 double margin = mAtlasMargin;
660 margin = ddMargin / 100;
672 if ( mGridStack->size() < 1 )
675 mGridStack->addGrid(
grid );
677 return mGridStack->grid( 0 );
682 if ( mOverviewStack->size() < 1 )
685 mOverviewStack->addOverview(
overview );
687 return mOverviewStack->overview( 0 );
697 for (
int i = 0; i < mGridStack->size(); ++i )
700 if (
grid->mEvaluatedEnabled )
703 frameBleed = std::max( frameBleed,
grid->mEvaluatedGridFrameWidth +
grid->mEvaluatedGridFrameMargin +
grid->mEvaluatedGridFrameLineThickness / 2.0 );
719 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"true" ) );
723 mapElem.setAttribute( QStringLiteral(
"keepLayerSet" ), QStringLiteral(
"false" ) );
726 if ( mDrawAnnotations )
728 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
732 mapElem.setAttribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"false" ) );
736 QDomElement extentElem = doc.createElement( QStringLiteral(
"Extent" ) );
741 mapElem.appendChild( extentElem );
745 QDomElement crsElem = doc.createElement( QStringLiteral(
"crs" ) );
747 mapElem.appendChild( crsElem );
751 mapElem.setAttribute( QStringLiteral(
"followPreset" ), mFollowVisibilityPreset ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
752 mapElem.setAttribute( QStringLiteral(
"followPresetName" ), mFollowVisibilityPresetName );
755 mapElem.setAttribute( QStringLiteral(
"mapRotation" ), QString::number( mMapRotation ) );
758 QDomElement layerSetElem = doc.createElement( QStringLiteral(
"LayerSet" ) );
763 QDomElement layerElem = doc.createElement( QStringLiteral(
"Layer" ) );
765 const auto it = std::find_if( mGroupLayers.cbegin(), mGroupLayers.cend(), [ &layerRef ](
const std::pair<
const QString, std::unique_ptr<QgsGroupLayer>> &groupLayer ) ->
bool
767 return groupLayer.second.get() == layerRef.get();
770 if ( it != mGroupLayers.end() )
776 layerId = layerRef.layerId;
779 QDomText layerIdText = doc.createTextNode( layerId );
780 layerElem.appendChild( layerIdText );
782 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
783 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
784 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
786 if ( it != mGroupLayers.end() )
788 const auto childLayers { it->second->childLayers() };
789 QDomElement childLayersElement = doc.createElement( QStringLiteral(
"childLayers" ) );
790 for (
const QgsMapLayer *childLayer : std::as_const( childLayers ) )
792 QDomElement childElement = doc.createElement( QStringLiteral(
"child" ) );
793 childElement.setAttribute( QStringLiteral(
"layerid" ), childLayer->id() );
794 childLayersElement.appendChild( childElement );
796 layerElem.appendChild( childLayersElement );
798 layerSetElem.appendChild( layerElem );
800 mapElem.appendChild( layerSetElem );
803 if ( mKeepLayerStyles )
805 QDomElement stylesElem = doc.createElement( QStringLiteral(
"LayerStyles" ) );
806 for (
auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
808 QDomElement styleElem = doc.createElement( QStringLiteral(
"LayerStyle" ) );
813 styleElem.setAttribute( QStringLiteral(
"layerid" ), ref.
layerId );
814 styleElem.setAttribute( QStringLiteral(
"name" ), ref.
name );
815 styleElem.setAttribute( QStringLiteral(
"source" ), ref.
source );
816 styleElem.setAttribute( QStringLiteral(
"provider" ), ref.
provider );
820 stylesElem.appendChild( styleElem );
822 mapElem.appendChild( stylesElem );
826 mGridStack->writeXml( mapElem, doc, context );
829 mOverviewStack->writeXml( mapElem, doc, context );
832 QDomElement atlasElem = doc.createElement( QStringLiteral(
"AtlasMap" ) );
833 atlasElem.setAttribute( QStringLiteral(
"atlasDriven" ), mAtlasDriven );
834 atlasElem.setAttribute( QStringLiteral(
"scalingMode" ), mAtlasScalingMode );
835 atlasElem.setAttribute( QStringLiteral(
"margin" ),
qgsDoubleToString( mAtlasMargin ) );
836 mapElem.appendChild( atlasElem );
838 mapElem.setAttribute( QStringLiteral(
"labelMargin" ), mLabelMargin.
encodeMeasurement() );
839 mapElem.setAttribute( QStringLiteral(
"mapFlags" ),
static_cast< int>( mMapFlags ) );
841 QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral(
"labelBlockingItems" ) );
842 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
847 QDomElement blockingItemElem = doc.createElement( QStringLiteral(
"item" ) );
848 blockingItemElem.setAttribute( QStringLiteral(
"uuid" ), item->uuid() );
849 labelBlockingItemsElem.appendChild( blockingItemElem );
851 mapElem.appendChild( labelBlockingItemsElem );
854 mapElem.setAttribute( QStringLiteral(
"isTemporal" ),
isTemporal() ? 1 : 0 );
857 mapElem.setAttribute( QStringLiteral(
"temporalRangeBegin" ),
temporalRange().
begin().toString( Qt::ISODate ) );
858 mapElem.setAttribute( QStringLiteral(
"temporalRangeEnd" ),
temporalRange().
end().toString( Qt::ISODate ) );
861 mapElem.setAttribute( QStringLiteral(
"enableZRange" ), mZRangeEnabled ? 1 : 0 );
862 if ( mZRange.
lower() != std::numeric_limits< double >::lowest() )
864 if ( mZRange.
upper() != std::numeric_limits< double >::max() )
867 mAtlasClippingSettings->
writeXml( mapElem, doc, context );
868 mItemClippingSettings->
writeXml( mapElem, doc, context );
875 mUpdatesEnabled =
false;
878 QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral(
"Extent" ) );
879 if ( !extentNodeList.isEmpty() )
881 QDomElement extentElem = extentNodeList.at( 0 ).toElement();
882 double xmin, xmax, ymin, ymax;
883 xmin = extentElem.attribute( QStringLiteral(
"xmin" ) ).toDouble();
884 xmax = extentElem.attribute( QStringLiteral(
"xmax" ) ).toDouble();
885 ymin = extentElem.attribute( QStringLiteral(
"ymin" ) ).toDouble();
886 ymax = extentElem.attribute( QStringLiteral(
"ymax" ) ).toDouble();
890 QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral(
"crs" ) );
892 if ( !crsNodeList.isEmpty() )
894 QDomElement crsElem = crsNodeList.at( 0 ).toElement();
900 mMapRotation = itemElem.attribute( QStringLiteral(
"mapRotation" ), QStringLiteral(
"0" ) ).toDouble();
901 mEvaluatedMapRotation = mMapRotation;
904 mFollowVisibilityPreset = itemElem.attribute( QStringLiteral(
"followPreset" ) ).compare( QLatin1String(
"true" ) ) == 0;
905 mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral(
"followPresetName" ) );
908 QString keepLayerSetFlag = itemElem.attribute( QStringLiteral(
"keepLayerSet" ) );
909 if ( keepLayerSetFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
911 mKeepLayerSet =
true;
915 mKeepLayerSet =
false;
918 QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral(
"drawCanvasItems" ), QStringLiteral(
"true" ) );
919 if ( drawCanvasItemsFlag.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 )
921 mDrawAnnotations =
true;
925 mDrawAnnotations =
false;
928 mLayerStyleOverrides.clear();
930 QList<QgsMapLayerRef> layerSet;
931 QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerSet" ) );
932 if ( !layerSetNodeList.isEmpty() )
934 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
935 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
936 layerSet.reserve( layerIdNodeList.size() );
937 for (
int i = 0; i < layerIdNodeList.size(); ++i )
939 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
940 QString layerId = layerElem.text();
941 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
942 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
943 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
945 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
953 setLayers( _qgis_listRefToRaw( layerSet ) );
956 if ( !layerSetNodeList.isEmpty() )
958 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
959 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
960 for (
int i = 0; i < layerIdNodeList.size(); ++i )
962 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
963 const QString layerId = layerElem.text();
964 const auto it = mGroupLayers.find( layerId );
965 if ( it != mGroupLayers.cend() )
967 QList<QgsMapLayerRef> childSet;
968 const QDomNodeList childLayersElements = layerElem.elementsByTagName( QStringLiteral(
"childLayers" ) );
969 const QDomNodeList children = childLayersElements.at( 0 ).childNodes();
970 for (
int i = 0; i < children.size(); ++i )
972 const QDomElement childElement = children.at( i ).toElement();
973 const QString
id = childElement.attribute( QStringLiteral(
"layerid" ) );
975 if ( layerRef.resolveWeakly(
mLayout->project() ) )
977 childSet.push_back( layerRef );
980 it->second->setChildLayers( _qgis_listRefToRaw( childSet ) );
987 QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral(
"LayerStyles" ) );
988 mKeepLayerStyles = !layerStylesNodeList.isEmpty();
989 if ( mKeepLayerStyles )
991 QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
992 QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral(
"LayerStyle" ) );
993 for (
int i = 0; i < layerStyleNodeList.size(); ++i )
995 const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
996 QString layerId = layerStyleElement.attribute( QStringLiteral(
"layerid" ) );
997 QString layerName = layerStyleElement.attribute( QStringLiteral(
"name" ) );
998 QString layerSource = layerStyleElement.attribute( QStringLiteral(
"source" ) );
999 QString layerProvider = layerStyleElement.attribute( QStringLiteral(
"provider" ) );
1000 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
1004 style.
readXml( layerStyleElement );
1010 mNumCachedLayers = 0;
1011 mCacheInvalidated =
true;
1014 mOverviewStack->readXml( itemElem, doc, context );
1017 mGridStack->readXml( itemElem, doc, context );
1020 QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral(
"AtlasMap" ) );
1021 if ( !atlasNodeList.isEmpty() )
1023 QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1024 mAtlasDriven = ( atlasElem.attribute( QStringLiteral(
"atlasDriven" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) );
1025 if ( atlasElem.hasAttribute( QStringLiteral(
"fixedScale" ) ) )
1027 mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral(
"fixedScale" ), QStringLiteral(
"0" ) ) != QLatin1String(
"0" ) ) ?
Fixed :
Auto;
1029 else if ( atlasElem.hasAttribute( QStringLiteral(
"scalingMode" ) ) )
1031 mAtlasScalingMode =
static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral(
"scalingMode" ) ).toInt() );
1033 mAtlasMargin = atlasElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"0.1" ) ).toDouble();
1038 mMapFlags =
static_cast< MapItemFlags>( itemElem.attribute( QStringLiteral(
"mapFlags" ),
nullptr ).toInt() );
1041 mBlockingLabelItems.clear();
1042 mBlockingLabelItemUuids.clear();
1043 QDomNodeList labelBlockingNodeList = itemElem.elementsByTagName( QStringLiteral(
"labelBlockingItems" ) );
1044 if ( !labelBlockingNodeList.isEmpty() )
1046 QDomElement blockingItems = labelBlockingNodeList.at( 0 ).toElement();
1047 QDomNodeList labelBlockingNodeList = blockingItems.childNodes();
1048 for (
int i = 0; i < labelBlockingNodeList.size(); ++i )
1050 const QDomElement &itemBlockingElement = labelBlockingNodeList.at( i ).toElement();
1051 const QString itemUuid = itemBlockingElement.attribute( QStringLiteral(
"uuid" ) );
1052 mBlockingLabelItemUuids << itemUuid;
1056 mAtlasClippingSettings->
readXml( itemElem, doc, context );
1057 mItemClippingSettings->
readXml( itemElem, doc, context );
1062 setIsTemporal( itemElem.attribute( QStringLiteral(
"isTemporal" ) ).toInt() );
1065 const QDateTime begin = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeBegin" ) ), Qt::ISODate );
1066 const QDateTime end = QDateTime::fromString( itemElem.attribute( QStringLiteral(
"temporalRangeEnd" ) ), Qt::ISODate );
1070 mZRangeEnabled = itemElem.attribute( QStringLiteral(
"enableZRange" ) ).toInt();
1072 double zLower = itemElem.attribute( QStringLiteral(
"zRangeLower" ) ).toDouble( &ok );
1075 zLower = std::numeric_limits< double >::lowest();
1077 double zUpper = itemElem.attribute( QStringLiteral(
"zRangeUpper" ) ).toDouble( &ok );
1080 zUpper = std::numeric_limits< double >::max();
1084 mUpdatesEnabled =
true;
1090 if ( mItemClippingSettings->
isActive() )
1101 if ( !
mLayout || !painter || !painter->device() || !mUpdatesEnabled )
1110 QRectF thisPaintRect = rect();
1116 if (
mLayout->renderContext().isPreviewRender() )
1118 bool renderInProgress =
false;
1119 mPreviewDevicePixelRatio = painter->device()->devicePixelRatioF();
1122 painter->setClipRect( thisPaintRect );
1123 if ( !mCacheFinalImage || mCacheFinalImage->isNull() )
1126 painter->setBrush( QBrush( QColor( 125, 125, 125, 125 ) ) );
1127 painter->drawRect( thisPaintRect );
1128 painter->setBrush( Qt::NoBrush );
1130 messageFont.setPointSize( 12 );
1131 painter->setFont( messageFont );
1132 painter->setPen( QColor( 255, 255, 255, 255 ) );
1133 painter->drawText( thisPaintRect, Qt::AlignCenter | Qt::AlignHCenter, tr(
"Rendering map" ) );
1134 if ( mPainterJob && mCacheInvalidated && !mDrawingPreview )
1138 mBackgroundUpdateTimer->start( 1 );
1140 else if ( !mPainterJob && !mDrawingPreview )
1144 mBackgroundUpdateTimer->start( 1 );
1146 renderInProgress =
true;
1150 if ( mCacheInvalidated && !mDrawingPreview )
1154 mBackgroundUpdateTimer->start( 1 );
1155 renderInProgress =
true;
1160 double imagePixelWidth = mCacheFinalImage->width();
1161 double scale = rect().width() / imagePixelWidth * mCacheFinalImage->devicePixelRatio();
1165 painter->translate( mLastRenderedImageOffsetX + mXOffset, mLastRenderedImageOffsetY + mYOffset );
1166 painter->setCompositionMode( blendModeForRender() );
1168 painter->drawImage( 0, 0, *mCacheFinalImage );
1173 painter->setClipRect( thisPaintRect, Qt::NoClip );
1175 mOverviewStack->drawItems( painter,
false );
1176 mGridStack->drawItems( painter );
1178 drawMapFrame( painter );
1180 if ( renderInProgress )
1191 QPaintDevice *paintDevice = painter->device();
1199 painter->setRenderHint( QPainter::LosslessImageRendering,
true );
1204 && ( !
mLayout || !forceVector ) )
1209 int widthInPixels =
static_cast< int >( std::round(
boundingRect().width() * layoutUnitsInInches * destinationDpi ) );
1210 int heightInPixels =
static_cast< int >( std::round(
boundingRect().height() * layoutUnitsInInches * destinationDpi ) );
1211 QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
1213 image.fill( Qt::transparent );
1214 image.setDotsPerMeterX(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1215 image.setDotsPerMeterY(
static_cast< int >( std::round( 1000 * destinationDpi / 25.4 ) ) );
1216 double dotsPerMM = destinationDpi / 25.4;
1217 QPainter p( &image );
1220 QRect imagePaintRect(
static_cast< int >( std::round( tl.x() * dotsPerMM ) ),
1221 static_cast< int >( std::round( tl.y() * dotsPerMM ) ),
1222 static_cast< int >( std::round( thisPaintRect.width() * dotsPerMM ) ),
1223 static_cast< int >( std::round( thisPaintRect.height() * dotsPerMM ) ) );
1224 p.setClipRect( imagePaintRect );
1226 p.translate( imagePaintRect.topLeft() );
1230 if ( shouldDrawPart( Background ) )
1232 p.scale( dotsPerMM, dotsPerMM );
1233 drawMapBackground( &p );
1234 p.scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
1237 drawMap( &p, cExtent, imagePaintRect.size(), image.logicalDpiX() );
1242 p.scale( dotsPerMM, dotsPerMM );
1244 if ( shouldDrawPart( OverviewMapExtent ) )
1246 mOverviewStack->drawItems( &p,
false );
1248 if ( shouldDrawPart( Grid ) )
1250 mGridStack->drawItems( &p );
1255 painter->setCompositionMode( blendModeForRender() );
1256 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1257 painter->drawImage( QPointF( -tl.x()* dotsPerMM, -tl.y() * dotsPerMM ), image );
1258 painter->scale( dotsPerMM, dotsPerMM );
1263 if ( shouldDrawPart( Background ) )
1265 drawMapBackground( painter );
1269 painter->setClipRect( thisPaintRect );
1274 painter->translate( mXOffset, mYOffset );
1276 double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
1278 painter->scale( 1 / dotsPerMM, 1 / dotsPerMM );
1280 if ( mCurrentExportPart != NotLayered )
1282 if ( !mStagedRendererJob )
1284 createStagedRenderJob( cExtent, size, paintDevice->logicalDpiX() );
1287 mStagedRendererJob->renderCurrentPart( painter );
1291 drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
1295 painter->setClipRect( thisPaintRect, Qt::NoClip );
1297 if ( shouldDrawPart( OverviewMapExtent ) )
1299 mOverviewStack->drawItems( painter,
false );
1301 if ( shouldDrawPart( Grid ) )
1303 mGridStack->drawItems( painter );
1308 if ( shouldDrawPart( Frame ) )
1310 drawMapFrame( painter );
1321 + ( layerCount + ( layerCount ? 1 : 0 ) )
1322 + ( mGridStack->hasEnabledItems() ? 1 : 0 )
1323 + ( mOverviewStack->hasEnabledItems() ? 1 : 0 )
1329 mCurrentExportPart = Start;
1331 mExportThemes = !mFollowVisibilityPreset ?
mLayout->renderContext().exportThemes() : QStringList();
1332 mExportThemeIt = mExportThemes.begin();
1337 mCurrentExportPart = NotLayered;
1338 mExportThemes.clear();
1339 mExportThemeIt = mExportThemes.begin();
1344 switch ( mCurrentExportPart )
1349 mCurrentExportPart = Background;
1355 mCurrentExportPart = Layer;
1359 if ( mStagedRendererJob )
1361 if ( mStagedRendererJob->nextPart() )
1365 mExportLabelingResults.reset( mStagedRendererJob->takeLabelingResults() );
1366 mStagedRendererJob.reset();
1370 if ( mExportThemeIt != mExportThemes.end() && ++mExportThemeIt != mExportThemes.end() )
1376 if ( mGridStack->hasEnabledItems() )
1378 mCurrentExportPart = Grid;
1384 for (
int i = 0; i < mOverviewStack->size(); ++i )
1389 mCurrentExportPart = OverviewMapExtent;
1395 case OverviewMapExtent:
1398 mCurrentExportPart = Frame;
1405 if ( isSelected() && !
mLayout->renderContext().isPreviewRender() )
1407 mCurrentExportPart = SelectionBoxes;
1412 case SelectionBoxes:
1413 mCurrentExportPart = End;
1434 switch ( mCurrentExportPart )
1444 if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
1447 if ( mStagedRendererJob )
1449 switch ( mStagedRendererJob->currentStage() )
1453 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1454 detail.
compositionMode = mStagedRendererJob->currentLayerCompositionMode();
1455 detail.
opacity = mStagedRendererJob->currentLayerOpacity();
1461 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), layer->name() );
1463 else if (
mLayout->project()->mainAnnotationLayer()->id() == detail.
mapLayerId )
1469 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), tr(
"Annotations" ) );
1474 const QList<QgsLayoutItemMapOverview *> res = mOverviewStack->asList();
1480 if ( item->mapLayer() && detail.
mapLayerId == item->mapLayer()->id() )
1483 detail.
name = QStringLiteral(
"%1 (%2): %3" ).arg(
displayName(), detail.
mapTheme, item->mapLayer()->name() );
1485 detail.
name = QStringLiteral(
"%1: %2" ).arg(
displayName(), item->mapLayer()->name() );
1494 detail.
mapLayerId = mStagedRendererJob->currentLayerId();
1500 detail.
name = tr(
"%1: %2 (Labels)" ).arg(
displayName(), layer->name() );
1535 case OverviewMapExtent:
1543 case SelectionBoxes:
1558void QgsLayoutItemMap::drawMap( QPainter *painter,
const QgsRectangle &extent, QSizeF size,
double dpi )
1572 if ( shouldDrawPart( OverviewMapExtent ) )
1574 ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
1578#ifdef HAVE_SERVER_PYTHON_PLUGINS
1579 job.setFeatureFilterProvider(
mLayout->renderContext().featureFilterProvider() );
1585 job.renderSynchronously();
1587 mExportLabelingResults.reset( job.takeLabelingResults() );
1589 mRenderingErrors = job.errors();
1592void QgsLayoutItemMap::recreateCachedImageInBackground()
1598 QPainter *oldPainter = mPainter.release();
1599 QImage *oldImage = mCacheRenderingImage.release();
1602 oldJob->deleteLater();
1610 mCacheRenderingImage.reset(
nullptr );
1614 Q_ASSERT( !mPainterJob );
1615 Q_ASSERT( !mPainter );
1616 Q_ASSERT( !mCacheRenderingImage );
1622 int w =
static_cast< int >( std::round( widthLayoutUnits * mPreviewScaleFactor ) );
1623 int h =
static_cast< int >( std::round( heightLayoutUnits * mPreviewScaleFactor ) );
1626 if ( w > 5000 || h > 5000 )
1631 h =
static_cast< int>( std::round( w * heightLayoutUnits / widthLayoutUnits ) );
1636 w =
static_cast< int >( std::round( h * widthLayoutUnits / heightLayoutUnits ) );
1640 if ( w <= 0 || h <= 0 )
1643 mCacheRenderingImage.reset(
new QImage( w * mPreviewDevicePixelRatio, h * mPreviewDevicePixelRatio, QImage::Format_ARGB32 ) );
1646 mCacheRenderingImage->setDotsPerMeterX(
static_cast< int >( std::round( 1000 * w / widthLayoutUnits ) ) );
1647 mCacheRenderingImage->setDotsPerMeterY(
static_cast< int >( std::round( 1000 * h / heightLayoutUnits ) ) );
1648 mCacheRenderingImage->setDevicePixelRatio( mPreviewDevicePixelRatio );
1651 mCacheRenderingImage->fill( QColor( 255, 255, 255, 0 ).rgba() );
1656 if ( mItemClippingSettings->
isActive() )
1658 QPainter p( mCacheRenderingImage.get() );
1660 p.setPen( Qt::NoPen );
1662 p.scale( mCacheRenderingImage->width() / widthLayoutUnits, mCacheRenderingImage->height() / heightLayoutUnits );
1672 mCacheInvalidated =
false;
1673 mPainter.reset(
new QPainter( mCacheRenderingImage.get() ) );
1676 if ( shouldDrawPart( OverviewMapExtent ) )
1678 settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
1683 mPainterJob->start();
1695 mDrawingPreview =
false;
1718 if (
layout()->renderContext().isPreviewRender() )
1721 jobMapSettings.
setDevicePixelRatio( mPainter ? mPainter->device()->devicePixelRatioF() : 1.0 );
1724 jobMapSettings.
setRotation( mEvaluatedMapRotation );
1732 if ( includeLayerSettings )
1737 if ( !
mLayout->project()->mainAnnotationLayer()->isEmpty() )
1740 layers.insert( 0,
mLayout->project()->mainAnnotationLayer() );
1747 if ( !
mLayout->renderContext().isPreviewRender() )
1791 if ( mEvaluatedLabelMargin.
length() > 0 )
1794 visiblePoly.append( visiblePoly.at( 0 ) );
1795 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1796 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1798 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1799 labelBoundary = mapBoundaryGeom;
1802 if ( !mBlockingLabelItems.isEmpty() )
1815 if ( mZRangeEnabled )
1820 if ( mAtlasClippingSettings->
enabled() &&
mLayout->reportContext().feature().isValid() )
1831 if ( !labelBoundary.
isEmpty() )
1833 labelBoundary = clipGeom.
intersection( labelBoundary );
1837 labelBoundary = clipGeom;
1842 if ( mItemClippingSettings->
isActive() )
1851 const double layoutLabelMargin =
mLayout->convertToLayoutUnits( mEvaluatedLabelMargin );
1852 const double layoutLabelMarginInMapUnits = layoutLabelMargin / rect().width() * jobMapSettings.
extent().
width();
1854 mapBoundaryGeom = mapBoundaryGeom.
buffer( -layoutLabelMarginInMapUnits, 0 );
1855 if ( !labelBoundary.
isEmpty() )
1857 labelBoundary = mapBoundaryGeom.
intersection( labelBoundary );
1861 labelBoundary = mapBoundaryGeom;
1867 if ( !labelBoundary.
isNull() )
1870 return jobMapSettings;
1877 mBlockingLabelItems.clear();
1878 for (
const QString &
uuid : std::as_const( mBlockingLabelItemUuids ) )
1887 mOverviewStack->finalizeRestoreFromXml();
1888 mGridStack->finalizeRestoreFromXml();
1900 return mCurrentRectangle;
1914 const double mapScale =
scale();
1938 QVariantList layersIds;
1948 const QList<QgsMapLayer *> layersInMap =
layersToRender( &context );
1950 layersIds.reserve( layersInMap.count() );
1951 layers.reserve( layersInMap.count() );
1954 layersIds << layer->id();
1960 scope->
addFunction( QStringLiteral(
"is_layer_visible" ),
new QgsExpressionContextUtils::GetLayerVisibility( layersInMap,
scale() ) );
1982 if ( extentWidth <= 0 )
1986 return rect().width() / extentWidth;
1991 double dx = mXOffset;
1992 double dy = mYOffset;
1993 transformShift( dx, dy );
1994 QPolygonF poly = calculateVisibleExtentPolygon(
false );
1995 poly.translate( -dx, -dy );
2001 if ( !mBlockingLabelItems.contains( item ) )
2002 mBlockingLabelItems.append( item );
2009 mBlockingLabelItems.removeAll( item );
2016 return mBlockingLabelItems.contains( item );
2021 return mPreviewLabelingResults.get();
2030 if ( mOverviewStack )
2032 for (
int i = 0; i < mOverviewStack->size(); ++i )
2034 if ( mOverviewStack->item( i )->accept( visitor ) )
2041 for (
int i = 0; i < mGridStack->size(); ++i )
2043 if ( mGridStack->item( i )->accept( visitor ) )
2056 mRenderedFeatureHandlers.append( handler );
2061 mRenderedFeatureHandlers.removeAll( handler );
2067 if ( mapPoly.empty() )
2069 return QPointF( 0, 0 );
2074 double dx = mapCoords.x() - rotationPoint.
x();
2075 double dy = mapCoords.y() - rotationPoint.
y();
2077 QgsPointXY backRotatedCoords( rotationPoint.
x() + dx, rotationPoint.
y() + dy );
2080 double xItem = rect().width() * ( backRotatedCoords.
x() - unrotatedExtent.
xMinimum() ) / unrotatedExtent.
width();
2081 double yItem = rect().height() * ( 1 - ( backRotatedCoords.
y() - unrotatedExtent.
yMinimum() ) / unrotatedExtent.
height() );
2082 return QPointF( xItem, yItem );
2096 mapPolygon( newExtent, poly );
2097 QRectF bRect = poly.boundingRect();
2111 mCacheInvalidated =
true;
2117 QRectF rectangle = rect();
2118 double frameExtension =
frameEnabled() ? pen().widthF() / 2.0 : 0.0;
2120 double topExtension = 0.0;
2121 double rightExtension = 0.0;
2122 double bottomExtension = 0.0;
2123 double leftExtension = 0.0;
2126 mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
2128 topExtension = std::max( topExtension, frameExtension );
2129 rightExtension = std::max( rightExtension, frameExtension );
2130 bottomExtension = std::max( bottomExtension, frameExtension );
2131 leftExtension = std::max( leftExtension, frameExtension );
2133 rectangle.setLeft( rectangle.left() - leftExtension );
2134 rectangle.setRight( rectangle.right() + rightExtension );
2135 rectangle.setTop( rectangle.top() - topExtension );
2136 rectangle.setBottom( rectangle.bottom() + bottomExtension );
2137 if ( rectangle != mCurrentRectangle )
2139 prepareGeometryChange();
2140 mCurrentRectangle = rectangle;
2168 refreshMapExtents( &context );
2170 if ( mExtent != beforeExtent )
2177 refreshLabelMargin(
false );
2181 const QString previousTheme = mLastEvaluatedThemeName.isEmpty() ? mFollowVisibilityPresetName : mLastEvaluatedThemeName;
2183 if ( mLastEvaluatedThemeName != previousTheme )
2202 double zLower = mZRange.
lower();
2203 double zUpper = mZRange.
upper();
2214 mCacheInvalidated =
true;
2219void QgsLayoutItemMap::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
2222 if ( !mLayers.isEmpty() || mLayerStyleOverrides.isEmpty() )
2226 mLayerStyleOverrides.remove( layer->id() );
2228 _qgis_removeLayers( mLayers,
layers );
2234 if ( mGroupLayers.erase( layer->id() ) == 0 )
2237 for (
auto it = mGroupLayers.begin(); it != mGroupLayers.end(); ++it )
2240 if ( groupLayer->
childLayers().contains( layer ) )
2242 QList<QgsMapLayer *> childLayers { groupLayer->
childLayers() };
2243 childLayers.removeAll( layer );
2251void QgsLayoutItemMap::painterJobFinished()
2254 mPreviewLabelingResults.reset( mPainterJob->takeLabelingResults() );
2255 mPainterJob.reset(
nullptr );
2256 mPainter.reset(
nullptr );
2257 mCacheFinalImage = std::move( mCacheRenderingImage );
2258 mLastRenderedImageOffsetX = 0;
2259 mLastRenderedImageOffsetY = 0;
2265void QgsLayoutItemMap::shapeChanged()
2270 double w = rect().width();
2271 double h = rect().height();
2274 double newWidth = mExtent.
width();
2276 double newHeight = newWidth * h / w;
2281 refreshMapExtents();
2288void QgsLayoutItemMap::mapThemeChanged(
const QString &theme )
2290 if ( theme == mCachedLayerStyleOverridesPresetName )
2291 mCachedLayerStyleOverridesPresetName.clear();
2294void QgsLayoutItemMap::currentMapThemeRenamed(
const QString &theme,
const QString &newTheme )
2296 if ( theme == mFollowVisibilityPresetName )
2298 mFollowVisibilityPresetName = newTheme;
2302void QgsLayoutItemMap::connectUpdateSlot()
2310 this, &QgsLayoutItemMap::layersAboutToBeRemoved );
2314 if ( layers().isEmpty() )
2343 if ( mAtlasScalingMode == Predefined )
2344 updateAtlasFeature();
2350 QPolygonF thisExtent = calculateVisibleExtentPolygon(
false );
2351 QTransform mapTransform;
2352 QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, rect().width(), rect().height() ) );
2354 thisRectPoly.pop_back();
2355 thisExtent.pop_back();
2357 QPolygonF thisItemPolyInLayout = mapToScene( thisRectPoly );
2360 QTransform::quadToQuad( thisItemPolyInLayout, thisExtent, mapTransform );
2361 return mapTransform;
2366 mZRangeEnabled = enabled;
2371 return mZRangeEnabled;
2384QList<QgsLabelBlockingRegion> QgsLayoutItemMap::createLabelBlockingRegions(
const QgsMapSettings & )
const
2387 QList< QgsLabelBlockingRegion > blockers;
2388 blockers.reserve( mBlockingLabelItems.count() );
2389 for (
const auto &item : std::as_const( mBlockingLabelItems ) )
2396 if ( item->property(
"wasVisible" ).isValid() )
2398 if ( !item->property(
"wasVisible" ).toBool() )
2401 else if ( !item->isVisible() )
2404 QPolygonF itemRectInMapCoordinates = mapTransform.map( item->mapToScene( item->rect() ) );
2405 itemRectInMapCoordinates.append( itemRectInMapCoordinates.at( 0 ) );
2414 return mLabelMargin;
2419 mLabelMargin = margin;
2420 refreshLabelMargin(
false );
2423void QgsLayoutItemMap::updateToolTip()
2432 if ( mFollowVisibilityPreset )
2434 presetName = mFollowVisibilityPresetName;
2438 else if ( !mExportThemes.empty() && mExportThemeIt != mExportThemes.end() )
2439 presetName = *mExportThemeIt;
2450 QList<QgsMapLayer *> renderLayers;
2452 QString presetName = themeToRender( *evalContext );
2453 if ( !presetName.isEmpty() )
2455 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2456 renderLayers =
mLayout->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
2458 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2460 else if ( !
layers().isEmpty() )
2466 renderLayers =
mLayout->project()->mapThemeCollection()->masterVisibleLayers();
2473 renderLayers.clear();
2475 const QStringList layerNames = ddLayers.split(
'|' );
2477 for (
const QString &name : layerNames )
2479 const QList< QgsMapLayer * > matchingLayers =
mLayout->project()->mapLayersByName( name );
2482 renderLayers << layer;
2491 int removeAt = renderLayers.indexOf(
mLayout->reportContext().layer() );
2492 if ( removeAt != -1 )
2494 renderLayers.removeAt( removeAt );
2499 renderLayers.erase( std::remove_if( renderLayers.begin(), renderLayers.end(), [](
QgsMapLayer * layer )
2501 return !layer || !layer->isValid();
2502 } ), renderLayers.end() );
2504 return renderLayers;
2507QMap<QString, QString> QgsLayoutItemMap::layerStyleOverridesToRender(
const QgsExpressionContext &context )
const
2509 QString presetName = themeToRender( context );
2510 if ( !presetName.isEmpty() )
2512 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2514 if ( presetName != mCachedLayerStyleOverridesPresetName )
2517 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2518 mCachedLayerStyleOverridesPresetName = presetName;
2521 return mCachedPresetLayerStyleOverrides;
2524 return QMap<QString, QString>();
2526 else if ( mFollowVisibilityPreset )
2528 QString presetName = mFollowVisibilityPresetName;
2531 if (
mLayout->project()->mapThemeCollection()->hasMapTheme( presetName ) )
2533 if ( presetName.isEmpty() || presetName != mCachedLayerStyleOverridesPresetName )
2536 mCachedPresetLayerStyleOverrides =
mLayout->project()->mapThemeCollection()->mapThemeStyleOverrides( presetName );
2537 mCachedLayerStyleOverridesPresetName = presetName;
2540 return mCachedPresetLayerStyleOverrides;
2543 return QMap<QString, QString>();
2545 else if ( mKeepLayerStyles )
2547 return mLayerStyleOverrides;
2551 return QMap<QString, QString>();
2555QgsRectangle QgsLayoutItemMap::transformedExtent()
const
2557 double dx = mXOffset;
2558 double dy = mYOffset;
2559 transformShift( dx, dy );
2563void QgsLayoutItemMap::mapPolygon(
const QgsRectangle &extent, QPolygonF &poly )
const
2573 poly << QPointF( poly.at( 0 ) );
2585 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2591 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2597 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2603 poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2606 poly << QPointF( poly.at( 0 ) );
2609void QgsLayoutItemMap::transformShift(
double &xShift,
double &yShift )
const
2612 double dxScaled = xShift * mmToMapUnits;
2613 double dyScaled = - yShift * mmToMapUnits;
2628 const QList< QgsAnnotation * > annotations =
mLayout->project()->annotationManager()->annotations();
2629 if ( annotations.isEmpty() )
2640 if ( !annotation || !annotation->isVisible() )
2644 if ( annotation->mapLayer() && !
layers.contains( annotation->mapLayer() ) )
2647 drawAnnotation( annotation, rc );
2661 double itemX, itemY;
2664 QPointF mapPos = layoutMapPosForItem( annotation );
2673 context.
painter()->translate( itemX, itemY );
2676 double dotsPerMM = context.
painter()->device()->logicalDpiX() / 25.4;
2677 context.
painter()->scale( 1 / dotsPerMM, 1 / dotsPerMM );
2679 annotation->
render( context );
2682QPointF QgsLayoutItemMap::layoutMapPosForItem(
const QgsAnnotation *annotation )
const
2685 return QPointF( 0, 0 );
2694 if ( annotationCrs !=
crs() )
2701 t.transformInPlace( mapX, mapY, z );
2711void QgsLayoutItemMap::drawMapFrame( QPainter *p )
2722void QgsLayoutItemMap::drawMapBackground( QPainter *p )
2733bool QgsLayoutItemMap::shouldDrawPart( QgsLayoutItemMap::PartType part )
const
2735 if ( mCurrentExportPart == NotLayered )
2753 return mCurrentExportPart == Layer;
2756 return mCurrentExportPart == Grid && mGridStack->hasEnabledItems();
2758 case OverviewMapExtent:
2759 return mCurrentExportPart == OverviewMapExtent && mOverviewStack->hasEnabledItems();
2764 case SelectionBoxes:
2765 return mCurrentExportPart == SelectionBoxes && isSelected();
2786 bool useDdXMin =
false;
2787 bool useDdXMax =
false;
2788 bool useDdYMin =
false;
2789 bool useDdYMax =
false;
2820 if ( newExtent != mExtent )
2826 double currentWidthHeightRatio = mExtent.
width() / mExtent.
height();
2827 double newWidthHeightRatio = newExtent.
width() / newExtent.
height();
2829 if ( currentWidthHeightRatio < newWidthHeightRatio )
2832 double newHeight = newExtent.
width() / currentWidthHeightRatio;
2833 double deltaHeight = newHeight - newExtent.
height();
2840 double newWidth = currentWidthHeightRatio * newExtent.
height();
2841 double deltaWidth = newWidth - newExtent.
width();
2846 mExtent = newExtent;
2856 newExtent = mExtent;
2859 if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
2863 if ( useDdXMin && !useDdXMax )
2869 else if ( !useDdXMin && useDdXMax )
2875 if ( useDdYMin && !useDdYMax )
2881 else if ( !useDdYMin && useDdYMax )
2888 if ( newExtent != mExtent )
2890 mExtent = newExtent;
2907void QgsLayoutItemMap::refreshLabelMargin(
bool updateItem )
2920void QgsLayoutItemMap::updateAtlasFeature()
2939 if ( mAtlasScalingMode ==
Fixed || mAtlasScalingMode ==
Predefined || isPointLayer )
2948 double originalScale = calc.
calculate( originalExtent, rect().width() );
2949 double geomCenterX = ( xa1 + xa2 ) / 2.0;
2950 double geomCenterY = ( ya1 + ya2 ) / 2.0;
2951 QVector<qreal> scales;
2953 if ( !
mLayout->reportContext().predefinedScales().empty() )
2954 scales =
mLayout->reportContext().predefinedScales();
2956 scales =
mLayout->renderContext().predefinedScales();
2958 if ( mAtlasScalingMode ==
Fixed || scales.isEmpty() || ( isPointLayer && mAtlasScalingMode !=
Predefined ) )
2961 double xMin = geomCenterX - originalExtent.
width() / 2.0;
2962 double yMin = geomCenterY - originalExtent.
height() / 2.0;
2965 xMin + originalExtent.
width(),
2966 yMin + originalExtent.
height() );
2970 double newScale = calc.
calculate( newExtent, rect().width() );
2971 newExtent.
scale( originalScale / newScale );
2976 double newWidth = originalExtent.
width();
2977 double newHeight = originalExtent.
height();
2978 for (
int i = 0; i < scales.size(); i++ )
2980 double ratio = scales[i] / originalScale;
2981 newWidth = originalExtent.
width() * ratio;
2982 newHeight = originalExtent.
height() * ratio;
2985 double xMin = geomCenterX - newWidth / 2.0;
2986 double yMin = geomCenterY - newHeight / 2.0;
2994 const double newScale = calc.
calculate( newExtent, rect().width() );
2998 newExtent.
scale( scales[i] / newScale );
3008 else if ( mAtlasScalingMode ==
Auto )
3012 double geomRatio = bounds.
width() / bounds.
height();
3013 double mapRatio = originalExtent.
width() / originalExtent.
height();
3016 if ( geomRatio < mapRatio )
3019 double adjWidth = ( mapRatio * bounds.
height() - bounds.
width() ) / 2.0;
3024 else if ( geomRatio > mapRatio )
3027 double adjHeight = ( bounds.
width() / mapRatio - bounds.
height() ) / 2.0;
3033 const double evaluatedAtlasMargin =
atlasMargin();
3034 if ( evaluatedAtlasMargin > 0.0 )
3036 newExtent.
scale( 1 + evaluatedAtlasMargin );
3062 double dx = std::max( std::abs( prevCenter.
x() - bounds.
xMinimum() ),
3063 std::abs( prevCenter.
x() - bounds.
xMaximum() ) );
3064 double dy = std::max( std::abs( prevCenter.
y() - bounds.
yMinimum() ),
3065 std::abs( prevCenter.
y() - bounds.
yMaximum() ) );
3068 center.
x() + dx, center.
y() + dy );
3076void QgsLayoutItemMap::createStagedRenderJob(
const QgsRectangle &extent,
const QSizeF size,
double dpi )
3079 settings.
setLayers( mOverviewStack->modifyMapLayerList( settings.
layers() ) );
3081 mStagedRendererJob = std::make_unique< QgsMapRendererStagedRenderJob >( settings,
3085 mStagedRendererJob->start();
3101 this, &QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved );
3107 return mClipToAtlasFeature;
3112 if (
enabled == mClipToAtlasFeature )
3115 mClipToAtlasFeature =
enabled;
3121 return mFeatureClippingType;
3126 if ( mFeatureClippingType == type )
3129 mFeatureClippingType = type;
3135 return mForceLabelsInsideFeature;
3140 if ( forceInside == mForceLabelsInsideFeature )
3143 mForceLabelsInsideFeature = forceInside;
3149 return mRestrictToLayers;
3154 if ( mRestrictToLayers ==
enabled )
3163 return _qgis_listRefToRaw( mLayersToClip );
3174 QDomElement settingsElem = document.createElement( QStringLiteral(
"atlasClippingSettings" ) );
3175 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mClipToAtlasFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3176 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3177 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3178 settingsElem.setAttribute( QStringLiteral(
"restrictLayers" ), mRestrictToLayers ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3181 QDomElement layerSetElem = document.createElement( QStringLiteral(
"layersToClip" ) );
3186 QDomElement layerElem = document.createElement( QStringLiteral(
"Layer" ) );
3187 QDomText layerIdText = document.createTextNode( layerRef.layerId );
3188 layerElem.appendChild( layerIdText );
3190 layerElem.setAttribute( QStringLiteral(
"name" ), layerRef.name );
3191 layerElem.setAttribute( QStringLiteral(
"source" ), layerRef.source );
3192 layerElem.setAttribute( QStringLiteral(
"provider" ), layerRef.provider );
3194 layerSetElem.appendChild( layerElem );
3196 settingsElem.appendChild( layerSetElem );
3198 element.appendChild( settingsElem );
3204 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"atlasClippingSettings" ) );
3206 mClipToAtlasFeature = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3207 mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3209 mRestrictToLayers = settingsElem.attribute( QStringLiteral(
"restrictLayers" ), QStringLiteral(
"0" ) ).toInt();
3211 mLayersToClip.clear();
3212 QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral(
"layersToClip" ) );
3213 if ( !layerSetNodeList.isEmpty() )
3215 QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
3216 QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral(
"Layer" ) );
3217 mLayersToClip.reserve( layerIdNodeList.size() );
3218 for (
int i = 0; i < layerIdNodeList.size(); ++i )
3220 QDomElement layerElem = layerIdNodeList.at( i ).toElement();
3221 QString layerId = layerElem.text();
3222 QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
3223 QString layerSource = layerElem.attribute( QStringLiteral(
"source" ) );
3224 QString layerProvider = layerElem.attribute( QStringLiteral(
"provider" ) );
3226 QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
3229 mLayersToClip << ref;
3236void QgsLayoutItemMapAtlasClippingSettings::layersAboutToBeRemoved(
const QList<QgsMapLayer *> &layers )
3238 if ( !mLayersToClip.isEmpty() )
3240 _qgis_removeLayers( mLayersToClip, layers );
3255 return mEnabled && mClipPathSource;
3270 if ( mClipPathSource )
3273 mClipPathSource->refresh();
3282 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3293 QgsGeometry clipGeom( mClipPathSource->clipPath() );
3294 clipGeom.
transform( mMap->sceneTransform().inverted() );
3309 if ( mClipPathSource == item )
3312 if ( mClipPathSource )
3321 mClipPathSource = item;
3323 if ( mClipPathSource )
3332 mClipPathSource->refresh();
3346 return mClipPathSource;
3351 return mFeatureClippingType;
3356 if ( mFeatureClippingType == type )
3359 mFeatureClippingType = type;
3365 return mForceLabelsInsideClipPath;
3370 if ( forceInside == mForceLabelsInsideClipPath )
3373 mForceLabelsInsideClipPath = forceInside;
3379 QDomElement settingsElem = document.createElement( QStringLiteral(
"itemClippingSettings" ) );
3380 settingsElem.setAttribute( QStringLiteral(
"enabled" ), mEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3381 settingsElem.setAttribute( QStringLiteral(
"forceLabelsInside" ), mForceLabelsInsideClipPath ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3382 settingsElem.setAttribute( QStringLiteral(
"clippingType" ), QString::number(
static_cast<int>( mFeatureClippingType ) ) );
3383 if ( mClipPathSource )
3384 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), mClipPathSource->uuid() );
3386 settingsElem.setAttribute( QStringLiteral(
"clipSource" ), QString() );
3388 element.appendChild( settingsElem );
3394 const QDomElement settingsElem = element.firstChildElement( QStringLiteral(
"itemClippingSettings" ) );
3396 mEnabled = settingsElem.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"0" ) ).toInt();
3397 mForceLabelsInsideClipPath = settingsElem.attribute( QStringLiteral(
"forceLabelsInside" ), QStringLiteral(
"0" ) ).toInt();
3399 mClipPathUuid = settingsElem.attribute( QStringLiteral(
"clipSource" ) );
3406 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...
@ 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.
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.
Stores computed placement from labeling engine.
void layerOrderChanged()
Emitted when the layer order has changed.
Contains settings relating to clipping a layout map by the current atlas feature.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the current atlas feature.
bool restrictToLayers() const
Returns true if clipping should be restricted to a subset of layers.
QgsLayoutItemMapAtlasClippingSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapAtlasClippingSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setRestrictToLayers(bool enabled)
Sets whether clipping should be restricted to a subset of layers.
void setLayersToClip(const QList< QgsMapLayer * > &layers)
Sets the list of map layers to clip to the atlas feature.
QList< QgsMapLayer * > layersToClip() const
Returns the list of map layers to clip to the atlas feature.
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the current atlas feature.
void changed()
Emitted when the atlas clipping settings are changed.
bool forceLabelsInsideFeature() const
Returns true if labels should only be placed inside the atlas feature geometry.
bool enabled() const
Returns true if the map content should be clipped to the current atlas feature.
void setForceLabelsInsideFeature(bool forceInside)
Sets whether labels should only be placed inside the atlas feature geometry.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the current atlas feature.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
Contains settings relating to clipping a layout map by another layout item.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores settings in a DOM element, where element is the DOM element corresponding to a 'LayoutMap' tag...
void setForceLabelsInsideClipPath(bool forceInside)
Sets whether labels should only be placed inside the clip path geometry.
void setSourceItem(QgsLayoutItem *item)
Sets the source item which will provide the clipping path for the map.
QgsLayoutItemMapItemClipPathSettings(QgsLayoutItemMap *map=nullptr)
Constructor for QgsLayoutItemMapItemClipPathSettings, with the specified map parent.
bool readXml(const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context)
Sets the setting's state from a DOM document, where element is the DOM node corresponding to a 'Layou...
QgsGeometry clipPathInMapItemCoordinates() const
Returns the clipping path geometry, in the map item's coordinate space.
QgsGeometry clippedMapExtent() const
Returns the geometry to use for clipping the parent map, in the map item's CRS.
QgsLayoutItem * sourceItem()
Returns the source item which will provide the clipping path for the map, or nullptr if no item is se...
void setEnabled(bool enabled)
Sets whether the map content should be clipped to the associated item.
bool forceLabelsInsideClipPath() const
Returns true if labels should only be placed inside the clip path geometry.
void finalizeRestoreFromXml()
To be called after all pending items have been restored from XML.
QgsMapClippingRegion::FeatureClippingType featureClippingType() const
Returns the feature clipping type to apply when clipping to the associated item.
bool enabled() const
Returns true if the map content should be clipped to the associated item.
QgsMapClippingRegion toMapClippingRegion() const
Returns the clip path as a map clipping region.
void changed()
Emitted when the item clipping settings are changed.
void setFeatureClippingType(QgsMapClippingRegion::FeatureClippingType type)
Sets the feature clipping type to apply when clipping to the associated item.
bool isActive() const
Returns true if the item clipping is enabled and set to a valid source item.
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
@ StackAboveMapLabels
Render above all map layers and labels.
StackingPosition stackingPosition() const
Returns the item's stacking position, which specifies where the in the map's stack the item should be...
bool enabled() const
Returns whether the item will be drawn.
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
Layout graphical items for displaying a map.
void setFollowVisibilityPreset(bool follow)
Sets whether the map should follow a map theme.
bool nextExportPart() override
Moves to the next export part for a multi-layered export item, during a multi-layered export.
void removeRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Removes a previously added rendered feature handler.
void extentChanged()
Emitted when the map's extent changes.
QPointF mapToItemCoords(QPointF mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset)
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
~QgsLayoutItemMap() override
QIcon icon() const override
Returns the item's icon.
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties) override
void preparedForAtlas()
Emitted when the map has been prepared for atlas rendering, just before actual rendering.
void setFollowVisibilityPresetName(const QString &name)
Sets preset name for map rendering.
QTransform layoutToMapCoordsTransform() const
Creates a transform from layout coordinates to map coordinates.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
bool isLabelBlockingItem(QgsLayoutItem *item) const
Returns true if the specified item is a "label blocking item".
void storeCurrentLayerStyles()
Stores the current project layer styles into style overrides.
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
QgsLayoutMeasurement labelMargin() const
Returns the margin from the map edges in which no labels may be placed.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
@ Predefined
A scale is chosen from the predefined scales.
@ Auto
The extent is adjusted so that each feature is fully visible.
@ Fixed
The current scale of the map is used for each feature of the atlas.
bool requiresRasterization() const override
Returns true if the item is drawn in such a way that forces the whole layout to be rasterized when ex...
Q_DECL_DEPRECATED int numberExportLayers() const override
void layerStyleOverridesChanged()
Emitted when layer style overrides are changed... a means to let associated legend items know they sh...
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
void moveContent(double dx, double dy) override
Moves the content of the item, by a specified dx and dy in layout units.
void setZRangeEnabled(bool enabled)
Sets whether the z range is enabled (i.e.
QgsLayoutItemMapGrid * grid()
Returns the map item's first grid.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
int type() const override
void previewRefreshed()
Emitted whenever the item's map preview has been refreshed.
friend class QgsLayoutItemMapOverview
void setExtent(const QgsRectangle &extent)
Sets a new extent for the map.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
QFlags< MapItemFlag > MapItemFlags
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
QPolygonF visibleExtentPolygon() const
Returns a polygon representing the current visible map extent, considering map extents and rotation.
QgsRectangle requestedExtent() const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
void setMapFlags(QgsLayoutItemMap::MapItemFlags flags)
Sets the map item's flags, which control how the map content is drawn.
void zoomContent(double factor, QPointF point) override
Zooms content of item.
QList< QgsMapLayer * > layersToRender(const QgsExpressionContext *context=nullptr) const
Returns a list of the layers which will be rendered within this map item, considering any locked laye...
void crsChanged()
Emitted when the map's coordinate reference system is changed.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the stored layers set.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
static QgsLayoutItemMap * create(QgsLayout *layout)
Returns a new map item for the specified layout.
QRectF boundingRect() const override
QString displayName() const override
Gets item display name.
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
void setZRange(const QgsDoubleRange &range)
Sets the map's z range, which is used to filter the map's content to only display features within the...
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for layers.
void stopLayeredExport() override
Stops a multi-layer export operation.
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map.
double estimatedFrameBleed() const override
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainterPath framePath() const override
Returns the path to use when drawing the item's frame or background.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void startLayeredExport() override
Starts a multi-layer export operation.
bool containsWmsLayer() const
Returns true if the map contains a WMS layer.
void setScale(double scale, bool forceUpdate=true)
Sets new map scale and changes only the map extent.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
double mapUnitsToLayoutUnits() const
Returns the conversion factor from map units to layout units.
QgsLayoutItemMap::MapItemFlags mapFlags() const
Returns the map item's flags, which control how the map content is drawn.
bool zRangeEnabled() const
Returns whether the z range is enabled (i.e.
void setLabelMargin(const QgsLayoutMeasurement &margin)
Sets the margin from the map edges in which no labels may be placed.
void themeChanged(const QString &theme)
Emitted when the map's associated theme is changed.
QgsLayoutItem::ExportLayerDetail exportLayerDetails() const override
Returns the details for the specified current export layer.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
double scale() const
Returns the map scale.
@ ShowPartialLabels
Whether to draw labels which are partially outside of the map view.
@ ShowUnplacedLabels
Whether to render unplaced labels in the map view.
bool drawAnnotations() const
Returns whether annotations are drawn within the map.
QgsDoubleRange zRange() const
Returns the map's z range, which is used to filter the map's content to only display features within ...
void removeLabelBlockingItem(QgsLayoutItem *item)
Removes the specified layout item from the map's "label blocking items".
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the map's preset crs (coordinate reference system).
void invalidateCache() override
QgsRectangle extent() const
Returns the current map extent.
QgsLayoutItemMapOverview * overview()
Returns the map item's first overview.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setFrameStrokeWidth(QgsLayoutMeasurement width) override
Sets the frame stroke width.
bool containsAdvancedEffects() const override
Returns true if the item contains contents with blend modes or transparency effects which can only be...
friend class QgsLayoutItemMapGrid
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
void setMoveContentPreviewOffset(double dx, double dy) override
Sets temporary offset for the item, by a specified dx and dy in layout units.
void setMapRotation(double rotation)
Sets the rotation for the map - this does not affect the layout item shape, only the way the map is d...
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
double atlasMargin(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue)
Returns the margin size (percentage) used when the map is in atlas mode.
void addLabelBlockingItem(QgsLayoutItem *item)
Sets the specified layout item as a "label blocking item" for this map.
void assignFreeId()
Sets the map id() to a number not yet used in the layout.
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
QgsLabelingResults * previewLabelingResults() const
Returns the labeling results of the most recent preview map render.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Base class for graphical items within a QgsLayout.
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
virtual QPainterPath framePath() const
Returns the path to use when drawing the item's frame or background.
QColor backgroundColor(bool useDataDefined=true) const
Returns the background color for this item.
void drawRefreshingOverlay(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle)
Draws a "refreshing" overlay icon on the item.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
void rotationChanged(double newRotation)
Emitted on item rotation change.
friend class QgsLayoutItemMap
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void drawBackground(QgsRenderContext &context)
Draws the background for the item.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
@ FlagOverridesPaint
Item overrides the default layout item painting method.
@ FlagDisableSceneCaching
Item should not have QGraphicsItem caching enabled.
virtual bool containsAdvancedEffects() const
Returns true if the item contains contents with blend modes or transparency effects which can only be...
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
QString id() const
Returns the item's ID name.
bool frameEnabled() const
Returns true if the item includes a frame.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ ItemContainsSubLayers
Item contains multiple sublayers which must be individually exported.
void clipPathChanged()
Emitted when the item's clipping path has changed.
bool hasBackground() const
Returns true if the item has a background.
void refresh() override
Refreshes the item, causing a recalculation of any property overrides and recalculation of its positi...
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
void backgroundTaskCountChanged(int count)
Emitted whenever the number of background tasks an item is executing changes.
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.
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.