Skip to content

Commit fb08b0a

Browse files
committedSep 24, 2017
[processing] Allow encoding crs into text definitions of extents
1 parent ec44e60 commit fb08b0a

File tree

2 files changed

+127
-18
lines changed

2 files changed

+127
-18
lines changed
 

‎src/core/processing/qgsprocessingparameters.cpp

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -524,19 +524,36 @@ QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingPara
524524
if ( rectText.isEmpty() )
525525
return QgsRectangle();
526526

527-
QStringList parts = rectText.split( ',' );
528-
if ( parts.count() == 4 )
527+
QRegularExpression rx( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" );
528+
QRegularExpressionMatch match = rx.match( rectText );
529+
if ( match.hasMatch() )
529530
{
530531
bool xMinOk = false;
531-
double xMin = parts.at( 0 ).toDouble( &xMinOk );
532+
double xMin = match.captured( 1 ).toDouble( &xMinOk );
532533
bool xMaxOk = false;
533-
double xMax = parts.at( 1 ).toDouble( &xMaxOk );
534+
double xMax = match.captured( 2 ).toDouble( &xMaxOk );
534535
bool yMinOk = false;
535-
double yMin = parts.at( 2 ).toDouble( &yMinOk );
536+
double yMin = match.captured( 3 ).toDouble( &yMinOk );
536537
bool yMaxOk = false;
537-
double yMax = parts.at( 3 ).toDouble( &yMaxOk );
538+
double yMax = match.captured( 4 ).toDouble( &yMaxOk );
538539
if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
539-
return QgsRectangle( xMin, yMin, xMax, yMax );
540+
{
541+
QgsRectangle rect( xMin, yMin, xMax, yMax );
542+
QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
543+
if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
544+
{
545+
QgsCoordinateTransform ct( rectCrs, crs );
546+
try
547+
{
548+
return ct.transformBoundingBox( rect );
549+
}
550+
catch ( QgsCsException & )
551+
{
552+
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
553+
}
554+
}
555+
return rect;
556+
}
540557
}
541558

542559
// try as layer extent
@@ -573,6 +590,49 @@ QgsGeometry QgsProcessingParameters::parameterAsExtentGeometry( const QgsProcess
573590
}
574591
}
575592

593+
QString rectText;
594+
if ( val.canConvert<QgsProperty>() )
595+
rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
596+
else
597+
rectText = val.toString();
598+
599+
if ( !rectText.isEmpty() )
600+
{
601+
QRegularExpression rx( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" );
602+
QRegularExpressionMatch match = rx.match( rectText );
603+
if ( match.hasMatch() )
604+
{
605+
bool xMinOk = false;
606+
double xMin = match.captured( 1 ).toDouble( &xMinOk );
607+
bool xMaxOk = false;
608+
double xMax = match.captured( 2 ).toDouble( &xMaxOk );
609+
bool yMinOk = false;
610+
double yMin = match.captured( 3 ).toDouble( &yMinOk );
611+
bool yMaxOk = false;
612+
double yMax = match.captured( 4 ).toDouble( &yMaxOk );
613+
if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
614+
{
615+
QgsRectangle rect( xMin, yMin, xMax, yMax );
616+
QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
617+
QgsGeometry g = QgsGeometry::fromRect( rect );
618+
if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
619+
{
620+
g = g.densifyByCount( 20 );
621+
QgsCoordinateTransform ct( rectCrs, crs );
622+
try
623+
{
624+
g.transform( ct );
625+
}
626+
catch ( QgsCsException & )
627+
{
628+
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
629+
}
630+
return g;
631+
}
632+
}
633+
}
634+
}
635+
576636
return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
577637
}
578638

@@ -589,6 +649,17 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( cons
589649
}
590650
}
591651

652+
QRegularExpression rx( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" );
653+
654+
QString valueAsString = parameterAsString( definition, parameters, context );
655+
QRegularExpressionMatch match = rx.match( valueAsString );
656+
if ( match.hasMatch() )
657+
{
658+
QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
659+
if ( crs.isValid() )
660+
return crs;
661+
}
662+
592663
if ( context.project() )
593664
return context.project()->crs();
594665
else
@@ -1301,17 +1372,18 @@ bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input
13011372
return true;
13021373
}
13031374

1304-
QStringList parts = input.toString().split( ',' );
1305-
if ( parts.count() == 4 )
1375+
QRegularExpression rx( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" );
1376+
QRegularExpressionMatch match = rx.match( input.toString() );
1377+
if ( match.hasMatch() )
13061378
{
13071379
bool xMinOk = false;
1308-
( void )parts.at( 0 ).toDouble( &xMinOk );
1380+
( void )match.captured( 1 ).toDouble( &xMinOk );
13091381
bool xMaxOk = false;
1310-
( void )parts.at( 1 ).toDouble( &xMaxOk );
1382+
( void )match.captured( 2 ).toDouble( &xMaxOk );
13111383
bool yMinOk = false;
1312-
( void )parts.at( 2 ).toDouble( &yMinOk );
1384+
( void )match.captured( 3 ).toDouble( &yMinOk );
13131385
bool yMaxOk = false;
1314-
( void )parts.at( 3 ).toDouble( &yMaxOk );
1386+
( void )match.captured( 4 ).toDouble( &yMaxOk );
13151387
if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
13161388
return true;
13171389
}
@@ -1328,15 +1400,15 @@ QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value
13281400
if ( value.canConvert< QgsRectangle >() )
13291401
{
13301402
QgsRectangle r = value.value<QgsRectangle>();
1331-
return QStringLiteral( "QgsRectangle( %1, %2, %3, %4 )" ).arg( qgsDoubleToString( r.xMinimum() ),
1403+
return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
13321404
qgsDoubleToString( r.yMinimum() ),
13331405
qgsDoubleToString( r.xMaximum() ),
13341406
qgsDoubleToString( r.yMaximum() ) );
13351407
}
13361408
if ( value.canConvert< QgsReferencedRectangle >() )
13371409
{
13381410
QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
1339-
return QStringLiteral( "QgsReferencedRectangle( QgsRectangle( %1, %2, %3, %4 ), QgsCoordinateReferenceSystem( '%5' ) )" ).arg( qgsDoubleToString( r.xMinimum() ),
1411+
return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
13401412
qgsDoubleToString( r.yMinimum() ),
13411413
qgsDoubleToString( r.xMaximum() ),
13421414
qgsDoubleToString( r.yMaximum() ), r.crs().authid() );

‎tests/src/core/testqgsprocessing.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,21 @@ void TestQgsProcessing::parameterExtent()
18441844
QVERIFY( !def->checkValueIsAcceptable( true ) );
18451845
QVERIFY( !def->checkValueIsAcceptable( 5 ) );
18461846
QVERIFY( def->checkValueIsAcceptable( "1,2,3,4" ) );
1847+
QVERIFY( def->checkValueIsAcceptable( " 1, 2 ,3 , 4 " ) );
1848+
QVERIFY( def->checkValueIsAcceptable( " 1, 2 ,3 , 4 ", &context ) );
1849+
QVERIFY( def->checkValueIsAcceptable( "-1.1,2,-3,-4" ) );
1850+
QVERIFY( def->checkValueIsAcceptable( "-1.1,2,-3,-4", &context ) );
1851+
QVERIFY( def->checkValueIsAcceptable( "-1.1,-2.2,-3.3,-4.4" ) );
1852+
QVERIFY( def->checkValueIsAcceptable( "-1.1,-2.2,-3.3,-4.4", &context ) );
1853+
QVERIFY( def->checkValueIsAcceptable( "1.1,2,3,4.4[EPSG:4326]" ) );
1854+
QVERIFY( def->checkValueIsAcceptable( "1.1,2,3,4.4[EPSG:4326]", &context ) );
1855+
QVERIFY( def->checkValueIsAcceptable( "1.1,2,3,4.4 [EPSG:4326]" ) );
1856+
QVERIFY( def->checkValueIsAcceptable( "1.1,2,3,4.4 [EPSG:4326]", &context ) );
1857+
QVERIFY( def->checkValueIsAcceptable( " -1.1, -2, -3, -4.4 [EPSG:4326] " ) );
1858+
QVERIFY( def->checkValueIsAcceptable( " -1.1, -2, -3, -4.4 [EPSG:4326] ", &context ) );
1859+
QVERIFY( def->checkValueIsAcceptable( "121774.38859446358,948723.6921024882,-264546.200347173,492749.6672022904 [EPSG:3785]" ) );
1860+
QVERIFY( def->checkValueIsAcceptable( "121774.38859446358,948723.6921024882,-264546.200347173,492749.6672022904 [EPSG:3785]", &context ) );
1861+
18471862
QVERIFY( !def->checkValueIsAcceptable( "" ) );
18481863
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
18491864
QVERIFY( def->checkValueIsAcceptable( QgsRectangle( 1, 2, 3, 4 ) ) );
@@ -1894,6 +1909,27 @@ void TestQgsProcessing::parameterExtent()
18941909
QGSCOMPARENEAR( ext.yMinimum(), 3.3, 0.001 );
18951910
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );
18961911

1912+
// with crs in string
1913+
params.insert( "non_optional", QString( "1.1,3.3,2.2,4.4 [EPSG:4326]" ) );
1914+
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:4326" ) );
1915+
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context );
1916+
QGSCOMPARENEAR( ext.xMinimum(), 1.1, 0.001 );
1917+
QGSCOMPARENEAR( ext.xMaximum(), 3.3, 0.001 );
1918+
QGSCOMPARENEAR( ext.yMinimum(), 2.2, 0.001 );
1919+
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );
1920+
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
1921+
QGSCOMPARENEAR( ext.xMinimum(), 122451, 100 );
1922+
QGSCOMPARENEAR( ext.xMaximum(), 367354, 100 );
1923+
QGSCOMPARENEAR( ext.yMinimum(), 244963, 100 );
1924+
QGSCOMPARENEAR( ext.yMaximum(), 490287, 100 );
1925+
QgsGeometry gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
1926+
QCOMPARE( gExt.geometry()->vertexCount(), 85 );
1927+
ext = gExt.boundingBox();
1928+
QGSCOMPARENEAR( ext.xMinimum(), 122451, 100 );
1929+
QGSCOMPARENEAR( ext.xMaximum(), 367354, 100 );
1930+
QGSCOMPARENEAR( ext.yMinimum(), 244963, 100 );
1931+
QGSCOMPARENEAR( ext.yMaximum(), 490287, 100 );
1932+
18971933
// nonsense string
18981934
params.insert( "non_optional", QString( "i'm not a crs, and nothing you can do will make me one" ) );
18991935
QVERIFY( QgsProcessingParameters::parameterAsExtent( def.get(), params, context ).isNull() );
@@ -1913,7 +1949,7 @@ void TestQgsProcessing::parameterExtent()
19131949
QGSCOMPARENEAR( ext.yMinimum(), 12.2, 0.001 );
19141950
QGSCOMPARENEAR( ext.yMaximum(), 14.4, 0.001 );
19151951

1916-
QgsGeometry gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
1952+
gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
19171953
QCOMPARE( gExt.exportToWkt( 1 ), QStringLiteral( "Polygon ((11.1 12.2, 13.3 12.2, 13.3 14.4, 11.1 14.4, 11.1 12.2))" ) );
19181954

19191955
p.setCrs( QgsCoordinateReferenceSystem( "EPSG:3785" ) );
@@ -1949,8 +1985,9 @@ void TestQgsProcessing::parameterExtent()
19491985
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( r1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) );
19501986
QCOMPARE( def->valueAsPythonString( raster2, context ), QString( "'" ) + testDataDir + QStringLiteral( "landsat.tif'" ) );
19511987
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) );
1952-
QCOMPARE( def->valueAsPythonString( QgsRectangle( 11, 12, 13, 14 ), context ), QStringLiteral( "QgsRectangle( 11, 12, 13, 14 )" ) );
1953-
QCOMPARE( def->valueAsPythonString( QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QStringLiteral( "QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( 'EPSG:4326' ) )" ) );
1988+
QCOMPARE( def->valueAsPythonString( QgsRectangle( 11, 12, 13, 14 ), context ), QStringLiteral( "'11, 13, 12, 14'" ) );
1989+
QCOMPARE( def->valueAsPythonString( QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QStringLiteral( "'11, 13, 12, 14 [EPSG:4326]'" ) );
1990+
QCOMPARE( def->valueAsPythonString( "1,2,3,4 [EPSG:4326]", context ), QStringLiteral( "'1,2,3,4 [EPSG:4326]'" ) );
19541991

19551992
QString code = def->asScriptCode();
19561993
QCOMPARE( code, QStringLiteral( "##non_optional=extent 1,2,3,4" ) );

0 commit comments

Comments
 (0)
Please sign in to comment.