QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 #include "qgslinesymbol.h"
22 #include "qgsannotationitemnode.h"
24 
27  , mCurve( curve )
28  , mSymbol( std::make_unique< QgsLineSymbol >() )
29 {
30 
31 }
32 
34 
36 {
37  return QStringLiteral( "linestring" );
38 }
39 
41 {
42  QPolygonF pts = mCurve->asQPolygonF();
43 
44  //transform the QPolygonF to screen coordinates
45  if ( context.coordinateTransform().isValid() )
46  {
47  try
48  {
49  context.coordinateTransform().transformPolygon( pts );
50  }
51  catch ( QgsCsException & )
52  {
53  // we don't abort the rendering here, instead we remove any invalid points and just plot those which ARE valid
54  }
55  }
56 
57  // remove non-finite points, e.g. infinite or NaN points caused by reprojecting errors
58  pts.erase( std::remove_if( pts.begin(), pts.end(),
59  []( const QPointF point )
60  {
61  return !std::isfinite( point.x() ) || !std::isfinite( point.y() );
62  } ), pts.end() );
63 
64  QPointF *ptr = pts.data();
65  for ( int i = 0; i < pts.size(); ++i, ++ptr )
66  {
67  context.mapToPixel().transformInPlace( ptr->rx(), ptr->ry() );
68  }
69 
70  mSymbol->startRender( context );
71  mSymbol->renderPolyline( pts, nullptr, context );
72  mSymbol->stopRender( context );
73 }
74 
75 bool QgsAnnotationLineItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
76 {
77  element.setAttribute( QStringLiteral( "wkt" ), mCurve->asWkt() );
78  element.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "lineSymbol" ), mSymbol.get(), document, context ) );
79  writeCommonProperties( element, document, context );
80 
81  return true;
82 }
83 
84 QList<QgsAnnotationItemNode> QgsAnnotationLineItem::nodes() const
85 {
86  QList< QgsAnnotationItemNode > res;
87  int i = 0;
88  for ( auto it = mCurve->vertices_begin(); it != mCurve->vertices_end(); ++it, ++i )
89  {
90  res.append( QgsAnnotationItemNode( it.vertexId(), QgsPointXY( ( *it ).x(), ( *it ).y() ), Qgis::AnnotationItemNodeType::VertexHandle ) );
91  }
92  return res;
93 }
94 
96 {
97  switch ( operation->type() )
98  {
100  {
101  QgsAnnotationItemEditOperationMoveNode *moveOperation = qgis::down_cast< QgsAnnotationItemEditOperationMoveNode * >( operation );
102  if ( mCurve->moveVertex( moveOperation->nodeId(), QgsPoint( moveOperation->after() ) ) )
104  break;
105  }
106 
108  {
109  QgsAnnotationItemEditOperationDeleteNode *deleteOperation = qgis::down_cast< QgsAnnotationItemEditOperationDeleteNode * >( operation );
110  if ( mCurve->deleteVertex( deleteOperation->nodeId() ) )
112  break;
113  }
114 
116  {
117  QgsAnnotationItemEditOperationAddNode *addOperation = qgis::down_cast< QgsAnnotationItemEditOperationAddNode * >( operation );
118 
119  QgsPoint segmentPoint;
120  QgsVertexId endOfSegmentVertex;
121  mCurve->closestSegment( addOperation->point(), segmentPoint, endOfSegmentVertex );
122  if ( mCurve->insertVertex( endOfSegmentVertex, segmentPoint ) )
124  break;
125  }
126 
128  {
129  QgsAnnotationItemEditOperationTranslateItem *moveOperation = qgis::down_cast< QgsAnnotationItemEditOperationTranslateItem * >( operation );
130  const QTransform transform = QTransform::fromTranslate( moveOperation->translationX(), moveOperation->translationY() );
131  mCurve->transform( transform );
133  }
134  }
135 
137 }
138 
140 {
141  switch ( operation->type() )
142  {
144  {
145  QgsAnnotationItemEditOperationMoveNode *moveOperation = dynamic_cast< QgsAnnotationItemEditOperationMoveNode * >( operation );
146  std::unique_ptr< QgsCurve > modifiedCurve( mCurve->clone() );
147  if ( modifiedCurve->moveVertex( moveOperation->nodeId(), QgsPoint( moveOperation->after() ) ) )
148  {
149  return new QgsAnnotationItemEditOperationTransientResults( QgsGeometry( std::move( modifiedCurve ) ) );
150  }
151  break;
152  }
153 
155  {
156  QgsAnnotationItemEditOperationTranslateItem *moveOperation = qgis::down_cast< QgsAnnotationItemEditOperationTranslateItem * >( operation );
157  const QTransform transform = QTransform::fromTranslate( moveOperation->translationX(), moveOperation->translationY() );
158  std::unique_ptr< QgsCurve > modifiedCurve( mCurve->clone() );
159  modifiedCurve->transform( transform );
160  return new QgsAnnotationItemEditOperationTransientResults( QgsGeometry( std::move( modifiedCurve ) ) );
161  }
162 
165  break;
166  }
167  return nullptr;
168 }
169 
171 {
172  return new QgsAnnotationLineItem( new QgsLineString() );
173 }
174 
175 bool QgsAnnotationLineItem::readXml( const QDomElement &element, const QgsReadWriteContext &context )
176 {
177  const QString wkt = element.attribute( QStringLiteral( "wkt" ) );
179  if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geometry.constGet() ) )
180  mCurve.reset( curve->clone() );
181 
182  const QDomElement symbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
183  if ( !symbolElem.isNull() )
184  setSymbol( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( symbolElem, context ) );
185 
186  readCommonProperties( element, context );
187 
188  return true;
189 }
190 
192 {
193  return mCurve->boundingBox();
194 }
195 
197 {
198  std::unique_ptr< QgsAnnotationLineItem > item = std::make_unique< QgsAnnotationLineItem >( mCurve->clone() );
199  item->setSymbol( mSymbol->clone() );
200  item->copyCommonProperties( this );
201  return item.release();
202 }
203 
205 {
206  return mSymbol.get();
207 }
208 
210 {
211  mSymbol.reset( symbol );
212 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsAbstractAnnotationItemEditOperation::Type::DeleteNode
@ DeleteNode
Delete a node.
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:258
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsAnnotationLineItem::render
void render(QgsRenderContext &context, QgsFeedback *feedback) override
Renders the item to the specified render context.
Definition: qgsannotationlineitem.cpp:40
QgsAnnotationItemEditOperationTranslateItem
Annotation item edit operation consisting of translating (moving) an item.
Definition: qgsannotationitemeditoperation.h:182
QgsAnnotationItemEditOperationDeleteNode
Annotation item edit operation consisting of deleting a node.
Definition: qgsannotationitemeditoperation.h:120
qgssymbollayerutils.h
QgsAnnotationLineItem::boundingBox
QgsRectangle boundingBox() const override
Returns the bounding box of the item's geographic location, in the parent layer's coordinate referenc...
Definition: qgsannotationlineitem.cpp:191
QgsGeometry::fromWkt
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsAbstractAnnotationItemEditOperation::type
virtual Type type() const =0
Returns the operation type.
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
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:900
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsAnnotationLineItem::clone
QgsAnnotationLineItem * clone() override
Returns a clone of the item.
Definition: qgsannotationlineitem.cpp:196
QgsAnnotationItemEditOperationAddNode::point
QgsPoint point() const
Returns the node position (in layer coordinates).
Definition: qgsannotationitemeditoperation.h:168
qgsannotationlineitem.h
Qgis::AnnotationItemEditOperationResult
AnnotationItemEditOperationResult
Results from an edit operation on an annotation item.
Definition: qgis.h:1153
Qgis::AnnotationItemEditOperationResult::ItemCleared
@ ItemCleared
The operation results in the item being cleared, and the item should be removed from the layer as a r...
QgsRenderContext::coordinateTransform
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Definition: qgsrendercontext.h:178
QgsAnnotationItemEditOperationMoveNode::nodeId
QgsVertexId nodeId() const
Returns the associated node ID.
Definition: qgsannotationitemeditoperation.h:90
QgsAnnotationLineItem::transientEditResults
QgsAnnotationItemEditOperationTransientResults * transientEditResults(QgsAbstractAnnotationItemEditOperation *operation) override
Retrieves the results of a transient (in progress) edit operation on the item.
Definition: qgsannotationlineitem.cpp:139
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsAnnotationLineItem::readXml
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the item's state from the given DOM element.
Definition: qgsannotationlineitem.cpp:175
QgsAnnotationLineItem::type
QString type() const override
Returns a unique (untranslated) string identifying the type of item.
Definition: qgsannotationlineitem.cpp:35
QgsAbstractAnnotationItemEditOperation::Type::TranslateItem
@ TranslateItem
Translate (move) an item.
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsAnnotationLineItem::symbol
const QgsLineSymbol * symbol() const
Returns the symbol used to render the item.
Definition: qgsannotationlineitem.cpp:204
QgsAnnotationItem::writeCommonProperties
bool writeCommonProperties(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Writes common properties from the base class into an XML element.
Definition: qgsannotationitem.cpp:48
QgsLineSymbol
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:29
QgsAnnotationItem::readCommonProperties
bool readCommonProperties(const QDomElement &element, const QgsReadWriteContext &context)
Reads common properties from the base class from the given DOM element.
Definition: qgsannotationitem.cpp:56
QgsAnnotationItemEditOperationDeleteNode::nodeId
QgsVertexId nodeId() const
Returns the deleted node ID.
Definition: qgsannotationitemeditoperation.h:135
QgsAnnotationItemEditOperationMoveNode
Annotation item edit operation consisting of moving a node.
Definition: qgsannotationitemeditoperation.h:75
QgsAbstractAnnotationItemEditOperation
Abstract base class for annotation item edit operations.
Definition: qgsannotationitemeditoperation.h:32
QgsAnnotationLineItem::geometry
const QgsCurve * geometry() const
Returns the geometry of the item.
Definition: qgsannotationlineitem.h:67
qgsannotationitemnode.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsAnnotationItemEditOperationMoveNode::after
QgsPoint after() const
Returns the node position after the move occurred (in layer coordinates).
Definition: qgsannotationitemeditoperation.h:104
QgsAnnotationLineItem::nodes
QList< QgsAnnotationItemNode > nodes() const override
Returns the nodes for the item, used for editing the item.
Definition: qgsannotationlineitem.cpp:84
Qgis::AnnotationItemNodeType::VertexHandle
@ VertexHandle
Node is a handle for manipulating vertices.
QgsMapToPixel::transformInPlace
void transformInPlace(double &x, double &y) const
Transforms device coordinates to map coordinates.
Definition: qgsmaptopixel.h:128
Qgis::AnnotationItemEditOperationResult::Success
@ Success
Item was modified successfully.
QgsAnnotationItemNode
Contains information about a node used for editing an annotation item.
Definition: qgsannotationitemnode.h:31
QgsAbstractAnnotationItemEditOperation::Type::AddNode
@ AddNode
Add a node.
QgsAbstractAnnotationItemEditOperation::Type::MoveNode
@ MoveNode
Move a node.
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsAnnotationLineItem::setSymbol
void setSymbol(QgsLineSymbol *symbol)
Sets the symbol used to render the marker item.
Definition: qgsannotationlineitem.cpp:209
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
QgsAnnotationLineItem::applyEdit
Qgis::AnnotationItemEditOperationResult applyEdit(QgsAbstractAnnotationItemEditOperation *operation) override
Applies an edit operation to the item.
Definition: qgsannotationlineitem.cpp:95
QgsAnnotationLineItem::~QgsAnnotationLineItem
~QgsAnnotationLineItem() override
QgsCoordinateTransform::transformPolygon
void transformPolygon(QPolygonF &polygon, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const SIP_THROW(QgsCsException)
Transforms a polygon to the destination coordinate system.
Definition: qgscoordinatetransform.cpp:421
QgsAnnotationLineItem
An annotation item which renders a line symbol along a line geometry.
Definition: qgsannotationlineitem.h:33
QgsAnnotationLineItem::writeXml
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes the item's state into an XML element.
Definition: qgsannotationlineitem.cpp:75
QgsAnnotationLineItem::QgsAnnotationLineItem
QgsAnnotationLineItem(QgsCurve *curve)
Constructor for QgsAnnotationLineItem, with the specified linestring.
Definition: qgsannotationlineitem.cpp:25
QgsAnnotationLineItem::create
static QgsAnnotationLineItem * create()
Creates a new linestring annotation item.
Definition: qgsannotationlineitem.cpp:170
QgsAnnotationItemEditOperationAddNode
Annotation item edit operation consisting of adding a node.
Definition: qgsannotationitemeditoperation.h:154
QgsAnnotationItemEditOperationTranslateItem::translationY
double translationY() const
Returns the y-axis translation, in layer units.
Definition: qgsannotationitemeditoperation.h:211
qgsannotationitemeditoperation.h
QgsAnnotationItemEditOperationTranslateItem::translationX
double translationX() const
Returns the x-axis translation, in layer units.
Definition: qgsannotationitemeditoperation.h:204
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
QgsAnnotationItem
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
Definition: qgsannotationitem.h:42
QgsAnnotationItemEditOperationTransientResults
Encapsulates the transient results of an in-progress annotation edit operation.
Definition: qgsannotationitemeditoperation.h:226
qgslinesymbol.h
Qgis::AnnotationItemEditOperationResult::Invalid
@ Invalid
Operation has invalid parameters for the item, no change occurred.