Skip to content
Permalink
Browse files

[processing] Accept geometry values for extent parameters

The bounding box of the geometry is used for the extent

This allows simple expression based values for extent parameters,
utilising Qgis expression's rich geometry handling methods
  • Loading branch information
nyalldawson committed Mar 25, 2020
1 parent 1915a16 commit 9771b15ff0007d098944b3993578447a33c4a2dd
@@ -956,6 +956,12 @@ QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingPara
{
return val.value<QgsRectangle>();
}
if ( val.canConvert< QgsGeometry >() )
{
const QgsGeometry geom = val.value<QgsGeometry>();
if ( !geom.isNull() )
return geom.boundingBox();
}
if ( val.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
@@ -2545,6 +2551,10 @@ bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input
QgsRectangle r = input.value<QgsRectangle>();
return !r.isNull();
}
if ( input.canConvert< QgsGeometry >() )
{
return true;
}
if ( input.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
@@ -2600,14 +2610,23 @@ QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value
qgsDoubleToString( r.xMaximum() ),
qgsDoubleToString( r.yMaximum() ) );
}
if ( value.canConvert< QgsReferencedRectangle >() )
else if ( value.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
qgsDoubleToString( r.yMinimum() ),
qgsDoubleToString( r.xMaximum() ),
qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
}
else if ( value.canConvert< QgsGeometry >() )
{
const QgsGeometry g = value.value<QgsGeometry>();
if ( !g.isNull() )
{
const QString wkt = g.asWkt();
return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
}
}

QVariantMap p;
p.insert( name(), value );
@@ -620,7 +620,8 @@ class CORE_EXPORT QgsProcessingParameterTypeExtent : public QgsProcessingParamet
<< QObject::tr( "QgsProcessingFeatureSourceDefinition: Extent of source is used" )
<< QStringLiteral( "QgsProperty" )
<< QStringLiteral( "QgsRectangle" )
<< QStringLiteral( "QgsReferencedRectangle" );
<< QStringLiteral( "QgsReferencedRectangle" )
<< QStringLiteral( "QgsGeometry: bounding box of geometry is used" );;
}

QStringList acceptedStringValues() const override
@@ -2690,6 +2690,8 @@ void TestQgsProcessing::parameterExtent()
QVERIFY( !def->checkValueIsAcceptable( QgsRectangle() ) );
QVERIFY( def->checkValueIsAcceptable( QgsReferencedRectangle( QgsRectangle( 1, 2, 3, 4 ), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) ) );
QVERIFY( !def->checkValueIsAcceptable( QgsReferencedRectangle( QgsRectangle(), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) ) );
QVERIFY( def->checkValueIsAcceptable( QgsGeometry::fromRect( QgsRectangle( 1, 2, 3, 4 ) ) ) );
QVERIFY( def->checkValueIsAcceptable( QgsGeometry::fromWkt( QStringLiteral( "LineString(10 10, 20 20)" ) ) ) );

// these checks require a context - otherwise we could potentially be referring to a layer source
QVERIFY( def->checkValueIsAcceptable( "1,2,3" ) );
@@ -2866,6 +2868,20 @@ void TestQgsProcessing::parameterExtent()
p.setCrs( QgsCoordinateReferenceSystem( "EPSG:3785" ) );
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:3785" ) );

// QgsGeometry
params.insert( "non_optional", QgsGeometry::fromRect( QgsRectangle( 13, 14, 15, 16 ) ) );
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context );
QGSCOMPARENEAR( ext.xMinimum(), 13, 0.001 );
QGSCOMPARENEAR( ext.xMaximum(), 15, 0.001 );
QGSCOMPARENEAR( ext.yMinimum(), 14, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 16, 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(), 13, 0.001 );
QGSCOMPARENEAR( ext.xMaximum(), 15, 0.001 );
QGSCOMPARENEAR( ext.yMinimum(), 14, 0.001 );
QGSCOMPARENEAR( ext.yMaximum(), 16, 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 );
@@ -2902,6 +2918,7 @@ void TestQgsProcessing::parameterExtent()
QCOMPARE( def->valueAsPythonString( "1,2,3,4 [EPSG:4326]", context ), QStringLiteral( "'1,2,3,4 [EPSG:4326]'" ) );
QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) );
QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) );
QCOMPARE( def->valueAsPythonString( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context ), QStringLiteral( "QgsGeometry.fromWkt('LineString (10 10, 20 20)')" ) );

QString pythonCode = def->asPythonString();
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterExtent('non_optional', '', defaultValue='1,2,3,4')" ) );

0 comments on commit 9771b15

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