mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-07 00:15:48 -04:00
[FEATURE] line_substring function
Returns the portion of a line (or curve) geometry which falls between the specified start and end distances (measured from the beginning of the line). Z and M values are linearly interpolated from existing values. Fixes #15611
This commit is contained in:
parent
513bcb68e4
commit
a4386d6116
9
resources/function_help/json/line_substring
Normal file
9
resources/function_help/json/line_substring
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "line_substring",
|
||||
"type": "function",
|
||||
"description": "Returns the portion of a line (or curve) geometry which falls between the specified start and end distances (measured from the beginning of the line). Z and M values are linearly interpolated from existing values.",
|
||||
"arguments": [ {"arg":"geometry","description":"a linestring or curve geometry"},
|
||||
{"arg":"start_distance","description":"distance to start of substring"},
|
||||
{"arg":"end_distance","description":"distance to end of substring"}],
|
||||
"examples": [ { "expression":"geom_to_wkt(line_substring(geometry:=geom_from_wkt('LineString(0 0, 10 0)'),start_distance:=2,end_distance=6))", "returns":"'LineString (2 0,6 0)'"}]
|
||||
}
|
@ -3047,6 +3047,39 @@ static QVariant fcnLineInterpolatePoint( const QVariantList &values, const QgsEx
|
||||
return result;
|
||||
}
|
||||
|
||||
static QVariant fcnLineSubset( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
if ( lineGeom.type() != QgsWkbTypes::LineGeometry )
|
||||
{
|
||||
parent->setEvalErrorString( QObject::tr( "line_substring requires a curve geometry input" ) );
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const QgsCurve *curve = nullptr;
|
||||
if ( !lineGeom.isMultipart() )
|
||||
curve = qgsgeometry_cast< const QgsCurve * >( lineGeom.constGet() );
|
||||
else
|
||||
{
|
||||
if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( lineGeom.constGet() ) )
|
||||
{
|
||||
if ( collection->numGeometries() > 0 )
|
||||
{
|
||||
curve = qgsgeometry_cast< const QgsCurve * >( collection->geometryN( 0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !curve )
|
||||
return QVariant();
|
||||
|
||||
double startDistance = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
|
||||
double endDistance = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
|
||||
|
||||
std::unique_ptr< QgsCurve > substring( curve->curveSubstring( startDistance, endDistance ) );
|
||||
QgsGeometry result( std::move( substring ) );
|
||||
return !result.isNull() ? QVariant::fromValue( result ) : QVariant();
|
||||
}
|
||||
|
||||
static QVariant fcnLineInterpolateAngle( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry lineGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
@ -4527,7 +4560,9 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "angle_at_vertex" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "vertex" ) ), fcnAngleAtVertex, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "distance_to_vertex" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "vertex" ) ), fcnDistanceToVertex, QStringLiteral( "GeometryGroup" ) );
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "vertex" ) ), fcnDistanceToVertex, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "line_substring" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "start_distance" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "end_distance" ) ), fcnLineSubset, QStringLiteral( "GeometryGroup" ) );
|
||||
|
||||
|
||||
// **Record** functions
|
||||
|
@ -988,6 +988,10 @@ class TestQgsExpression: public QObject
|
||||
QTest::newRow( "distance_to_vertex null" ) << "distance_to_vertex(NULL, 0)" << false << QVariant();
|
||||
QTest::newRow( "distance_to_vertex point" ) << "distance_to_vertex(geom_from_wkt('POINT(1 2)'),0)" << false << QVariant( 0.0 );
|
||||
QTest::newRow( "distance_to_vertex line" ) << "distance_to_vertex(geometry:=geom_from_wkt('LineString(0 0, 10 0, 10 10)'),vertex:=1)" << false << QVariant( 10.0 );
|
||||
QTest::newRow( "line_substring not geom" ) << "line_substring('g', 5, 6)" << true << QVariant();
|
||||
QTest::newRow( "line_substring null" ) << "line_substring(NULL, 5, 6)" << false << QVariant();
|
||||
QTest::newRow( "line_substring point" ) << "line_substring(geom_from_wkt('POINT(1 2)'),5,6)" << true << QVariant();
|
||||
QTest::newRow( "line_substring line" ) << "geom_to_wkt(line_substring(geometry:=geom_from_wkt('LineString(0 0, 10 0)'),start_distance:=5,end_distance:=6))" << false << QVariant( "LineString (5 0, 6 0)" );
|
||||
QTest::newRow( "simplify not geom" ) << "simplify('g',5)" << true << QVariant();
|
||||
QTest::newRow( "simplify null" ) << "simplify(NULL,5)" << false << QVariant();
|
||||
QTest::newRow( "simplify point" ) << "geom_to_wkt(simplify(geom_from_wkt('POINT(1 2)'),10))" << false << QVariant( "Point (1 2)" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user