18#include "qgspointcloudexpression.h"
23#include <QDomDocument>
33 QWidget *parent, Qt::WindowFlags fl )
43 connect( lstAttributes->selectionModel(), &QItemSelectionModel::currentChanged,
this, &QgsPointCloudQueryBuilder::lstAttributes_currentChanged );
44 connect( lstAttributes, &QListView::doubleClicked,
this, &QgsPointCloudQueryBuilder::lstAttributes_doubleClicked );
45 connect( lstValues, &QListView::doubleClicked,
this, &QgsPointCloudQueryBuilder::lstValues_doubleClicked );
46 connect( btnEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnEqual_clicked );
47 connect( btnLessThan, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnLessThan_clicked );
48 connect( btnGreaterThan, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnGreaterThan_clicked );
49 connect( btnIn, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnIn_clicked );
50 connect( btnNotIn, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnNotIn_clicked );
51 connect( btnLessEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnLessEqual_clicked );
52 connect( btnGreaterEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnGreaterEqual_clicked );
53 connect( btnNotEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnNotEqual_clicked );
54 connect( btnAnd, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnAnd_clicked );
55 connect( btnOr, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnOr_clicked );
57 QPushButton *pbn =
new QPushButton( tr(
"&Test" ) );
58 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
59 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::test );
61 pbn =
new QPushButton( tr(
"&Clear" ) );
62 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
63 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::clear );
65 pbn =
new QPushButton( tr(
"&Save…" ) );
66 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
67 pbn->setToolTip( tr(
"Save query to QQF file" ) );
68 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::saveQuery );
70 pbn =
new QPushButton( tr(
"&Load…" ) );
71 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
72 pbn->setToolTip( tr(
"Load query from QQF file" ) );
73 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::loadQuery );
77 lblDataUri->setText( tr(
"Set provider filter on %1" ).arg( layer->
name() ) );
78 mTxtSql->setText( mOrigSubsetString );
84 QDialog::showEvent( event );
87void QgsPointCloudQueryBuilder::setupGuiViews()
90 mModelAttributes =
new QStandardItemModel();
91 mModelValues =
new QStandardItemModel();
94 lstAttributes->setViewMode( QListView::ListMode );
95 lstValues->setViewMode( QListView::ListMode );
96 lstAttributes->setSelectionBehavior( QAbstractItemView::SelectRows );
97 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
98 lstAttributes->setEditTriggers( QAbstractItemView::NoEditTriggers );
99 lstValues->setEditTriggers( QAbstractItemView::NoEditTriggers );
101 lstAttributes->setUniformItemSizes(
true );
102 lstValues->setUniformItemSizes(
true );
104 lstAttributes->setAlternatingRowColors(
true );
105 lstValues->setAlternatingRowColors(
true );
107 lstAttributes->setModel( mModelAttributes );
108 lstValues->setModel( mModelValues );
111void QgsPointCloudQueryBuilder::populateAttributes()
114 mTxtSql->setFields( fields );
115 for (
int idx = 0; idx < fields.
count(); ++idx )
118 mModelAttributes->insertRow( mModelAttributes->rowCount(), myItem );
122void QgsPointCloudQueryBuilder::lstAttributes_currentChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
126 mModelValues->clear();
127 const QString attribute = current.data().toString();
128 if ( attribute.compare( QLatin1String(
"Classification" ), Qt::CaseInsensitive ) == 0 )
131 for (
int i = 0; i <= 18; ++i )
133 QStandardItem *item =
new QStandardItem( QString(
"%1: %2" ).arg( i ).arg( codes.value( i ) ) );
134 item->setData( i, Qt::UserRole );
135 mModelValues->insertRow( mModelValues->rowCount(), item );
141 double value = stats.
minimum( attribute );
142 QString valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
143 QStandardItem *item =
new QStandardItem( tr(
"Minimum: %1" ).arg( valueString ) );
144 item->setData( value, Qt::UserRole );
145 mModelValues->insertRow( mModelValues->rowCount(), item );
147 value = stats.
maximum( attribute );
148 valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
149 item =
new QStandardItem( tr(
"Maximum: %1" ).arg( valueString ) );
150 item->setData( value, Qt::UserRole );
151 mModelValues->insertRow( mModelValues->rowCount(), item );
153 value = stats.
mean( attribute );
154 valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
155 item =
new QStandardItem( tr(
"Mean: %1" ).arg( valueString ) );
156 item->setData( value, Qt::UserRole );
157 mModelValues->insertRow( mModelValues->rowCount(), item );
159 value = stats.
stDev( attribute );
160 valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
161 item =
new QStandardItem( tr(
"StdDev: %1" ).arg( valueString ) );
162 item->setData( value, Qt::UserRole );
163 mModelValues->insertRow( mModelValues->rowCount(), item );
167void QgsPointCloudQueryBuilder::lstAttributes_doubleClicked(
const QModelIndex &index )
169 mTxtSql->insertText( QStringLiteral(
"%1 " ).arg( mModelAttributes->data( index ).toString() ) );
173void QgsPointCloudQueryBuilder::lstValues_doubleClicked(
const QModelIndex &index )
175 mTxtSql->insertText( QStringLiteral(
"%1 " ).arg( mModelValues->data( index, Qt::UserRole ).toString() ) );
179void QgsPointCloudQueryBuilder::btnEqual_clicked()
181 mTxtSql->insertText( QStringLiteral(
"= " ) );
185void QgsPointCloudQueryBuilder::btnLessThan_clicked()
187 mTxtSql->insertText( QStringLiteral(
"< " ) );
191void QgsPointCloudQueryBuilder::btnGreaterThan_clicked()
193 mTxtSql->insertText( QStringLiteral(
"> " ) );
197void QgsPointCloudQueryBuilder::btnIn_clicked()
199 mTxtSql->insertText( QStringLiteral(
"IN () " ) );
201 mTxtSql->getCursorPosition( &i, &j );
202 mTxtSql->setCursorPosition( i, j - 2 );
206void QgsPointCloudQueryBuilder::btnNotIn_clicked()
208 mTxtSql->insertText( QStringLiteral(
"NOT IN () " ) );
210 mTxtSql->getCursorPosition( &i, &j );
211 mTxtSql->setCursorPosition( i, j - 2 );
215void QgsPointCloudQueryBuilder::btnLessEqual_clicked()
217 mTxtSql->insertText( QStringLiteral(
"<= " ) );
221void QgsPointCloudQueryBuilder::btnGreaterEqual_clicked()
223 mTxtSql->insertText( QStringLiteral(
">= " ) );
227void QgsPointCloudQueryBuilder::btnNotEqual_clicked()
229 mTxtSql->insertText( QStringLiteral(
"!= " ) );
233void QgsPointCloudQueryBuilder::btnAnd_clicked()
235 mTxtSql->insertText( QStringLiteral(
"AND " ) );
239void QgsPointCloudQueryBuilder::btnOr_clicked()
241 mTxtSql->insertText( QStringLiteral(
"OR " ) );
247 if ( mTxtSql->text() != mOrigSubsetString )
251 QMessageBox::warning(
this, tr(
"Query Result" ), tr(
"Error in query. The subset string could not be set." ) );
267void QgsPointCloudQueryBuilder::test()
269 QgsPointCloudExpression expression( mTxtSql->text() );
270 if ( !expression.isValid() && !mTxtSql->text().isEmpty() )
272 QMessageBox::warning(
this,
273 tr(
"Query Result" ),
274 tr(
"An error occurred while parsing the expression:\n%1" ).arg( expression.parserErrorString() ) );
278 const QSet<QString> attributes = expression.referencedAttributes();
280 for (
const auto &attribute : attributes )
285 QMessageBox::warning(
this,
286 tr(
"Query Result" ),
287 tr(
"\"%1\" not recognized as an available attribute." ).arg( attribute ) );
292 QMessageBox::information(
this,
293 tr(
"Query Result" ),
294 tr(
"The expression was successfully parsed." ) );
298void QgsPointCloudQueryBuilder::clear()
304void QgsPointCloudQueryBuilder::saveQuery()
310void QgsPointCloudQueryBuilder::loadQuery()
316 mTxtSql->insertText( subset );
QString displayNameWithAlias() const
Returns the name to use when displaying this field and adds the alias in parenthesis if it is defined...
Container of fields for a vector layer.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
QgsFields toFields() const
Converts the attribute collection to an equivalent QgsFields collection.
virtual QgsPointCloudAttributeCollection attributes() const =0
Returns the attributes available from this data provider.
static QMap< int, QString > translatedLasClassificationCodes()
Returns the map of LAS classification code to translated string value, corresponding to the ASPRS Sta...
Represents a map layer supporting display of point clouds.
QgsPointCloudDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
const QgsPointCloudStatistics statistics() const
Returns the object containing statistics.
QString subsetString() const
Returns the string used to define a subset of the layer.
bool setSubsetString(const QString &subset)
Sets the string used to define a subset of the layer.
QgsPointCloudQueryBuilder(QgsPointCloudLayer *layer, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
This constructor is used when the query builder is called from the layer properties dialog.
void showEvent(QShowEvent *event) override
Class used to store statistics of a point cloud dataset.
double maximum(const QString &attribute) const
Returns the maximum value for the attribute attribute If no matching statistic is available then NaN ...
double stDev(const QString &attribute) const
Returns the standard deviation value for the attribute attribute If no matching statistic is availabl...
double mean(const QString &attribute) const
Returns the mean value for the attribute attribute If no matching statistic is available then NaN wil...
double minimum(const QString &attribute) const
Returns the minimum value for the attribute attribute If no matching statistic is available then NaN ...
static bool loadQueryFromFile(QString &subset)
Load query from the XML file.
static bool saveQueryToFile(const QString &subset)
Save query to the XML file.
Interface for a dialog that can edit subset strings.