mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[FEATURE] Add expression functions for converting to/from wkb
Adds geom_from_wkb and geom_to_wkb, which mirror the existing geom_from_wkt/geom_to_wkt functions but for WKB representations of geometries. Since QGIS 3.6 we've had good support for binary blob values in expressions and field values, so adding these functions allows users to work with binary blob fields containing WKB representations of geometries (e.g. with a geometry generator showing the encoded geometries)
This commit is contained in:
parent
13ead42f5e
commit
fed75afa95
7
resources/function_help/json/geom_from_wkb
Normal file
7
resources/function_help/json/geom_from_wkb
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "geom_from_wkb",
|
||||
"type": "function",
|
||||
"description": "Returns a geometry created from a Well-Known Binary (WKB) representation.",
|
||||
"arguments": [ {"arg":"binary","description":"Well-Known Binary (WKB) representation of a geometry (as a binary blob)"}],
|
||||
"examples": [ { "expression":"geom_from_wkb( geom_to_wkb( make_point(4,5) ) )", "returns":"a point geometry object"}]
|
||||
}
|
8
resources/function_help/json/geom_to_wkb
Normal file
8
resources/function_help/json/geom_to_wkb
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "geom_to_wkb",
|
||||
"type": "function",
|
||||
"description": "Returns the Well-Known Binary (WKB) representation of a geometry as a binary blob.",
|
||||
"arguments": [ {"arg":"geometry","description":"a geometry"}],
|
||||
"examples": [ { "expression":"geom_to_wkb( $geometry )", "returns":"binary blob containing a geometry object"}
|
||||
]
|
||||
}
|
@ -2812,6 +2812,7 @@ static QVariant fcnGeometry( const QVariantList &, const QgsExpressionContext *c
|
||||
else
|
||||
return QVariant( QVariant::UserType );
|
||||
}
|
||||
|
||||
static QVariant fcnGeomFromWKT( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QString wkt = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
|
||||
@ -2819,6 +2820,18 @@ static QVariant fcnGeomFromWKT( const QVariantList &values, const QgsExpressionC
|
||||
QVariant result = !geom.isNull() ? QVariant::fromValue( geom ) : QVariant();
|
||||
return result;
|
||||
}
|
||||
|
||||
static QVariant fcnGeomFromWKB( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
const QByteArray wkb = QgsExpressionUtils::getBinaryValue( values.at( 0 ), parent );
|
||||
if ( wkb.isNull() )
|
||||
return QVariant();
|
||||
|
||||
QgsGeometry geom;
|
||||
geom.fromWkb( wkb );
|
||||
return !geom.isNull() ? QVariant::fromValue( geom ) : QVariant();
|
||||
}
|
||||
|
||||
static QVariant fcnGeomFromGML( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QString gml = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
|
||||
@ -3448,6 +3461,7 @@ static QVariant fcnCombine( const QVariantList &values, const QgsExpressionConte
|
||||
QVariant result = !geom.isNull() ? QVariant::fromValue( geom ) : QVariant();
|
||||
return result;
|
||||
}
|
||||
|
||||
static QVariant fcnGeomToWKT( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
if ( values.length() < 1 || values.length() > 2 )
|
||||
@ -3461,6 +3475,12 @@ static QVariant fcnGeomToWKT( const QVariantList &values, const QgsExpressionCon
|
||||
return QVariant( wkt );
|
||||
}
|
||||
|
||||
static QVariant fcnGeomToWKB( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
return fGeom.isNull() ? QVariant() : QVariant( fGeom.asWkb() );
|
||||
}
|
||||
|
||||
static QVariant fcnAzimuth( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
if ( values.length() != 2 )
|
||||
@ -5486,6 +5506,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "y_min" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geom" ) ), fcnYMin, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false, QStringList() << QStringLiteral( "ymin" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "y_max" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geom" ) ), fcnYMax, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false, QStringList() << QStringLiteral( "ymax" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "geom_from_wkt" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "text" ) ), fcnGeomFromWKT, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false, QStringList() << QStringLiteral( "geomFromWKT" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "geom_from_wkb" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "binary" ) ), fcnGeomFromWKB, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "geom_from_gml" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "gml" ) ), fcnGeomFromGML, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false, QStringList() << QStringLiteral( "geomFromGML" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "flip_coordinates" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geom" ) ), fcnFlipCoordinates, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "relate" ), -1, fcnRelate, QStringLiteral( "GeometryGroup" ) )
|
||||
@ -5605,6 +5626,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "geometry2" ) ),
|
||||
fcnCombine, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "geom_to_wkt" ), -1, fcnGeomToWKT, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false, QStringList() << QStringLiteral( "geomToWKT" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "geom_to_wkb" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ), fcnGeomToWKB, QStringLiteral( "GeometryGroup" ), QString(), false, QSet<QString>(), false )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "geometry" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "feature" ) ), fcnGetGeometry, QStringLiteral( "GeometryGroup" ), QString(), true )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "transform" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geom" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "source_auth_id" ) )
|
||||
|
@ -188,6 +188,23 @@ class QgsExpressionUtils
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression value converted to binary (byte array) value.
|
||||
*
|
||||
* An empty byte array will be returned if the value is NULL.
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
static QByteArray getBinaryValue( const QVariant &value, QgsExpression *parent )
|
||||
{
|
||||
if ( value.type() != QVariant::ByteArray )
|
||||
{
|
||||
parent->setEvalErrorString( QObject::tr( "Value is not a binary value" ) );
|
||||
return QByteArray();
|
||||
}
|
||||
return value.toByteArray();
|
||||
}
|
||||
|
||||
static double getDoubleValue( const QVariant &value, QgsExpression *parent )
|
||||
{
|
||||
bool ok;
|
||||
|
@ -788,6 +788,10 @@ class TestQgsExpression: public QObject
|
||||
QTest::newRow( "Y coordinate to degree minute second" ) << "to_dms(6.3545681,'y',2)" << false << QVariant( "6°21′16.45″" );
|
||||
|
||||
// geometry functions
|
||||
QTest::newRow( "geom_to_wkb" ) << "geom_to_wkt(geom_from_wkb(geom_to_wkb(make_point(4,5))))" << false << QVariant( "Point (4 5)" );
|
||||
QTest::newRow( "geom_to_wkb not geom" ) << "geom_to_wkt(geom_from_wkb(geom_to_wkb('a')))" << true << QVariant();
|
||||
QTest::newRow( "geom_from_wkb not geom" ) << "geom_to_wkt(geom_from_wkb(make_point(4,5)))" << true << QVariant();
|
||||
QTest::newRow( "geom_from_wkb null" ) << "geom_to_wkt(geom_from_wkb(NULL))" << false << QVariant();
|
||||
QTest::newRow( "num_points" ) << "num_points(geom_from_wkt('GEOMETRYCOLLECTION(LINESTRING(0 0, 1 0),POINT(6 5))'))" << false << QVariant( 3 );
|
||||
QTest::newRow( "num_interior_rings not geom" ) << "num_interior_rings('g')" << true << QVariant();
|
||||
QTest::newRow( "num_interior_rings null" ) << "num_interior_rings(NULL)" << false << QVariant();
|
||||
|
Loading…
x
Reference in New Issue
Block a user