35#include "moc_qgs3dhighlightfeaturehandler.cpp"
37using namespace Qt::StringLiterals;
45 qDeleteAll( mHighlightHandlers );
46 for (
auto it = mHighlightRuleBasedHandlers.constBegin(); it != mHighlightRuleBasedHandlers.constEnd(); ++it )
48 qDeleteAll( it.value() );
54 switch ( layer->
type() )
80 if ( renderContext.
crs() != layer->
crs() )
90 QgsDebugError( u
"Could not reproject identified feature to 3d view crs"_s );
97 if ( renderer->
type() ==
"vector"_L1 )
99 if ( !mHighlightHandlers.contains( layer ) )
103 if ( !renderer3d || !renderer3d->
symbol() )
115 QSet<QString> attributeNames;
119 if ( !handler->prepare( renderContext, attributeNames, box ) )
125 mHighlightHandlers[layer] = handler.release();
128 mHighlightHandlers[layer]->processFeature( feature, renderContext );
130 else if ( renderer->
type() ==
"rulebased"_L1 )
134 if ( !mHighlightRuleBasedHandlers.contains( layer ) )
138 QSet<QString> attributeNames;
142 rootRule->
prepare( renderContext, attributeNames, box, handlers );
143 mHighlightRuleBasedHandlers[layer] = handlers;
146 rootRule->
registerFeature( feature, renderContext, mHighlightRuleBasedHandlers[layer] );
150 if ( !mHighlightHandlerTimer && ( !mHighlightHandlers.isEmpty() || !mHighlightRuleBasedHandlers.isEmpty() ) )
152 mHighlightHandlerTimer = std::make_unique<QTimer>();
153 mHighlightHandlerTimer->setSingleShot(
true );
154 mHighlightHandlerTimer->setInterval( 0 );
155 connect( mHighlightHandlerTimer.get(), &QTimer::timeout,
this, [
this, renderContext] {
156 for ( auto it = mHighlightHandlers.constBegin(); it != mHighlightHandlers.constEnd(); ++it )
158 Qgs3DMapSceneEntity *entity = new Qgs3DMapSceneEntity( mScene->mapSettings(), nullptr );
159 entity->setObjectName( u
"%1_highlight"_s.arg( it.key()->name() ) );
160 QgsFeature3DHandler *handler = it.value();
161 handler->setHighlightingEnabled( true );
162 handler->finalize( entity, renderContext );
164 finalizeAndAddToScene( entity );
167 for (
auto rulesIt = mHighlightRuleBasedHandlers.constBegin(); rulesIt != mHighlightRuleBasedHandlers.constEnd(); ++rulesIt )
169 Qgs3DMapSceneEntity *entity = new Qgs3DMapSceneEntity( mScene->mapSettings(), nullptr );
170 entity->setObjectName( u
"%1_highlight"_s.arg( rulesIt.key()->name() ) );
172 for ( auto handlersIt = rulesIt.value().constBegin(); handlersIt != rulesIt.value().constEnd(); ++handlersIt )
174 QgsFeature3DHandler *handler = handlersIt.value();
175 handler->setHighlightingEnabled( true );
176 handler->finalize( entity, renderContext );
179 finalizeAndAddToScene( entity );
182 mHighlightHandlerTimer->start();
193 if ( !mRubberBands.contains( layer ) )
195 QgsRubberBand3D *band =
new QgsRubberBand3D( *mScene->mapSettings(), mScene->engine(), mScene->engine()->frameGraph()->rubberBandsRootEntity(),
Qgis::GeometryType::Point );
199 band->setColor( color );
200 band->setMarkerType( QgsRubberBand3D::MarkerType::Square );
203 band->setWidth( pcRenderer->symbol()->pointSize() + 1 );
205 mRubberBands.insert( layer, band );
209 mRubberBands[layer]->addPoint( pt );
215void Qgs3DHighlightFeatureHandler::onRenderer3DChanged()
217 if ( QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() ) )
219 if ( QgsPointCloudLayer3DRenderer *rnd =
dynamic_cast<QgsPointCloudLayer3DRenderer *
>( layer->renderer3D() ) )
221 if ( mRubberBands.contains( layer ) )
223 mRubberBands[layer]->setWidth( rnd->symbol()->pointSize() + 1 );
229void Qgs3DHighlightFeatureHandler::finalizeAndAddToScene( Qgs3DMapSceneEntity *entity )
232 QgsFrameGraph *frameGraph = mScene->engine()->frameGraph();
235 mScene->addSceneEntity( entity );
236 mHighlightEntities.append( entity );
241 mHighlightHandlerTimer.reset();
242 qDeleteAll( mHighlightHandlers );
243 mHighlightHandlers.clear();
244 for (
auto it = mHighlightRuleBasedHandlers.constBegin(); it != mHighlightRuleBasedHandlers.constEnd(); ++it )
246 qDeleteAll( it.value() );
248 mHighlightRuleBasedHandlers.clear();
250 for ( Qt3DCore::QEntity *e : std::as_const( mHighlightEntities ) )
252 mScene->removeSceneEntity(
static_cast<Qgs3DMapSceneEntity *
>( e ) );
254 mHighlightEntities.clear();
257 for (
auto it = mRubberBands.keyBegin(); it != mRubberBands.keyEnd(); it++ )
262 qDeleteAll( mRubberBands );
263 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)