Skip to content

Commit

Permalink
add clip 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 3a8a7cb commit f2d8bab
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -425,6 +425,7 @@ if (WITH_PDAL)

processing/pdal/qgsalgorithmpdalboundary.cpp
processing/pdal/qgsalgorithmpdalbuildvpc.cpp
processing/pdal/qgsalgorithmpdalclip.cpp
processing/pdal/qgsalgorithmpdalconvertformat.cpp
processing/pdal/qgsalgorithmpdaldensity.cpp
processing/pdal/qgsalgorithmpdalexportraster.cpp
Expand Down
94 changes: 94 additions & 0 deletions src/analysis/processing/pdal/qgsalgorithmpdalclip.cpp
@@ -0,0 +1,94 @@
/***************************************************************************
qgsalgorithmpdalclip.cpp
---------------------
begin : February 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 "qgsalgorithmpdalclip.h"

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

///@cond PRIVATE

QString QgsPdalClipAlgorithm::name() const
{
return QStringLiteral( "clip" );
}

QString QgsPdalClipAlgorithm::displayName() const
{
return QObject::tr( "Clip" );
}

QString QgsPdalClipAlgorithm::group() const
{
return QObject::tr( "Point cloud data management" );
}

QString QgsPdalClipAlgorithm::groupId() const
{
return QStringLiteral( "pointclouddatamanagement" );
}

QStringList QgsPdalClipAlgorithm::tags() const
{
return QObject::tr( "clip,intersect,intersection,mask" ).split( ',' );
}

QString QgsPdalClipAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm clips point cloud with clipping polygons, the resulting point cloud contains points that are inside these polygons." );
}

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

void QgsPdalClipAlgorithm::initAlgorithm( const QVariantMap & )
{
addParameter( new QgsProcessingParameterPointCloudLayer( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterVectorLayer( QStringLiteral( "OVERLAY" ), QObject::tr( "Clipping polygons" ), QList< int >() << QgsProcessing::TypeVectorPolygon ) );
addParameter( new QgsProcessingParameterPointCloudDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Clipped point cloud" ) ) );
}

QStringList QgsPdalClipAlgorithm::createArgumentLists( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
QgsPointCloudLayer *layer = parameterAsPointCloudLayer( parameters, QStringLiteral( "INPUT" ), context );
if ( !layer )
throw QgsProcessingException( invalidPointCloudError( parameters, QStringLiteral( "INPUT" ) ) );

QString overlayPath = parameterAsCompatibleSourceLayerPath( parameters,
QStringLiteral( "OVERLAY" ),
context,
QgsVectorFileWriter::supportedFormatExtensions(),
QgsVectorFileWriter::supportedFormatExtensions()[0],
feedback );

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

QStringList args = { QStringLiteral( "clip" ),
QStringLiteral( "--input=%1" ).arg( layer->source() ),
QStringLiteral( "--output=%1" ).arg( outputFile ),
QStringLiteral( "--polygon=%1" ).arg( overlayPath )
};

addThreadsParameter( args );
return args;
}

///@endcond
54 changes: 54 additions & 0 deletions src/analysis/processing/pdal/qgsalgorithmpdalclip.h
@@ -0,0 +1,54 @@
/***************************************************************************
qgsalgorithmpdalclip.h
---------------------
begin : February 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 QGSALGORITHMPDALCLIP_H
#define QGSALGORITHMPDALCLIP_H

#define SIP_NO_FILE

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

///@cond PRIVATE

/**
* Native point cloud clip algorithm.
*/
class QgsPdalClipAlgorithm : public QgsPdalAlgorithmBase
{

public:

QgsPdalClipAlgorithm() = 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;
QgsPdalClipAlgorithm *createInstance() const override SIP_FACTORY;

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

friend class TestQgsProcessingPdalAlgs;
};

///@endcond PRIVATE

#endif // QGSALGORITHMPDALCLIP_H
2 changes: 2 additions & 0 deletions src/analysis/processing/pdal/qgspdalalgorithms.cpp
Expand Up @@ -21,6 +21,7 @@

#include "qgsalgorithmpdalboundary.h"
#include "qgsalgorithmpdalbuildvpc.h"
#include "qgsalgorithmpdalclip.h"
#include "qgsalgorithmpdalconvertformat.h"
#include "qgsalgorithmpdaldensity.h"
#include "qgsalgorithmpdalexportraster.h"
Expand Down Expand Up @@ -90,6 +91,7 @@ void QgsPdalAlgorithms::loadAlgorithms()

addAlgorithm( new QgsPdalBoundaryAlgorithm() );
addAlgorithm( new QgsPdalBuildVpcAlgorithm() );
addAlgorithm( new QgsPdalClipAlgorithm() );
addAlgorithm( new QgsPdalConvertFormatAlgorithm() );
addAlgorithm( new QgsPdalDensityAlgorithm() );
addAlgorithm( new QgsPdalExportRasterAlgorithm() );
Expand Down
36 changes: 36 additions & 0 deletions tests/src/analysis/testqgsprocessingpdalalgs.cpp
Expand Up @@ -36,6 +36,7 @@ class TestQgsProcessingPdalAlgs: public QObject

void boundary();
void buildVpc();
void clip();
void convertFormat();
void density();
void exportRaster();
Expand Down Expand Up @@ -742,5 +743,40 @@ void TestQgsProcessingPdalAlgs::buildVpc()
);
}

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

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

QgsProcessingFeedback feedback;

const QString outputFile = QDir::tempPath() + "/clipped.las";
const QString polygonsFile = QString( TEST_DATA_DIR ) + "/polys.shp";

QVariantMap parameters;
parameters.insert( QStringLiteral( "INPUT" ), mPointCloudLayerPath );
parameters.insert( QStringLiteral( "OVERLAY" ), polygonsFile );
parameters.insert( QStringLiteral( "OUTPUT" ), outputFile );

QStringList args = alg->createArgumentLists( parameters, *context, &feedback );
QCOMPARE( args, QStringList() << QStringLiteral( "clip" )
<< QStringLiteral( "--input=%1" ).arg( mPointCloudLayerPath )
<< QStringLiteral( "--output=%1" ).arg( outputFile )
<< QStringLiteral( "--polygon=%1" ).arg( polygonsFile )
);

// 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( "clip" )
<< QStringLiteral( "--input=%1" ).arg( mPointCloudLayerPath )
<< QStringLiteral( "--output=%1" ).arg( outputFile )
<< QStringLiteral( "--polygon=%1" ).arg( polygonsFile )
<< QStringLiteral( "--threads=2" )
);
}

QGSTEST_MAIN( TestQgsProcessingPdalAlgs )
#include "testqgsprocessingpdalalgs.moc"

0 comments on commit f2d8bab

Please sign in to comment.