Skip to content
Permalink
Browse files

Allow use of Qgs(Referenced)Rectangle for processing extent parameter…

… values

And add a new target CRS argument to parameterAsExtent. If set, and
the source CRS of the rectangle parameter can be determined, then
the returned value will be the rectangle automatically reprojected
to the desired target CRS.
  • Loading branch information
nyalldawson committed Sep 14, 2017
1 parent d8db3ec commit ae8bc04b6c92627e6d17690f479e888b555bfdc0
@@ -662,9 +662,13 @@ class QgsProcessingAlgorithm
:rtype: QgsCoordinateReferenceSystem
%End

QgsRectangle parameterAsExtent( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const;
QgsRectangle parameterAsExtent( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) const;
%Docstring
Evaluates the parameter with matching ``name`` to a rectangular extent.

If ``crs`` is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
reprojected so that it is in the specified ``crs``. In this case the extent of the reproject rectangle will be returned.
:rtype: QgsRectangle
%End

@@ -534,9 +534,13 @@ class QgsProcessingParameters
:rtype: QgsCoordinateReferenceSystem
%End

static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context );
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
%Docstring
Evaluates the parameter with matching ``definition`` to a rectangular extent.

If ``crs`` is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
reprojected so that it is in the specified ``crs``. In this case the extent of the reproject rectangle will be returned.
:rtype: QgsRectangle
%End

@@ -550,9 +550,9 @@ QgsCoordinateReferenceSystem QgsProcessingAlgorithm::parameterAsCrs( const QVari
return QgsProcessingParameters::parameterAsCrs( parameterDefinition( name ), parameters, context );
}

QgsRectangle QgsProcessingAlgorithm::parameterAsExtent( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const
QgsRectangle QgsProcessingAlgorithm::parameterAsExtent( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs ) const
{
return QgsProcessingParameters::parameterAsExtent( parameterDefinition( name ), parameters, context );
return QgsProcessingParameters::parameterAsExtent( parameterDefinition( name ), parameters, context, crs );
}

QgsPointXY QgsProcessingAlgorithm::parameterAsPoint( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const
@@ -648,8 +648,12 @@ class CORE_EXPORT QgsProcessingAlgorithm

/**
* Evaluates the parameter with matching \a name to a rectangular extent.
*
* If \a crs is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
* reprojected so that it is in the specified \a crs. In this case the extent of the reproject rectangle will be returned.
*/
QgsRectangle parameterAsExtent( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const;
QgsRectangle parameterAsExtent( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) const;

/**
* Evaluates the parameter with matching \a name to a point.
@@ -22,6 +22,7 @@
#include "qgsprocessingoutputs.h"
#include "qgssettings.h"
#include "qgsvectorfilewriter.h"
#include "qgsreferencedgeometry.h"
#include <functional>

bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
@@ -484,12 +485,29 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsP
return crs;
}

QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs )
{
if ( !definition )
return QgsRectangle();

QVariant val = parameters.value( definition->name() );

if ( val.canConvert< QgsRectangle >() )
{
return val.value<QgsRectangle>();
}
if ( val.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
{
QgsCoordinateTransform ct( rr.crs(), crs );
return ct.transformBoundingBox( rr );
}
return rr;
}

QString rectText;
if ( val.canConvert<QgsProperty>() )
rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
@@ -1133,6 +1151,17 @@ bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input
return true;
}

if ( input.canConvert< QgsRectangle >() )
{
QgsRectangle r = input.value<QgsRectangle>();
return !r.isNull();
}
if ( input.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
return !r.isNull();
}

if ( input.type() != QVariant::String || input.toString().isEmpty() )
return mFlags & FlagOptional;

@@ -565,8 +565,12 @@ class CORE_EXPORT QgsProcessingParameters

/**
* Evaluates the parameter with matching \a definition to a rectangular extent.
*
* If \a crs is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
* reprojected so that it is in the specified \a crs. In this case the extent of the reproject rectangle will be returned.
*/
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context );
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );

/**
* Evaluates the parameter with matching \a definition to a point.
@@ -32,6 +32,7 @@
#include "qgsvectorfilewriter.h"
#include "qgsexpressioncontext.h"
#include "qgsxmlutils.h"
#include "qgsreferencedgeometry.h"

class DummyAlgorithm : public QgsProcessingAlgorithm
{
@@ -1844,6 +1845,10 @@ void TestQgsProcessing::parameterExtent()
QVERIFY( def->checkValueIsAcceptable( "1,2,3,4" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsRectangle( 1, 2, 3, 4 ) ) );
QVERIFY( !def->checkValueIsAcceptable( QgsRectangle() ) );
QVERIFY( def->checkValueIsAcceptable( QgsReferencedRectangle( QgsRectangle( 1, 2, 3, 4 ), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) ) );
QVERIFY( !def->checkValueIsAcceptable( QgsReferencedRectangle( QgsRectangle(), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) ) );

// these checks require a context - otherwise we could potentially be referring to a layer source
QVERIFY( def->checkValueIsAcceptable( "1,2,3" ) );
@@ -1881,10 +1886,47 @@ void TestQgsProcessing::parameterExtent()
QGSCOMPARENEAR( ext.yMinimum(), 3.3, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );

// with target CRS - should make no difference, because source CRS is unknown
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
QGSCOMPARENEAR( ext.xMinimum(), 1.1, 0.001 );
QGSCOMPARENEAR( ext.xMaximum(), 2.2, 0.001 );
QGSCOMPARENEAR( ext.yMinimum(), 3.3, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );

// nonsense string
params.insert( "non_optional", QString( "i'm not a crs, and nothing you can do will make me one" ) );
QVERIFY( QgsProcessingParameters::parameterAsExtent( def.get(), params, context ).isNull() );

// QgsRectangle
params.insert( "non_optional", QgsRectangle( 11.1, 12.2, 13.3, 14.4 ) );
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context );
QGSCOMPARENEAR( ext.xMinimum(), 11.1, 0.001 );
QGSCOMPARENEAR( ext.xMaximum(), 13.3, 0.001 );
QGSCOMPARENEAR( ext.yMinimum(), 12.2, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 14.4, 0.001 );

// with target CRS - should make no difference, because source CRS is unknown
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
QGSCOMPARENEAR( ext.xMinimum(), 11.1, 0.001 );
QGSCOMPARENEAR( ext.xMaximum(), 13.3, 0.001 );
QGSCOMPARENEAR( ext.yMinimum(), 12.2, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 14.4, 0.001 );

// QgsReferencedRectangle
params.insert( "non_optional", QgsReferencedRectangle( QgsRectangle( 1.1, 2.2, 3.3, 4.4 ), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) );
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context );
QGSCOMPARENEAR( ext.xMinimum(), 1.1, 0.001 );
QGSCOMPARENEAR( ext.xMaximum(), 3.3, 0.001 );
QGSCOMPARENEAR( ext.yMinimum(), 2.2, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );

// with target CRS
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
QGSCOMPARENEAR( ext.xMinimum(), 122451, 100 );
QGSCOMPARENEAR( ext.xMaximum(), 367354, 100 );
QGSCOMPARENEAR( ext.yMinimum(), 244963, 100 );
QGSCOMPARENEAR( ext.yMaximum(), 490287, 100 );

QCOMPARE( def->valueAsPythonString( "1,2,3,4", context ), QStringLiteral( "'1,2,3,4'" ) );
QCOMPARE( def->valueAsPythonString( r1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( r1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) );

0 comments on commit ae8bc04

Please sign in to comment.
You can’t perform that action at this time.