Skip to content

Commit

Permalink
Quick hack and add combo box to select attribute for 2d point cloud r…
Browse files Browse the repository at this point in the history
…endering

For proof of concept testing only!
  • Loading branch information
nyalldawson committed Nov 12, 2020
1 parent 3798f14 commit eedea26
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 37 deletions.
5 changes: 5 additions & 0 deletions src/app/pointcloud/qgspointcloudlayerproperties.cpp
Expand Up @@ -59,6 +59,9 @@ 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 @@ -104,6 +107,7 @@ void QgsPointCloudLayerProperties::apply()
mMetadataWidget->acceptMetadata();

// TODO -- move to proper widget classes!
mLayer->setCustomProperty( QStringLiteral( "pcAttribute" ), mAttributeComboBox->currentAttribute() );
mLayer->setCustomProperty( QStringLiteral( "pcMin" ), mMinZSpin->value() );
mLayer->setCustomProperty( QStringLiteral( "pcMax" ), mMaxZSpin->value() );
mLayer->setCustomProperty( QStringLiteral( "pcRamp" ), mBtnColorRamp->colorRampName().isEmpty() ? QStringLiteral( "Viridis" ) : mBtnColorRamp->colorRampName() );
Expand Down Expand Up @@ -138,6 +142,7 @@ void QgsPointCloudLayerProperties::syncToLayer()
connect( mInformationTextBrowser, &QTextBrowser::anchorClicked, this, &QgsPointCloudLayerProperties::urlClicked );

// TODO -- move to proper widget classes!
mAttributeComboBox->setAttribute( mLayer->customProperty( QStringLiteral( "pcAttribute" ), QStringLiteral( "Z" ) ).toString() );
mMinZSpin->setValue( mLayer->customProperty( QStringLiteral( "pcMin" ), 400 ).toInt() );
mMaxZSpin->setValue( mLayer->customProperty( QStringLiteral( "pcMax" ), 600 ).toInt() );
mBtnColorRamp->setColorRampFromName( mLayer->customProperty( QStringLiteral( "pcRamp" ), QStringLiteral( "Viridis" ) ).toString() );
Expand Down
2 changes: 2 additions & 0 deletions src/core/pointcloud/qgspointcloudlayer.cpp
Expand Up @@ -136,6 +136,7 @@ bool QgsPointCloudLayer::readSymbology( const QDomNode &node, QString &errorMess
setCustomProperty( QStringLiteral( "pcMin" ), elemRenderer.attribute( QStringLiteral( "pcMin" ), QStringLiteral( "400" ) ).toInt() );
setCustomProperty( QStringLiteral( "pcMax" ), elemRenderer.attribute( QStringLiteral( "pcMax" ), QStringLiteral( "600" ) ).toInt() );
setCustomProperty( QStringLiteral( "pcRamp" ), elemRenderer.attribute( QStringLiteral( "pcRamp" ), QStringLiteral( "Viridis" ) ) );
setCustomProperty( QStringLiteral( "pcAttribute" ), elemRenderer.attribute( QStringLiteral( "pcAttribute" ), QStringLiteral( "Z" ) ) );
}

return true;
Expand All @@ -156,6 +157,7 @@ bool QgsPointCloudLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QStr
elemRenderer.setAttribute( QStringLiteral( "pcMin" ), customProperty( QStringLiteral( "pcMin" ), 400 ).toInt() );
elemRenderer.setAttribute( QStringLiteral( "pcMax" ), customProperty( QStringLiteral( "pcMax" ), 600 ).toInt() );
elemRenderer.setAttribute( QStringLiteral( "pcRamp" ), customProperty( QStringLiteral( "pcRamp" ), QStringLiteral( "Viridis" ) ).toString() );
elemRenderer.setAttribute( QStringLiteral( "pcAttribute" ), customProperty( QStringLiteral( "pcAttribute" ), QStringLiteral( "Z" ) ).toString() );
elem.appendChild( elemRenderer );
}

Expand Down
62 changes: 50 additions & 12 deletions src/core/pointcloud/qgspointcloudrenderer.cpp
Expand Up @@ -92,6 +92,16 @@ float QgsPointCloudRendererConfig::maximumScreenError() const
return mMaximumScreenError;
}

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

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

///@endcond

QgsPointCloudLayerRenderer::QgsPointCloudLayerRenderer( QgsPointCloudLayer *layer, QgsRenderContext &context )
Expand All @@ -104,11 +114,22 @@ QgsPointCloudLayerRenderer::QgsPointCloudLayerRenderer( QgsPointCloudLayer *laye
mConfig.setZMin( layer->customProperty( QStringLiteral( "pcMin" ), 400 ).toInt() );
mConfig.setZMax( layer->customProperty( QStringLiteral( "pcMax" ), 600 ).toInt() );
mConfig.setColorRamp( QgsStyle::defaultStyle()->colorRamp( layer->customProperty( QStringLiteral( "pcRamp" ), QStringLiteral( "Viridis" ) ).toString() ) );
mConfig.setAttribute( layer->customProperty( QStringLiteral( "pcAttribute" ), QStringLiteral( "Z" ) ).toString() );

// 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() )
return;

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

int offset;
const QgsPointCloudAttribute *renderAttribute = mLayer->attributes().find( mConfig.attribute(), offset );
if ( !renderAttribute )
return;

mAttributes.push_back( *renderAttribute );
}

bool QgsPointCloudLayerRenderer::render()
Expand Down Expand Up @@ -151,13 +172,8 @@ bool QgsPointCloudLayerRenderer::render()
qDebug() << "canceled";
break;
}
QgsPointCloudAttributeCollection attributes;
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "X" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Y" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Z" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Classification" ), QgsPointCloudAttribute::Char ) );
QgsPointCloudRequest request;
request.setAttributes( attributes );
request.setAttributes( mAttributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
drawData( painter, block.get(), mConfig );
}
Expand Down Expand Up @@ -229,21 +245,43 @@ void QgsPointCloudLayerRenderer::drawData( QPainter *painter, const QgsPointClou

for ( int i = 0; i < count; ++i )
{
// TODO generic based on reques
// TODO clean up!
qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
char cls = *( char * )( ptr + i * recordSize + 12 );
Q_UNUSED( cls );

double x = offset.x() + scale.x() * ix;
double y = offset.y() + scale.y() * iy;
if ( mapExtent.contains( QgsPointXY( x, y ) ) )
{
double z = offset.z() + scale.z() * iz;
double atr = 0;
switch ( mAttributes.at( 2 ).type() )
{
case QgsPointCloudAttribute::Char:
continue;

case QgsPointCloudAttribute::Int32:
atr = *( qint32 * )( ptr + i * recordSize + 8 );
break;

case QgsPointCloudAttribute::Short:
atr = *( short * )( ptr + i * recordSize + 8 );
break;

case QgsPointCloudAttribute::Float:
atr = *( float * )( ptr + i * recordSize + 8 );
break;

case QgsPointCloudAttribute::Double:
atr = *( double * )( ptr + i * recordSize + 8 );
break;
}

if ( mAttributes.at( 2 ).name() == QLatin1String( "Z" ) )
atr = offset.z() + scale.z() * atr;

mapToPixel.transformInPlace( x, y );

pen.setColor( config.colorRamp()->color( ( z - config.zMin() ) / ( config.zMax() - config.zMin() ) ) );
pen.setColor( config.colorRamp()->color( ( atr - config.zMin() ) / ( config.zMax() - config.zMin() ) ) );
painter->setPen( pen );
painter->drawPoint( QPointF( x, y ) );
}
Expand Down
7 changes: 7 additions & 0 deletions src/core/pointcloud/qgspointcloudrenderer.h
Expand Up @@ -74,8 +74,12 @@ class CORE_EXPORT QgsPointCloudRendererConfig
//! Returns maximum allowed screen error in pixels
float maximumScreenError() const;

QString attribute() const;
void setAttribute( const QString &attribute );

private:
double mZMin = 0, mZMax = 0;
QString mAttribute;
int mPenWidth = 1;
std::unique_ptr<QgsColorRamp> mColorRamp;
float mMaximumScreenError = 5;
Expand Down Expand Up @@ -112,6 +116,8 @@ class CORE_EXPORT QgsPointCloudLayerRenderer: public QgsMapLayerRenderer

QgsPointCloudRendererConfig mConfig;

QgsPointCloudAttributeCollection mAttributes;

// int imgW, imgH; // DO WE NEED AT ALL?
// QgsPointCloudDataBounds mBounds; // DO WE NEED AT ALL?

Expand All @@ -120,6 +126,7 @@ class CORE_EXPORT QgsPointCloudLayerRenderer: public QgsMapLayerRenderer
int pointsDrawn = 0;

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

};
#endif

Expand Down
65 changes: 40 additions & 25 deletions src/ui/qgspointcloudlayerpropertiesbase.ui
Expand Up @@ -199,28 +199,21 @@
</widget>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Ramp</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Min z</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Max z</string>
<string>Max</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QgsColorRampButton" name="mBtnColorRamp">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
Expand All @@ -242,7 +235,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -255,7 +248,7 @@
</property>
</spacer>
</item>
<item row="1" column="2">
<item row="2" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand All @@ -268,23 +261,40 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsSpinBox" name="mMinZSpin">
<property name="minimum">
<number>-999999999</number>
<widget class="QgsPointCloudAttributeComboBox" name="mAttributeComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Attribute</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsDoubleSpinBox" name="mMinZSpin">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<number>999999999</number>
<double>999999.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsSpinBox" name="mMaxZSpin">
<property name="minimum">
<number>-999999999</number>
<item row="2" column="1">
<widget class="QgsDoubleSpinBox" name="mMaxZSpin">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<number>999999999</number>
<double>999999.000000000000000</double>
</property>
</widget>
</item>
Expand Down Expand Up @@ -377,9 +387,14 @@
<container>1</container>
</customwidget>
<customwidget>
<class>QgsSpinBox</class>
<extends>QSpinBox</extends>
<header>qgsspinbox.h</header>
<class>QgsPointCloudAttributeComboBox</class>
<extends>QComboBox</extends>
<header>qgspointcloudattributecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>qgsdoublespinbox.h</header>
</customwidget>
</customwidgets>
<tabstops>
Expand Down

0 comments on commit eedea26

Please sign in to comment.