Skip to content

Commit

Permalink
Move old dummy point cloud renderer code to proper QgsPointCloudAttri…
Browse files Browse the repository at this point in the history
…buteByRampRenderer class

And remove duplicate non-functional symbology tab in point cloud layer properties
  • Loading branch information
nyalldawson committed Dec 2, 2020
1 parent 8ba9866 commit af280eb
Show file tree
Hide file tree
Showing 17 changed files with 753 additions and 435 deletions.
@@ -0,0 +1,108 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/pointcloud/qgspointcloudattributebyramprenderer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsPointCloudAttributeByRampRenderer : QgsPointCloudRenderer
{
%Docstring
An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.

.. versionadded:: 3.18
%End

%TypeHeaderCode
#include "qgspointcloudattributebyramprenderer.h"
%End
public:

QgsPointCloudAttributeByRampRenderer();
%Docstring
Constructor for QgsPointCloudAttributeByRampRenderer.
%End

virtual QString type() const;

virtual QgsPointCloudRenderer *clone() const;

virtual void renderBlock( const QgsPointCloudBlock *block, QgsPointCloudRenderContext &context );

virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;

virtual void startRender( QgsPointCloudRenderContext &context );

virtual void stopRender( QgsPointCloudRenderContext &context );

virtual QSet< QString > usedAttributes( const QgsPointCloudRenderContext &context ) const;


static QgsPointCloudRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) /Factory/;
%Docstring
Creates an RGB renderer from an XML ``element``.
%End

QString attribute() const;
%Docstring
Returns the attribute to use for the renderer.

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

void setAttribute( const QString &attribute );
%Docstring
Sets the ``attribute`` to use for the renderer.

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

QgsColorRamp *colorRamp() const;
%Docstring
Returns the color ramp used for rendering the attribute.

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

void setColorRamp( QgsColorRamp *ramp /Transfer/ );
%Docstring
Sets the color ``ramp`` used for rendering the attribute.

Ownership of ``ramp`` is transferrred to the renderer.

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

double min() const;
%Docstring
Returns min
%End
void setMin( double value );
%Docstring
Sets min
%End

double max() const;
%Docstring
Returns max
%End

void setMax( double value );
%Docstring
Sets max
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/pointcloud/qgspointcloudattributebyramprenderer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -446,6 +446,7 @@
%Include auto_generated/mesh/qgsmeshtracerenderer.sip
%Include auto_generated/mesh/qgsmeshcalculator.sip
%Include auto_generated/pointcloud/qgspointcloudattribute.sip
%Include auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip
%Include auto_generated/pointcloud/qgspointcloudattributemodel.sip
%Include auto_generated/pointcloud/qgspointcloudblock.sip
%Include auto_generated/pointcloud/qgspointcloudlayer.sip
Expand Down
12 changes: 0 additions & 12 deletions src/app/pointcloud/qgspointcloudlayerproperties.cpp
Expand Up @@ -61,9 +61,6 @@ QgsPointCloudLayerProperties::QgsPointCloudLayerProperties( QgsPointCloudLayer *
metadataFrame->setLayout( layout );
mOptsPage_Metadata->setContentsMargins( 0, 0, 0, 0 );

mAttributeComboBox->setFilters( QgsPointCloudAttributeProxyModel::Numeric );
mAttributeComboBox->setLayer( mLayer );

// update based on lyr's current state
syncToLayer();

Expand Down Expand Up @@ -173,15 +170,6 @@ void QgsPointCloudLayerProperties::syncToLayer()
mInformationTextBrowser->setOpenLinks( false );
connect( mInformationTextBrowser, &QTextBrowser::anchorClicked, this, &QgsPointCloudLayerProperties::urlClicked );

// TODO -- move to proper widget classes!
if ( QgsDummyPointCloudRenderer *renderer = dynamic_cast< QgsDummyPointCloudRenderer * >( mLayer->renderer() ) )
{
mAttributeComboBox->setAttribute( renderer->attribute() );
mMinZSpin->setValue( renderer->zMin() );
mMaxZSpin->setValue( renderer->zMax() );
mBtnColorRamp->setColorRamp( renderer->colorRamp() );
}

for ( QgsMapLayerConfigWidget *w : mConfigWidgets )
w->syncToLayer( mLayer );
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -628,6 +628,7 @@ set(QGIS_CORE_SRCS
mesh/qgsmeshvirtualdatasetgroup.cpp

pointcloud/qgspointcloudattribute.cpp
pointcloud/qgspointcloudattributebyramprenderer.cpp
pointcloud/qgspointcloudattributemodel.cpp
pointcloud/qgspointcloudrequest.cpp
pointcloud/qgspointcloudblock.cpp
Expand Down Expand Up @@ -1332,6 +1333,7 @@ set(QGIS_CORE_HDRS
mesh/qgsmeshvirtualdatasetgroup.h

pointcloud/qgspointcloudattribute.h
pointcloud/qgspointcloudattributebyramprenderer.h
pointcloud/qgspointcloudattributemodel.h
pointcloud/qgspointcloudrequest.h
pointcloud/qgspointcloudblock.h
Expand Down
225 changes: 225 additions & 0 deletions src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp
@@ -0,0 +1,225 @@
/***************************************************************************
qgspointcloudattributebyramprenderer.h
--------------------
begin : October 2020
copyright : (C) 2020 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgspointcloudattributebyramprenderer.h"
#include "qgspointcloudblock.h"
#include "qgsstyle.h"
#include "qgscolorramp.h"
#include "qgssymbollayerutils.h"

QgsPointCloudAttributeByRampRenderer::QgsPointCloudAttributeByRampRenderer()
{
mColorRamp.reset( QgsStyle::defaultStyle()->colorRamp( QStringLiteral( "Viridis" ) ) );
}

QString QgsPointCloudAttributeByRampRenderer::type() const
{
return QStringLiteral( "ramp" );
}

QgsPointCloudRenderer *QgsPointCloudAttributeByRampRenderer::clone() const
{
std::unique_ptr< QgsPointCloudAttributeByRampRenderer > res = qgis::make_unique< QgsPointCloudAttributeByRampRenderer >();
res->mAttribute = mAttribute;
res->mColorRamp.reset( colorRamp() ? colorRamp()->clone() : QgsStyle::defaultStyle()->colorRamp( QStringLiteral( "Viridis" ) ) );
res->mMin = mMin;
res->mMax = mMax;

copyCommonProperties( res.get() );

return res.release();
}

void QgsPointCloudAttributeByRampRenderer::renderBlock( const QgsPointCloudBlock *block, QgsPointCloudRenderContext &context )
{
const QgsMapToPixel mapToPixel = context.renderContext().mapToPixel();

const QgsRectangle visibleExtent = context.renderContext().extent();

QPen pen;
pen.setWidth( mPainterPenWidth );
pen.setCapStyle( Qt::FlatCap );
//pen.setJoinStyle( Qt::MiterJoin );

const char *ptr = block->data();
int count = block->pointCount();
const QgsPointCloudAttributeCollection request = block->attributes();

const std::size_t recordSize = request.pointRecordSize();
int attributeOffset = 0;
const QgsPointCloudAttribute *attribute = request.find( mAttribute, attributeOffset );
if ( !attribute )
return;
const QgsPointCloudAttribute::DataType attributeType = attribute->type();

const QgsDoubleRange zRange = context.renderContext().zRange();
const bool considerZ = !zRange.isInfinite();

const bool applyZOffset = attribute->name() == QLatin1String( "Z" );

int rendered = 0;
double x = 0;
double y = 0;
double z = 0;
const QgsCoordinateTransform ct = context.renderContext().coordinateTransform();
const bool reproject = ct.isValid();
for ( int i = 0; i < count; ++i )
{
if ( considerZ )
{
// z value filtering is cheapest, if we're doing it...
z = pointZ( context, ptr, i );
if ( !zRange.contains( z ) )
continue;
}

pointXY( context, ptr, i, x, y );
if ( visibleExtent.contains( QgsPointXY( x, y ) ) )
{
if ( reproject )
{
try
{
ct.transformInPlace( x, y, z );
}
catch ( QgsCsException & )
{
continue;
}
}

double attributeValue = 0;
context.getAttribute( ptr, i * recordSize + attributeOffset, attributeType, attributeValue );

if ( applyZOffset )
attributeValue = context.offset().z() + context.scale().z() * attributeValue;

mapToPixel.transformInPlace( x, y );

const QColor color = mColorRamp->color( ( attributeValue - mMin ) / ( mMax - mMin ) );
#if 0
pen.setColor( QColor( red, green, blue ) );
context.renderContext().painter()->setPen( pen );
context.renderContext().painter()->drawPoint( QPointF( x, y ) );
#else

context.renderContext().painter()->fillRect( QRectF( x - mPainterPenWidth * 0.5,
y - mPainterPenWidth * 0.5,
mPainterPenWidth, mPainterPenWidth ), color );
#endif

rendered++;
}
}
context.incrementPointsRendered( rendered );
}


QgsPointCloudRenderer *QgsPointCloudAttributeByRampRenderer::create( QDomElement &element, const QgsReadWriteContext &context )
{
std::unique_ptr< QgsPointCloudAttributeByRampRenderer > r = qgis::make_unique< QgsPointCloudAttributeByRampRenderer >();

r->setAttribute( element.attribute( QStringLiteral( "attribute" ), QStringLiteral( "Intensity" ) ) );
QDomElement sourceColorRampElem = element.firstChildElement( QStringLiteral( "colorramp" ) );
if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "[source]" ) )
{
r->setColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
}
r->setMin( element.attribute( QStringLiteral( "min" ), QStringLiteral( "0" ) ).toDouble() );
r->setMax( element.attribute( QStringLiteral( "max" ), QStringLiteral( "100" ) ).toDouble() );

r->restoreCommonProperties( element, context );

return r.release();
}

QDomElement QgsPointCloudAttributeByRampRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
{
QDomElement rendererElem = doc.createElement( QStringLiteral( "renderer" ) );

rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "ramp" ) );
rendererElem.setAttribute( QStringLiteral( "min" ), mMin );
rendererElem.setAttribute( QStringLiteral( "max" ), mMax );

rendererElem.setAttribute( QStringLiteral( "attribute" ), mAttribute );
QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), mColorRamp.get(), doc );
rendererElem.appendChild( colorRampElem );

saveCommonProperties( rendererElem, context );

return rendererElem;
}

void QgsPointCloudAttributeByRampRenderer::startRender( QgsPointCloudRenderContext &context )
{
QgsPointCloudRenderer::startRender( context );

mPainterPenWidth = context.renderContext().convertToPainterUnits( pointSize(), pointSizeUnit(), pointSizeMapUnitScale() );
}

void QgsPointCloudAttributeByRampRenderer::stopRender( QgsPointCloudRenderContext &context )
{
QgsPointCloudRenderer::stopRender( context );
}

QSet<QString> QgsPointCloudAttributeByRampRenderer::usedAttributes( const QgsPointCloudRenderContext & ) const
{
QSet<QString> res;
res << mAttribute;
return res;
}

QString QgsPointCloudAttributeByRampRenderer::attribute() const
{
return mAttribute;
}

void QgsPointCloudAttributeByRampRenderer::setAttribute( const QString &attribute )
{
mAttribute = attribute;
}

QgsColorRamp *QgsPointCloudAttributeByRampRenderer::colorRamp() const
{
return mColorRamp.get();
}

void QgsPointCloudAttributeByRampRenderer::setColorRamp( QgsColorRamp *ramp )
{
mColorRamp.reset( ramp );
}

double QgsPointCloudAttributeByRampRenderer::min() const
{
return mMin;
}

void QgsPointCloudAttributeByRampRenderer::setMin( double value )
{
mMin = value;
}

double QgsPointCloudAttributeByRampRenderer::max() const
{
return mMax;
}

void QgsPointCloudAttributeByRampRenderer::setMax( double value )
{
mMax = value;
}

0 comments on commit af280eb

Please sign in to comment.