QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgspointcloudlayer3drenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudlayer3drenderer.cpp
3 --------------------------------------
4 Date : October 2020
5 Copyright : (C) 2020 by Peter Petrik
6 Email : zilolv dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgs3dutils.h"
19#include "qgschunkedentity_p.h"
21
22#include "qgspointcloudindex.h"
23#include "qgspointcloudlayer.h"
24#include "qgsxmlutils.h"
25#include "qgsapplication.h"
26#include "qgs3dsymbolregistry.h"
29
30QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr<QgsPointCloud3DSymbol> symbol, double zValueScale, double zValueFixedOffset )
31 : Qgs3DRenderContext( map )
32 , mSymbol( std::move( symbol ) )
33 , mZValueScale( zValueScale )
34 , mZValueFixedOffset( zValueFixedOffset )
35 , mCoordinateTransform( coordinateTransform )
36 , mFeedback( new QgsFeedback )
37{
38}
39
41{
42 mAttributes = attributes;
43}
44
46{
47 mSymbol.reset( symbol );
48}
49
51{
52 mFilteredOutCategories = categories;
53}
54
56{
57 QSet<int> filteredOut;
58 for ( const QgsPointCloudCategory &category : mFilteredOutCategories )
59 filteredOut.insert( category.value() );
60 return filteredOut;
61}
62
64{
65 mCoordinateTransform = coordinateTransform;
66}
67
69{
70 return mFeedback->isCanceled();
71}
72
74{
75 mFeedback->cancel();
76}
77// ---------
78
79
81 : Qgs3DRendererAbstractMetadata( QStringLiteral( "pointcloud" ) )
82{
83}
84
86{
88 r->readXml( elem, context );
89 return r;
90}
91
92
93// ---------
94
95
97{
98}
99
101{
102 mLayerRef = QgsMapLayerRef( layer );
103}
104
106{
107 return qobject_cast<QgsPointCloudLayer *>( mLayerRef.layer );
108}
109
111{
112 return QStringLiteral( "pointcloud" );
113}
114
116{
118 if ( mSymbol )
119 {
120 QgsAbstract3DSymbol *symbolClone = mSymbol->clone();
121 r->setSymbol( dynamic_cast<QgsPointCloud3DSymbol *>( symbolClone ) );
122 }
123 r->setMaximumScreenError( mMaximumScreenError );
124 r->setShowBoundingBoxes( mShowBoundingBoxes );
125 return r;
126}
127
129{
130 QgsPointCloudLayer *pcl = layer();
131 if ( !pcl || !pcl->dataProvider() || !pcl->dataProvider()->index() )
132 return nullptr;
133 if ( !mSymbol )
134 return nullptr;
135
136 const QgsCoordinateTransform coordinateTransform( pcl->crs(), map.crs(), map.transformContext() );
137
138 QgsPointCloudLayerChunkedEntity *entity = new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), map, coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), maximumScreenError(), showBoundingBoxes(),
139 static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zScale(),
140 static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zOffset(), mPointBudget );
141 return entity;
142}
143
145{
146 mSymbol.reset( symbol );
147}
148
149void QgsPointCloudLayer3DRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
150{
151 Q_UNUSED( context )
152
153 QDomDocument doc = elem.ownerDocument();
154
155 elem.setAttribute( QStringLiteral( "layer" ), mLayerRef.layerId );
156 elem.setAttribute( QStringLiteral( "max-screen-error" ), maximumScreenError() );
157 elem.setAttribute( QStringLiteral( "show-bounding-boxes" ), showBoundingBoxes() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
158 elem.setAttribute( QStringLiteral( "point-budget" ), mPointBudget );
159
160 QDomElement elemSymbol = doc.createElement( QStringLiteral( "symbol" ) );
161 if ( mSymbol )
162 {
163 elemSymbol.setAttribute( QStringLiteral( "type" ), mSymbol->symbolType() );
164 mSymbol->writeXml( elemSymbol, context );
165 }
166 elem.appendChild( elemSymbol );
167}
168
169void QgsPointCloudLayer3DRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
170{
171 mLayerRef = QgsMapLayerRef( elem.attribute( QStringLiteral( "layer" ) ) );
172
173 const QDomElement elemSymbol = elem.firstChildElement( QStringLiteral( "symbol" ) );
174
175 const QString symbolType = elemSymbol.attribute( QStringLiteral( "type" ) );
176 mShowBoundingBoxes = elem.attribute( QStringLiteral( "show-bounding-boxes" ), QStringLiteral( "0" ) ).toInt();
177 mMaximumScreenError = elem.attribute( QStringLiteral( "max-screen-error" ), QStringLiteral( "3.0" ) ).toDouble();
178 mPointBudget = elem.attribute( QStringLiteral( "point-budget" ), QStringLiteral( "5000000" ) ).toInt();
179
180 if ( symbolType == QLatin1String( "single-color" ) )
181 mSymbol.reset( new QgsSingleColorPointCloud3DSymbol );
182 else if ( symbolType == QLatin1String( "color-ramp" ) )
183 mSymbol.reset( new QgsColorRampPointCloud3DSymbol );
184 else if ( symbolType == QLatin1String( "rgb" ) )
185 mSymbol.reset( new QgsRgbPointCloud3DSymbol );
186 else if ( symbolType == QLatin1String( "classification" ) )
187 mSymbol.reset( new QgsClassificationPointCloud3DSymbol );
188 else
189 mSymbol.reset();
190
191 if ( mSymbol )
192 mSymbol->readXml( elemSymbol, context );
193}
194
196{
197 mLayerRef.setLayer( project.mapLayer( mLayerRef.layerId ) );
198}
199
201{
202 return mMaximumScreenError;
203}
204
206{
207 mMaximumScreenError = error;
208}
209
211{
212 return mShowBoundingBoxes;
213}
214
216{
217 mShowBoundingBoxes = showBoundingBoxes;
218}
219
221{
222 mPointBudget = budget;
223}
224
226{
227 std::unique_ptr< QgsPointCloudLayer3DRenderer > renderer3D = Qgs3DUtils::convert2DPointCloudRendererTo3D( renderer );
228 if ( !renderer3D )
229 {
230 setSymbol( nullptr );
231 return false;
232 }
233
234 QgsPointCloud3DSymbol *newSymbol = const_cast<QgsPointCloud3DSymbol *>(
235 static_cast<QgsPointCloud3DSymbol *>( renderer3D->symbol()->clone() )
236 );
237 // we need to retain some settings from the previous symbol, like point size
238 const QgsPointCloud3DSymbol *oldSymbol = symbol();
239 if ( oldSymbol )
240 oldSymbol->copyBaseSettings( newSymbol );
241 setSymbol( newSymbol );
242 return true;
243}
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Base metadata class for 3D renderers.
static std::unique_ptr< QgsPointCloudLayer3DRenderer > convert2DPointCloudRendererTo3D(QgsPointCloudRenderer *renderer)
Creates a QgsPointCloudLayer3DRenderer matching the symbol settings of a given QgsPointCloudRenderer.
Definition: qgs3dutils.cpp:738
Base class for all renderers that may to participate in 3D view.
Class for doing transforms between two map coordinate systems.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
double zScale() const
Returns the z scale, which is a scaling factor which should be applied to z values from the layer.
double zOffset() const
Returns the z offset, which is a fixed offset amount which should be added to z values from the layer...
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QSet< int > getFilteredOutValues() const
Returns a set containing the filtered out values.
QgsPointCloud3DSymbol * symbol() const
Returns the symbol used for rendering the point cloud.
void setFilteredOutCategories(const QgsPointCloudCategoryList &categories)
Sets the list of categories of the classification that won't be rendered.
QgsPointCloudAttributeCollection attributes() const
Returns the attributes associated with the rendered block.
void setSymbol(QgsPointCloud3DSymbol *symbol)
Sets the symbol used for rendering the point cloud Takes ownership over the passed symbol.
bool isCanceled() const
Returns true if the rendering is canceled.
void setCoordinateTransform(const QgsCoordinateTransform &coordinateTransform)
Sets the coordinate transform used to transform points from layer CRS to the map CRS.
QgsCoordinateTransform coordinateTransform() const
Returns the coordinate transform used to transform points from layer CRS to the map CRS.
void cancelRendering() const
Cancels rendering.
QgsPointCloud3DRenderContext(const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol, double zValueScale, double zValueFixedOffset)
Constructor for QgsPointCloud3DRenderContext.
void setAttributes(const QgsPointCloudAttributeCollection &attributes)
Sets the attributes associated with the rendered block.
void copyBaseSettings(QgsAbstract3DSymbol *destination) const override
Collection of point cloud attributes.
Represents an individual category (class) from a QgsPointCloudClassifiedRenderer.
virtual QgsPointCloudIndex * index() const
Returns the point cloud index associated with the provider.
QgsAbstract3DRenderer * createRenderer(QDomElement &elem, const QgsReadWriteContext &context) override
Creates an instance of a 3D renderer based on a DOM element with renderer configuration.
3D renderer that renders all points from a point cloud layer
void resolveReferences(const QgsProject &project) override
Resolves references to other objects - second phase of loading - after readXml()
void setLayer(QgsPointCloudLayer *layer)
Sets point cloud layer associated with the renderer.
double maximumScreenError() const
Returns the maximum screen error allowed when rendering the point cloud.
void setPointRenderingBudget(int budget)
Sets the maximum number of points to be rendered in the scene.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes renderer's properties to given XML element.
const QgsPointCloud3DSymbol * symbol() const
Returns 3D symbol associated with the renderer.
QString type() const override
Returns unique identifier of the renderer class (used to identify subclass)
Qt3DCore::QEntity * createEntity(const Qgs3DMapSettings &map) const override
Returns a 3D entity that will be used to show renderer's data in 3D scene.
bool showBoundingBoxes() const
Returns whether bounding boxes will be visible when rendering the point cloud.
QgsPointCloudLayer3DRenderer()
Takes ownership of the symbol object.
QgsPointCloudLayer3DRenderer * clone() const override
Returns a cloned instance.
QgsPointCloudLayer * layer() const
Returns point cloud layer associated with the renderer.
void setSymbol(QgsPointCloud3DSymbol *symbol)
Sets the 3D symbol associated with the renderer.
void setMaximumScreenError(double error)
Sets the maximum screen error allowed when rendering the point cloud.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads renderer's properties from given XML element.
bool convertFrom2DRenderer(QgsPointCloudRenderer *renderer) override
Updates the 3D renderer's symbol to match that of a given QgsPointCloudRenderer.
void setShowBoundingBoxes(bool showBoundingBoxes)
Sets whether bounding boxes will be visible when rendering the point cloud.
Point cloud layer specific subclass of QgsMapLayerElevationProperties.
Represents a map layer supporting display of point clouds.
QgsMapLayerElevationProperties * elevationProperties() override
Returns the layer's elevation properties.
QgsPointCloudDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
Abstract base class for 2d point cloud renderers.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
The class is used as a container of context for various read/write operations on other objects.
_LayerRef< QgsMapLayer > QgsMapLayerRef
QList< QgsPointCloudCategory > QgsPointCloudCategoryList
QPointer< TYPE > layer
Weak pointer to map layer.
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
QString layerId
Original layer ID.