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.
 
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.