QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgslayoutitemmap.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitemmap.h
3  -------------------
4  begin : July 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #ifndef QGSLAYOUTITEMMAP_H
18 #define QGSLAYOUTITEMMAP_H
19 
20 #include "qgis_core.h"
21 #include "qgslayoutitem.h"
22 #include "qgslayoutitemregistry.h"
23 #include "qgsmaplayerref.h"
25 #include "qgslayoutitemmapgrid.h"
28 #include "qgstemporalrangeobject.h"
29 
30 class QgsAnnotation;
32 
39 class CORE_EXPORT QgsLayoutItemMapAtlasClippingSettings : public QObject
40 {
41  Q_OBJECT
42 
43  public:
44 
49 
55  bool enabled() const;
56 
62  void setEnabled( bool enabled );
63 
69  QgsMapClippingRegion::FeatureClippingType featureClippingType() const;
70 
76  void setFeatureClippingType( QgsMapClippingRegion::FeatureClippingType type );
77 
83  bool forceLabelsInsideFeature() const;
84 
90  void setForceLabelsInsideFeature( bool forceInside );
91 
98  bool restrictToLayers() const;
99 
106  void setRestrictToLayers( bool enabled );
107 
116  QList< QgsMapLayer * > layersToClip() const;
117 
126  void setLayersToClip( const QList< QgsMapLayer * > &layers );
127 
133  bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
134 
140  bool readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context );
141 
142  signals:
143 
147  void changed();
148 
149  private slots:
150  void layersAboutToBeRemoved( const QList<QgsMapLayer *> &layers );
151 
152  private:
153 
154  QgsLayoutItemMap *mMap = nullptr;
155  bool mClipToAtlasFeature = false;
156  bool mRestrictToLayers = false;
157  QList< QgsMapLayerRef > mLayersToClip;
159  bool mForceLabelsInsideFeature = false;
160 };
161 
162 
169 class CORE_EXPORT QgsLayoutItemMapItemClipPathSettings : public QObject
170 {
171  Q_OBJECT
172 
173  public:
174 
179 
186  bool isActive() const;
187 
193  bool enabled() const;
194 
200  void setEnabled( bool enabled );
201 
207  QgsGeometry clippedMapExtent() const;
208 
218  QgsGeometry clipPathInMapItemCoordinates() const;
219 
223  QgsMapClippingRegion toMapClippingRegion() const;
224 
232  void setSourceItem( QgsLayoutItem *item );
233 
240  QgsLayoutItem *sourceItem();
241 
247  QgsMapClippingRegion::FeatureClippingType featureClippingType() const;
248 
254  void setFeatureClippingType( QgsMapClippingRegion::FeatureClippingType type );
255 
261  bool forceLabelsInsideClipPath() const;
262 
268  void setForceLabelsInsideClipPath( bool forceInside );
269 
275  bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
276 
283  bool readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context );
284 
289  void finalizeRestoreFromXml();
290 
291  signals:
292 
296  void changed();
297 
298  private:
299 
300  QgsLayoutItemMap *mMap = nullptr;
301  bool mEnabled = false;
303  bool mForceLabelsInsideClipPath = false;
304 
305  QPointer< QgsLayoutItem > mClipPathSource;
306  QString mClipPathUuid;
307 
308 };
309 
310 
317 class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem, public QgsTemporalRangeObject
318 {
319 
320  Q_OBJECT
321 
322  public:
323 
328  {
330 
338 
344  Auto
345  };
346 
352  {
353  ShowPartialLabels = 1 << 0,
354  ShowUnplacedLabels = 1 << 1,
355  };
356  Q_DECLARE_FLAGS( MapItemFlags, MapItemFlag )
357 
358 
361  explicit QgsLayoutItemMap( QgsLayout *layout );
362  ~QgsLayoutItemMap() override;
363 
364  int type() const override;
365  QIcon icon() const override;
366  QgsLayoutItem::Flags itemFlags() const override;
367 
373  QgsLayoutItemMap::MapItemFlags mapFlags() const;
374 
380  void setMapFlags( QgsLayoutItemMap::MapItemFlags flags );
381 
385  void assignFreeId();
386 
387  //overridden to show "Map 1" type names
388  QString displayName() const override;
389 
395  static QgsLayoutItemMap *create( QgsLayout *layout ) SIP_FACTORY;
396 
397  // for now, map items behave a bit differently and don't implement draw. TODO - see if we can avoid this
398  void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override;
399  Q_DECL_DEPRECATED int numberExportLayers() const override SIP_DEPRECATED;
400  void startLayeredExport() override;
401  void stopLayeredExport() override;
402  bool nextExportPart() override;
403  ExportLayerBehavior exportLayerBehavior() const override;
404  QgsLayoutItem::ExportLayerDetail exportLayerDetails() const override;
405  void setFrameStrokeWidth( QgsLayoutMeasurement width ) override;
406 
412  double scale() const;
413 
421  void setScale( double scale, bool forceUpdate = true );
422 
430  void setExtent( const QgsRectangle &extent );
431 
439  void zoomToExtent( const QgsRectangle &extent );
440 
446  QgsRectangle extent() const;
447 
448 
456  QPolygonF visibleExtentPolygon() const;
457 
467 
476  QgsCoordinateReferenceSystem presetCrs() const { return mCrs; }
477 
485  void setCrs( const QgsCoordinateReferenceSystem &crs );
486 
495  bool keepLayerSet() const { return mKeepLayerSet; }
496 
505  void setKeepLayerSet( bool enabled ) { mKeepLayerSet = enabled; }
506 
513  QList<QgsMapLayer *> layers() const;
514 
521  void setLayers( const QList<QgsMapLayer *> &layers );
522 
527  bool keepLayerStyles() const { return mKeepLayerStyles; }
528 
533  void setKeepLayerStyles( bool enabled ) { mKeepLayerStyles = enabled; }
534 
539  QMap<QString, QString> layerStyleOverrides() const { return mLayerStyleOverrides; }
540 
545  void setLayerStyleOverrides( const QMap<QString, QString> &overrides );
546 
550  void storeCurrentLayerStyles();
551 
562  bool followVisibilityPreset() const { return mFollowVisibilityPreset; }
563 
567  void setFollowVisibilityPreset( bool follow );
568 
576  QString followVisibilityPresetName() const { return mFollowVisibilityPresetName; }
577 
584  void setFollowVisibilityPresetName( const QString &name );
585 
586  void moveContent( double dx, double dy ) override;
587  void setMoveContentPreviewOffset( double dx, double dy ) override;
588 
589  void zoomContent( double factor, QPointF point ) override;
590 
591 
593  bool containsWmsLayer() const;
594 
595  bool requiresRasterization() const override;
596  bool containsAdvancedEffects() const override;
597 
604  void setMapRotation( double rotation );
605 
614  double mapRotation( QgsLayoutObject::PropertyValueType valueType = QgsLayoutObject::EvaluatedValue ) const;
615 
620  void setDrawAnnotations( bool draw ) { mDrawAnnotations = draw; }
621 
626  bool drawAnnotations() const { return mDrawAnnotations; }
627 
628 
635  bool atlasDriven() const { return mAtlasDriven; }
636 
643  void setAtlasDriven( bool enabled );
644 
654  AtlasScalingMode atlasScalingMode() const { return mAtlasScalingMode; }
655 
665  void setAtlasScalingMode( AtlasScalingMode mode ) { mAtlasScalingMode = mode; }
666 
678 
686  void setAtlasMargin( double margin ) { mAtlasMargin = margin; }
687 
693  QgsLayoutItemMapGridStack *grids() { return mGridStack.get(); }
694 
699  QgsLayoutItemMapGrid *grid();
700 
707  QgsLayoutItemMapOverviewStack *overviews() { return mOverviewStack.get(); }
708 
714  QgsLayoutItemMapOverview *overview();
715 
726  QgsLayoutMeasurement labelMargin() const;
727 
738  void setLabelMargin( const QgsLayoutMeasurement &margin );
739 
740  QgsExpressionContext createExpressionContext() const override;
741 
747  double mapUnitsToLayoutUnits() const;
748 
756  QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings ) const;
757 
758  void finalizeRestoreFromXml() override;
759 
764  QList<QgsMapLayer *> layersToRender( const QgsExpressionContext *context = nullptr ) const;
765 
777  void addLabelBlockingItem( QgsLayoutItem *item );
778 
790  void removeLabelBlockingItem( QgsLayoutItem *item );
791 
803  bool isLabelBlockingItem( QgsLayoutItem *item ) const;
804 
809  QgsMapRendererJob::Errors renderingErrors() const { return mRenderingErrors; }
810 
811  bool accept( QgsStyleEntityVisitorInterface *visitor ) const override;
812 
825  void addRenderedFeatureHandler( QgsRenderedFeatureHandlerInterface *handler );
826 
833  void removeRenderedFeatureHandler( QgsRenderedFeatureHandlerInterface *handler );
834 
838  QTransform layoutToMapCoordsTransform() const;
839 
845  QgsLayoutItemMapAtlasClippingSettings *atlasClippingSettings() { return mAtlasClippingSettings; }
846 
852  QgsLayoutItemMapItemClipPathSettings *itemClippingSettings() { return mItemClippingSettings; }
853 
854  protected:
855 
856  void draw( QgsLayoutItemRenderContext &context ) override;
857  bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
858  bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;
859  QPainterPath framePath() const override;
860 
862  bool isDrawing() const {return mDrawing;}
863 
864  // In case of annotations, the bounding rectangle can be larger than the map item rectangle
865  QRectF boundingRect() const override;
866 
868  QPolygonF transformedMapPolygon() const;
869 
871  QPointF mapToItemCoords( QPointF mapCoords ) const;
872 
876  QgsRectangle requestedExtent() const;
877 
878  signals:
879 
886 
892  void mapRotationChanged( double newRotation );
893 
896 
902 
911  void themeChanged( const QString &theme );
912 
918  void crsChanged();
919 
920  public slots:
921 
922  void refresh() override;
923 
924  void invalidateCache() override;
925 
927  void updateBoundingRect();
928 
929  void refreshDataDefinedProperty( QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties ) override;
930 
931  private slots:
932  void layersAboutToBeRemoved( const QList<QgsMapLayer *> &layers );
933 
934  void painterJobFinished();
935 
936  void shapeChanged();
937 
938  void mapThemeChanged( const QString &theme );
939 
941  void currentMapThemeRenamed( const QString &theme, const QString &newTheme );
942 
944  void recreateCachedImageInBackground();
945 
946  void updateAtlasFeature();
947  private:
948 
949  QgsLayoutItemMap::MapItemFlags mMapFlags = QgsLayoutItemMap::MapItemFlags();
950 
952  int mMapId = 1;
953 
954  std::unique_ptr< QgsLayoutItemMapGridStack > mGridStack;
955  std::unique_ptr< QgsLayoutItemMapOverviewStack > mOverviewStack;
956 
957  // Map region in map units really used for rendering
958  // It can be the same as mUserExtent, but it can be bigger in on dimension if mCalculate==Scale,
959  // so that full rectangle in paper is used.
960  QgsRectangle mExtent;
961 
964 
965  // Current temporary map region in map units. This is overwritten when atlas feature changes. It's also
966  // used when the user changes the map extent and an atlas preview is enabled. This allows the user
967  // to manually tweak each atlas preview page without affecting the actual original map extent.
968  QgsRectangle mAtlasFeatureExtent;
969 
970  // We have two images used for rendering/storing cached map images.
971  // the first (mCacheFinalImage) is used ONLY for storing the most recent completed map render. It's always
972  // used when drawing map item previews. The second (mCacheRenderingImage) is used temporarily while
973  // rendering a new preview image in the background. If (and only if) the background render completes, then
974  // mCacheRenderingImage is pushed into mCacheFinalImage, and used from then on when drawing the item preview.
975  // This ensures that something is always shown in the map item, even while refreshing the preview image in the
976  // background
977  std::unique_ptr< QImage > mCacheFinalImage;
978  std::unique_ptr< QImage > mCacheRenderingImage;
979  bool mUpdatesEnabled = true;
980 
982  bool mCacheInvalidated = true;
983 
985  int mNumCachedLayers;
986 
987  // Set to true if in state of drawing. Concurrent requests to draw method are returned if set to true
988  bool mDrawing = false;
989 
990  QTimer *mBackgroundUpdateTimer = nullptr;
991  double mPreviewScaleFactor = 0;
992 
993  bool mDrawingPreview = false;
994 
996  double mXOffset = 0.0;
998  double mYOffset = 0.0;
999 
1000  double mLastRenderedImageOffsetX = 0.0;
1001  double mLastRenderedImageOffsetY = 0.0;
1002 
1004  double mMapRotation = 0;
1005 
1010  double mEvaluatedMapRotation = 0;
1011 
1013  bool mKeepLayerSet = false;
1014 
1016  QList< QgsMapLayerRef > mLayers;
1017 
1018  bool mKeepLayerStyles = false;
1020  QMap<QString, QString> mLayerStyleOverrides;
1021 
1023  mutable QString mCachedLayerStyleOverridesPresetName;
1025  mutable QMap<QString, QString> mCachedPresetLayerStyleOverrides;
1026 
1032  bool mFollowVisibilityPreset = false;
1033 
1038  QString mFollowVisibilityPresetName;
1039 
1041  QString mLastEvaluatedThemeName;
1042 
1050  void drawMap( QPainter *painter, const QgsRectangle &extent, QSizeF size, double dpi );
1051 
1053  void connectUpdateSlot();
1054 
1056  void syncLayerSet();
1057 
1059  const QgsLayoutItemMapGrid *constFirstMapGrid() const;
1060 
1062  const QgsLayoutItemMapOverview *constFirstMapOverview() const;
1063 
1068  QList< QgsLabelBlockingRegion > createLabelBlockingRegions( const QgsMapSettings &mapSettings ) const;
1069 
1071  QRectF mCurrentRectangle;
1073  bool mDrawAnnotations = true;
1074 
1076  bool mAtlasDriven = false;
1078  AtlasScalingMode mAtlasScalingMode = Auto;
1080  double mAtlasMargin = 0.10;
1081 
1082  std::unique_ptr< QPainter > mPainter;
1083  std::unique_ptr< QgsMapRendererCustomPainterJob > mPainterJob;
1084  bool mPainterCancelWait = false;
1085 
1086  QgsLayoutMeasurement mLabelMargin{ 0 };
1087  QgsLayoutMeasurement mEvaluatedLabelMargin{ 0 };
1088 
1089  QStringList mBlockingLabelItemUuids;
1090  QList< QPointer< QgsLayoutItem > > mBlockingLabelItems;
1091 
1093  QgsMapRendererJob::Errors mRenderingErrors;
1094 
1095  QList< QgsRenderedFeatureHandlerInterface * > mRenderedFeatureHandlers;
1096 
1097  std::unique_ptr< QgsMapRendererStagedRenderJob > mStagedRendererJob;
1098 
1099  void init();
1100 
1102  void updateToolTip();
1103 
1104  QString themeToRender( const QgsExpressionContext &context ) const;
1105 
1107  QMap<QString, QString> layerStyleOverridesToRender( const QgsExpressionContext &context ) const;
1108 
1110  QgsRectangle transformedExtent() const;
1111 
1113  void mapPolygon( const QgsRectangle &extent, QPolygonF &poly ) const;
1114 
1120  void transformShift( double &xShift, double &yShift ) const;
1121 
1122  void drawAnnotations( QPainter *painter );
1123  void drawAnnotation( const QgsAnnotation *item, QgsRenderContext &context );
1124  QPointF layoutMapPosForItem( const QgsAnnotation *item ) const;
1125 
1126  void drawMapFrame( QPainter *p );
1127  void drawMapBackground( QPainter *p );
1128 
1129  enum PartType
1130  {
1131  Start,
1132  Background,
1133  Layer,
1134  Grid,
1135  OverviewMapExtent,
1136  Frame,
1137  SelectionBoxes,
1138  End,
1139  NotLayered,
1140  };
1141 
1143  bool shouldDrawPart( PartType part ) const;
1144 
1145  PartType mCurrentExportPart = NotLayered;
1146  QStringList mExportThemes;
1147  QStringList::iterator mExportThemeIt;
1148 
1149  QgsLayoutItemMapAtlasClippingSettings *mAtlasClippingSettings = nullptr;
1150  QgsLayoutItemMapItemClipPathSettings *mItemClippingSettings = nullptr;
1151 
1156  void refreshMapExtents( const QgsExpressionContext *context = nullptr );
1157 
1158  void refreshLabelMargin( bool updateItem );
1159 
1160  QgsRectangle computeAtlasRectangle();
1161 
1162  void createStagedRenderJob( const QgsRectangle &extent, const QSizeF size, double dpi );
1163 
1164  QPolygonF calculateVisibleExtentPolygon( bool includeClipping ) const;
1165 
1166  friend class QgsLayoutItemMapGrid;
1168  friend class QgsLayoutItemLegend;
1169  friend class TestQgsLayoutMap;
1171  friend class QgsGeoPdfRenderedFeatureHandler;
1172 
1173 };
1174 
1175 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayoutItemMap::MapItemFlags )
1176 
1177 #endif //QGSLAYOUTITEMMAP_H
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:52
QgsCompositionConverter class converts a QGIS 2.x composition to a QGIS 3.x layout.
This class represents a coordinate reference system (CRS).
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
A layout item subclass for map legends.
Contains settings relating to clipping a layout map by the current atlas feature.
void changed()
Emitted when the atlas clipping settings are changed.
A collection of grids which is drawn above the map content in a QgsLayoutItemMap.
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.
void changed()
Emitted when the item clipping settings are changed.
A collection of overviews which are drawn above the map content in a QgsLayoutItemMap.
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
void preparedForAtlas()
Emitted when the map has been prepared for atlas rendering, just before actual rendering.
QgsMapRendererJob::Errors renderingErrors() const
Returns map rendering errors.
bool keepLayerSet() const
Returns whether a stored layer set should be used or the current layer set from the project associate...
void setKeepLayerSet(bool enabled)
Sets whether the stored layer set should be used or the current layer set of the associated project.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
@ Predefined
A scale is chosen from the predefined scales.
@ Fixed
The current scale of the map is used for each feature of the atlas.
void layerStyleOverridesChanged()
Emitted when layer style overrides are changed...
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
bool isDrawing() const
True if a draw is already in progress.
QString followVisibilityPresetName() const
Preset name that decides which layers and layer styles are used for map rendering.
QMap< QString, QString > layerStyleOverrides() const
Returns stored overrides of styles for layers.
void setDrawAnnotations(bool draw)
Sets whether annotations are drawn within the map.
bool followVisibilityPreset() const
Returns whether the map should follow a map theme.
void crsChanged()
Emitted when the map's coordinate reference system is changed.
QgsLayoutItemMapItemClipPathSettings * itemClippingSettings()
Returns the map's item based clip path settings.
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
bool keepLayerStyles() const
Returns whether current styles of layers should be overridden by previously stored styles.
AtlasScalingMode atlasScalingMode() const
Returns the current atlas scaling mode.
void setAtlasScalingMode(AtlasScalingMode mode)
Sets the current atlas scaling mode.
QgsLayoutItemMapAtlasClippingSettings * atlasClippingSettings()
Returns the map's atlas clipping settings.
void themeChanged(const QString &theme)
Emitted when the map's associated theme is changed.
MapItemFlag
Various flags that affect drawing of map items.
bool drawAnnotations() const
Returns whether annotations are drawn within the map.
QgsLayoutItemMapOverviewStack * overviews()
Returns the map item's overview stack, which is used to control how overviews are drawn over the map'...
QgsLayoutItemMapGridStack * grids()
Returns the map item's grid stack, which is used to control how grids are drawn over the map's conten...
void setAtlasMargin(double margin)
Sets the margin size (percentage) used when the map is in atlas mode.
void setKeepLayerStyles(bool enabled)
Sets whether current styles of layers should be overridden by previously stored styles.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Definition: qgslayoutitem.h:45
Base class for graphical items within a QgsLayout.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
DataDefinedProperty
Data defined properties for different item types.
@ 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.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
A map clipping region (in map coordinates and CRS).
FeatureClippingType
Feature clipping behavior, which controls how features from vector layers will be clipped.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. feature boundaries will be unchanged, but may be invisibl...
QList< QgsMapRendererJob::Error > Errors
The QgsMapSettings class contains configuration for rendering of the map.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Contains information about the context of a rendering operation.
An interface for classes which provider custom handlers for features rendered as part of a map render...
An interface for classes which can visit style entity (e.g.
Base class for objects with an associated (optional) temporal range.
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_TRANSFERTHIS
Definition: qgis_sip.h:53
#define SIP_FACTORY
Definition: qgis_sip.h:76
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
const QgsCoordinateReferenceSystem & crs