Skip to content
Permalink
Browse files

Quick hack and add combo box to select attribute for 2d point cloud r…

…endering

For proof of concept testing only!
  • Loading branch information
nyalldawson committed Nov 12, 2020
1 parent 3798f14 commit eedea2694e88fa16a67629b5f0f164a423000be1
@@ -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();

@@ -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() );
@@ -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() );
@@ -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;
@@ -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 );
}

@@ -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 )
@@ -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()
@@ -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 );
}
@@ -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 ) );
}
@@ -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;
@@ -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?

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

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

};
#endif

@@ -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">
@@ -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>
@@ -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>
@@ -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>
@@ -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>

0 comments on commit eedea26

Please sign in to comment.
You can’t perform that action at this time.