mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
[FEATURE] Add make_line expression function variant which accepts
an array of points Allows creation of lines from variable numbers of points, and from sequences from aggregates/dynamically generated sequences Fixes #31268
This commit is contained in:
parent
36173d7c40
commit
80d77b4788
@ -2,12 +2,22 @@
|
||||
"name": "make_line",
|
||||
"type": "function",
|
||||
"description": "Creates a line geometry from a series of point geometries.",
|
||||
"variableLenArguments": true,
|
||||
"arguments": [
|
||||
"variants": [
|
||||
{ "variant": "List of arguments variant",
|
||||
"variant_description": "Line vertices are specified as seperate arguments to the function.",
|
||||
"variableLenArguments": true,
|
||||
"arguments": [
|
||||
{"arg":"point1", "syntaxOnly": true},
|
||||
{"arg":"point2", "syntaxOnly": true},
|
||||
{"arg":"point", "descOnly": true, "description":"a point geometry"}],
|
||||
{"arg":"point", "descOnly": true, "description":"a point geometry (or array of points)"}],
|
||||
"examples": [ { "expression":"geom_to_wkt(make_line(make_point(2,4),make_point(3,5)))", "returns":"'LineString (2 4, 3 5)'"},
|
||||
{ "expression":"geom_to_wkt(make_line(make_point(2,4),make_point(3,5),make_point(9,7)))", "returns":"'LineString (2 4, 3 5, 9 7)'"}
|
||||
]
|
||||
]},
|
||||
{
|
||||
"variant": "Array variant",
|
||||
"variant_description": "Line vertices are specified as an array of points.",
|
||||
"arguments": [ {"arg":"array","description":"array of points"}],
|
||||
"examples": [ { "expression":"geom_to_wkt(make_line(array(make_point(2,4),make_point(3,5),make_point(9,7))))", "returns":"'LineString (2 4, 3 5, 9 7)'"} ]
|
||||
}]
|
||||
|
||||
}
|
||||
|
@ -2425,31 +2425,49 @@ static QVariant fcnMakePointM( const QVariantList &values, const QgsExpressionCo
|
||||
|
||||
static QVariant fcnMakeLine( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
if ( values.count() < 2 )
|
||||
if ( values.empty() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QgsLineString *lineString = new QgsLineString();
|
||||
lineString->clear();
|
||||
QVector<QgsPoint> points;
|
||||
points.reserve( values.count() );
|
||||
|
||||
for ( const QVariant &value : values )
|
||||
auto addPoint = [&points]( const QgsGeometry & geom )
|
||||
{
|
||||
QgsGeometry geom = QgsExpressionUtils::getGeometry( value, parent );
|
||||
if ( geom.isNull() )
|
||||
continue;
|
||||
return;
|
||||
|
||||
if ( geom.type() != QgsWkbTypes::PointGeometry || geom.isMultipart() )
|
||||
continue;
|
||||
return;
|
||||
|
||||
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.constGet() );
|
||||
if ( !point )
|
||||
continue;
|
||||
return;
|
||||
|
||||
lineString->addVertex( *point );
|
||||
points << *point;
|
||||
};
|
||||
|
||||
for ( const QVariant &value : values )
|
||||
{
|
||||
if ( value.type() == QVariant::List )
|
||||
{
|
||||
const QVariantList list = value.toList();
|
||||
for ( const QVariant &v : list )
|
||||
{
|
||||
addPoint( QgsExpressionUtils::getGeometry( v, parent ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addPoint( QgsExpressionUtils::getGeometry( value, parent ) );
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant::fromValue( QgsGeometry( lineString ) );
|
||||
if ( points.count() < 2 )
|
||||
return QVariant();
|
||||
|
||||
return QgsGeometry( new QgsLineString( points ) );
|
||||
}
|
||||
|
||||
static QVariant fcnMakePolygon( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
|
@ -994,6 +994,11 @@ class TestQgsExpression: public QObject
|
||||
QTest::newRow( "make_line" ) << "geom_to_wkt(make_line(make_point(2,4),make_point(4,6)))" << false << QVariant( "LineString (2 4, 4 6)" );
|
||||
QTest::newRow( "make_line" ) << "geom_to_wkt(make_line(make_point(2,4),make_point(4,6),make_point(7,9)))" << false << QVariant( "LineString (2 4, 4 6, 7 9)" );
|
||||
QTest::newRow( "make_line" ) << "geom_to_wkt(make_line(make_point(2,4,1,3),make_point(4,6,9,8),make_point(7,9,3,4)))" << false << QVariant( "LineStringZM (2 4 1 3, 4 6 9 8, 7 9 3 4)" );
|
||||
QTest::newRow( "make_line array" ) << "geom_to_wkt(make_line(array(make_point(2,4),make_point(4,6))))" << false << QVariant( "LineString (2 4, 4 6)" );
|
||||
QTest::newRow( "make_line one" ) << "geom_to_wkt(make_line(array(make_point(2,4))))" << false << QVariant();
|
||||
QTest::newRow( "make_line array mixed" ) << "geom_to_wkt(make_line(array(make_point(2,4),make_point(4,6)),make_point(8,9)))" << false << QVariant( "LineString (2 4, 4 6, 8 9)" );
|
||||
QTest::newRow( "make_line array bad" ) << "geom_to_wkt(make_line(array(make_point(2,4),66)))" << true << QVariant();
|
||||
QTest::newRow( "make_line array empty" ) << "geom_to_wkt(make_line(array()))" << false << QVariant();
|
||||
QTest::newRow( "make_polygon bad" ) << "make_polygon(make_point(2,4))" << false << QVariant();
|
||||
QTest::newRow( "make_polygon" ) << "geom_to_wkt(make_polygon(geom_from_wkt('LINESTRING( 0 0, 0 1, 1 1, 1 0, 0 0 )')))" << false << QVariant( "Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))" );
|
||||
QTest::newRow( "make_polygon rings" ) << "geom_to_wkt(make_polygon(geom_from_wkt('LINESTRING( 0 0, 0 1, 1 1, 1 0, 0 0 )'),geom_from_wkt('LINESTRING( 0.1 0.1, 0.1 0.2, 0.2 0.2, 0.2 0.1, 0.1 0.1 )'),geom_from_wkt('LINESTRING( 0.8 0.8, 0.8 0.9, 0.9 0.9, 0.9 0.8, 0.8 0.8 )')))" << false
|
||||
|
Loading…
x
Reference in New Issue
Block a user