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