19#include "qgspointcloudexpression.h"
24#include <QDomDocument>
32#include "moc_qgspointcloudquerybuilder.cpp"
44 connect( lstAttributes->selectionModel(), &QItemSelectionModel::currentChanged,
this, &QgsPointCloudQueryBuilder::lstAttributes_currentChanged );
45 connect( lstAttributes, &QListView::doubleClicked,
this, &QgsPointCloudQueryBuilder::lstAttributes_doubleClicked );
46 connect( lstValues, &QListView::doubleClicked,
this, &QgsPointCloudQueryBuilder::lstValues_doubleClicked );
47 connect( btnEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnEqual_clicked );
48 connect( btnLessThan, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnLessThan_clicked );
49 connect( btnGreaterThan, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnGreaterThan_clicked );
50 connect( btnIn, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnIn_clicked );
51 connect( btnNotIn, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnNotIn_clicked );
52 connect( btnLessEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnLessEqual_clicked );
53 connect( btnGreaterEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnGreaterEqual_clicked );
54 connect( btnNotEqual, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnNotEqual_clicked );
55 connect( btnAnd, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnAnd_clicked );
56 connect( btnOr, &QPushButton::clicked,
this, &QgsPointCloudQueryBuilder::btnOr_clicked );
58 QPushButton *pbn =
new QPushButton( tr(
"&Test" ) );
59 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
60 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::test );
62 pbn =
new QPushButton( tr(
"&Clear" ) );
63 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
64 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::clear );
66 pbn =
new QPushButton( tr(
"&Save…" ) );
67 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
68 pbn->setToolTip( tr(
"Save query to QQF file" ) );
69 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::saveQuery );
71 pbn =
new QPushButton( tr(
"&Load…" ) );
72 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
73 pbn->setToolTip( tr(
"Load query from QQF file" ) );
74 connect( pbn, &QAbstractButton::clicked,
this, &QgsPointCloudQueryBuilder::loadQuery );
76 lblDataUri->setText( tr(
"Set provider filter on %1" ).arg( layer->
name() ) );
82 QDialog::showEvent( event );
85void QgsPointCloudQueryBuilder::setupGuiViews()
88 mModelAttributes =
new QStandardItemModel();
89 mModelValues =
new QStandardItemModel();
92 lstAttributes->setViewMode( QListView::ListMode );
93 lstValues->setViewMode( QListView::ListMode );
94 lstAttributes->setSelectionBehavior( QAbstractItemView::SelectRows );
95 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
96 lstAttributes->setEditTriggers( QAbstractItemView::NoEditTriggers );
97 lstValues->setEditTriggers( QAbstractItemView::NoEditTriggers );
99 lstAttributes->setUniformItemSizes(
true );
100 lstValues->setUniformItemSizes(
true );
102 lstAttributes->setAlternatingRowColors(
true );
103 lstValues->setAlternatingRowColors(
true );
105 lstAttributes->setModel( mModelAttributes );
106 lstValues->setModel( mModelValues );
109void QgsPointCloudQueryBuilder::populateAttributes()
111 const QgsFields &fields = mLayer->dataProvider()->attributes().toFields();
112 mTxtSql->setFields( fields );
113 for (
int idx = 0; idx < fields.
count(); ++idx )
116 mModelAttributes->insertRow( mModelAttributes->rowCount(), myItem );
120void QgsPointCloudQueryBuilder::lstAttributes_currentChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
124 mModelValues->clear();
125 const QString attribute = current.data().toString();
126 if ( attribute.compare( QLatin1String(
"Classification" ), Qt::CaseInsensitive ) == 0 )
129 for (
int i = 0; i <= 18; ++i )
131 QStandardItem *item =
new QStandardItem( QString(
"%1: %2" ).arg( i ).arg( codes.value( i ) ) );
132 item->setData( i, Qt::UserRole );
133 mModelValues->insertRow( mModelValues->rowCount(), item );
138 const QgsPointCloudStatistics stats = mLayer->statistics();
139 double value = stats.
minimum( attribute );
140 QString valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
141 QStandardItem *item =
new QStandardItem( tr(
"Minimum: %1" ).arg( valueString ) );
142 item->setData( value, Qt::UserRole );
143 mModelValues->insertRow( mModelValues->rowCount(), item );
145 value = stats.
maximum( attribute );
146 valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
147 item =
new QStandardItem( tr(
"Maximum: %1" ).arg( valueString ) );
148 item->setData( value, Qt::UserRole );
149 mModelValues->insertRow( mModelValues->rowCount(), item );
151 value = stats.
mean( attribute );
152 valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
153 item =
new QStandardItem( tr(
"Mean: %1" ).arg( valueString ) );
154 item->setData( value, Qt::UserRole );
155 mModelValues->insertRow( mModelValues->rowCount(), item );
157 value = stats.
stDev( attribute );
158 valueString = std::isnan( value ) ? tr(
"n/a" ) : QString::number( value );
159 item =
new QStandardItem( tr(
"StdDev: %1" ).arg( valueString ) );
160 item->setData( value, Qt::UserRole );
161 mModelValues->insertRow( mModelValues->rowCount(), item );
165void QgsPointCloudQueryBuilder::lstAttributes_doubleClicked(
const QModelIndex &index )
167 mTxtSql->insertText( QStringLiteral(
"%1 " ).arg( mModelAttributes->data( index ).toString() ) );
171void QgsPointCloudQueryBuilder::lstValues_doubleClicked(
const QModelIndex &index )
173 mTxtSql->insertText( QStringLiteral(
"%1 " ).arg( mModelValues->data( index, Qt::UserRole ).toString() ) );
177void QgsPointCloudQueryBuilder::btnEqual_clicked()
179 mTxtSql->insertText( QStringLiteral(
"= " ) );
183void QgsPointCloudQueryBuilder::btnLessThan_clicked()
185 mTxtSql->insertText( QStringLiteral(
"< " ) );
189void QgsPointCloudQueryBuilder::btnGreaterThan_clicked()
191 mTxtSql->insertText( QStringLiteral(
"> " ) );
195void QgsPointCloudQueryBuilder::btnIn_clicked()
197 mTxtSql->insertText( QStringLiteral(
"IN () " ) );
199 mTxtSql->getCursorPosition( &i, &j );
200 mTxtSql->setCursorPosition( i, j - 2 );
204void QgsPointCloudQueryBuilder::btnNotIn_clicked()
206 mTxtSql->insertText( QStringLiteral(
"NOT IN () " ) );
208 mTxtSql->getCursorPosition( &i, &j );
209 mTxtSql->setCursorPosition( i, j - 2 );
213void QgsPointCloudQueryBuilder::btnLessEqual_clicked()
215 mTxtSql->insertText( QStringLiteral(
"<= " ) );
219void QgsPointCloudQueryBuilder::btnGreaterEqual_clicked()
221 mTxtSql->insertText( QStringLiteral(
">= " ) );
225void QgsPointCloudQueryBuilder::btnNotEqual_clicked()
227 mTxtSql->insertText( QStringLiteral(
"!= " ) );
231void QgsPointCloudQueryBuilder::btnAnd_clicked()
233 mTxtSql->insertText( QStringLiteral(
"AND " ) );
237void QgsPointCloudQueryBuilder::btnOr_clicked()
239 mTxtSql->insertText( QStringLiteral(
"OR " ) );
253 mTxtSql->setText( mOrigSubsetString );
258bool QgsPointCloudQueryBuilder::test(
bool skipConfirmation )
260 QgsPointCloudExpression expression( mTxtSql->text() );
261 if ( !expression.isValid() && !mTxtSql->text().isEmpty() )
263 QMessageBox::warning(
this, tr(
"Query Result" ), tr(
"An error occurred while parsing the expression:\n%1" ).arg( expression.parserErrorString() ) );
268 const QSet<QString> attributes = expression.referencedAttributes();
270 for (
const auto &attribute : attributes )
272 if ( mLayer->dataProvider() && !mLayer->dataProvider()->attributes().find( attribute, offset ) )
274 QMessageBox::warning(
this, tr(
"Query Result" ), tr(
"\"%1\" not recognized as an available attribute." ).arg( attribute ) );
279 if ( !skipConfirmation )
280 QMessageBox::information(
this, tr(
"Query Result" ), tr(
"The expression was successfully parsed." ) );
285void QgsPointCloudQueryBuilder::clear()
290void QgsPointCloudQueryBuilder::saveQuery()
296void QgsPointCloudQueryBuilder::loadQuery()
302 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...
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...
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.
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
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.
QgsSubsetStringEditorInterface(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Constructor.