QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgslayoutitempolygon.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitempolygon.cpp
3  begin : March 2016
4  copyright : (C) 2016 Paul Blottiere, Oslandia
5  email : paul dot blottiere at oslandia dot com
6  ***************************************************************************/
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 #include "qgslayoutitempolygon.h"
18 #include "qgslayoutitemregistry.h"
19 #include "qgslayoututils.h"
20 #include "qgslayout.h"
21 #include "qgspathresolver.h"
22 #include "qgsreadwritecontext.h"
23 #include "qgssymbollayerutils.h"
24 #include "qgssymbol.h"
25 #include "qgsmapsettings.h"
26 #include "qgsstyleentityvisitor.h"
27 #include "qgsfillsymbol.h"
28 
29 #include <limits>
30 
32  : QgsLayoutNodesItem( layout )
33 {
34  createDefaultPolygonStyleSymbol();
35 }
36 
37 QgsLayoutItemPolygon::QgsLayoutItemPolygon( const QPolygonF &polygon, QgsLayout *layout )
38  : QgsLayoutNodesItem( polygon, layout )
39 {
40  createDefaultPolygonStyleSymbol();
41 }
42 
44 
46 {
47  return new QgsLayoutItemPolygon( layout );
48 }
49 
51 {
53 }
54 
56 {
57  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemPolygon.svg" ) );
58 }
59 
60 bool QgsLayoutItemPolygon::_addNode( const int indexPoint,
61  QPointF newPoint,
62  const double radius )
63 {
64  Q_UNUSED( radius )
65  mPolygon.insert( indexPoint + 1, newPoint );
66  return true;
67 }
68 
69 void QgsLayoutItemPolygon::createDefaultPolygonStyleSymbol()
70 {
71  QVariantMap properties;
72  properties.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
73  properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
74  properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
75  properties.insert( QStringLiteral( "color_border" ), QStringLiteral( "black" ) );
76  properties.insert( QStringLiteral( "width_border" ), QStringLiteral( "0.3" ) );
77  properties.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
78 
79  mPolygonStyleSymbol.reset( QgsFillSymbol::createSimple( properties ) );
80 
81  refreshSymbol();
82 }
83 
84 void QgsLayoutItemPolygon::refreshSymbol()
85 {
86  if ( auto *lLayout = layout() )
87  {
88  const QgsRenderContext rc = QgsLayoutUtils::createRenderContextForLayout( lLayout, nullptr, lLayout->renderContext().dpi() );
89  mMaxSymbolBleed = ( 25.4 / lLayout->renderContext().dpi() ) * QgsSymbolLayerUtils::estimateMaxSymbolBleed( mPolygonStyleSymbol.get(), rc );
90  }
91 
93 
94  emit frameChanged();
95 }
96 
98 {
99  if ( !id().isEmpty() )
100  return id();
101 
102  return tr( "<Polygon>" );
103 }
104 
106 {
107  if ( mPolygonStyleSymbol )
108  {
109  QgsStyleSymbolEntity entity( mPolygonStyleSymbol.get() );
110  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, uuid(), displayName() ) ) )
111  return false;
112  }
113 
114  return true;
115 }
116 
117 QgsLayoutItem::Flags QgsLayoutItemPolygon::itemFlags() const
118 {
119  QgsLayoutItem::Flags flags = QgsLayoutNodesItem::itemFlags();
121  return flags;
122 }
123 
125 {
126  QPolygonF path = mapToScene( mPolygon );
127  // ensure polygon is closed
128  if ( path.at( 0 ) != path.constLast() )
129  path << path.at( 0 );
130  return QgsGeometry::fromQPolygonF( path );
131 }
132 
134 {
135  return mPolygonStyleSymbol.get();
136 }
137 
138 void QgsLayoutItemPolygon::_draw( QgsLayoutItemRenderContext &context, const QStyleOptionGraphicsItem * )
139 {
140  //setup painter scaling to dots so that raster symbology is drawn to scale
141  const double scale = context.renderContext().convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
142  const QTransform t = QTransform::fromScale( scale, scale );
143 
144  const QVector<QPolygonF> rings; //empty
145  QPainterPath polygonPath;
146  polygonPath.addPolygon( mPolygon );
147 
148  mPolygonStyleSymbol->startRender( context.renderContext() );
149  mPolygonStyleSymbol->renderPolygon( polygonPath.toFillPolygon( t ), &rings,
150  nullptr, context.renderContext() );
151  mPolygonStyleSymbol->stopRender( context.renderContext() );
152 }
153 
154 void QgsLayoutItemPolygon::_readXmlStyle( const QDomElement &elmt, const QgsReadWriteContext &context )
155 {
156  mPolygonStyleSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( elmt, context ) );
157 }
158 
160 {
161  mPolygonStyleSymbol.reset( static_cast<QgsFillSymbol *>( symbol->clone() ) );
162  refreshSymbol();
163 }
164 
165 void QgsLayoutItemPolygon::_writeXmlStyle( QDomDocument &doc, QDomElement &elmt, const QgsReadWriteContext &context ) const
166 {
167  const QDomElement pe = QgsSymbolLayerUtils::saveSymbol( QString(),
168  mPolygonStyleSymbol.get(),
169  doc,
170  context );
171  elmt.appendChild( pe );
172 }
173 
174 bool QgsLayoutItemPolygon::_removeNode( const int index )
175 {
176  if ( index < 0 || index >= mPolygon.size() )
177  return false;
178 
179  mPolygon.remove( index );
180 
181  if ( mPolygon.size() < 3 )
182  mPolygon.clear();
183  else
184  {
185  int newSelectNode = index;
186  if ( index == mPolygon.size() )
187  newSelectNode = 0;
188  setSelectedNode( newSelectNode );
189  }
190 
191  return true;
192 }
193 
QgsLayoutItemRegistry::LayoutPolygon
@ LayoutPolygon
Polygon shape item.
Definition: qgslayoutitemregistry.h:352
QgsLayoutItem::id
QString id() const
Returns the item's ID name.
Definition: qgslayoutitem.h:359
QgsLayoutObject::layout
const QgsLayout * layout() const
Returns the layout the object is attached to.
Definition: qgslayoutobject.cpp:216
QgsLayoutItemPolygon::setSymbol
void setSymbol(QgsFillSymbol *symbol)
Sets the symbol used to draw the shape.
Definition: qgslayoutitempolygon.cpp:159
qgslayoutitempolygon.h
QgsLayoutItemPolygon::symbol
QgsFillSymbol * symbol()
Returns the fill symbol used to draw the shape.
Definition: qgslayoutitempolygon.cpp:133
QgsLayoutNodesItem::mMaxSymbolBleed
double mMaxSymbolBleed
Max symbol bleed.
Definition: qgslayoutitemnodeitem.h:150
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsStyleSymbolEntity
A symbol entity for QgsStyle databases.
Definition: qgsstyle.h:1341
QgsLayoutItemPolygon::_readXmlStyle
void _readXmlStyle(const QDomElement &elmt, const QgsReadWriteContext &context) override
Method called in readXml.
Definition: qgslayoutitempolygon.cpp:154
qgsreadwritecontext.h
qgssymbollayerutils.h
QgsLayoutItemRenderContext
Contains settings and helpers relating to a render of a QgsLayoutItem.
Definition: qgslayoutitem.h:44
qgspathresolver.h
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsStyleEntityVisitorInterface
An interface for classes which can visit style entity (e.g. symbol) nodes (using the visitor pattern)...
Definition: qgsstyleentityvisitor.h:33
QgsUnitTypes::RenderMillimeters
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
QgsLayoutNodesItem::setSelectedNode
bool setSelectedNode(int index)
Selects a node by index.
Definition: qgslayoutitemnodeitem.cpp:319
qgsmapsettings.h
QgsStyleEntityVisitorInterface::StyleLeaf
Contains information relating to the style entity currently being visited.
Definition: qgsstyleentityvisitor.h:60
QgsLayoutNodesItem::updateSceneRect
void updateSceneRect()
Update the current scene rectangle for this item.
Definition: qgslayoutitemnodeitem.cpp:332
QgsLayoutItem::FlagProvidesClipPath
@ FlagProvidesClipPath
Item can act as a clipping path provider (see clipPath())
Definition: qgslayoutitem.h:306
QgsLayoutNodesItem::mPolygon
QPolygonF mPolygon
Shape's nodes.
Definition: qgslayoutitemnodeitem.h:147
qgslayoututils.h
QgsLayoutItemPolygon::QgsLayoutItemPolygon
QgsLayoutItemPolygon(QgsLayout *layout)
Constructor for QgsLayoutItemPolygon for the specified layout.
Definition: qgslayoutitempolygon.cpp:31
QgsLayoutUtils::createRenderContextForLayout
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
Definition: qgslayoututils.cpp:141
QgsLayoutItemPolygon::clipPath
QgsGeometry clipPath() const override
Returns the clipping path generated by this item, in layout coordinates.
Definition: qgslayoutitempolygon.cpp:124
QgsLayoutItemPolygon::displayName
QString displayName() const override
Gets item display name.
Definition: qgslayoutitempolygon.cpp:97
QgsLayoutItem::frameChanged
void frameChanged()
Emitted if the item's frame style changes.
QgsLayoutItemPolygon::_writeXmlStyle
void _writeXmlStyle(QDomDocument &doc, QDomElement &elmt, const QgsReadWriteContext &context) const override
Method called in writeXml.
Definition: qgslayoutitempolygon.cpp:165
QgsFillSymbol::createSimple
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Definition: qgsfillsymbol.cpp:20
qgslayout.h
QgsRenderContext::convertToPainterUnits
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
Definition: qgsrendercontext.cpp:367
QgsLayoutItemPolygon::itemFlags
QgsLayoutItem::Flags itemFlags() const override
Returns the item's flags, which indicate how the item behaves.
Definition: qgslayoutitempolygon.cpp:117
QgsLayoutItem::itemFlags
virtual Flags itemFlags() const
Returns the item's flags, which indicate how the item behaves.
Definition: qgslayoutitem.cpp:129
QgsLayoutItemRenderContext::renderContext
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgslayoutitem.h:72
QgsLayoutItem::uuid
virtual QString uuid() const
Returns the item identification string.
Definition: qgslayoutitem.h:345
QgsLayoutItemPolygon::_removeNode
bool _removeNode(int nodeIndex) override
Method called in removeNode.
Definition: qgslayoutitempolygon.cpp:174
QgsLayoutItemPolygon::_draw
void _draw(QgsLayoutItemRenderContext &context, const QStyleOptionGraphicsItem *itemStyle=nullptr) override
Method called in paint.
Definition: qgslayoutitempolygon.cpp:138
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsLayout
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
QgsLayoutItemPolygon::_addNode
bool _addNode(int indexPoint, QPointF newPoint, double radius) override
Method called in addNode.
Definition: qgslayoutitempolygon.cpp:60
QgsLayoutNodesItem
An abstract layout item that provides generic methods for node based shapes such as polygon or polyli...
Definition: qgslayoutitemnodeitem.h:29
QgsFillSymbol::clone
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgsfillsymbol.cpp:144
QgsFillSymbol
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:29
QgsLayoutItemPolygon::accept
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
Definition: qgslayoutitempolygon.cpp:105
QgsStyleEntityVisitorInterface::visit
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
Definition: qgsstyleentityvisitor.h:153
QgsLayoutItemPolygon
Layout item for node based polygon shapes.
Definition: qgslayoutitempolygon.h:30
QgsLayoutItemPolygon::create
static QgsLayoutItemPolygon * create(QgsLayout *layout)
Returns a new polygon item for the specified layout.
Definition: qgslayoutitempolygon.cpp:45
QgsGeometry::fromQPolygonF
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Definition: qgsgeometry.cpp:3408
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Definition: qgsapplication.cpp:693
QgsSymbolLayerUtils::estimateMaxSymbolBleed
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
Definition: qgssymbollayerutils.cpp:934
QgsLayoutItemPolygon::~QgsLayoutItemPolygon
~QgsLayoutItemPolygon() override
qgslayoutitemregistry.h
qgsfillsymbol.h
qgssymbol.h
QgsSymbolLayerUtils::saveSymbol
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Definition: qgssymbollayerutils.cpp:1397
QgsLayoutItemPolygon::icon
QIcon icon() const override
Returns the item's icon.
Definition: qgslayoutitempolygon.cpp:55
qgsstyleentityvisitor.h
QgsLayoutItemPolygon::type
int type() const override
Definition: qgslayoutitempolygon.cpp:50