28 #include <QtConcurrent>
29 #include <Qt3DCore/QTransform>
34 QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader(
const QgsRuleBasedChunkLoaderFactory *factory, QgsChunkNode *node )
35 : QgsChunkLoader( node )
37 , mContext( factory->mMap )
40 if ( node->level() < mFactory->mLeafLevel )
42 QTimer::singleShot( 0,
this, &QgsRuleBasedChunkLoader::finished );
51 mContext.setExpressionContext( exprContext );
57 mRootRule.reset( mFactory->mRootRule->clone() );
61 QSet<QString> attributeNames;
62 mRootRule->
prepare( mContext, attributeNames, mHandlers );
76 mFutureWatcher =
new QFutureWatcher<void>(
this );
77 connect( mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsChunkQueueJob::finished );
79 const QFuture<void> future = QtConcurrent::run( [req,
this]
81 const QgsEventTracing::ScopedEvent e( QStringLiteral(
"3D" ), QStringLiteral(
"RB chunk load" ) );
89 mContext.expressionContext().setFeature( f );
95 mFutureWatcher->setFuture( future );
98 QgsRuleBasedChunkLoader::~QgsRuleBasedChunkLoader()
100 if ( mFutureWatcher && !mFutureWatcher->isFinished() )
102 disconnect( mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsChunkQueueJob::finished );
103 mFutureWatcher->waitForFinished();
106 qDeleteAll( mHandlers );
110 void QgsRuleBasedChunkLoader::cancel()
115 Qt3DCore::QEntity *QgsRuleBasedChunkLoader::createEntity( Qt3DCore::QEntity *parent )
117 if ( mNode->level() < mFactory->mLeafLevel )
119 return new Qt3DCore::QEntity( parent );
122 long long featureCount = 0;
123 for (
auto it = mHandlers.constBegin(); it != mHandlers.constEnd(); ++it )
125 featureCount += it.value()->featureCount();
127 if ( featureCount == 0 )
133 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity( parent );
134 float zMin = std::numeric_limits<float>::max();
135 float zMax = std::numeric_limits<float>::lowest();
136 for (
auto it = mHandlers.constBegin(); it != mHandlers.constEnd(); ++it )
138 QgsFeature3DHandler *handler = it.value();
139 handler->finalize( entity, mContext );
140 if ( handler->zMinimum() < zMin )
141 zMin = handler->zMinimum();
142 if ( handler->zMaximum() > zMax )
143 zMax = handler->zMaximum();
147 if ( zMin != std::numeric_limits<float>::max() && zMax != std::numeric_limits<float>::lowest() )
152 mNode->setExactBbox( box );
153 mNode->updateParentBoundingBoxesRecursively();
166 , mRootRule( rootRule->clone() )
167 , mLeafLevel( leafLevel )
170 setupQuadtree( rootBbox, -1, leafLevel );
173 QgsRuleBasedChunkLoaderFactory::~QgsRuleBasedChunkLoaderFactory() =
default;
175 QgsChunkLoader *QgsRuleBasedChunkLoaderFactory::createChunkLoader( QgsChunkNode *node )
const
177 return new QgsRuleBasedChunkLoader(
this, node );
184 : QgsChunkedEntity( -1,
185 new QgsRuleBasedChunkLoaderFactory( map, vl, rootRule, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true )
187 mTransform =
new Qt3DCore::QTransform;
189 this->addComponent( mTransform );
195 QgsRuleBasedChunkedEntity::~QgsRuleBasedChunkedEntity()
201 void QgsRuleBasedChunkedEntity::onTerrainElevationOffsetChanged(
float newOffset )
203 mTransform->setTranslation( QVector3D( 0.0f, newOffset, 0.0f ) );