QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgspointcloudextentrenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudextentrenderer.h
3 --------------------
4 begin : December 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
20#include "qgscurve.h"
21#include "qgsfillsymbol.h"
23#include "qgslinesymbollayer.h"
24#include "qgspointcloudblock.h"
25#include "qgspolygon.h"
26#include "qgsstyle.h"
27#include "qgssymbol.h"
28#include "qgssymbollayerutils.h"
29#include "qgstextdocument.h"
31#include "qgstextrenderer.h"
32
34 : mFillSymbol( symbol ? symbol : defaultFillSymbol() )
35{
36
37}
38
40
42{
43 return QStringLiteral( "extent" );
44}
45
47{
48 auto res = std::make_unique< QgsPointCloudExtentRenderer >( mFillSymbol ? mFillSymbol->clone() : nullptr );
49 copyCommonProperties( res.get() );
50 return res.release();
51}
52
57
59{
60 auto r = std::make_unique< QgsPointCloudExtentRenderer >();
61
62 const QDomElement symbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
63 if ( !symbolElem.isNull() )
64 {
65 r->mFillSymbol = QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context );
66 }
67
68 r->restoreCommonProperties( element, context );
69 return r.release();
70}
71
73{
74 auto transformRing = [&context]( QPolygonF & pts )
75 {
76 //transform the QPolygonF to screen coordinates
77 if ( context.renderContext().coordinateTransform().isValid() )
78 {
79 try
80 {
82 }
83 catch ( QgsCsException & )
84 {
85 // we don't abort the rendering here, instead we remove any invalid points and just plot those which ARE valid
86 }
87 }
88
89 // remove non-finite points, e.g. infinite or NaN points caused by reprojecting errors
90 pts.erase( std::remove_if( pts.begin(), pts.end(),
91 []( const QPointF point )
92 {
93 return !std::isfinite( point.x() ) || !std::isfinite( point.y() );
94 } ), pts.end() );
95
96 QPointF *ptr = pts.data();
97 for ( int i = 0; i < pts.size(); ++i, ++ptr )
98 {
99 context.renderContext().mapToPixel().transformInPlace( ptr->rx(), ptr->ry() );
100 }
101 };
102
103 for ( auto it = extent.const_parts_begin(); it != extent.const_parts_end(); ++it )
104 {
105 if ( const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( *it ) )
106 {
107 QPolygonF exterior = polygon->exteriorRing()->asQPolygonF();
108 transformRing( exterior );
109 QVector<QPolygonF> rings;
110 rings.reserve( polygon->numInteriorRings() );
111 for ( int i = 0; i < polygon->numInteriorRings(); ++i )
112 {
113 QPolygonF ring = polygon->interiorRing( i )->asQPolygonF();
114 transformRing( ring );
115 rings.append( ring );
116 }
117
118 mFillSymbol->renderPolygon( exterior, rings.empty() ? nullptr : &rings, nullptr, context.renderContext() );
119 }
120 }
121}
122
124{
125 auto layer = std::make_unique< QgsSimpleLineSymbolLayer >();
126 layer->setColor( QColor( 228, 26, 28 ) );
127 layer->setWidth( 0.960000 );
128 layer->setPenStyle( Qt::DotLine );
129 layer->setWidthUnit( Qgis::RenderUnit::Millimeters );
130 return new QgsFillSymbol( QgsSymbolLayerList() << layer.release() );
131}
132
134{
135 return mFillSymbol.get();
136}
137
139{
140 mFillSymbol.reset( symbol );
141}
142void QgsPointCloudExtentRenderer::renderLabel( const QRectF &extent, const QString &text, QgsPointCloudRenderContext &context ) const
143{
146 const QSizeF textSize = metrics.documentSize( Qgis::TextLayoutMode::Rectangle, labelTextFormat().orientation() );
147 if ( textSize.width() < extent.width() && textSize.height() < extent.height() )
148 {
150 }
151}
152
153QDomElement QgsPointCloudExtentRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
154{
155 QDomElement rendererElem = doc.createElement( QStringLiteral( "renderer" ) );
156
157 rendererElem.setAttribute( QStringLiteral( "type" ), type() );
158
159 const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QString(), mFillSymbol.get(), doc, context );
160 rendererElem.appendChild( symbolElem );
161
162 saveCommonProperties( rendererElem, context );
163 return rendererElem;
164}
165
167{
169 mFillSymbol->startRender( context.renderContext() );
170}
171
173{
175 mFillSymbol->stopRender( context.renderContext() );
176}
177
178QList<QgsLayerTreeModelLegendNode *> QgsPointCloudExtentRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
179{
180 QList<QgsLayerTreeModelLegendNode *> nodes;
181
182 const QgsLegendSymbolItem extentItem( mFillSymbol.get(), QStringLiteral( "extent" ), QStringLiteral( "extent" ) );
183 QgsSymbolLegendNode *node = new QgsSymbolLegendNode( nodeLayer, extentItem );
184 node->setEmbeddedInParent( true );
185 nodes << node;
186
187 return nodes;
188}
@ Rectangle
Text within rectangle layout mode.
Definition qgis.h:2902
@ Millimeters
Millimeters.
Definition qgis.h:5184
@ VerticalCenter
Center align.
Definition qgis.h:2963
@ Center
Center align.
Definition qgis.h:2944
void transformPolygon(QPolygonF &polygon, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transforms a polygon to the destination coordinate system.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Custom exception class for Coordinate Reference System related exceptions.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
A geometry is the spatial representation of a feature.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
Layer tree node points to a map layer.
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
void transformInPlace(double &x, double &y) const
Transforms map coordinates to device coordinates.
Base class for storing raw data from point cloud nodes.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Saves the renderer configuration to an XML element.
QgsFillSymbol * fillSymbol() const
Returns the symbol used to render the cloud's extent.
QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Creates a set of legend nodes representing the renderer.
void startRender(QgsPointCloudRenderContext &context) override
Must be called when a new render cycle is started.
static QgsPointCloudRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates an extent renderer from an XML element.
void stopRender(QgsPointCloudRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
~QgsPointCloudExtentRenderer() override
void setFillSymbol(QgsFillSymbol *symbol)
Sets the symbol used to render the cloud's extent.
void renderExtent(const QgsGeometry &extent, QgsPointCloudRenderContext &context)
Renders a polygon extent geometry to the specified render context.
void renderBlock(const QgsPointCloudBlock *block, QgsPointCloudRenderContext &context) override
Renders a block of point cloud data using the specified render context.
static QgsFillSymbol * defaultFillSymbol()
Returns a new instance of the default fill symbol to use for showing point cloud extents.
QgsPointCloudRenderer * clone() const override
Create a deep copy of this renderer.
void renderLabel(const QRectF &extent, const QString &text, QgsPointCloudRenderContext &context) const
Renders a label inside the specified extent rectangle.
QString type() const override
Returns the identifier of the renderer type.
QgsPointCloudExtentRenderer(QgsFillSymbol *symbol=nullptr)
Constructor for QgsPointCloudExtentRenderer.
Encapsulates the render context for a 2D point cloud rendering operation.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
QgsTextFormat labelTextFormat() const
Returns the text format renderer is using for rendering labels.
void saveCommonProperties(QDomElement &element, const QgsReadWriteContext &context) const
Saves common renderer properties (such as point size and screen error) to the specified DOM element.
void copyCommonProperties(QgsPointCloudRenderer *destination) const
Copies common point cloud properties (such as point size and screen error) to the destination rendere...
virtual void startRender(QgsPointCloudRenderContext &context)
Must be called when a new render cycle is started.
virtual void stopRender(QgsPointCloudRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
Polygon geometry type.
Definition qgspolygon.h:33
A container for the context for various read/write operations on objects.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
void setEmbeddedInParent(bool embedded) override
Contains pre-calculated metrics of a QgsTextDocument.
static QgsTextDocumentMetrics calculateMetrics(const QgsTextDocument &document, const QgsTextFormat &format, const QgsRenderContext &context, double scaleFactor=1.0, const QgsTextDocumentRenderContext &documentContext=QgsTextDocumentRenderContext())
Returns precalculated text metrics for a text document, when rendered using the given base format and...
Represents a document consisting of one or more QgsTextBlock objects.
static QgsTextDocument fromTextAndFormat(const QStringList &lines, const QgsTextFormat &format)
Constructor for QgsTextDocument consisting of a set of lines, respecting settings from a text format.
static void drawDocument(const QRectF &rect, const QgsTextFormat &format, const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics, QgsRenderContext &context, Qgis::TextHorizontalAlignment horizontalAlignment=Qgis::TextHorizontalAlignment::Left, Qgis::TextVerticalAlignment verticalAlignment=Qgis::TextVerticalAlignment::Top, double rotation=0, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws a text document within a rectangle using the specified settings.
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30