Skip to content

Commit

Permalink
handle virtual point clouds rendering
Browse files Browse the repository at this point in the history
disable preview rendering
  • Loading branch information
uclaros authored and wonder-sk committed Apr 13, 2023
1 parent f896513 commit 2dae033
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 6 deletions.
26 changes: 26 additions & 0 deletions src/core/pointcloud/qgspointcloudlayer.cpp
Expand Up @@ -18,6 +18,7 @@
#include "qgspointcloudlayer.h"
#include "qgspointcloudlayerrenderer.h"
#include "qgspointcloudindex.h"
#include "qgspointcloudsubindex.h"
#include "qgsrectangle.h"
#include "qgspointclouddataprovider.h"
#include "qgsproviderregistry.h"
Expand Down Expand Up @@ -108,6 +109,9 @@ QgsMapLayerRenderer *QgsPointCloudLayer::createMapRenderer( QgsRenderContext &re
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

if ( mRenderer->type() != QLatin1String( "extent" ) )
loadIndexesForRenderContext( rendererContext );

return new QgsPointCloudLayerRenderer( this, rendererContext );
}

Expand Down Expand Up @@ -949,3 +953,25 @@ void QgsPointCloudLayer::resetRenderer()

emit rendererChanged();
}

void QgsPointCloudLayer::loadIndexesForRenderContext( QgsRenderContext &rendererContext ) const
{
if ( mDataProvider->capabilities() & QgsPointCloudDataProvider::ContainSubIndexes )
{
const QgsRectangle renderExtent = rendererContext.coordinateTransform().transformBoundingBox( rendererContext.mapExtent(), Qgis::TransformDirection::Reverse );
QVector<QgsPointCloudSubIndex> subIndex = mDataProvider->subIndexes();
for ( int i = 0; i < subIndex.size(); ++i )
{
// no need to load as it's there
if ( subIndex.at( i ).index )
continue;

const QgsRectangle intersection = subIndex.at( i ).extent.intersect( renderExtent );
if ( !intersection.isEmpty() &&
renderExtent.width() < subIndex.at( i ).extent.width() )
{
mDataProvider->loadIndex( i );
}
}
}
}
2 changes: 2 additions & 0 deletions src/core/pointcloud/qgspointcloudlayer.h
Expand Up @@ -279,6 +279,8 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer, public QgsAbstractPro

void resetRenderer();

void loadIndexesForRenderContext( QgsRenderContext &rendererContext ) const;

#ifdef SIP_RUN
QgsPointCloudLayer( const QgsPointCloudLayer &rhs );
#endif
Expand Down
60 changes: 54 additions & 6 deletions src/core/pointcloud/qgspointcloudlayerrenderer.cpp
Expand Up @@ -46,6 +46,7 @@ QgsPointCloudLayerRenderer::QgsPointCloudLayerRenderer( QgsPointCloudLayer *laye
return;

mRenderer.reset( mLayer->renderer()->clone() );
mSubExtentsRenderer.reset( new QgsPointCloudExtentRenderer() );

if ( mLayer->dataProvider()->index() )
{
Expand Down Expand Up @@ -94,9 +95,12 @@ bool QgsPointCloudLayerRenderer::render()
return true;
}

const bool hasMultipleIndexes = mLayer->dataProvider()->capabilities() & QgsPointCloudDataProvider::ContainSubIndexes;

// TODO cache!?
QgsPointCloudIndex *pc = mLayer->dataProvider()->index();
if ( !pc || !pc->isValid() )
if ( !hasMultipleIndexes &&
( !pc || !pc->isValid() ) )
{
mReadyToCompose = true;
return false;
Expand Down Expand Up @@ -140,7 +144,55 @@ bool QgsPointCloudLayerRenderer::render()
mAttributes.push_back( mLayerAttributes.at( layerIndex ) );
}

QgsPointCloudDataBounds db;
const QgsRectangle renderExtent = renderContext()->coordinateTransform().transformBoundingBox( renderContext()->mapExtent(), Qgis::TransformDirection::Reverse );
bool canceled = false;
if ( !hasMultipleIndexes )
{
canceled = !renderIndex( pc );
}
else
{
const auto subLayers = mLayer->dataProvider()->subIndexes();
for ( const auto &sl : subLayers )
{
if ( canceled )
break;

QgsPointCloudIndex *pc = sl.index.get();

const auto commonExtent = renderExtent.intersect( sl.extent );
if ( commonExtent.isEmpty() )
continue;

if ( !pc || !pc->isValid() || renderExtent.width() > sl.extent.width() )
{
// when dealing with virtual point clouds, we want to render the individual extents when zoomed out
// and only use the selected renderer when zoomed in
mSubExtentsRenderer->startRender( context );
mSubExtentsRenderer->renderExtent( sl.geometry, context );
mSubExtentsRenderer->stopRender( context );
}
else
{
canceled = !renderIndex( pc );
}
}
}

mRenderer->stopRender( context );
mReadyToCompose = true;
return !canceled;
}

bool QgsPointCloudLayerRenderer::renderIndex( QgsPointCloudIndex *pc )
{
QgsPointCloudRenderContext context( *renderContext(),
pc->scale(),
pc->offset(),
mZScale,
mZOffset,
mFeedback.get() );


#ifdef QGISDEBUG
QElapsedTimer t;
Expand Down Expand Up @@ -178,7 +230,6 @@ bool QgsPointCloudLayerRenderer::render()
if ( ( rootErrorInMapCoordinates < 0.0 ) || ( mapUnitsPerPixel < 0.0 ) || ( maximumError < 0.0 ) )
{
QgsDebugMsg( QStringLiteral( "invalid screen error" ) );
mReadyToCompose = true;
return false;
}
double rootErrorPixels = rootErrorInMapCoordinates / mapUnitsPerPixel; // in pixels
Expand Down Expand Up @@ -225,9 +276,6 @@ bool QgsPointCloudLayerRenderer::render()
( void )nodesDrawn;
#endif

mRenderer->stopRender( context );

mReadyToCompose = true;
return !canceled;
}

Expand Down
3 changes: 3 additions & 0 deletions src/core/pointcloud/qgspointcloudlayerrenderer.h
Expand Up @@ -29,6 +29,7 @@
#include "qgspointcloudindex.h"
#include "qgsidentifycontext.h"
#include "qgspointcloudrenderer.h"
#include "qgspointcloudextentrenderer.h"
#include "qgsmapclippingregion.h"
#include "qgsrasterinterface.h"

Expand Down Expand Up @@ -73,10 +74,12 @@ class CORE_EXPORT QgsPointCloudLayerRenderer: public QgsMapLayerRenderer
int renderNodesSync( const QVector<IndexedPointCloudNode> &nodes, QgsPointCloudIndex *pc, QgsPointCloudRenderContext &context, QgsPointCloudRequest &request, bool &canceled );
int renderNodesAsync( const QVector<IndexedPointCloudNode> &nodes, QgsPointCloudIndex *pc, QgsPointCloudRenderContext &context, QgsPointCloudRequest &request, bool &canceled );
int renderNodesSorted( const QVector<IndexedPointCloudNode> &nodes, QgsPointCloudIndex *pc, QgsPointCloudRenderContext &context, QgsPointCloudRequest &request, bool &canceled, Qgis::PointCloudDrawOrder order );
bool renderIndex( QgsPointCloudIndex *pc );

QgsPointCloudLayer *mLayer = nullptr;

std::unique_ptr< QgsPointCloudRenderer > mRenderer;
std::unique_ptr< QgsPointCloudExtentRenderer > mSubExtentsRenderer;

QgsVector3D mScale;
QgsVector3D mOffset;
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/vpc/qgsvirtualpointcloudprovider.h
Expand Up @@ -58,6 +58,7 @@ class QgsVirtualPointCloudProvider: public QgsPointCloudDataProvider
void loadIndex( int i ) override;
bool setSubsetString( const QString &subset, bool updateFeatureCount = false ) override;
QgsPointCloudRenderer *createRenderer( const QVariantMap &configuration = QVariantMap() ) const override SIP_FACTORY;
bool renderInPreview( const QgsDataProvider::PreviewContext & ) override { return false; }

private:
void parseFile();
Expand Down

0 comments on commit 2dae033

Please sign in to comment.