Skip to content

Commit

Permalink
add filter algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy authored and wonder-sk committed Mar 22, 2023
1 parent 4b94f2b commit 8dc5c2a
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -431,6 +431,7 @@ if (WITH_PDAL)
processing/pdal/qgsalgorithmpdalexportraster.cpp
processing/pdal/qgsalgorithmpdalexportrastertin.cpp
processing/pdal/qgsalgorithmpdalexportvector.cpp
processing/pdal/qgsalgorithmpdalfilter.cpp
processing/pdal/qgsalgorithmpdalfixprojection.cpp
processing/pdal/qgsalgorithmpdalinformation.cpp
processing/pdal/qgsalgorithmpdalmerge.cpp
Expand Down
88 changes: 88 additions & 0 deletions src/analysis/processing/pdal/qgsalgorithmpdalfilter.cpp
@@ -0,0 +1,88 @@
/***************************************************************************
qgsalgorithmpdalfilter.cpp
---------------------
begin : March 2023
copyright : (C) 2023 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsalgorithmpdalfilter.h"

#include "qgsrunprocess.h"
#include "qgspointcloudlayer.h"

///@cond PRIVATE

QString QgsPdalFilterAlgorithm::name() const
{
return QStringLiteral( "filter" );
}

QString QgsPdalFilterAlgorithm::displayName() const
{
return QObject::tr( "Filter" );
}

QString QgsPdalFilterAlgorithm::group() const
{
return QObject::tr( "Point cloud extraction" );
}

QString QgsPdalFilterAlgorithm::groupId() const
{
return QStringLiteral( "pointcloudextraction" );
}

QStringList QgsPdalFilterAlgorithm::tags() const
{
return QObject::tr( "filter,subset,extract,dimension,attribute" ).split( ',' );
}

QString QgsPdalFilterAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm extracts point from the input point cloud which match PDAL expression." );
}

QgsPdalFilterAlgorithm *QgsPdalFilterAlgorithm::createInstance() const
{
return new QgsPdalFilterAlgorithm();
}

void QgsPdalFilterAlgorithm::initAlgorithm( const QVariantMap & )
{
addParameter( new QgsProcessingParameterPointCloudLayer( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterString( QStringLiteral( "FILTER" ), QObject::tr( "Filter expression" ) ) );
addParameter( new QgsProcessingParameterPointCloudDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Output" ) ) );
}

QStringList QgsPdalFilterAlgorithm::createArgumentLists( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
Q_UNUSED( feedback );

QgsPointCloudLayer *layer = parameterAsPointCloudLayer( parameters, QStringLiteral( "INPUT" ), context );
if ( !layer )
throw QgsProcessingException( invalidPointCloudError( parameters, QStringLiteral( "INPUT" ) ) );

const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( "OUTPUT" ), context );
setOutputValue( QStringLiteral( "OUTPUT" ), outputFile );

QStringList args = { QStringLiteral( "translate" ),
QStringLiteral( "--input=%1" ).arg( layer->source() ),
QStringLiteral( "--filter=%1" ).arg( parameterAsString( parameters, QStringLiteral( "FILTER" ), context ) ),
QStringLiteral( "--output=%1" ).arg( outputFile )
};

addThreadsParameter( args );
return args;
}

///@endcond
54 changes: 54 additions & 0 deletions src/analysis/processing/pdal/qgsalgorithmpdalfilter.h
@@ -0,0 +1,54 @@
/***************************************************************************
qgsalgorithmpdalfilter.h
---------------------
begin : March 2023
copyright : (C) 2023 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSALGORITHMPDALFILTER_H
#define QGSALGORITHMPDALFILTER_H

#define SIP_NO_FILE

#include "qgis_sip.h"
#include "qgspdalalgorithmbase.h"

///@cond PRIVATE

/**
* Native point cloud filter algorithm.
*/
class QgsPdalFilterAlgorithm : public QgsPdalAlgorithmBase
{

public:

QgsPdalFilterAlgorithm() = default;
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
QString name() const override;
QString displayName() const override;
QString group() const override;
QString groupId() const override;
QStringList tags() const override;
QString shortHelpString() const override;
QgsPdalFilterAlgorithm *createInstance() const override SIP_FACTORY;

QStringList createArgumentLists( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;

friend class TestQgsProcessingPdalAlgs;
};

///@endcond PRIVATE

#endif // QGSALGORITHMPDALFILTER_H
2 changes: 2 additions & 0 deletions src/analysis/processing/pdal/qgspdalalgorithms.cpp
Expand Up @@ -27,6 +27,7 @@
#include "qgsalgorithmpdalexportraster.h"
#include "qgsalgorithmpdalexportrastertin.h"
#include "qgsalgorithmpdalexportvector.h"
#include "qgsalgorithmpdalfilter.h"
#include "qgsalgorithmpdalfixprojection.h"
#include "qgsalgorithmpdalinformation.h"
#include "qgsalgorithmpdalmerge.h"
Expand Down Expand Up @@ -97,6 +98,7 @@ void QgsPdalAlgorithms::loadAlgorithms()
addAlgorithm( new QgsPdalExportRasterAlgorithm() );
addAlgorithm( new QgsPdalExportRasterTinAlgorithm() );
addAlgorithm( new QgsPdalExportVectorAlgorithm() );
addAlgorithm( new QgsPdalFilterAlgorithm() );
addAlgorithm( new QgsPdalFixProjectionAlgorithm() );
addAlgorithm( new QgsPdalInformationAlgorithm() );
addAlgorithm( new QgsPdalMergeAlgorithm() );
Expand Down
35 changes: 35 additions & 0 deletions tests/src/analysis/testqgsprocessingpdalalgs.cpp
Expand Up @@ -42,6 +42,7 @@ class TestQgsProcessingPdalAlgs: public QObject
void exportRaster();
void exportRasterTin();
void exportVector();
void filter();
void fixProjection();
void info();
void merge();
Expand Down Expand Up @@ -772,5 +773,39 @@ void TestQgsProcessingPdalAlgs::clip()
);
}

void TestQgsProcessingPdalAlgs::filter()
{
QgsPdalAlgorithmBase *alg = const_cast<QgsPdalAlgorithmBase *>( static_cast< const QgsPdalAlgorithmBase * >( QgsApplication::processingRegistry()->algorithmById( QStringLiteral( "pdal:filter" ) ) ) );

std::unique_ptr< QgsProcessingContext > context = std::make_unique< QgsProcessingContext >();
context->setProject( QgsProject::instance() );

QgsProcessingFeedback feedback;

const QString outputPointCloud = QDir::tempPath() + "/filtered.laz";

QVariantMap parameters;
parameters.insert( QStringLiteral( "INPUT" ), mPointCloudLayerPath );
parameters.insert( QStringLiteral( "FILTER" ), QStringLiteral( "Classification == 7 || Classification == 8" ) );
parameters.insert( QStringLiteral( "OUTPUT" ), outputPointCloud );

QStringList args = alg->createArgumentLists( parameters, *context, &feedback );
QCOMPARE( args, QStringList() << QStringLiteral( "translate" )
<< QStringLiteral( "--input=%1" ).arg( mPointCloudLayerPath )
<< QStringLiteral( "--filter=Classification == 7 || Classification == 8" )
<< QStringLiteral( "--output=%1" ).arg( outputPointCloud )
);

// set max threads to 2, a --threads argument should be added
QgsSettings().setValue( QStringLiteral( "/Processing/Configuration/MAX_THREADS" ), 2 );
args = alg->createArgumentLists( parameters, *context, &feedback );
QCOMPARE( args, QStringList() << QStringLiteral( "translate" )
<< QStringLiteral( "--input=%1" ).arg( mPointCloudLayerPath )
<< QStringLiteral( "--filter=Classification == 7 || Classification == 8" )
<< QStringLiteral( "--output=%1" ).arg( outputPointCloud )
<< QStringLiteral( "--threads=2" )
);
}

QGSTEST_MAIN( TestQgsProcessingPdalAlgs )
#include "testqgsprocessingpdalalgs.moc"

0 comments on commit 8dc5c2a

Please sign in to comment.