Skip to content

Commit

Permalink
Hook QgsPointCloudRenderer into QgsPointCloudLayerRenderer (non-funct…
Browse files Browse the repository at this point in the history
…ional for now)
  • Loading branch information
nyalldawson committed Nov 12, 2020
1 parent abbd634 commit c2fe0d3
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 17 deletions.
17 changes: 17 additions & 0 deletions python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in
Expand Up @@ -97,6 +97,23 @@ QgsPointCloudLayer cannot be copied.
QgsPointCloudAttributeCollection attributes() const;
%Docstring
Returns the attributes available from the layer.
%End

QgsPointCloudRenderer *renderer();
%Docstring
Returns the 2D renderer for the point cloud.

.. seealso:: :py:func:`setRenderer`
%End


void setRenderer( QgsPointCloudRenderer *renderer /Transfer/ );
%Docstring
Sets the 2D ``renderer`` for the point cloud.

Ownership of ``renderer`` is transferred to the layer.

.. seealso:: :py:func:`renderer`
%End

private:
Expand Down
43 changes: 41 additions & 2 deletions src/core/pointcloud/qgspointcloudlayer.cpp
Expand Up @@ -23,6 +23,7 @@
#include "qgsproviderregistry.h"
#include "qgslogger.h"
#include "qgslayermetadataformatter.h"
#include "qgspointcloudrenderer.h"

QgsPointCloudLayer::QgsPointCloudLayer( const QString &path,
const QString &baseName,
Expand All @@ -48,6 +49,10 @@ QgsPointCloudLayer *QgsPointCloudLayer::clone() const

QgsPointCloudLayer *layer = new QgsPointCloudLayer( source(), name(), mProviderKey, options );
QgsMapLayer::clone( layer );

if ( mRenderer )
layer->setRenderer( mRenderer->clone() );

return layer;
}

Expand Down Expand Up @@ -207,10 +212,24 @@ void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString

setCrs( mDataProvider->crs() );

if ( loadDefaultStyleFlag )
if ( !mRenderer || loadDefaultStyleFlag )
{
std::unique_ptr< QgsScopedRuntimeProfile > profile;
if ( QgsApplication::profiler()->groupIsActive( QStringLiteral( "projectload" ) ) )
profile = qgis::make_unique< QgsScopedRuntimeProfile >( tr( "Load layer style" ), QStringLiteral( "projectload" ) );

bool defaultLoadedFlag = false;
loadDefaultStyle( defaultLoadedFlag );

if ( !defaultLoadedFlag && loadDefaultStyleFlag )
{
loadDefaultStyle( defaultLoadedFlag );
}

if ( !defaultLoadedFlag )
{
// all else failed, create default renderer
setRenderer( QgsPointCloudRenderer::defaultRenderer() );
}
}

connect( mDataProvider.get(), &QgsPointCloudDataProvider::dataChanged, this, &QgsPointCloudLayer::dataChanged );
Expand Down Expand Up @@ -333,3 +352,23 @@ QgsPointCloudAttributeCollection QgsPointCloudLayer::attributes() const
{
return mDataProvider ? mDataProvider->attributes() : QgsPointCloudAttributeCollection();
}

QgsPointCloudRenderer *QgsPointCloudLayer::renderer()
{
return mRenderer.get();
}

const QgsPointCloudRenderer *QgsPointCloudLayer::renderer() const
{
return mRenderer.get();
}

void QgsPointCloudLayer::setRenderer( QgsPointCloudRenderer *renderer )
{
if ( renderer == mRenderer.get() )
return;

mRenderer.reset( renderer );
emit rendererChanged();
emit styleChanged();
}
28 changes: 28 additions & 0 deletions src/core/pointcloud/qgspointcloudlayer.h
Expand Up @@ -27,6 +27,8 @@ class QgsPointCloudLayerRenderer;
#include <QString>
#include <memory>

class QgsPointCloudRenderer;

/**
* \ingroup core
*
Expand Down Expand Up @@ -126,6 +128,30 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer
*/
QgsPointCloudAttributeCollection attributes() const;

/**
* Returns the 2D renderer for the point cloud.
*
* \see setRenderer()
*/
QgsPointCloudRenderer *renderer();

/**
* Returns the 2D renderer for the point cloud.
* \note not available in Python bindings
*
* \see setRenderer()
*/
const QgsPointCloudRenderer *renderer() const SIP_SKIP;

/**
* Sets the 2D \a renderer for the point cloud.
*
* Ownership of \a renderer is transferred to the layer.
*
* \see renderer()
*/
void setRenderer( QgsPointCloudRenderer *renderer SIP_TRANSFER );

private:

bool isReadOnly() const override {return true;}
Expand All @@ -136,6 +162,8 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer

std::unique_ptr<QgsPointCloudDataProvider> mDataProvider;

std::unique_ptr<QgsPointCloudRenderer> mRenderer;

};


Expand Down
32 changes: 18 additions & 14 deletions src/core/pointcloud/qgspointcloudlayerrenderer.cpp
Expand Up @@ -25,6 +25,7 @@
#include "qgscolorramp.h"
#include "qgspointcloudrequest.h"
#include "qgspointcloudattribute.h"
#include "qgspointcloudrenderer.h"
#include "qgslogger.h"

///@cond PRIVATE
Expand Down Expand Up @@ -120,9 +121,11 @@ QgsPointCloudLayerRenderer::QgsPointCloudLayerRenderer( QgsPointCloudLayer *laye

// TODO: we must not keep pointer to mLayer (it's dangerous) - we must copy anything we need for rendering
// or use some locking to prevent read/write from multiple threads
if ( !mLayer || !mLayer->dataProvider() || !mLayer->dataProvider()->index() )
if ( !mLayer || !mLayer->dataProvider() || !mLayer->dataProvider()->index() || !mLayer->renderer() )
return;

mRenderer.reset( mLayer->renderer()->clone() );

mAttributes.push_back( QgsPointCloudAttribute( QStringLiteral( "X" ), QgsPointCloudAttribute::Int32 ) );
mAttributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Y" ), QgsPointCloudAttribute::Int32 ) );

Expand All @@ -141,13 +144,14 @@ bool QgsPointCloudLayerRenderer::render()
if ( !pc )
return false;

QgsRenderContext &context = *renderContext();
QgsPointCloudRenderContext context( *renderContext() );


// Set up the render configuration options
QPainter *painter = context.painter();
QPainter *painter = context.renderContext().painter();

painter->save();
context.setPainterFlagsUsingContext( painter );
QgsScopedQPainterState painterState( painter );
context.renderContext().setPainterFlagsUsingContext( painter );

QgsPointCloudDataBounds db;

Expand All @@ -157,33 +161,31 @@ bool QgsPointCloudLayerRenderer::render()
const IndexedPointCloudNode root = pc->root();
float maximumError = mConfig.maximumScreenError(); // in pixels
float rootError = pc->nodeError( root ); // in map coords
double mapUnitsPerPixel = context.mapToPixel().mapUnitsPerPixel();
double mapUnitsPerPixel = context.renderContext().mapToPixel().mapUnitsPerPixel();
if ( ( rootError < 0.0 ) || ( mapUnitsPerPixel < 0.0 ) || ( maximumError < 0.0 ) )
{
qDebug() << "invalid screen error";
return false;
}
float rootErrorPixels = rootError / mapUnitsPerPixel; // in pixels
const QList<IndexedPointCloudNode> nodes = traverseTree( pc, context, pc->root(), maximumError, rootErrorPixels );
const QList<IndexedPointCloudNode> nodes = traverseTree( pc, context.renderContext(), pc->root(), maximumError, rootErrorPixels );

// drawing
for ( const IndexedPointCloudNode &n : nodes )
{
if ( context.renderingStopped() )
if ( context.renderContext().renderingStopped() )
{
qDebug() << "canceled";
break;
}
QgsPointCloudRequest request;
request.setAttributes( mAttributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
drawData( painter, block.get(), mConfig );
drawData( context, block.get(), mConfig );
}

qDebug() << "totals:" << nodesDrawn << "nodes | " << pointsDrawn << " points | " << t.elapsed() << "ms";

painter->restore();

return true;
}

Expand Down Expand Up @@ -221,14 +223,16 @@ QList<IndexedPointCloudNode> QgsPointCloudLayerRenderer::traverseTree( const Qgs

QgsPointCloudLayerRenderer::~QgsPointCloudLayerRenderer() = default;

void QgsPointCloudLayerRenderer::drawData( QPainter *painter, const QgsPointCloudBlock *data, const QgsPointCloudRendererConfig &config )
void QgsPointCloudLayerRenderer::drawData( QgsPointCloudRenderContext &context, const QgsPointCloudBlock *data, const QgsPointCloudRendererConfig &config )
{
Q_ASSERT( mLayer->dataProvider() );
Q_ASSERT( mLayer->dataProvider()->index() );

if ( !data )
return;

mRenderer->renderBlock( data, context );

const QgsMapToPixel mapToPixel = renderContext()->mapToPixel();
const QgsVector3D scale = mLayer->dataProvider()->index()->scale();
const QgsVector3D offset = mLayer->dataProvider()->index()->offset();
Expand Down Expand Up @@ -284,8 +288,8 @@ void QgsPointCloudLayerRenderer::drawData( QPainter *painter, const QgsPointClou
mapToPixel.transformInPlace( x, y );

pen.setColor( config.colorRamp()->color( ( atr - config.zMin() ) / ( config.zMax() - config.zMin() ) ) );
painter->setPen( pen );
painter->drawPoint( QPointF( x, y ) );
context.renderContext().painter()->setPen( pen );
context.renderContext().painter()->drawPoint( QPointF( x, y ) );
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/core/pointcloud/qgspointcloudlayerrenderer.h
Expand Up @@ -30,6 +30,8 @@

class QgsRenderContext;
class QgsPointCloudLayer;
class QgsPointCloudRenderer;
class QgsPointCloudRenderContext;

#define SIP_NO_FILE

Expand Down Expand Up @@ -114,6 +116,8 @@ class CORE_EXPORT QgsPointCloudLayerRenderer: public QgsMapLayerRenderer

QgsPointCloudLayer *mLayer = nullptr;

std::unique_ptr< QgsPointCloudRenderer > mRenderer;

QgsPointCloudRendererConfig mConfig;

QgsPointCloudAttributeCollection mAttributes;
Expand All @@ -125,7 +129,7 @@ class CORE_EXPORT QgsPointCloudLayerRenderer: public QgsMapLayerRenderer
int nodesDrawn = 0;
int pointsDrawn = 0;

void drawData( QPainter *painter, const QgsPointCloudBlock *data, const QgsPointCloudRendererConfig &config );
void drawData( QgsPointCloudRenderContext &context, const QgsPointCloudBlock *data, const QgsPointCloudRendererConfig &config );

};

Expand Down

0 comments on commit c2fe0d3

Please sign in to comment.