35#include "moc_qgs3dhighlightfeaturehandler.cpp"
37using namespace Qt::StringLiterals;
46 qDeleteAll( mHighlightHandlers );
47 for (
auto it = mHighlightRuleBasedHandlers.constBegin(); it != mHighlightRuleBasedHandlers.constEnd(); ++it )
49 qDeleteAll( it.value() );
55 switch ( layer->
type() )
81 if ( renderContext.
crs() != layer->
crs() )
91 QgsDebugError( u
"Could not reproject identified feature to 3d view crs"_s );
98 if ( renderer->
type() ==
"vector"_L1 )
100 if ( !mHighlightHandlers.contains( layer ) )
104 if ( !renderer3d || !renderer3d->
symbol() )
116 QSet<QString> attributeNames;
120 if ( !handler->prepare( renderContext, attributeNames, box ) )
126 mHighlightHandlers[layer] = handler.release();
129 mHighlightHandlers[layer]->processFeature( feature, renderContext );
131 else if ( renderer->
type() ==
"rulebased"_L1 )
135 if ( !mHighlightRuleBasedHandlers.contains( layer ) )
139 QSet<QString> attributeNames;
143 rootRule->
prepare( renderContext, attributeNames, box, handlers );
144 mHighlightRuleBasedHandlers[layer] = handlers;
147 rootRule->
registerFeature( feature, renderContext, mHighlightRuleBasedHandlers[layer] );
151 if ( !mHighlightHandlerTimer && ( !mHighlightHandlers.isEmpty() || !mHighlightRuleBasedHandlers.isEmpty() ) )
153 mHighlightHandlerTimer = std::make_unique<QTimer>();
154 mHighlightHandlerTimer->setSingleShot(
true );
155 mHighlightHandlerTimer->setInterval( 0 );
156 connect( mHighlightHandlerTimer.get(), &QTimer::timeout,
this, [
this, renderContext] {
157 for ( auto it = mHighlightHandlers.constBegin(); it != mHighlightHandlers.constEnd(); ++it )
159 Qgs3DMapSceneEntity *entity = new Qgs3DMapSceneEntity( mScene->mapSettings(), nullptr );
160 entity->setObjectName( u
"%1_highlight"_s.arg( it.key()->name() ) );
161 QgsFeature3DHandler *handler = it.value();
162 handler->setHighlightingEnabled( true );
163 handler->finalize( entity, renderContext );
165 finalizeAndAddToScene( entity );
168 for (
auto rulesIt = mHighlightRuleBasedHandlers.constBegin(); rulesIt != mHighlightRuleBasedHandlers.constEnd(); ++rulesIt )
170 Qgs3DMapSceneEntity *entity = new Qgs3DMapSceneEntity( mScene->mapSettings(), nullptr );
171 entity->setObjectName( u
"%1_highlight"_s.arg( rulesIt.key()->name() ) );
173 for ( auto handlersIt = rulesIt.value().constBegin(); handlersIt != rulesIt.value().constEnd(); ++handlersIt )
175 QgsFeature3DHandler *handler = handlersIt.value();
176 handler->setHighlightingEnabled( true );
177 handler->finalize( entity, renderContext );
180 finalizeAndAddToScene( entity );
183 mHighlightHandlerTimer->start();
194 if ( !mRubberBands.contains( layer ) )
196 QgsRubberBand3D *band =
new QgsRubberBand3D( *mScene->mapSettings(), mScene->engine(), mScene->engine()->frameGraph()->rubberBandsRootEntity(),
Qgis::GeometryType::Point );
200 band->setColor( color );
201 band->setMarkerType( QgsRubberBand3D::MarkerType::Square );
204 band->setWidth( pcRenderer->symbol()->pointSize() + 1 );
206 mRubberBands.insert( layer, band );
210 mRubberBands[layer]->addPoint( pt );
216void Qgs3DHighlightFeatureHandler::onRenderer3DChanged()
218 if ( QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() ) )
220 if ( QgsPointCloudLayer3DRenderer *rnd =
dynamic_cast<QgsPointCloudLayer3DRenderer *
>( layer->renderer3D() ) )
222 if ( mRubberBands.contains( layer ) )
224 mRubberBands[layer]->setWidth( rnd->symbol()->pointSize() + 1 );
230void Qgs3DHighlightFeatureHandler::finalizeAndAddToScene( Qgs3DMapSceneEntity *entity )
233 QgsFrameGraph *frameGraph = mScene->engine()->frameGraph();
236 mScene->addSceneEntity( entity );
237 mHighlightEntities.append( entity );
242 mHighlightHandlerTimer.reset();
243 qDeleteAll( mHighlightHandlers );
244 mHighlightHandlers.clear();
245 for (
auto it = mHighlightRuleBasedHandlers.constBegin(); it != mHighlightRuleBasedHandlers.constEnd(); ++it )
247 qDeleteAll( it.value() );
249 mHighlightRuleBasedHandlers.clear();
251 for ( Qt3DCore::QEntity *e : std::as_const( mHighlightEntities ) )
253 mScene->removeSceneEntity(
static_cast<Qgs3DMapSceneEntity *
>( e ) );
255 mHighlightEntities.clear();
258 for (
auto it = mRubberBands.keyBegin(); it != mRubberBands.keyEnd(); it++ )
263 qDeleteAll( mRubberBands );
264 mRubberBands.clear();
static const QColor DEFAULT_HIGHLIGHT_COLOR
Default highlight color.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
~Qgs3DHighlightFeatureHandler() override
Qgs3DHighlightFeatureHandler(Qgs3DMapScene *scene)
Constructor.
void highlightFeature(QgsFeature feature, QgsMapLayer *layer)
Highlights feature of layer in the 3d scene When multiple features are identified,...
void clearHighlights()
Clears all highlights.
Entity that encapsulates our 3D scene - contains all other entities (such as terrain) as children.
Rendering context for preparation of 3D entities.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system used in the 3D scene.
static Qgs3DRenderContext fromMapSettings(const Qgs3DMapSettings *mapSettings)
Creates an initialized Qgs3DRenderContext instance from given Qgs3DMapSettings.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Base class for all renderers that participate in 3D views.
virtual QString type() const =0
Returns unique identifier of the renderer class (used to identify subclass).
virtual QString type() const =0
Returns identifier of symbol type. Each 3D symbol implementation should return a different type.
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
A 3-dimensional box composed of x, y, z coordinates.
Custom exception class for Coordinate Reference System related exceptions.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
QgsHighlightsRenderView & highlightsRenderView()
Returns the highlights renderview, used for rendering highlight overlays of identified features.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qt3DRender::QLayer * highlightsLayer()
Returns a layer that should be attached to entities meant to be rendered by QgsHighlightsRenderView.
Base class for all map layer types.
QgsAbstract3DRenderer * renderer3D() const
Returns 3D renderer associated with the layer.
QgsCoordinateReferenceSystem crs
void renderer3DChanged()
Signal emitted when 3D renderer associated with the layer has changed.
3D renderer that renders all points from a point cloud layer.
Point geometry type, with support for z-dimension and m-values.
QgsBox3D toBox3d(double zMin, double zMax) const
Converts the rectangle to a 3D box, with the specified zMin and zMax z values.
A child rule for a QgsRuleBased3DRenderer.
void prepare(const Qgs3DRenderContext &context, QSet< QString > &attributeNames, const QgsBox3D &chunkExtent, RuleToHandlerMap &handlers) const
call prepare() on handlers and populate attributeNames
RegisterResult registerFeature(const QgsFeature &feature, Qgs3DRenderContext &context, const RuleToHandlerMap &handlers) const
register individual features
void createHandlers(QgsVectorLayer *layer, RuleToHandlerMap &handlers) const
add handlers
QHash< const QgsRuleBased3DRenderer::Rule *, QgsFeature3DHandler * > RuleToHandlerMap
QgsRuleBased3DRenderer::Rule * rootRule()
Returns pointer to the root rule.
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
3D renderer that renders all features of a vector layer with the same 3D symbol.
const QgsAbstract3DSymbol * symbol() const
Returns 3D symbol associated with the renderer.
Represents a vector layer which manages a vector based dataset.
#define QgsDebugError(str)