QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsannotationpolygonitem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsannotationpolygonitem.cpp
3  ----------------
4  begin : July 2020
5  copyright : (C) 2020 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgssymbol.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgssurface.h"
22 
25  , mPolygon( polygon )
26  , mSymbol( qgis::make_unique< QgsFillSymbol >() )
27 {
28 
29 }
30 
32 
34 {
35  return QStringLiteral( "polygon" );
36 }
37 
39 {
40 
41  auto transformRing = [&context]( QPolygonF & pts )
42  {
43  //transform the QPolygonF to screen coordinates
44  if ( context.coordinateTransform().isValid() )
45  {
46  try
47  {
48  context.coordinateTransform().transformPolygon( pts );
49  }
50  catch ( QgsCsException & )
51  {
52  // we don't abort the rendering here, instead we remove any invalid points and just plot those which ARE valid
53  }
54  }
55 
56  // remove non-finite points, e.g. infinite or NaN points caused by reprojecting errors
57  pts.erase( std::remove_if( pts.begin(), pts.end(),
58  []( const QPointF point )
59  {
60  return !std::isfinite( point.x() ) || !std::isfinite( point.y() );
61  } ), pts.end() );
62 
63  QPointF *ptr = pts.data();
64  for ( int i = 0; i < pts.size(); ++i, ++ptr )
65  {
66  context.mapToPixel().transformInPlace( ptr->rx(), ptr->ry() );
67  }
68  };
69 
70  QPolygonF exterior = mPolygon->exteriorRing()->asQPolygonF();
71  transformRing( exterior );
72  QVector<QPolygonF> rings;
73  rings.reserve( mPolygon->numInteriorRings() );
74  for ( int i = 0; i < mPolygon->numInteriorRings(); ++i )
75  {
76  QPolygonF ring = mPolygon->interiorRing( i )->asQPolygonF();
77  transformRing( ring );
78  rings.append( ring );
79  }
80 
81  mSymbol->startRender( context );
82  mSymbol->renderPolygon( exterior, rings.empty() ? nullptr : &rings, nullptr, context );
83  mSymbol->stopRender( context );
84 }
85 
86 bool QgsAnnotationPolygonItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
87 {
88  element.setAttribute( QStringLiteral( "wkt" ), mPolygon->asWkt() );
89 
90  element.setAttribute( QStringLiteral( "zIndex" ), zIndex() );
91  element.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "lineSymbol" ), mSymbol.get(), document, context ) );
92 
93  return true;
94 }
95 
97 {
98  return new QgsAnnotationPolygonItem( new QgsPolygon() );
99 }
100 
101 bool QgsAnnotationPolygonItem::readXml( const QDomElement &element, const QgsReadWriteContext &context )
102 {
103  const QString wkt = element.attribute( QStringLiteral( "wkt" ) );
105  if ( const QgsCurvePolygon *polygon = qgsgeometry_cast< const QgsCurvePolygon * >( geometry.constGet() ) )
106  mPolygon.reset( polygon->clone() );
107 
108  setZIndex( element.attribute( QStringLiteral( "zIndex" ) ).toInt() );
109 
110  const QDomElement symbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
111  if ( !symbolElem.isNull() )
112  setSymbol( QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( symbolElem, context ) );
113 
114  return true;
115 }
116 
118 {
119  std::unique_ptr< QgsAnnotationPolygonItem > item = qgis::make_unique< QgsAnnotationPolygonItem >( mPolygon->clone() );
120  item->setSymbol( mSymbol->clone() );
121  item->setZIndex( zIndex() );
122  return item.release();
123 }
124 
126 {
127  return mPolygon->boundingBox();
128 }
129 
131 {
132  return mSymbol.get();
133 }
134 
136 {
137  mSymbol.reset( symbol );
138 }
QgsAnnotationPolygonItem::writeXml
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes the item's state into an XML element.
Definition: qgsannotationpolygonitem.cpp:86
QgsAnnotationPolygonItem::clone
QgsAnnotationPolygonItem * clone() override
Returns a clone of the item.
Definition: qgsannotationpolygonitem.cpp:117
QgsRenderContext::mapToPixel
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
Definition: qgsrendercontext.h:325
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:34
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsAnnotationPolygonItem::render
void render(QgsRenderContext &context, QgsFeedback *feedback) override
Renders the item to the specified render context.
Definition: qgsannotationpolygonitem.cpp:38
QgsCurvePolygon
Curve polygon geometry type.
Definition: qgscurvepolygon.h:35
qgsannotationpolygonitem.h
qgssymbollayerutils.h
QgsAnnotationPolygonItem::~QgsAnnotationPolygonItem
~QgsAnnotationPolygonItem() override
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsCoordinateTransform::isValid
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Definition: qgscoordinatetransform.cpp:892
QgsAnnotationPolygonItem::type
QString type() const override
Returns a unique (untranslated) string identifying the type of item.
Definition: qgsannotationpolygonitem.cpp:33
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsCoordinateTransform::transformPolygon
void transformPolygon(QPolygonF &polygon, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transforms a polygon to the destination coordinate system.
Definition: qgscoordinatetransform.cpp:370
QgsRenderContext::coordinateTransform
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Definition: qgsrendercontext.h:245
QgsAnnotationPolygonItem::geometry
const QgsCurvePolygon * geometry() const
Returns the geometry of the item.
Definition: qgsannotationpolygonitem.h:62
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
QgsAnnotationPolygonItem::readXml
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the item's state from the given DOM element.
Definition: qgsannotationpolygonitem.cpp:101
QgsAnnotationPolygonItem
An annotation item which renders a fill symbol for a polygon geometry.
Definition: qgsannotationpolygonitem.h:33
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsAnnotationPolygonItem::symbol
const QgsFillSymbol * symbol() const
Returns the symbol used to render the item.
Definition: qgsannotationpolygonitem.cpp:130
QgsGeometry::fromWkt
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
Definition: qgsgeometry.cpp:154
QgsAnnotationItem::zIndex
int zIndex() const
Returns the item's z index, which controls the order in which annotation items are rendered in the la...
Definition: qgsannotationitem.h:121
QgsMapToPixel::transformInPlace
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
Definition: qgsmaptopixel.cpp:233
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsFillSymbol
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgssymbol.h:1234
QgsAnnotationPolygonItem::setSymbol
void setSymbol(QgsFillSymbol *symbol)
Sets the symbol used to render the polygon item.
Definition: qgsannotationpolygonitem.cpp:135
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:1182
QgsAnnotationItem::setZIndex
void setZIndex(int index)
Sets the item's z index, which controls the order in which annotation items are rendered in the layer...
Definition: qgsannotationitem.h:129
QgsAnnotationPolygonItem::QgsAnnotationPolygonItem
QgsAnnotationPolygonItem(QgsCurvePolygon *polygon)
Constructor for QgsAnnotationPolygonItem, with the specified polygon geometry.
Definition: qgsannotationpolygonitem.cpp:23
QgsAnnotationPolygonItem::boundingBox
QgsRectangle boundingBox() const override
Returns the bounding box of the item's geographic location, in the parent layer's coordinate referenc...
Definition: qgsannotationpolygonitem.cpp:125
QgsAnnotationItem
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
Definition: qgsannotationitem.h:39
QgsAnnotationPolygonItem::create
static QgsAnnotationPolygonItem * create()
Creates a new polygon annotation item.
Definition: qgsannotationpolygonitem.cpp:96
qgssurface.h