QGIS API Documentation  3.17.0-Master (a84647cf30)
qgsannotationlineitem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsannotationlineitem.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 
18 #include "qgsannotationlineitem.h"
19 #include "qgssymbol.h"
20 #include "qgssymbollayerutils.h"
21 
24  , mCurve( curve )
25  , mSymbol( qgis::make_unique< QgsLineSymbol >() )
26 {
27 
28 }
29 
31 
33 {
34  return QStringLiteral( "linestring" );
35 }
36 
38 {
39  QPolygonF pts = mCurve->asQPolygonF();
40 
41  //transform the QPolygonF to screen coordinates
42  if ( context.coordinateTransform().isValid() )
43  {
44  try
45  {
46  context.coordinateTransform().transformPolygon( pts );
47  }
48  catch ( QgsCsException & )
49  {
50  // we don't abort the rendering here, instead we remove any invalid points and just plot those which ARE valid
51  }
52  }
53 
54  // remove non-finite points, e.g. infinite or NaN points caused by reprojecting errors
55  pts.erase( std::remove_if( pts.begin(), pts.end(),
56  []( const QPointF point )
57  {
58  return !std::isfinite( point.x() ) || !std::isfinite( point.y() );
59  } ), pts.end() );
60 
61  QPointF *ptr = pts.data();
62  for ( int i = 0; i < pts.size(); ++i, ++ptr )
63  {
64  context.mapToPixel().transformInPlace( ptr->rx(), ptr->ry() );
65  }
66 
67  mSymbol->startRender( context );
68  mSymbol->renderPolyline( pts, nullptr, context );
69  mSymbol->stopRender( context );
70 }
71 
72 bool QgsAnnotationLineItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
73 {
74  element.setAttribute( QStringLiteral( "wkt" ), mCurve->asWkt() );
75  element.setAttribute( QStringLiteral( "zIndex" ), zIndex() );
76 
77  element.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "lineSymbol" ), mSymbol.get(), document, context ) );
78 
79  return true;
80 }
81 
83 {
84  return new QgsAnnotationLineItem( new QgsLineString() );
85 }
86 
87 bool QgsAnnotationLineItem::readXml( const QDomElement &element, const QgsReadWriteContext &context )
88 {
89  const QString wkt = element.attribute( QStringLiteral( "wkt" ) );
91  if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geometry.constGet() ) )
92  mCurve.reset( curve->clone() );
93 
94  setZIndex( element.attribute( QStringLiteral( "zIndex" ) ).toInt() );
95 
96  const QDomElement symbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
97  if ( !symbolElem.isNull() )
98  setSymbol( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( symbolElem, context ) );
99 
100  return true;
101 }
102 
104 {
105  return mCurve->boundingBox();
106 }
107 
109 {
110  std::unique_ptr< QgsAnnotationLineItem > item = qgis::make_unique< QgsAnnotationLineItem >( mCurve->clone() );
111  item->setSymbol( mSymbol->clone() );
112  item->setZIndex( zIndex() );
113  return item.release();
114 }
115 
117 {
118  return mSymbol.get();
119 }
120 
122 {
123  mSymbol.reset( symbol );
124 }
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:41
void setZIndex(int index)
Sets the item&#39;s z index, which controls the order in which annotation items are rendered in the layer...
void render(QgsRenderContext &context, QgsFeedback *feedback) override
Renders the item to the specified render context.
const QgsCurve * geometry() const
Returns the geometry of the item.
QgsRectangle boundingBox() const override
Returns the bounding box of the item&#39;s geographic location, in the parent layer&#39;s coordinate referenc...
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:123
const QgsLineSymbol * symbol() const
Returns the symbol used to render the item.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
QString type() const override
Returns a unique (untranslated) string identifying the type of item.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1192
void transformPolygon(QPolygonF &polygon, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transforms a polygon to the destination coordinate system.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:43
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
~QgsAnnotationLineItem() override
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes the item&#39;s state into an XML element.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
void setSymbol(QgsLineSymbol *symbol)
Sets the symbol used to render the marker item.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the item&#39;s state from the given DOM element.
QgsAnnotationLineItem(QgsCurve *curve)
Constructor for QgsAnnotationLineItem, with the specified linestring.
int zIndex() const
Returns the item&#39;s z index, which controls the order in which annotation items are rendered in the la...
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
Contains information about the context of a rendering operation.
const QgsMapToPixel & mapToPixel() const
Returns the context&#39;s map to pixel transform, which transforms between map coordinates and device coo...
static QgsAnnotationLineItem * create()
Creates a new linestring annotation item.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsAnnotationLineItem * clone() override
Returns a clone of the item.
An annotation item which renders a line symbol along a line geometry.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65