23#include "qgspointcloudexpression.h" 
   33QgsProcessingPointCloudExpressionLineEdit::QgsProcessingPointCloudExpressionLineEdit( QWidget *parent )
 
   37  mLineEdit->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
 
   39  mButton = 
new QToolButton();
 
   40  mButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
 
   42  connect( mButton, &QAbstractButton::clicked, 
this, &QgsProcessingPointCloudExpressionLineEdit::editExpression );
 
   44  QHBoxLayout *layout = 
new QHBoxLayout();
 
   45  layout->setContentsMargins( 0, 0, 0, 0 );
 
   46  layout->addWidget( mLineEdit );
 
   47  layout->addWidget( mButton );
 
   50  setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
 
   51  setFocusProxy( mLineEdit );
 
   52  connect( mLineEdit, &QLineEdit::textChanged, 
this, 
static_cast < void ( QgsProcessingPointCloudExpressionLineEdit::* )( 
const QString & ) 
> ( &QgsProcessingPointCloudExpressionLineEdit::expressionEdited ) );
 
   54  setExpression( expression() );
 
   57QgsProcessingPointCloudExpressionLineEdit::~QgsProcessingPointCloudExpressionLineEdit() = 
default;
 
   69QString QgsProcessingPointCloudExpressionLineEdit::expression()
 const 
   72    return mLineEdit->text();
 
   77void QgsProcessingPointCloudExpressionLineEdit::setExpression( 
const QString &newExpression )
 
   80    mLineEdit->setText( newExpression );
 
   83void QgsProcessingPointCloudExpressionLineEdit::editExpression()
 
   85  const QString currentExpression = expression();
 
   86  QgsProcessingPointCloudExpressionDialog dlg( mLayer );
 
   87  dlg.setExpression( currentExpression );
 
   91    const QString newExpression = dlg.expression();
 
   92    setExpression( newExpression );
 
   96void QgsProcessingPointCloudExpressionLineEdit::expressionEdited()
 
   98  emit expressionChanged( expression() );
 
  101void QgsProcessingPointCloudExpressionLineEdit::expressionEdited( 
const QString &expression )
 
  103  emit expressionChanged( expression );
 
  107QgsProcessingPointCloudExpressionDialog::QgsProcessingPointCloudExpressionDialog( 
QgsPointCloudLayer *layer, 
const QString &startExpression, QWidget *parent )
 
  110  , mInitialText( startExpression )
 
  115  mModelAttributes = 
new QStandardItemModel();
 
  116  mModelValues = 
new QStandardItemModel();
 
  117  lstAttributes->setModel( mModelAttributes );
 
  118  lstValues->setModel( mModelValues );
 
  120  populateAttributes();
 
  122  connect( lstAttributes->selectionModel(), &QItemSelectionModel::currentChanged, 
this, &QgsProcessingPointCloudExpressionDialog::lstAttributes_currentChanged );
 
  123  connect( lstAttributes, &QListView::doubleClicked, 
this, &QgsProcessingPointCloudExpressionDialog::lstAttributes_doubleClicked );
 
  124  connect( lstValues, &QListView::doubleClicked, 
this, &QgsProcessingPointCloudExpressionDialog::lstValues_doubleClicked );
 
  125  connect( btnEqual, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnEqual_clicked );
 
  126  connect( btnLessThan, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnLessThan_clicked );
 
  127  connect( btnGreaterThan, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnGreaterThan_clicked );
 
  128  connect( btnIn, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnIn_clicked );
 
  129  connect( btnNotIn, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnNotIn_clicked );
 
  130  connect( btnLessEqual, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnLessEqual_clicked );
 
  131  connect( btnGreaterEqual, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnGreaterEqual_clicked );
 
  132  connect( btnNotEqual, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnNotEqual_clicked );
 
  133  connect( btnAnd, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnAnd_clicked );
 
  134  connect( btnOr, &QPushButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::btnOr_clicked );
 
  136  QPushButton *pbn = 
new QPushButton( tr( 
"&Test" ) );
 
  137  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
  138  connect( pbn, &QAbstractButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::test );
 
  140  pbn = 
new QPushButton( tr( 
"&Clear" ) );
 
  141  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
  142  connect( pbn, &QAbstractButton::clicked, 
this, &QgsProcessingPointCloudExpressionDialog::clear );
 
  144  mTxtSql->setText( mInitialText );
 
  147void QgsProcessingPointCloudExpressionDialog::setExpression( 
const QString &text )
 
  149  mTxtSql->setText( text );
 
  152QString QgsProcessingPointCloudExpressionDialog::expression()
 
  154  return mTxtSql->text();
 
  157void QgsProcessingPointCloudExpressionDialog::populateAttributes()
 
  164  const QgsFields &fields = mLayer->dataProvider()->attributes().toFields();
 
  165  mTxtSql->setFields( fields );
 
  166  for ( 
int idx = 0; idx < fields.
count(); ++idx )
 
  169    mModelAttributes->insertRow( mModelAttributes->rowCount(), myItem );
 
  173void QgsProcessingPointCloudExpressionDialog::lstAttributes_currentChanged( 
const QModelIndex ¤t, 
const QModelIndex &previous )
 
  177  mModelValues->clear();
 
  178  const QString attribute = current.data().toString();
 
  179  if ( attribute.compare( QLatin1String( 
"Classification" ), Qt::CaseInsensitive ) == 0 )
 
  182    for ( 
int i = 0; i <= 18; ++i )
 
  184      QStandardItem *item = 
new QStandardItem( QString( 
"%1: %2" ).arg( i ).arg( codes.value( i ) ) );
 
  185      item->setData( i, Qt::UserRole );
 
  186      mModelValues->insertRow( mModelValues->rowCount(), item );
 
  192    double value = stats.
minimum( attribute );
 
  193    QString valueString = std::isnan( value ) ? tr( 
"n/a" ) : QString::number( value );
 
  194    QStandardItem *item = 
new QStandardItem( tr( 
"Minimum: %1" ).arg( valueString ) );
 
  195    item->setData( value, Qt::UserRole );
 
  196    mModelValues->insertRow( mModelValues->rowCount(), item );
 
  198    value = stats.
maximum( attribute );
 
  199    valueString = std::isnan( value ) ? tr( 
"n/a" ) : QString::number( value );
 
  200    item = 
new QStandardItem( tr( 
"Maximum: %1" ).arg( valueString ) );
 
  201    item->setData( value, Qt::UserRole );
 
  202    mModelValues->insertRow( mModelValues->rowCount(), item );
 
  204    value = stats.
mean( attribute );
 
  205    valueString = std::isnan( value ) ? tr( 
"n/a" ) : QString::number( value );
 
  206    item = 
new QStandardItem( tr( 
"Mean: %1" ).arg( valueString ) );
 
  207    item->setData( value, Qt::UserRole );
 
  208    mModelValues->insertRow( mModelValues->rowCount(), item );
 
  210    value = stats.
stDev( attribute );
 
  211    valueString = std::isnan( value ) ? tr( 
"n/a" ) : QString::number( value );
 
  212    item = 
new QStandardItem( tr( 
"StdDev: %1" ).arg( valueString ) );
 
  213    item->setData( value, Qt::UserRole );
 
  214    mModelValues->insertRow( mModelValues->rowCount(), item );
 
  218void QgsProcessingPointCloudExpressionDialog::lstAttributes_doubleClicked( 
const QModelIndex &index )
 
  220  mTxtSql->insertText( QStringLiteral( 
"%1 " ).arg( mModelAttributes->data( index ).toString() ) );
 
  224void QgsProcessingPointCloudExpressionDialog::lstValues_doubleClicked( 
const QModelIndex &index )
 
  226  mTxtSql->insertText( QStringLiteral( 
"%1 " ).arg( mModelValues->data( index, Qt::UserRole ).toString() ) );
 
  230void QgsProcessingPointCloudExpressionDialog::btnEqual_clicked()
 
  232  mTxtSql->insertText( QStringLiteral( 
"= " ) );
 
  236void QgsProcessingPointCloudExpressionDialog::btnLessThan_clicked()
 
  238  mTxtSql->insertText( QStringLiteral( 
"< " ) );
 
  242void QgsProcessingPointCloudExpressionDialog::btnGreaterThan_clicked()
 
  244  mTxtSql->insertText( QStringLiteral( 
"> " ) );
 
  248void QgsProcessingPointCloudExpressionDialog::btnIn_clicked()
 
  250  mTxtSql->insertText( QStringLiteral( 
"IN () " ) );
 
  252  mTxtSql->getCursorPosition( &i, &j );
 
  253  mTxtSql->setCursorPosition( i, j - 2 );
 
  257void QgsProcessingPointCloudExpressionDialog::btnNotIn_clicked()
 
  259  mTxtSql->insertText( QStringLiteral( 
"NOT IN () " ) );
 
  261  mTxtSql->getCursorPosition( &i, &j );
 
  262  mTxtSql->setCursorPosition( i, j - 2 );
 
  266void QgsProcessingPointCloudExpressionDialog::btnLessEqual_clicked()
 
  268  mTxtSql->insertText( QStringLiteral( 
"<= " ) );
 
  272void QgsProcessingPointCloudExpressionDialog::btnGreaterEqual_clicked()
 
  274  mTxtSql->insertText( QStringLiteral( 
">= " ) );
 
  278void QgsProcessingPointCloudExpressionDialog::btnNotEqual_clicked()
 
  280  mTxtSql->insertText( QStringLiteral( 
"!= " ) );
 
  284void QgsProcessingPointCloudExpressionDialog::btnAnd_clicked()
 
  286  mTxtSql->insertText( QStringLiteral( 
"AND " ) );
 
  290void QgsProcessingPointCloudExpressionDialog::btnOr_clicked()
 
  292  mTxtSql->insertText( QStringLiteral( 
"OR " ) );
 
  296void QgsProcessingPointCloudExpressionDialog::test()
 
  298  QgsPointCloudExpression expression( mTxtSql->text() );
 
  300  if ( !expression.isValid() && !mTxtSql->text().isEmpty() )
 
  302    QMessageBox::warning( 
this,
 
  303                          tr( 
"Query Result" ),
 
  304                          tr( 
"An error occurred while parsing the expression:\n%1" ).arg( expression.parserErrorString() ) );
 
  308    const QSet<QString> attributes = expression.referencedAttributes();
 
  310    for ( 
const auto &attribute : attributes )
 
  312      if ( mLayer && mLayer->dataProvider() &&
 
  313           !mLayer->dataProvider()->attributes().find( attribute, offset ) )
 
  315        QMessageBox::warning( 
this,
 
  316                              tr( 
"Query Result" ),
 
  317                              tr( 
"\"%1\" not recognized as an available attribute." ).arg( attribute ) );
 
  321    QMessageBox::information( 
this,
 
  322                              tr( 
"Query Result" ),
 
  323                              tr( 
"The expression was successfully parsed." ) );
 
  327void QgsProcessingPointCloudExpressionDialog::clear()
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
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.
 
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
 
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
 
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.
 
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 ...