QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsannotationpointtextitem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsannotationpointtextitem.cpp
3  ----------------
4  begin : August 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 "qgstextrenderer.h"
20 #include "qgsannotationitemnode.h"
22 #include "qgsrendercontext.h"
23 
26  , mText( text )
27  , mPoint( point )
28 {
29 
30 }
31 
32 Qgis::AnnotationItemFlags QgsAnnotationPointTextItem::flags() const
33 {
34  // in truth this should depend on whether the text format is scale dependent or not!
36 }
37 
39 
41 {
42  return QStringLiteral( "pointtext" );
43 }
44 
46 {
47  QPointF pt;
48  if ( context.coordinateTransform().isValid() )
49  {
50  double x = mPoint.x();
51  double y = mPoint.y();
52  double z = 0.0;
53  context.coordinateTransform().transformInPlace( x, y, z );
54  pt = QPointF( x, y );
55  }
56  else
57  pt = mPoint.toQPointF();
58 
59  context.mapToPixel().transformInPlace( pt.rx(), pt.ry() );
60 
61  const QString displayText = QgsExpression::replaceExpressionText( mText, &context.expressionContext(), &context.distanceArea() );
62  QgsTextRenderer::drawText( pt, mAngle * M_PI / 180.0,
64  displayText.split( '\n' ), context, mTextFormat );
65 }
66 
67 bool QgsAnnotationPointTextItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
68 {
69  element.setAttribute( QStringLiteral( "x" ), qgsDoubleToString( mPoint.x() ) );
70  element.setAttribute( QStringLiteral( "y" ), qgsDoubleToString( mPoint.y() ) );
71  element.setAttribute( QStringLiteral( "text" ), mText );
72  element.setAttribute( QStringLiteral( "angle" ), qgsDoubleToString( mAngle ) );
73  element.setAttribute( QStringLiteral( "alignment" ), QString::number( mAlignment ) );
74 
75  QDomElement textFormatElem = document.createElement( QStringLiteral( "pointTextFormat" ) );
76  textFormatElem.appendChild( mTextFormat.writeXml( document, context ) );
77  element.appendChild( textFormatElem );
78 
79  writeCommonProperties( element, document, context );
80  return true;
81 }
82 
84 {
85  return new QgsAnnotationPointTextItem( QString(), QgsPointXY() );
86 }
87 
88 bool QgsAnnotationPointTextItem::readXml( const QDomElement &element, const QgsReadWriteContext &context )
89 {
90  const double x = element.attribute( QStringLiteral( "x" ) ).toDouble();
91  const double y = element.attribute( QStringLiteral( "y" ) ).toDouble();
92  mPoint = QgsPointXY( x, y );
93  mText = element.attribute( QStringLiteral( "text" ) );
94  mAngle = element.attribute( QStringLiteral( "angle" ) ).toDouble();
95  mAlignment = static_cast< Qt::Alignment >( element.attribute( QStringLiteral( "alignment" ) ).toInt() );
96 
97  const QDomElement textFormatElem = element.firstChildElement( QStringLiteral( "pointTextFormat" ) );
98  if ( !textFormatElem.isNull() )
99  {
100  const QDomNodeList textFormatNodeList = textFormatElem.elementsByTagName( QStringLiteral( "text-style" ) );
101  const QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
102  mTextFormat.readXml( textFormatElem, context );
103  }
104 
105  readCommonProperties( element, context );
106  return true;
107 }
108 
110 {
111  std::unique_ptr< QgsAnnotationPointTextItem > item = std::make_unique< QgsAnnotationPointTextItem >( mText, mPoint );
112  item->setFormat( mTextFormat );
113  item->setAngle( mAngle );
114  item->setAlignment( mAlignment );
115  item->copyCommonProperties( this );
116  return item.release();
117 }
118 
120 {
121  return QgsRectangle( mPoint.x(), mPoint.y(), mPoint.x(), mPoint.y() );
122 }
123 
125 {
126  const QString displayText = QgsExpression::replaceExpressionText( mText, &context.expressionContext(), &context.distanceArea() );
127 
128  const double widthInPixels = QgsTextRenderer::textWidth( context, mTextFormat, displayText.split( '\n' ) );
129  const double heightInPixels = QgsTextRenderer::textHeight( context, mTextFormat, displayText.split( '\n' ) );
130 
131  // text size has already been calculated using any symbology reference scale factor above -- we need
132  // to temporarily remove the reference scale here or we'll be undoing the scaling
133  QgsScopedRenderContextReferenceScaleOverride resetScaleFactor( context, -1.0 );
134  const double widthInMapUnits = context.convertToMapUnits( widthInPixels, QgsUnitTypes::RenderPixels );
135  const double heightInMapUnits = context.convertToMapUnits( heightInPixels, QgsUnitTypes::RenderPixels );
136 
137  return QgsRectangle( mPoint.x(), mPoint.y(), mPoint.x() + widthInMapUnits, mPoint.y() + heightInMapUnits );
138 }
139 
140 QList<QgsAnnotationItemNode> QgsAnnotationPointTextItem::nodes() const
141 {
143 }
144 
146 {
147  switch ( operation->type() )
148  {
150  {
151  QgsAnnotationItemEditOperationMoveNode *moveOperation = dynamic_cast< QgsAnnotationItemEditOperationMoveNode * >( operation );
152  mPoint = moveOperation->after();
154  }
155 
157  {
159  }
160 
162  {
163  QgsAnnotationItemEditOperationTranslateItem *moveOperation = qgis::down_cast< QgsAnnotationItemEditOperationTranslateItem * >( operation );
164  mPoint.setX( mPoint.x() + moveOperation->translationX() );
165  mPoint.setY( mPoint.y() + moveOperation->translationY() );
167  }
168 
170  break;
171  }
172 
174 }
175 
177 {
178  switch ( operation->type() )
179  {
181  {
182  QgsAnnotationItemEditOperationMoveNode *moveOperation = dynamic_cast< QgsAnnotationItemEditOperationMoveNode * >( operation );
183  return new QgsAnnotationItemEditOperationTransientResults( QgsGeometry( moveOperation->after().clone() ) );
184  }
185 
187  {
188  QgsAnnotationItemEditOperationTranslateItem *moveOperation = qgis::down_cast< QgsAnnotationItemEditOperationTranslateItem * >( operation );
189  return new QgsAnnotationItemEditOperationTransientResults( QgsGeometry( new QgsPoint( mPoint.x() + moveOperation->translationX(), mPoint.y() + moveOperation->translationY() ) ) );
190  }
191 
194  break;
195  }
196  return nullptr;
197 }
198 
200 {
201  return mTextFormat;
202 }
203 
205 {
206  mTextFormat = format;
207 }
208 
210 {
211  return mAlignment;
212 }
213 
214 void QgsAnnotationPointTextItem::setAlignment( Qt::Alignment alignment )
215 {
216  mAlignment = alignment;
217 }
QgsCoordinateTransform::transformInPlace
void transformInPlace(double &x, double &y, double &z, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const SIP_THROW(QgsCsException)
Transforms an array of x, y and z double coordinates in place, from the source CRS to the destination...
Definition: qgscoordinatetransform.cpp:364
QgsScopedRenderContextReferenceScaleOverride
Scoped object for temporary override of the symbologyReferenceScale property of a QgsRenderContext.
Definition: qgsrendercontext.h:1375
QgsPointXY::y
double y
Definition: qgspointxy.h:63
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
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:625
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsAnnotationPointTextItem::flags
Qgis::AnnotationItemFlags flags() const override
Returns item flags.
Definition: qgsannotationpointtextitem.cpp:32
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
qgstextrenderer.h
QgsAnnotationPointTextItem::boundingBox
QgsRectangle boundingBox() const override
Returns the bounding box of the item's geographic location, in the parent layer's coordinate referenc...
Definition: qgsannotationpointtextitem.cpp:119
QgsAnnotationItemEditOperationTranslateItem
Annotation item edit operation consisting of translating (moving) an item.
Definition: qgsannotationitemeditoperation.h:182
QgsAbstractAnnotationItemEditOperation::type
virtual Type type() const =0
Returns the operation type.
QgsPointXY::setY
void setY(double y) SIP_HOLDGIL
Sets the y value of the point.
Definition: qgspointxy.h:132
QgsRenderContext::convertToMapUnits
double convertToMapUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
Definition: qgsrendercontext.cpp:475
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsPointXY::toQPointF
QPointF toQPointF() const
Converts a point to a QPointF.
Definition: qgspointxy.h:169
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
QgsPointXY::setX
void setX(double x) SIP_HOLDGIL
Sets the x value of the point.
Definition: qgspointxy.h:122
QgsRenderContext::distanceArea
const QgsDistanceArea & distanceArea() const
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Definition: qgsrendercontext.h:184
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
qgsDoubleToString
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:2204
QgsTextRenderer::textHeight
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, DrawMode mode=Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
Definition: qgstextrenderer.cpp:620
QgsPoint::clone
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspoint.cpp:104
QgsAnnotationPointTextItem::clone
QgsAnnotationPointTextItem * clone() override
Returns a clone of the item.
Definition: qgsannotationpointtextitem.cpp:109
QgsTextRenderer::textWidth
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
Definition: qgstextrenderer.cpp:545
QgsAnnotationPointTextItem::~QgsAnnotationPointTextItem
~QgsAnnotationPointTextItem() override
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
QgsTextFormat
Container for all settings relating to text rendering.
Definition: qgstextformat.h:40
QgsAnnotationPointTextItem::writeXml
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes the item's state into an XML element.
Definition: qgsannotationpointtextitem.cpp:67
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
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
qgsrendercontext.h
QgsAnnotationPointTextItem::type
QString type() const override
Returns a unique (untranslated) string identifying the type of item.
Definition: qgsannotationpointtextitem.cpp:40
QgsTextRenderer::drawText
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws text within a rectangle using the specified settings.
Definition: qgstextrenderer.cpp:81
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
QgsTextFormat::readXml
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
Definition: qgstextformat.cpp:488
QgsAnnotationItemEditOperationMoveNode
Annotation item edit operation consisting of moving a node.
Definition: qgsannotationitemeditoperation.h:75
QgsAnnotationPointTextItem::QgsAnnotationPointTextItem
QgsAnnotationPointTextItem(const QString &text, QgsPointXY point)
Constructor for QgsAnnotationPointTextItem, containing the specified text at the specified point.
Definition: qgsannotationpointtextitem.cpp:24
QgsAbstractAnnotationItemEditOperation
Abstract base class for annotation item edit operations.
Definition: qgsannotationitemeditoperation.h:32
QgsUnitTypes::RenderPixels
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
QgsAnnotationPointTextItem::readXml
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the item's state from the given DOM element.
Definition: qgsannotationpointtextitem.cpp:88
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
QgsAnnotationPointTextItem::setAlignment
void setAlignment(Qt::Alignment alignment)
Sets the text's alignment relative to the reference point().
Definition: qgsannotationpointtextitem.cpp:214
QgsAnnotationPointTextItem::create
static QgsAnnotationPointTextItem * create()
Creates a new text at point annotation item.
Definition: qgsannotationpointtextitem.cpp:83
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
QgsAnnotationPointTextItem::transientEditResults
QgsAnnotationItemEditOperationTransientResults * transientEditResults(QgsAbstractAnnotationItemEditOperation *operation) override
Retrieves the results of a transient (in progress) edit operation on the item.
Definition: qgsannotationpointtextitem.cpp:176
Qgis::AnnotationItemEditOperationResult::Success
@ Success
Item was modified successfully.
qgsannotationpointtextitem.h
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
QgsAnnotationPointTextItem::setFormat
void setFormat(const QgsTextFormat &format)
Sets the text format used to render the text.
Definition: qgsannotationpointtextitem.cpp:204
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
QgsAnnotationPointTextItem::format
QgsTextFormat format() const
Returns the text format used to render the text.
Definition: qgsannotationpointtextitem.cpp:199
QgsAnnotationPointTextItem::applyEdit
Qgis::AnnotationItemEditOperationResult applyEdit(QgsAbstractAnnotationItemEditOperation *operation) override
Applies an edit operation to the item.
Definition: qgsannotationpointtextitem.cpp:145
Qgis::AnnotationItemFlag::ScaleDependentBoundingBox
@ ScaleDependentBoundingBox
Item's bounding box will vary depending on map scale.
QgsAnnotationPointTextItem::nodes
QList< QgsAnnotationItemNode > nodes() const override
Returns the nodes for the item, used for editing the item.
Definition: qgsannotationpointtextitem.cpp:140
QgsTextRenderer::convertQtHAlignment
static HAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a QgsTextRenderer::HAlignment value.
Definition: qgstextrenderer.cpp:46
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
QgsExpression::replaceExpressionText
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
Definition: qgsexpression.cpp:434
QgsAnnotationPointTextItem::render
void render(QgsRenderContext &context, QgsFeedback *feedback) override
Renders the item to the specified render context.
Definition: qgsannotationpointtextitem.cpp:45
QgsTextFormat::writeXml
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
Definition: qgstextformat.cpp:671
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
QgsAnnotationPointTextItem::alignment
Qt::Alignment alignment() const
Returns the text's alignment relative to the reference point().
Definition: qgsannotationpointtextitem.cpp:209
QgsAnnotationPointTextItem
An annotation item which renders a text string at a point location.
Definition: qgsannotationpointtextitem.h:33
Qgis::AnnotationItemEditOperationResult::Invalid
@ Invalid
Operation has invalid parameters for the item, no change occurred.